From 2ab4cecc64446fcdbaddf307a5efbf52707db985 Mon Sep 17 00:00:00 2001 From: Jacob Keeler Date: Tue, 27 Sep 2016 13:25:48 -0400 Subject: [PATCH 001/681] Add PLAY_PAUSE button name to all relevant tests --- files/OnAppregistered/connecttest.lua | 1 + files/connecttest_Navigation_Unsupported.lua | 1 + files/hmi_capabilities_SearchButton.json | 6 ++++++ files/hmi_capabilities_Without_PRESET9.json | 6 ++++++ .../API/ATF_BasicCommunication_OnReady.lua | 1 + ...OnButtonSubscription_if_subscription_failed.lua | 4 ++-- ...ButtonSubscription_if_unsubscription_failed.lua | 4 ++-- test_scripts/API/ATF_OnButtonEvent.lua | 5 ++++- test_scripts/API/ATF_OnButtonPress.lua | 5 ++++- test_scripts/API/ATF_OnButtonSubscription.lua | 4 ++-- test_scripts/API/ATF_OnScreenPresetsAvailable.lua | 2 ++ test_scripts/API/ATF_SetDisplayLayout.lua | 14 ++++++++++---- test_scripts/API/ATF_SubscribeButton.lua | 13 +++++++------ test_scripts/API/ATF_UnsubscribeButton.lua | 14 +++++++++----- test_scripts/API/ATF_VehicleInfo_IsReady.lua | 1 + test_scripts/ATF_Expanded_smoke_test_Genivi.lua | 7 +++++-- .../Capabilities/ATF_Buttons_GetCapabilities.lua | 12 ++++++++++-- .../ATF_Buttons_GetCapabilities_ButtonName.lua | 3 +++ .../ATF_No_Resumption_PersistentData.lua | 2 +- .../Resumption/ATF_Resumption_PersistentData.lua | 2 +- ...F_SubscribeButton_TOO_MANY_PENDING_REQUESTS.lua | 2 +- ...UnsubscribeButton_TOO_MANY_PENDING_REQUESTS.lua | 2 +- 22 files changed, 80 insertions(+), 31 deletions(-) diff --git a/files/OnAppregistered/connecttest.lua b/files/OnAppregistered/connecttest.lua index 43a8128f77..db8f523f0c 100644 --- a/files/OnAppregistered/connecttest.lua +++ b/files/OnAppregistered/connecttest.lua @@ -306,6 +306,7 @@ function module:InitHMI_onReady() button_capability("PRESET_8"), button_capability("PRESET_9"), button_capability("OK", true, false, true), + button_capability("PLAY_PAUSE"), button_capability("SEEKLEFT"), button_capability("SEEKRIGHT"), button_capability("TUNEUP"), diff --git a/files/connecttest_Navigation_Unsupported.lua b/files/connecttest_Navigation_Unsupported.lua index 5ad40d8e6f..4f8fddbf4b 100644 --- a/files/connecttest_Navigation_Unsupported.lua +++ b/files/connecttest_Navigation_Unsupported.lua @@ -452,6 +452,7 @@ function module:runSDL() button_capability("PRESET_8"), button_capability("PRESET_9"), button_capability("OK", true, false, true), + button_capability("PLAY_PAUSE"), button_capability("SEEKLEFT"), button_capability("SEEKRIGHT"), button_capability("TUNEUP"), diff --git a/files/hmi_capabilities_SearchButton.json b/files/hmi_capabilities_SearchButton.json index 1ae0822155..3e3cbb8e08 100644 --- a/files/hmi_capabilities_SearchButton.json +++ b/files/hmi_capabilities_SearchButton.json @@ -413,6 +413,12 @@ "longPressAvailable" :true, "upDownAvailable" :true }, + { + "name":"PLAY_PAUSE", + "shortPressAvailable":true, + "longPressAvailable" :true, + "upDownAvailable" :true + }, { "name":"SEEKLEFT", "shortPressAvailable":true, diff --git a/files/hmi_capabilities_Without_PRESET9.json b/files/hmi_capabilities_Without_PRESET9.json index 2309e84a15..ec9ef6210b 100644 --- a/files/hmi_capabilities_Without_PRESET9.json +++ b/files/hmi_capabilities_Without_PRESET9.json @@ -407,6 +407,12 @@ "longPressAvailable" :true, "upDownAvailable" :true }, + { + "name":"PLAY_PAUSE", + "shortPressAvailable":true, + "longPressAvailable" :true, + "upDownAvailable" :true + }, { "name":"SEEKLEFT", "shortPressAvailable":true, diff --git a/test_scripts/API/ATF_BasicCommunication_OnReady.lua b/test_scripts/API/ATF_BasicCommunication_OnReady.lua index c6bf3d4560..26989868fe 100644 --- a/test_scripts/API/ATF_BasicCommunication_OnReady.lua +++ b/test_scripts/API/ATF_BasicCommunication_OnReady.lua @@ -128,6 +128,7 @@ function Test:initHMI_BasicCommunication_OnReady_Invalid(case) button_capability("PRESET_8"), button_capability("PRESET_9"), button_capability("OK", true, false, true), + button_capability("PLAY_PAUSE"), button_capability("SEEKLEFT"), button_capability("SEEKRIGHT"), button_capability("TUNEUP"), diff --git a/test_scripts/API/ATF_No_OnButtonSubscription_if_subscription_failed.lua b/test_scripts/API/ATF_No_OnButtonSubscription_if_subscription_failed.lua index f3608bbb02..0923acf1dd 100644 --- a/test_scripts/API/ATF_No_OnButtonSubscription_if_subscription_failed.lua +++ b/test_scripts/API/ATF_No_OnButtonSubscription_if_subscription_failed.lua @@ -100,7 +100,7 @@ commonPreconditions:Connecttest_OnButtonSubscription("connecttest_OnButton.lua") if pattern2Result == nil then print(" \27[31m capabilities array is not found in /user_modules/connecttest_OnButton.lua \27[0m ") else - fileContent = string.gsub(fileContent, pattern2, '{capabilities = {button_capability("PRESET_0"),button_capability("PRESET_1"),button_capability("PRESET_2"),button_capability("PRESET_3"),button_capability("PRESET_4"),button_capability("PRESET_5"),button_capability("PRESET_6"),button_capability("PRESET_7"),button_capability("PRESET_8"),button_capability("PRESET_9"),button_capability("OK", true, false, true),button_capability("SEEKLEFT"),button_capability("SEEKRIGHT"),button_capability("TUNEUP"),button_capability("TUNEDOWN"),button_capability("CUSTOM_BUTTON")}') + fileContent = string.gsub(fileContent, pattern2, '{capabilities = {button_capability("PRESET_0"),button_capability("PRESET_1"),button_capability("PRESET_2"),button_capability("PRESET_3"),button_capability("PRESET_4"),button_capability("PRESET_5"),button_capability("PRESET_6"),button_capability("PRESET_7"),button_capability("PRESET_8"),button_capability("PRESET_9"),button_capability("OK", true, false, true),button_capability("PLAY_PAUSE"),button_capability("SEEKLEFT"),button_capability("SEEKRIGHT"),button_capability("TUNEUP"),button_capability("TUNEDOWN"),button_capability("CUSTOM_BUTTON")}') end f = assert(io.open('./user_modules/connecttest_OnButton.lua', "w+")) @@ -122,7 +122,7 @@ config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a config.defaultProtocolVersion = 2 local iTimeout = 5000 -local buttonName = {"OK","SEEKLEFT","SEEKRIGHT","TUNEUP","TUNEDOWN", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8"} +local buttonName = {"OK","PLAY_PAUSE","SEEKLEFT","SEEKRIGHT","TUNEUP","TUNEDOWN", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8"} local buttonNameNonMediaApp = {"OK", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8"} local UnsupportButtonName = {"PRESET_9", "SEARCH"} diff --git a/test_scripts/API/ATF_No_OnButtonSubscription_if_unsubscription_failed.lua b/test_scripts/API/ATF_No_OnButtonSubscription_if_unsubscription_failed.lua index 20aec67343..b47a704430 100644 --- a/test_scripts/API/ATF_No_OnButtonSubscription_if_unsubscription_failed.lua +++ b/test_scripts/API/ATF_No_OnButtonSubscription_if_unsubscription_failed.lua @@ -95,7 +95,7 @@ commonPreconditions:Connecttest_OnButtonSubscription("connecttest_OnButton.lua") if pattern2Result == nil then print(" \27[31m capabilities array is not found in /user_modules/connecttest_OnButton.lua \27[0m ") else - fileContent = string.gsub(fileContent, pattern2, '{capabilities = {button_capability("PRESET_0"),button_capability("PRESET_1"),button_capability("PRESET_2"),button_capability("PRESET_3"),button_capability("PRESET_4"),button_capability("PRESET_5"),button_capability("PRESET_6"),button_capability("PRESET_7"),button_capability("PRESET_8"),button_capability("PRESET_9"),button_capability("OK", true, false, true),button_capability("SEEKLEFT"),button_capability("SEEKRIGHT"),button_capability("TUNEUP"),button_capability("TUNEDOWN"),button_capability("CUSTOM_BUTTON")}') + fileContent = string.gsub(fileContent, pattern2, '{capabilities = {button_capability("PRESET_0"),button_capability("PRESET_1"),button_capability("PRESET_2"),button_capability("PRESET_3"),button_capability("PRESET_4"),button_capability("PRESET_5"),button_capability("PRESET_6"),button_capability("PRESET_7"),button_capability("PRESET_8"),button_capability("PRESET_9"),button_capability("OK", true, false, true),button_capability("PLAY_PAUSE"),button_capability("SEEKLEFT"),button_capability("SEEKRIGHT"),button_capability("TUNEUP"),button_capability("TUNEDOWN"),button_capability("CUSTOM_BUTTON")}') end f = assert(io.open('./user_modules/connecttest_OnButton.lua', "w+")) @@ -112,7 +112,7 @@ local file_connection = require('file_connection') local config = require('config') local iTimeout = 5000 -local buttonName = {"OK","SEEKLEFT","SEEKRIGHT","TUNEUP","TUNEDOWN", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8"} +local buttonName = {"OK","PLAY_PAUSE","SEEKLEFT","SEEKRIGHT","TUNEUP","TUNEDOWN", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8"} local buttonNameNonMediaApp = {"OK", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8"} local UnsupportButtonName = {"PRESET_9", "SEARCH"} diff --git a/test_scripts/API/ATF_OnButtonEvent.lua b/test_scripts/API/ATF_OnButtonEvent.lua index 2e3264cbbb..f19c9481fc 100644 --- a/test_scripts/API/ATF_OnButtonEvent.lua +++ b/test_scripts/API/ATF_OnButtonEvent.lua @@ -57,7 +57,7 @@ commonPreconditions:Connecttest_OnButtonSubscription("connecttest_OnButton.lua") if pattern2Result == nil then print(" \27[31m capabilities array is not found in /user_modules/connecttest_OnButton.lua \27[0m ") else - fileContent = string.gsub(fileContent, pattern2, '{capabilities = {button_capability("PRESET_0"),button_capability("PRESET_1"),button_capability("PRESET_2"),button_capability("PRESET_3"),button_capability("PRESET_4"),button_capability("PRESET_5"),button_capability("PRESET_6"),button_capability("PRESET_7"),button_capability("PRESET_8"),button_capability("PRESET_9"),button_capability("OK", true, false, true),button_capability("SEEKLEFT"),button_capability("SEEKRIGHT"),button_capability("TUNEUP"),button_capability("TUNEDOWN"),button_capability("SEARCH")}') + fileContent = string.gsub(fileContent, pattern2, '{capabilities = {button_capability("PRESET_0"),button_capability("PRESET_1"),button_capability("PRESET_2"),button_capability("PRESET_3"),button_capability("PRESET_4"),button_capability("PRESET_5"),button_capability("PRESET_6"),button_capability("PRESET_7"),button_capability("PRESET_8"),button_capability("PRESET_9"),button_capability("OK", true, false, true),button_capability("PLAY_PAUSE"),button_capability("SEEKLEFT"),button_capability("SEEKRIGHT"),button_capability("TUNEUP"),button_capability("TUNEDOWN"),button_capability("SEARCH")}') end f = assert(io.open('./user_modules/connecttest_OnButton.lua', "w+")) @@ -95,6 +95,7 @@ if config.application1.registerAppInterfaceParams.isMediaApplication then ButtonNames_WithoutCUSTOM_BUTTON = { "OK", + "PLAY_PAUSE", "SEEKLEFT", "SEEKRIGHT", "TUNEUP", @@ -113,6 +114,7 @@ if config.application1.registerAppInterfaceParams.isMediaApplication then } ButtonNames_WithoutCUSTOM_BUTTON_OK = { + "PLAY_PAUSE", "SEEKLEFT", "SEEKRIGHT", "TUNEUP", @@ -144,6 +146,7 @@ end -- group of media buttons, this group should be update also with PRESETS 0-9 due to APPLINK-14516 (APPLINK-14503) local MediaButtons = { + "PLAY_PAUSE", "SEEKLEFT", "SEEKRIGHT", "TUNEUP", diff --git a/test_scripts/API/ATF_OnButtonPress.lua b/test_scripts/API/ATF_OnButtonPress.lua index bd0bdda481..6045322096 100644 --- a/test_scripts/API/ATF_OnButtonPress.lua +++ b/test_scripts/API/ATF_OnButtonPress.lua @@ -25,7 +25,7 @@ commonPreconditions:Connecttest_OnButtonSubscription("connecttest_OnButton.lua") if pattern2Result == nil then print(" \27[31m capabilities array is not found in /user_modules/connecttest_OnButton.lua \27[0m ") else - fileContent = string.gsub(fileContent, pattern2, '{capabilities = {button_capability("PRESET_0"),button_capability("PRESET_1"),button_capability("PRESET_2"),button_capability("PRESET_3"),button_capability("PRESET_4"),button_capability("PRESET_5"),button_capability("PRESET_6"),button_capability("PRESET_7"),button_capability("PRESET_8"),button_capability("PRESET_9"),button_capability("OK", true, false, true),button_capability("SEEKLEFT"),button_capability("SEEKRIGHT"),button_capability("TUNEUP"),button_capability("TUNEDOWN"),button_capability("SEARCH")}') + fileContent = string.gsub(fileContent, pattern2, '{capabilities = {button_capability("PRESET_0"),button_capability("PRESET_1"),button_capability("PRESET_2"),button_capability("PRESET_3"),button_capability("PRESET_4"),button_capability("PRESET_5"),button_capability("PRESET_6"),button_capability("PRESET_7"),button_capability("PRESET_8"),button_capability("PRESET_9"),button_capability("OK", true, false, true),button_capability("PLAY_PAUSE"),button_capability("SEEKLEFT"),button_capability("SEEKRIGHT"),button_capability("TUNEUP"),button_capability("TUNEDOWN"),button_capability("SEARCH")}') end f = assert(io.open('./user_modules/connecttest_OnButton.lua', "w+")) @@ -65,6 +65,7 @@ if config.application1.registerAppInterfaceParams.isMediaApplication == true the ButtonNames_WithoutCUSTOM_BUTTON = { "OK", + "PLAY_PAUSE", "SEEKLEFT", "SEEKRIGHT", "TUNEUP", @@ -83,6 +84,7 @@ if config.application1.registerAppInterfaceParams.isMediaApplication == true the } ButtonNames_WithoutCUSTOM_BUTTON_OK = { + "PLAY_PAUSE", "SEEKLEFT", "SEEKRIGHT", "TUNEUP", @@ -115,6 +117,7 @@ end -- group of media buttons, this group should be update also with PRESETS 0-9 due to APPLINK-14516 (APPLINK-14503) local MediaButtons = { + "PLAY_PAUSE", "SEEKLEFT", "SEEKRIGHT", "TUNEUP", diff --git a/test_scripts/API/ATF_OnButtonSubscription.lua b/test_scripts/API/ATF_OnButtonSubscription.lua index 4d597e1efd..b5c4d30191 100644 --- a/test_scripts/API/ATF_OnButtonSubscription.lua +++ b/test_scripts/API/ATF_OnButtonSubscription.lua @@ -31,7 +31,7 @@ if pattern2Result == nil then print(" \27[31m capabilities array is not found in /user_modules/connecttest_OnButtonSubscription.lua \27[0m ") else - fileContent = string.gsub(fileContent, pattern2, '{capabilities = {button_capability("PRESET_0"),button_capability("PRESET_1"),button_capability("PRESET_2"),button_capability("PRESET_3"),button_capability("PRESET_4"),button_capability("PRESET_5"),button_capability("PRESET_6"),button_capability("PRESET_7"),button_capability("PRESET_8"),button_capability("PRESET_9"),button_capability("OK", true, false, true),button_capability("SEEKLEFT"),button_capability("SEEKRIGHT"),button_capability("TUNEUP"),button_capability("TUNEDOWN"),button_capability("CUSTOM_BUTTON")}') + fileContent = string.gsub(fileContent, pattern2, '{capabilities = {button_capability("PRESET_0"),button_capability("PRESET_1"),button_capability("PRESET_2"),button_capability("PRESET_3"),button_capability("PRESET_4"),button_capability("PRESET_5"),button_capability("PRESET_6"),button_capability("PRESET_7"),button_capability("PRESET_8"),button_capability("PRESET_9"),button_capability("OK", true, false, true),button_capability("PLAY_PAUSE"),button_capability("SEEKLEFT"),button_capability("SEEKRIGHT"),button_capability("TUNEUP"),button_capability("TUNEDOWN"),button_capability("CUSTOM_BUTTON")}') end f = assert(io.open('./user_modules/connecttest_OnButtonSubscription.lua', "w+")) @@ -65,7 +65,7 @@ local application = config.application2.registerAppInterfaceParams --Requirement id in JAMA/or Jira ID: APPLINK-20056 --Verification criteria: Described buttons are defined according to enum "ButtonName" in HMI API -local AllbuttonName = {"OK", "SEEKLEFT", "SEEKRIGHT", "TUNEUP", "TUNEDOWN", "PRESET_0", "PRESET_1", "PRESET_2", "PRESET_3", "PRESET_4", "PRESET_5", "PRESET_6", "PRESET_7", "PRESET_8"} +local AllbuttonName = {"OK", "PLAY_PAUSE", "SEEKLEFT", "SEEKRIGHT", "TUNEUP", "TUNEDOWN", "PRESET_0", "PRESET_1", "PRESET_2", "PRESET_3", "PRESET_4", "PRESET_5", "PRESET_6", "PRESET_7", "PRESET_8"} local NonMediaButton = {"OK"} --------------------------------------------------------------------------------------------- diff --git a/test_scripts/API/ATF_OnScreenPresetsAvailable.lua b/test_scripts/API/ATF_OnScreenPresetsAvailable.lua index 9ec996d2f5..89e3c45c69 100644 --- a/test_scripts/API/ATF_OnScreenPresetsAvailable.lua +++ b/test_scripts/API/ATF_OnScreenPresetsAvailable.lua @@ -222,6 +222,7 @@ function Test:initHMI_onReady(bOnScreenPresetsAvailable) button_capability("PRESET_8"), button_capability("PRESET_9"), button_capability("OK", true, false, true), + button_capability("PLAY_PAUSE"), button_capability("SEEKLEFT"), button_capability("SEEKRIGHT"), button_capability("TUNEUP"), @@ -843,6 +844,7 @@ end button_capability("PRESET_8"), button_capability("PRESET_9"), button_capability("OK", true, false, true), + button_capability("PLAY_PAUSE"), button_capability("SEEKLEFT"), button_capability("SEEKRIGHT"), button_capability("TUNEUP"), diff --git a/test_scripts/API/ATF_SetDisplayLayout.lua b/test_scripts/API/ATF_SetDisplayLayout.lua index 96e67024de..734c2c37a1 100644 --- a/test_scripts/API/ATF_SetDisplayLayout.lua +++ b/test_scripts/API/ATF_SetDisplayLayout.lua @@ -238,6 +238,12 @@ function butCap_Value() longPressAvailable = true, upDownAvailable = true }, + { + name = "PLAY_PAUSE", + shortPressAvailable = true, + longPressAvailable = true, + upDownAvailable = true + }, { name = "SEEKLEFT", shortPressAvailable = true, @@ -1953,7 +1959,7 @@ end :Timeout(iTimeout) :Do(function(_,data) --hmi side: sending UI.SetDisplayLayout response - self.hmiConnection:Send('{"id":' .. tostring(data.id) .. ',"result":{"softButtonCapabilities":[{"upDownAvailable":true,"longPressAvailable":true,"imageSupported":true,"shortPressAvailable":true}],"buttonCapabilities":[{"name":"PRESET_0","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_1","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_2","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_3","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_4","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_5","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_6","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_7","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_8","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_9","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"OK","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"SEEKLEFT","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"SEEKRIGHT","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"TUNEUP","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"TUNEDOWN","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true}],"presetBankCapabilities":{"onScreenPresetsAvailable":true},"displayCapabilities":{"displayType":"GEN2_8_DMA","screenParams":{"resolution":{"resolutionWidth":800,"resolutionHeight":480},"touchEventAvailable":{"doublePressAvailable":false,"multiTouchAvailable":true,"pressAvailable":true}},"textFields":[],"mediaClockFormats":["CLOCK1","CLOCK2","CLOCK3","CLOCKTEXT1","CLOCKTEXT2","CLOCKTEXT3","CLOCKTEXT4"],"imageCapabilities":["DYNAMIC","STATIC"],"templatesAvailable":["ONSCREEN_PRESETS"],"imageFields":[{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"softButtonImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"choiceImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"choiceSecondaryImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"vrHelpItem","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"turnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"menuIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"cmdIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"graphic","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTNextTurnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTNextTurnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]}],"numCustomPresetsAvailable":10,"graphicSupported":true},"code":0,"method":"UI.SetDisplayLayout"},"jsonrpc":"2.0"} ') + self.hmiConnection:Send('{"id":' .. tostring(data.id) .. ',"result":{"softButtonCapabilities":[{"upDownAvailable":true,"longPressAvailable":true,"imageSupported":true,"shortPressAvailable":true}],"buttonCapabilities":[{"name":"PRESET_0","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_1","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_2","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_3","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_4","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_5","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_6","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_7","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_8","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_9","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"OK","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PLAY_PAUSE","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"SEEKLEFT","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"SEEKRIGHT","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"TUNEUP","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"TUNEDOWN","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true}],"presetBankCapabilities":{"onScreenPresetsAvailable":true},"displayCapabilities":{"displayType":"GEN2_8_DMA","screenParams":{"resolution":{"resolutionWidth":800,"resolutionHeight":480},"touchEventAvailable":{"doublePressAvailable":false,"multiTouchAvailable":true,"pressAvailable":true}},"textFields":[],"mediaClockFormats":["CLOCK1","CLOCK2","CLOCK3","CLOCKTEXT1","CLOCKTEXT2","CLOCKTEXT3","CLOCKTEXT4"],"imageCapabilities":["DYNAMIC","STATIC"],"templatesAvailable":["ONSCREEN_PRESETS"],"imageFields":[{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"softButtonImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"choiceImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"choiceSecondaryImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"vrHelpItem","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"turnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"menuIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"cmdIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"graphic","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTNextTurnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTNextTurnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]}],"numCustomPresetsAvailable":10,"graphicSupported":true},"code":0,"method":"UI.SetDisplayLayout"},"jsonrpc":"2.0"} ') end) @@ -2526,7 +2532,7 @@ end :Timeout(iTimeout) :Do(function(_,data) --hmi side: sending UI.SetDisplayLayout response - self.hmiConnection:Send('{"id":' .. tostring(data.id) .. ',"result":{"softButtonCapabilities":[{"upDownAvailable":true,"longPressAvailable":true,"imageSupported":true,"shortPressAvailable":true}],"buttonCapabilities":[{"name":"PRESET_0","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_1","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_2","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_3","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_4","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_5","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_6","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_7","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_8","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_9","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"OK","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"SEEKLEFT","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"SEEKRIGHT","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"TUNEUP","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"TUNEDOWN","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true}],"presetBankCapabilities":{"onScreenPresetsAvailable":true},"displayCapabilities":{"displayType":"GEN2_8_DMA","screenParams":{"resolution":{"resolutionWidth":800,"resolutionHeight":480},"touchEventAvailable":{"doublePressAvailable":false,"multiTouchAvailable":true,"pressAvailable":true}},"textFields":[{"name":"mainField1","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mainField2","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mainField3","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mainField4","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"statusBar","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mediaClock","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mediaTrack","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"alertText1","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"alertText2","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"alertText3","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"scrollableMessageBody","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"initialInteractionText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"navigationText1","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"navigationText2","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"ETA","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"totalDistance","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"navigationText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"audioPassThruDisplayText1","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"audioPassThruDisplayText2","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"sliderHeader","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"sliderFooter","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"notificationText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"menuName","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"secondaryText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"tertiaryText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"timeToDestination","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"turnText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"menuTitle","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"locationName","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"locationDescription","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"addressLines","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"phoneNumber","characterSet":"TYPE2SET","width":500,"rows":1}],"mediaClockFormats":["CLOCK1","CLOCK2","CLOCK3","CLOCKTEXT1","CLOCKTEXT2","CLOCKTEXT3","CLOCKTEXT4"],"imageCapabilities":[],"templatesAvailable":["ONSCREEN_PRESETS"],"imageFields":[{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"softButtonImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"choiceImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"choiceSecondaryImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"vrHelpItem","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"turnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"menuIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"cmdIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"graphic","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTNextTurnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTNextTurnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]}],"numCustomPresetsAvailable":10,"graphicSupported":true},"code":0,"method":"UI.SetDisplayLayout"},"jsonrpc":"2.0"}') + self.hmiConnection:Send('{"id":' .. tostring(data.id) .. ',"result":{"softButtonCapabilities":[{"upDownAvailable":true,"longPressAvailable":true,"imageSupported":true,"shortPressAvailable":true}],"buttonCapabilities":[{"name":"PRESET_0","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_1","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_2","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_3","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_4","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_5","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_6","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_7","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_8","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_9","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"OK","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PLAY_PAUSE","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"SEEKLEFT","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"SEEKRIGHT","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"TUNEUP","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"TUNEDOWN","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true}],"presetBankCapabilities":{"onScreenPresetsAvailable":true},"displayCapabilities":{"displayType":"GEN2_8_DMA","screenParams":{"resolution":{"resolutionWidth":800,"resolutionHeight":480},"touchEventAvailable":{"doublePressAvailable":false,"multiTouchAvailable":true,"pressAvailable":true}},"textFields":[{"name":"mainField1","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mainField2","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mainField3","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mainField4","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"statusBar","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mediaClock","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mediaTrack","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"alertText1","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"alertText2","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"alertText3","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"scrollableMessageBody","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"initialInteractionText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"navigationText1","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"navigationText2","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"ETA","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"totalDistance","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"navigationText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"audioPassThruDisplayText1","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"audioPassThruDisplayText2","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"sliderHeader","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"sliderFooter","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"notificationText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"menuName","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"secondaryText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"tertiaryText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"timeToDestination","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"turnText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"menuTitle","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"locationName","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"locationDescription","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"addressLines","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"phoneNumber","characterSet":"TYPE2SET","width":500,"rows":1}],"mediaClockFormats":["CLOCK1","CLOCK2","CLOCK3","CLOCKTEXT1","CLOCKTEXT2","CLOCKTEXT3","CLOCKTEXT4"],"imageCapabilities":[],"templatesAvailable":["ONSCREEN_PRESETS"],"imageFields":[{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"softButtonImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"choiceImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"choiceSecondaryImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"vrHelpItem","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"turnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"menuIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"cmdIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"graphic","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTNextTurnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTNextTurnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]}],"numCustomPresetsAvailable":10,"graphicSupported":true},"code":0,"method":"UI.SetDisplayLayout"},"jsonrpc":"2.0"}') end) @@ -2768,7 +2774,7 @@ end :Timeout(iTimeout) :Do(function(_,data) --hmi side: sending UI.SetDisplayLayout response - self.hmiConnection:Send('{"id":' .. tostring(data.id) .. ',"result":{"softButtonCapabilities":[{"upDownAvailable":true,"longPressAvailable":true,"imageSupported":true,"shortPressAvailable":true}],"buttonCapabilities":[{"name":"PRESET_0","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_1","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_2","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_3","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_4","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_5","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_6","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_7","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_8","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_9","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"OK","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"SEEKLEFT","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"SEEKRIGHT","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"TUNEUP","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"TUNEDOWN","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true}],"presetBankCapabilities":{"onScreenPresetsAvailable":true},"displayCapabilities":{"displayType":"GEN2_8_DMA","screenParams":{"resolution":{"resolutionWidth":800,"resolutionHeight":480},"touchEventAvailable":{"doublePressAvailable":false,"multiTouchAvailable":true,"pressAvailable":true}},"textFields":[{"name":"mainField1","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mainField2","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mainField3","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mainField4","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"statusBar","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mediaClock","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mediaTrack","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"alertText1","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"alertText2","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"alertText3","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"scrollableMessageBody","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"initialInteractionText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"navigationText1","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"navigationText2","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"ETA","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"totalDistance","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"navigationText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"audioPassThruDisplayText1","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"audioPassThruDisplayText2","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"sliderHeader","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"sliderFooter","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"notificationText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"menuName","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"secondaryText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"tertiaryText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"timeToDestination","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"turnText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"menuTitle","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"locationName","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"locationDescription","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"addressLines","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"phoneNumber","characterSet":"TYPE2SET","width":500,"rows":1}],"mediaClockFormats":["CLOCK1","CLOCK2","CLOCK3","CLOCKTEXT1","CLOCKTEXT2","CLOCKTEXT3","CLOCKTEXT4"],"imageCapabilities":["DYNAMIC","STATIC"],"templatesAvailable":[],"imageFields":[{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"softButtonImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"choiceImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"choiceSecondaryImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"vrHelpItem","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"turnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"menuIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"cmdIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"graphic","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTNextTurnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTNextTurnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]}],"numCustomPresetsAvailable":10,"graphicSupported":true},"code":0,"method":"UI.SetDisplayLayout"},"jsonrpc":"2.0"} ') + self.hmiConnection:Send('{"id":' .. tostring(data.id) .. ',"result":{"softButtonCapabilities":[{"upDownAvailable":true,"longPressAvailable":true,"imageSupported":true,"shortPressAvailable":true}],"buttonCapabilities":[{"name":"PRESET_0","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_1","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_2","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_3","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_4","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_5","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_6","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_7","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_8","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PRESET_9","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"OK","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"PLAY_PAUSE","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"SEEKLEFT","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"SEEKRIGHT","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"TUNEUP","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"name":"TUNEDOWN","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true}],"presetBankCapabilities":{"onScreenPresetsAvailable":true},"displayCapabilities":{"displayType":"GEN2_8_DMA","screenParams":{"resolution":{"resolutionWidth":800,"resolutionHeight":480},"touchEventAvailable":{"doublePressAvailable":false,"multiTouchAvailable":true,"pressAvailable":true}},"textFields":[{"name":"mainField1","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mainField2","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mainField3","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mainField4","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"statusBar","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mediaClock","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"mediaTrack","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"alertText1","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"alertText2","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"alertText3","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"scrollableMessageBody","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"initialInteractionText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"navigationText1","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"navigationText2","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"ETA","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"totalDistance","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"navigationText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"audioPassThruDisplayText1","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"audioPassThruDisplayText2","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"sliderHeader","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"sliderFooter","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"notificationText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"menuName","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"secondaryText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"tertiaryText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"timeToDestination","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"turnText","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"menuTitle","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"locationName","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"locationDescription","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"addressLines","characterSet":"TYPE2SET","width":500,"rows":1},{"name":"phoneNumber","characterSet":"TYPE2SET","width":500,"rows":1}],"mediaClockFormats":["CLOCK1","CLOCK2","CLOCK3","CLOCKTEXT1","CLOCKTEXT2","CLOCKTEXT3","CLOCKTEXT4"],"imageCapabilities":["DYNAMIC","STATIC"],"templatesAvailable":[],"imageFields":[{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"softButtonImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"choiceImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"choiceSecondaryImage","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"vrHelpItem","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"turnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"menuIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"cmdIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"graphic","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTNextTurnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]},{"imageResolution":{"resolutionWidth":64,"resolutionHeight":64},"name":"showConstantTBTNextTurnIcon","imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"]}],"numCustomPresetsAvailable":10,"graphicSupported":true},"code":0,"method":"UI.SetDisplayLayout"},"jsonrpc":"2.0"} ') end) @@ -10820,7 +10826,7 @@ end }) - local message = '{"id":30,"jsonrpc":"2.0","result":{"buttonCapabilities":[{"longPressAvailable":true,"name":"PRESET_0","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_1","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_2","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_3","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_4","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_5","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_6","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_7","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_8","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_9","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"OK","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"SEEKLEFT","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"SEEKRIGHT","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"TUNEUP","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"TUNEDOWN","shortPressAvailable":true,"upDownAvailable":true}],"code" 0,"displayCapabilities":{"displayType":"GEN2_8_DMA","graphicSupported":true,"imageCapabilities":["DYNAMIC","STATIC"],"imageFields":[{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"softButtonImage"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"choiceImage"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"choiceSecondaryImage"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"vrHelpItem"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"turnIcon"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"menuIcon"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"cmdIcon"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"graphic"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"showConstantTBTIcon"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"showConstantTBTNextTurnIcon"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"showConstantTBTNextTurnIcon"}],"mediaClockFormats":["CLOCK1","CLOCK2","CLOCK3","CLOCKTEXT1","CLOCKTEXT2","CLOCKTEXT3","CLOCKTEXT4"],"numCustomPresetsAvailable":10,"screenParams":{"resolution":{"resolutionHeight":480,"resolutionWidth":800},"touchEventAvailable":{"doublePressAvailable":false,"multiTouchAvailable":true,"pressAvailable":true}},"templatesAvailable":["ONSCREEN_PRESETS"],"textFields":[{"characterSet":"TYPE2SET","name":"mainField1","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"mainField2","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"mainField3","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"mainField4","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"statusBar","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"mediaClock","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"mediaTrack","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"alertText1","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"alertText2","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"alertText3","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"scrollableMessageBody","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"initialInteractionText","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"navigationText1","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"navigationText2","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"ETA","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"totalDistance","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"navigationText","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"audioPassThruDisplayText1","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"audioPassThruDisplayText2","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"sliderHeader","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"sliderFooter","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"notificationText","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"menuName","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"secondaryText","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"tertiaryText","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"timeToDestination","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"turnText","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"menuTitle","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"locationName","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"locationDescription","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"addressLines","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"phoneNumber","rows":1,"width":500}]},"method":"UI.SetDisplayLayout","presetBankCapabilities":{"onScreenPresetsAvailable":true},"softButtonCapabilities":[{"imageSupported":true,"longPressAvailable":true,"shortPressAvailable":true,"upDownAvailable":true}]}}' + local message = '{"id":30,"jsonrpc":"2.0","result":{"buttonCapabilities":[{"longPressAvailable":true,"name":"PRESET_0","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_1","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_2","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_3","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_4","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_5","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_6","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_7","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_8","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"PRESET_9","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"OK","shortPressAvailable":true,"upDownAvailable":true},{"name":"PLAY_PAUSE","longPressAvailable":true,"upDownAvailable":true,"shortPressAvailable":true},{"longPressAvailable":true,"name":"SEEKLEFT","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"SEEKRIGHT","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"TUNEUP","shortPressAvailable":true,"upDownAvailable":true},{"longPressAvailable":true,"name":"TUNEDOWN","shortPressAvailable":true,"upDownAvailable":true}],"code" 0,"displayCapabilities":{"displayType":"GEN2_8_DMA","graphicSupported":true,"imageCapabilities":["DYNAMIC","STATIC"],"imageFields":[{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"softButtonImage"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"choiceImage"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"choiceSecondaryImage"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"vrHelpItem"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"turnIcon"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"menuIcon"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"cmdIcon"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"graphic"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"showConstantTBTIcon"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"showConstantTBTNextTurnIcon"},{"imageResolution":{"resolutionHeight":64,"resolutionWidth":64},"imageTypeSupported":["GRAPHIC_BMP","GRAPHIC_JPEG","GRAPHIC_PNG"],"name":"showConstantTBTNextTurnIcon"}],"mediaClockFormats":["CLOCK1","CLOCK2","CLOCK3","CLOCKTEXT1","CLOCKTEXT2","CLOCKTEXT3","CLOCKTEXT4"],"numCustomPresetsAvailable":10,"screenParams":{"resolution":{"resolutionHeight":480,"resolutionWidth":800},"touchEventAvailable":{"doublePressAvailable":false,"multiTouchAvailable":true,"pressAvailable":true}},"templatesAvailable":["ONSCREEN_PRESETS"],"textFields":[{"characterSet":"TYPE2SET","name":"mainField1","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"mainField2","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"mainField3","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"mainField4","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"statusBar","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"mediaClock","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"mediaTrack","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"alertText1","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"alertText2","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"alertText3","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"scrollableMessageBody","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"initialInteractionText","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"navigationText1","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"navigationText2","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"ETA","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"totalDistance","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"navigationText","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"audioPassThruDisplayText1","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"audioPassThruDisplayText2","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"sliderHeader","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"sliderFooter","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"notificationText","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"menuName","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"secondaryText","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"tertiaryText","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"timeToDestination","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"turnText","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"menuTitle","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"locationName","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"locationDescription","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"addressLines","rows":1,"width":500},{"characterSet":"TYPE2SET","name":"phoneNumber","rows":1,"width":500}]},"method":"UI.SetDisplayLayout","presetBankCapabilities":{"onScreenPresetsAvailable":true},"softButtonCapabilities":[{"imageSupported":true,"longPressAvailable":true,"shortPressAvailable":true,"upDownAvailable":true}]}}' --hmi side: expect UI.SetDisplayLayout request diff --git a/test_scripts/API/ATF_SubscribeButton.lua b/test_scripts/API/ATF_SubscribeButton.lua index 745cb71dd4..4d81cff02d 100644 --- a/test_scripts/API/ATF_SubscribeButton.lua +++ b/test_scripts/API/ATF_SubscribeButton.lua @@ -39,7 +39,7 @@ APIName = "SubscribeButton" -- set request name config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" local iTimeout = 5000 -local buttonName = {"OK","SEEKLEFT","SEEKRIGHT","TUNEUP","TUNEDOWN", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8"} +local buttonName = {"OK","PLAY_PAUSE","SEEKLEFT","SEEKRIGHT","TUNEUP","TUNEDOWN", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8"} local buttonNameNonMediaApp = {"OK", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8"} local UnsupportButtonName = {"PRESET_9", "SEARCH"} @@ -1066,10 +1066,11 @@ function RegisterAppInterface(self, appNumber) --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-538 --Verification criteria: - --1. SDL must return "resultCode: REJECTED, success: false" to SubscribeButton (SEEKLEFT) in case such RPC comes from non-media app. - --2. SDL must return "resultCode: REJECTED, success: false" to SubscribeButton (SEEKRIGHT) in case such RPC comes from non-media app. - --3. SDL must return "resultCode: REJECTED, success: false" to SubscribeButton (TUNEUP) in case such RPC comes from non-media app. - --4. SDL must return "resultCode: REJECTED, success: false" to SubscribeButton (TUNEDOWN) in case such RPC comes from non-media app. + --1. SDL must return "resultCode: REJECTED, success: false" to SubscribeButton (PLAY_PAUSE) in case such RPC comes from non-media app. + --2. SDL must return "resultCode: REJECTED, success: false" to SubscribeButton (SEEKLEFT) in case such RPC comes from non-media app. + --3. SDL must return "resultCode: REJECTED, success: false" to SubscribeButton (SEEKRIGHT) in case such RPC comes from non-media app. + --4. SDL must return "resultCode: REJECTED, success: false" to SubscribeButton (TUNEUP) in case such RPC comes from non-media app. + --5. SDL must return "resultCode: REJECTED, success: false" to SubscribeButton (TUNEDOWN) in case such RPC comes from non-media app. -- register non-media application 2 @@ -1083,7 +1084,7 @@ function RegisterAppInterface(self, appNumber) ActivateApplication(self, application2_nonmedia.registerAppInterfaceParams.appName) end - buttonName1 = {"SEEKLEFT", "SEEKRIGHT", "TUNEUP", "TUNEDOWN"} + buttonName1 = {"PLAY_PAUSE", "SEEKLEFT", "SEEKRIGHT", "TUNEUP", "TUNEDOWN"} for i=1,#buttonName1 do Test["SubscribeButton_resultCode_REJECTED_" .. tostring(buttonName1[i]).."_REJECTED"] = function(self) diff --git a/test_scripts/API/ATF_UnsubscribeButton.lua b/test_scripts/API/ATF_UnsubscribeButton.lua index 60c898813d..3088c837fe 100644 --- a/test_scripts/API/ATF_UnsubscribeButton.lua +++ b/test_scripts/API/ATF_UnsubscribeButton.lua @@ -15,7 +15,7 @@ local config = require('config') require('user_modules/AppTypes') local iTimeout = 5000 -local buttonName = {"OK","SEEKLEFT","SEEKRIGHT","TUNEUP","TUNEDOWN", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8"} +local buttonName = {"OK","PLAY_PAUSE","SEEKLEFT","SEEKRIGHT","TUNEUP","TUNEDOWN", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8"} local buttonNameNonMediaApp = {"OK", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8"} local UnsupportButtonName = {"PRESET_9", "SEARCH"} @@ -132,7 +132,8 @@ local function Precondition_TC_SubscribeButton(self, btnName) return true elseif self.isMediaApplication == false and - (btnName == "SEEKLEFT" or + (btnName == "PLAY_PAUSE" or + btnName == "SEEKLEFT" or btnName == "SEEKRIGHT" or btnName == "TUNEUP" or btnName == "TUNEDOWN") then @@ -232,7 +233,8 @@ local function TC_UnsubscribeButtonSUCCESS(self, btnName, strTestCaseName) if self.isMediaApplication == false and - (btnName == "SEEKLEFT" or + (btnName == "PLAY_PAUSE" or + btnName == "SEEKLEFT" or btnName == "SEEKRIGHT" or btnName == "TUNEUP" or btnName == "TUNEDOWN") then @@ -473,7 +475,8 @@ function RegisterAppInterface(self, appNumber) if self.isMediaApplication == false and - (buttonName[i] == "SEEKLEFT" or + (buttonName[i] == "PLAY_PAUSE" or + buttonName[i] == "SEEKLEFT" or buttonName[i] == "SEEKRIGHT" or buttonName[i] == "TUNEUP" or buttonName[i] == "TUNEDOWN") then @@ -537,7 +540,8 @@ function RegisterAppInterface(self, appNumber) if self.isMediaApplication == false and - (buttonName[i] == "SEEKLEFT" or + (buttonName[i] == "PLAY_PAUSE" or + buttonName[i] == "SEEKLEFT" or buttonName[i] == "SEEKRIGHT" or buttonName[i] == "TUNEUP" or buttonName[i] == "TUNEDOWN") then diff --git a/test_scripts/API/ATF_VehicleInfo_IsReady.lua b/test_scripts/API/ATF_VehicleInfo_IsReady.lua index 7df09f1747..19c1433558 100644 --- a/test_scripts/API/ATF_VehicleInfo_IsReady.lua +++ b/test_scripts/API/ATF_VehicleInfo_IsReady.lua @@ -171,6 +171,7 @@ function Test:initHMI_onReady_VehicleinfoIsReady(method1, resultCode, params1, c button_capability("PRESET_8"), button_capability("PRESET_9"), button_capability("OK", true, false, true), + button_capability("PLAY_PAUSE"), button_capability("SEEKLEFT"), button_capability("SEEKRIGHT"), button_capability("TUNEUP"), diff --git a/test_scripts/ATF_Expanded_smoke_test_Genivi.lua b/test_scripts/ATF_Expanded_smoke_test_Genivi.lua index f272cf7e7d..46308af254 100644 --- a/test_scripts/ATF_Expanded_smoke_test_Genivi.lua +++ b/test_scripts/ATF_Expanded_smoke_test_Genivi.lua @@ -35,7 +35,7 @@ config.SDLStoragePath = config.pathToSDL .. "storage/" config.sharedMemoryPath = "" local dif_fileType = {{typeV = "GRAPHIC_BMP", file = "files/PutFile/bmp_6kb.bmp" }, {typeV = "GRAPHIC_JPEG", file = "files/PutFile/jpeg_4kb.jpg" }, {typeV = "GRAPHIC_PNG", file = "files/PutFile/icon.png" }, {typeV = "AUDIO_WAVE", file = "files/PutFile/WAV_6kb.wav" }, {typeV = "AUDIO_MP3", file = "files/PutFile/MP3_123kb.mp3" }, {typeV = "AUDIO_AAC", file = "files/PutFile/Alarm.aac" }, {typeV = "BINARY", file = "files/PutFile/binaryFile" }, {typeV = "JSON", file = "files/PutFile/luxoftPT.json" }} -local ButtonArray = {"OK","SEEKLEFT", "SEEKRIGHT", "TUNEUP", "TUNEDOWN", "PRESET_0", "PRESET_1", "PRESET_2", "PRESET_3", "PRESET_4", "PRESET_5", "PRESET_6", "PRESET_7", "PRESET_8", "PRESET_9"} +local ButtonArray = {"OK","PLAY_PAUSE","SEEKLEFT", "SEEKRIGHT", "TUNEUP", "TUNEDOWN", "PRESET_0", "PRESET_1", "PRESET_2", "PRESET_3", "PRESET_4", "PRESET_5", "PRESET_6", "PRESET_7", "PRESET_8", "PRESET_9"} -------------------------------------------------------------------------------------------- @@ -51,7 +51,7 @@ local PathToAppFolder = config.pathToSDL .. SDLConfig:GetValue("AppStorageFolder local updateModeNotRequireStartEndTime = {"PAUSE", "RESUME", "CLEAR"} local updateMode = {"COUNTUP", "COUNTDOWN", "PAUSE", "RESUME", "CLEAR"} local updateModeCountUpDown = {"COUNTUP", "COUNTDOWN"} -local buttonName = {"OK","SEEKLEFT","SEEKRIGHT","TUNEUP","TUNEDOWN", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8"} +local buttonName = {"OK","PLAY_PAUSE","SEEKLEFT","SEEKRIGHT","TUNEUP","TUNEDOWN", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8"} local PositiveChoiceSets local textPromtValue = {"Please speak one of the following commands," ,"Please say a command,"} @@ -6729,6 +6729,7 @@ end EXPECT_NOTIFICATION("OnHashChange") else if + ButtonArray[i] == "PLAY_PAUSE" or ButtonArray[i] == "SEEKLEFT" or ButtonArray[i] == "SEEKRIGHT" or ButtonArray[i] == "TUNEUP" or @@ -6797,6 +6798,7 @@ end self.mobileSession:ExpectResponse(cid, { success = false, resultCode = "IGNORED"}) else if + ButtonArray[i] == "PLAY_PAUSE" or ButtonArray[i] == "SEEKLEFT" or ButtonArray[i] == "SEEKRIGHT" or ButtonArray[i] == "TUNEUP" or @@ -6864,6 +6866,7 @@ end EXPECT_NOTIFICATION("OnHashChange") else if + ButtonArray[i] == "PLAY_PAUSE" or ButtonArray[i] == "SEEKLEFT" or ButtonArray[i] == "SEEKRIGHT" or ButtonArray[i] == "TUNEUP" or diff --git a/test_scripts/Capabilities/ATF_Buttons_GetCapabilities.lua b/test_scripts/Capabilities/ATF_Buttons_GetCapabilities.lua index 4dfa053995..12a3778c72 100644 --- a/test_scripts/Capabilities/ATF_Buttons_GetCapabilities.lua +++ b/test_scripts/Capabilities/ATF_Buttons_GetCapabilities.lua @@ -26,13 +26,14 @@ local ButtonNames_NoCUSTOM_BUTTON local ButtonNames_NoCUSTOM_BUTTON_OK if config.application1.registerAppInterfaceParams.isMediaApplication then - ButtonNames_NoCUSTOM_BUTTON = {"OK","SEEKLEFT","SEEKRIGHT", "TUNEUP", "TUNEDOWN","PRESET_0", "PRESET_1", "PRESET_2", "PRESET_3", "PRESET_4", "PRESET_5", "PRESET_6", "PRESET_7", "PRESET_8", "PRESET_9", "SEARCH"} + ButtonNames_NoCUSTOM_BUTTON = {"OK","PLAY_PAUSE","SEEKLEFT","SEEKRIGHT", "TUNEUP", "TUNEDOWN","PRESET_0", "PRESET_1", "PRESET_2", "PRESET_3", "PRESET_4", "PRESET_5", "PRESET_6", "PRESET_7", "PRESET_8", "PRESET_9", "SEARCH"} - ButtonNames_NoCUSTOM_BUTTON_OK = {"SEEKLEFT","SEEKRIGHT", "TUNEUP", "TUNEDOWN", "PRESET_0", "PRESET_1", "PRESET_2", "PRESET_3", "PRESET_4", "PRESET_5", "PRESET_6", "PRESET_7", "PRESET_8", "PRESET_9", "SEARCH"} + ButtonNames_NoCUSTOM_BUTTON_OK = {"PLAY_PAUSE","SEEKLEFT","SEEKRIGHT", "TUNEUP", "TUNEDOWN", "PRESET_0", "PRESET_1", "PRESET_2", "PRESET_3", "PRESET_4", "PRESET_5", "PRESET_6", "PRESET_7", "PRESET_8", "PRESET_9", "SEARCH"} -- group of media buttons, this group should be updated with PRESETS 0-9 due to APPLINK-14516 (APPLINK-14503) MediaButtons = { + "PLAY_PAUSE", "SEEKLEFT", "SEEKRIGHT", "TUNEUP", @@ -84,6 +85,7 @@ local Input_Timeoutcapabilities = button_capability("PRESET_8"), button_capability("PRESET_9"), button_capability("OK", true, false, true), + button_capability("PLAY_PAUSE"), button_capability("SEEKLEFT"), button_capability("SEEKRIGHT"), button_capability("TUNEUP"), @@ -110,6 +112,7 @@ local Input_ButtonsCapabilities_RAI = button_capability("PRESET_8"), button_capability("PRESET_9"), button_capability("OK", true, false, true), + button_capability("PLAY_PAUSE"), button_capability("SEEKLEFT"), button_capability("SEEKRIGHT"), button_capability("TUNEUP"), @@ -603,6 +606,7 @@ local function HMI_Send_Button_GetCapabilities_Response_Timeout(Input_Timeoutcap button_capability("PRESET_8"), button_capability("PRESET_9"), button_capability("OK", true, false, true), + button_capability("PLAY_PAUSE"), button_capability("SEEKLEFT"), button_capability("SEEKRIGHT"), button_capability("TUNEUP"), @@ -888,6 +892,7 @@ local function HMI_Send_Button_GetCapabilities_Response_Invalid() button_capability("PRESET_8"), button_capability("PRESET_9"), button_capability("OK", true, false, true), + button_capability("PLAY_PAUSE"), button_capability("SEEKLEFT"), button_capability("SEEKRIGHT"), button_capability("TUNEUP"), @@ -1195,6 +1200,7 @@ stopSDL() --APPLINK-20199: [HMI API]Buttons.GetCapabilities request/response --Description: Defines the hard (physical) and soft (touchscreen) buttons available from SYNC --OK + --PLAY_PAUSE --SEEKLEFT --SEEKRIGHT --TUNEUP @@ -1240,6 +1246,7 @@ stopSDL() button_capability("PRESET_8"), button_capability("PRESET_9"), button_capability("OK", true, false, true), + button_capability("PLAY_PAUSE"), button_capability("SEEKLEFT"), button_capability("SEEKRIGHT"), button_capability("TUNEUP"), @@ -1270,6 +1277,7 @@ stopSDL() button_capability("PRESET_8"), button_capability("PRESET_9"), button_capability("OK", true, false, true), + button_capability("PLAY_PAUSE"), button_capability("SEEKLEFT"), button_capability("SEEKRIGHT"), button_capability("TUNEUP"), diff --git a/test_scripts/Capabilities/ATF_Buttons_GetCapabilities_ButtonName.lua b/test_scripts/Capabilities/ATF_Buttons_GetCapabilities_ButtonName.lua index b7c209b62c..3af56da813 100644 --- a/test_scripts/Capabilities/ATF_Buttons_GetCapabilities_ButtonName.lua +++ b/test_scripts/Capabilities/ATF_Buttons_GetCapabilities_ButtonName.lua @@ -34,6 +34,7 @@ local ButtonNames = { "PRESET_8", "PRESET_9", "OK", + "PLAY_PAUSE", "SEEKLEFT", "SEEKRIGHT", "TUNEUP", @@ -413,6 +414,7 @@ stopSDL() --SDLAQ-N_CRS-148: ButtonName --Description: Defines the hard (physical) and soft (touchscreen) buttons available from SYNC --OK + --PLAY_PAUSE --SEEKLEFT --SEEKRIGHT --TUNEUP @@ -457,6 +459,7 @@ stopSDL() button_capability("PRESET_8"), button_capability("PRESET_9"), button_capability("OK", true, false, true), + button_capability("PLAY_PAUSE"), button_capability("SEEKLEFT"), button_capability("SEEKRIGHT"), button_capability("TUNEUP"), diff --git a/test_scripts/Resumption/ATF_No_Resumption_PersistentData.lua b/test_scripts/Resumption/ATF_No_Resumption_PersistentData.lua index ddaecae91d..666dc84e17 100644 --- a/test_scripts/Resumption/ATF_No_Resumption_PersistentData.lua +++ b/test_scripts/Resumption/ATF_No_Resumption_PersistentData.lua @@ -103,7 +103,7 @@ local applicationData = if pattern2Result == nil then print(" \27[31m capabilities array is not found in /user_modules/connecttest_OnButtonSubscription.lua \27[0m ") else - fileContent = string.gsub(fileContent, pattern2, '{capabilities = {button_capability("PRESET_0"),button_capability("PRESET_1"),button_capability("PRESET_2"),button_capability("PRESET_3"),button_capability("PRESET_4"),button_capability("PRESET_5"),button_capability("PRESET_6"),button_capability("PRESET_7"),button_capability("PRESET_8"),button_capability("PRESET_9"),button_capability("OK", true, false, true),button_capability("SEEKLEFT"),button_capability("SEEKRIGHT"),button_capability("TUNEUP"),button_capability("TUNEDOWN"),button_capability("CUSTOM_BUTTON")}') + fileContent = string.gsub(fileContent, pattern2, '{capabilities = {button_capability("PRESET_0"),button_capability("PRESET_1"),button_capability("PRESET_2"),button_capability("PRESET_3"),button_capability("PRESET_4"),button_capability("PRESET_5"),button_capability("PRESET_6"),button_capability("PRESET_7"),button_capability("PRESET_8"),button_capability("PRESET_9"),button_capability("OK", true, false, true),button_capability("PLAY_PAUSE"),button_capability("SEEKLEFT"),button_capability("SEEKRIGHT"),button_capability("TUNEUP"),button_capability("TUNEDOWN"),button_capability("CUSTOM_BUTTON")}') end f = assert(io.open('./user_modules/connecttest_OnButtonSubscription.lua', "w+")) diff --git a/test_scripts/Resumption/ATF_Resumption_PersistentData.lua b/test_scripts/Resumption/ATF_Resumption_PersistentData.lua index f0ca54256e..7d4e8e03a1 100644 --- a/test_scripts/Resumption/ATF_Resumption_PersistentData.lua +++ b/test_scripts/Resumption/ATF_Resumption_PersistentData.lua @@ -74,7 +74,7 @@ local json = require("json") if pattern2Result == nil then print(" \27[31m capabilities array is not found in /user_modules/connecttest_OnButtonSubscription.lua \27[0m ") else - fileContent = string.gsub(fileContent, pattern2, '{capabilities = {button_capability("PRESET_0"),button_capability("PRESET_1"),button_capability("PRESET_2"),button_capability("PRESET_3"),button_capability("PRESET_4"),button_capability("PRESET_5"),button_capability("PRESET_6"),button_capability("PRESET_7"),button_capability("PRESET_8"),button_capability("PRESET_9"),button_capability("OK", true, false, true),button_capability("SEEKLEFT"),button_capability("SEEKRIGHT"),button_capability("TUNEUP"),button_capability("TUNEDOWN"),button_capability("CUSTOM_BUTTON")}') + fileContent = string.gsub(fileContent, pattern2, '{capabilities = {button_capability("PRESET_0"),button_capability("PRESET_1"),button_capability("PRESET_2"),button_capability("PRESET_3"),button_capability("PRESET_4"),button_capability("PRESET_5"),button_capability("PRESET_6"),button_capability("PRESET_7"),button_capability("PRESET_8"),button_capability("PRESET_9"),button_capability("OK", true, false, true),button_capability("PLAY_PAUSE"),button_capability("SEEKLEFT"),button_capability("SEEKRIGHT"),button_capability("TUNEUP"),button_capability("TUNEDOWN"),button_capability("CUSTOM_BUTTON")}') end f = assert(io.open('./user_modules/connecttest_OnButtonSubscription.lua', "w+")) diff --git a/test_scripts/TOO_MANY_PENDING_REQUESTS/ATF_SubscribeButton_TOO_MANY_PENDING_REQUESTS.lua b/test_scripts/TOO_MANY_PENDING_REQUESTS/ATF_SubscribeButton_TOO_MANY_PENDING_REQUESTS.lua index 4159f50652..0b9a3ad345 100644 --- a/test_scripts/TOO_MANY_PENDING_REQUESTS/ATF_SubscribeButton_TOO_MANY_PENDING_REQUESTS.lua +++ b/test_scripts/TOO_MANY_PENDING_REQUESTS/ATF_SubscribeButton_TOO_MANY_PENDING_REQUESTS.lua @@ -68,7 +68,7 @@ SetPendingRequestsAmountto2() --Script cheks TOO_MANY_PENDING_REQUEST resultCode in SubscribeButton response from SDL --///////////////////////////////////////////////////////////////////////////-- -local buttonName = {"OK","SEEKLEFT","SEEKRIGHT","TUNEUP","TUNEDOWN", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8","PRESET_9"} +local buttonName = {"OK","PLAY_PAUSE","SEEKLEFT","SEEKRIGHT","TUNEUP","TUNEDOWN", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8","PRESET_9"} diff --git a/test_scripts/TOO_MANY_PENDING_REQUESTS/ATF_UnsubscribeButton_TOO_MANY_PENDING_REQUESTS.lua b/test_scripts/TOO_MANY_PENDING_REQUESTS/ATF_UnsubscribeButton_TOO_MANY_PENDING_REQUESTS.lua index faedf46b63..ea81983326 100644 --- a/test_scripts/TOO_MANY_PENDING_REQUESTS/ATF_UnsubscribeButton_TOO_MANY_PENDING_REQUESTS.lua +++ b/test_scripts/TOO_MANY_PENDING_REQUESTS/ATF_UnsubscribeButton_TOO_MANY_PENDING_REQUESTS.lua @@ -68,7 +68,7 @@ SetPendingRequestsAmountto3() --Script cheks TOO_MANY_PENDING_REQUEST resultCode in UnsubscribeButton response from SDL --///////////////////////////////////////////////////////////////////////////-- -local buttonName = {"OK","SEEKLEFT","SEEKRIGHT","TUNEUP","TUNEDOWN", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8","PRESET_9"} +local buttonName = {"OK","PLAY_PAUSE","SEEKLEFT","SEEKRIGHT","TUNEUP","TUNEDOWN", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8","PRESET_9"} From eec0b1354c892db9796eb1cd11a165b9444e2eab Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 7 Jul 2017 16:27:48 +0300 Subject: [PATCH 002/681] Initial version --- test_scripts/RC/ButtonPress/001.lua | 63 +++ test_scripts/RC/ButtonPress/002c.lua | 39 ++ test_scripts/RC/ButtonPress/002r.lua | 39 ++ test_scripts/RC/ButtonPress/003.lua | 55 +++ .../RC/GetInteriorVehicleData/001.lua | 81 ++++ .../RC/GetInteriorVehicleData/002c.lua | 40 ++ .../RC/GetInteriorVehicleData/002r.lua | 40 ++ .../RC/GetInteriorVehicleData/003.lua | 57 +++ .../001.lua | 51 +++ .../002.lua | 47 +++ .../003.lua | 47 +++ .../004.lua | 36 ++ .../005.lua | 36 ++ .../006.lua | 40 ++ .../007.lua | 43 +++ .../008.lua | 45 +++ .../009.lua | 37 ++ .../010.lua | 30 ++ .../011.lua | 40 ++ .../012.lua | 37 ++ .../099_not_completed.lua | 59 +++ test_scripts/RC/OnInteriorVehicleData/001.lua | 153 ++++++++ .../RC/OnInteriorVehicleData/001b.lua | 114 ++++++ .../RC/OnInteriorVehicleData/002c.lua | 70 ++++ .../RC/OnInteriorVehicleData/002r.lua | 70 ++++ .../RC/SetInteriorVehicleData/001.lua | 79 ++++ .../RC/SetInteriorVehicleData/002c.lua | 40 ++ .../RC/SetInteriorVehicleData/002r.lua | 40 ++ .../RC/SetInteriorVehicleData/003.lua | 57 +++ test_scripts/RC/commonRC.lua | 362 ++++++++++++++++++ .../rc_GetInteriorVehicleDataCapabilities.txt | 12 + user_modules/script_runner.lua | 94 +++++ 32 files changed, 2053 insertions(+) create mode 100644 test_scripts/RC/ButtonPress/001.lua create mode 100644 test_scripts/RC/ButtonPress/002c.lua create mode 100644 test_scripts/RC/ButtonPress/002r.lua create mode 100644 test_scripts/RC/ButtonPress/003.lua create mode 100644 test_scripts/RC/GetInteriorVehicleData/001.lua create mode 100644 test_scripts/RC/GetInteriorVehicleData/002c.lua create mode 100644 test_scripts/RC/GetInteriorVehicleData/002r.lua create mode 100644 test_scripts/RC/GetInteriorVehicleData/003.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/001.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/002.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/003.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/004.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/005.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/006.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/007.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/008.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/009.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/010.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/011.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/012.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/099_not_completed.lua create mode 100644 test_scripts/RC/OnInteriorVehicleData/001.lua create mode 100644 test_scripts/RC/OnInteriorVehicleData/001b.lua create mode 100644 test_scripts/RC/OnInteriorVehicleData/002c.lua create mode 100644 test_scripts/RC/OnInteriorVehicleData/002r.lua create mode 100644 test_scripts/RC/SetInteriorVehicleData/001.lua create mode 100644 test_scripts/RC/SetInteriorVehicleData/002c.lua create mode 100644 test_scripts/RC/SetInteriorVehicleData/002r.lua create mode 100644 test_scripts/RC/SetInteriorVehicleData/003.lua create mode 100644 test_scripts/RC/commonRC.lua create mode 100644 test_sets/rc_GetInteriorVehicleDataCapabilities.txt create mode 100644 user_modules/script_runner.lua diff --git a/test_scripts/RC/ButtonPress/001.lua b/test_scripts/RC/ButtonPress/001.lua new file mode 100644 index 0000000000..fcad59566a --- /dev/null +++ b/test_scripts/RC/ButtonPress/001.lua @@ -0,0 +1,63 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: ButtonPress +-- Script: 001 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("ButtonPress", { + zone = commonRC.getInteriorZone(), + moduleType = "CLIMATE", + buttonName = "AC", + buttonPressMode = "SHORT" + }) + + EXPECT_HMICALL("Buttons.ButtonPress", { + appID = self.applications["Test Application"], + zone = commonRC.getInteriorZone(), + moduleType = "CLIMATE", + buttonName = "AC", + buttonPressMode = "SHORT" + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function step2(self) + local cid = self.mobileSession:SendRPC("ButtonPress", { + zone = commonRC.getInteriorZone(), + moduleType = "RADIO", + buttonName = "VOLUME_UP", + buttonPressMode = "LONG" + }) + + EXPECT_HMICALL("Buttons.ButtonPress", { + appID = self.applications["Test Application"], + zone = commonRC.getInteriorZone(), + moduleType = "RADIO", + buttonName = "VOLUME_UP", + buttonPressMode = "LONG" + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("ButtonPress_CLIMATE", step1) +runner.Step("ButtonPress_RADIO", step2) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/ButtonPress/002c.lua b/test_scripts/RC/ButtonPress/002c.lua new file mode 100644 index 0000000000..42fd23fcd9 --- /dev/null +++ b/test_scripts/RC/ButtonPress/002c.lua @@ -0,0 +1,39 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: ButtonPress +-- Script: 002 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("ButtonPress", { + zone = commonRC.getInteriorZone(), + moduleType = "CLIMATE", + buttonName = "AC", + buttonPressMode = "SHORT" + }) + + EXPECT_HMICALL("Buttons.ButtonPress") + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Title("Test") +runner.Step("ButtonPress_CLIMATE", step1) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/ButtonPress/002r.lua b/test_scripts/RC/ButtonPress/002r.lua new file mode 100644 index 0000000000..ed7d8a7008 --- /dev/null +++ b/test_scripts/RC/ButtonPress/002r.lua @@ -0,0 +1,39 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: ButtonPress +-- Script: 002 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("ButtonPress", { + zone = commonRC.getInteriorZone(), + moduleType = "RADIO", + buttonName = "VOLUME_UP", + buttonPressMode = "LONG" + }) + + EXPECT_HMICALL("Buttons.ButtonPress") + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Title("Test") +runner.Step("ButtonPress_RADIO", step1) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/ButtonPress/003.lua b/test_scripts/RC/ButtonPress/003.lua new file mode 100644 index 0000000000..e5af93f72e --- /dev/null +++ b/test_scripts/RC/ButtonPress/003.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: ButtonPress +-- Script: 003 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("ButtonPress", { + zone = commonRC.getInteriorZone(), + moduleType = "CLIMATE", + buttonName = "AC", + buttonPressMode = "SHORT" + }) + + EXPECT_HMICALL("Buttons.ButtonPress") + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function step2(self) + local cid = self.mobileSession:SendRPC("ButtonPress", { + zone = commonRC.getInteriorZone(), + moduleType = "RADIO", + buttonName = "VOLUME_UP", + buttonPressMode = "LONG" + }) + + EXPECT_HMICALL("Buttons.ButtonPress") + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("ButtonPress_CLIMATE", step1) +runner.Step("ButtonPress_RADIO", step2) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/001.lua b/test_scripts/RC/GetInteriorVehicleData/001.lua new file mode 100644 index 0000000000..2a429907d4 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleData/001.lua @@ -0,0 +1,81 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleData +-- Script: 001 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + isSubscribed = true, + moduleData = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone(), + climateControlData = commonRC.getClimateControlData() + } + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true }) +end + +local function step2(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + isSubscribed = true, + moduleData = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone(), + radioControlData = commonRC.getRadioControlData() + } + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleData_CLIMATE", step1) +runner.Step("GetInteriorVehicleData_RADIO", step2) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/002c.lua b/test_scripts/RC/GetInteriorVehicleData/002c.lua new file mode 100644 index 0000000000..818a786049 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleData/002c.lua @@ -0,0 +1,40 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleData +-- Script: 002 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Title("Test") +runner.Step("GetInteriorVehicleData_CLIMATE", step1) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/002r.lua b/test_scripts/RC/GetInteriorVehicleData/002r.lua new file mode 100644 index 0000000000..c1b1507d34 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleData/002r.lua @@ -0,0 +1,40 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleData +-- Script: 002 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Title("Test") +runner.Step("GetInteriorVehicleData_RADIO", step1) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/003.lua b/test_scripts/RC/GetInteriorVehicleData/003.lua new file mode 100644 index 0000000000..e39decd740 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleData/003.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleData +-- Script: 003 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData") + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function step2(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData") + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleData_CLIMATE", step1) +runner.Step("GetInteriorVehicleData_RADIO", step2) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/001.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/001.lua new file mode 100644 index 0000000000..0102b50186 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/001.lua @@ -0,0 +1,51 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 001 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Functions ]] +local function step(module_types, self) + self, module_types = commonRC.getSelfAndParams(module_types, self) + + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = module_types + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { + appID = self.applications["Test Application"], + moduleTypes = module_types + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) + }) + end) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataConsent") + :Times(0) + + EXPECT_RESPONSE(cid, { + success = true, + resultCode = "SUCCESS", + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) + }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) +runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE_RADIO", step, { { "CLIMATE", "RADIO" } }) +runner.Step("GetInteriorVehicleDataCapabilities_absent", step, { nil }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/002.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/002.lua new file mode 100644 index 0000000000..89adfd5c49 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/002.lua @@ -0,0 +1,47 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 002 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function step(module_types, self) + self, module_types = commonRC.getSelfAndParams(module_types, self) + + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = module_types + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { + appID = self.applications["Test Application"], + moduleTypes = { "CLIMATE" } + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities({ "CLIMATE" }) + }) + end) + + EXPECT_RESPONSE(cid, { + success = true, + resultCode = "SUCCESS", + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities({ "CLIMATE" }) + }) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE_both", step, { { "CLIMATE", "RADIO" } }) +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE_absent", step, { nil }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/003.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/003.lua new file mode 100644 index 0000000000..61281884ae --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/003.lua @@ -0,0 +1,47 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 003 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function step(module_types, self) + self, module_types = commonRC.getSelfAndParams(module_types, self) + + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = module_types + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { + appID = self.applications["Test Application"], + moduleTypes = { "RADIO" } + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities({ "RADIO" }) + }) + end) + + EXPECT_RESPONSE(cid, { + success = true, + resultCode = "SUCCESS", + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities({ "RADIO" }) + }) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_RADIO_both", step, { { "CLIMATE", "RADIO" } }) +runner.Step("GetInteriorVehicleDataCapabilities_RADIO_absent", step, { nil }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/004.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/004.lua new file mode 100644 index 0000000000..ce4ed6fd4f --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/004.lua @@ -0,0 +1,36 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 004 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Functions ]] +local function step(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = { "CLIMATE" } + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/005.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/005.lua new file mode 100644 index 0000000000..a0a4570884 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/005.lua @@ -0,0 +1,36 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 005 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Functions ]] +local function step(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = { "RADIO" } + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/006.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/006.lua new file mode 100644 index 0000000000..b0903ae6b9 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/006.lua @@ -0,0 +1,40 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 006 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Functions ]] +local function step(module_types, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = module_types + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities") + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].AppHMIType = { "DEFAULT" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) +runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/007.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/007.lua new file mode 100644 index 0000000000..602b0628ee --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/007.lua @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 007 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function step(module_types, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = { "CLIMATE", "RADIO" } + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { + appID = self.applications["Test Application"], + moduleTypes = { "CLIMATE", "RADIO" } + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "WARNINGS", { + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types), + info = "Radio module is not available" + }) + end) + + EXPECT_RESPONSE(cid, { + success = true, + resultCode = "WARNINGS", + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types), + info = "Radio module is not available" + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) +runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/008.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/008.lua new file mode 100644 index 0000000000..ff920227ff --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/008.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 008 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function step(module_types, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = module_types + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { + appID = self.applications["Test Application"], + moduleTypes = module_types + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) + }) + end) + + EXPECT_RESPONSE(cid, { + success = true, + resultCode = "SUCCESS", + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) + }) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) +runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/009.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/009.lua new file mode 100644 index 0000000000..616d049bba --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/009.lua @@ -0,0 +1,37 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 009 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Functions ]] +local function step(module_types, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = module_types + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) +runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/010.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/010.lua new file mode 100644 index 0000000000..d3dc0a64cc --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/010.lua @@ -0,0 +1,30 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 010 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function step(module_types, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = module_types + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_fake_value", step, { { "FAKE_VALUE" } }) +runner.Step("GetInteriorVehicleDataCapabilities_invalid_type", step, { 1 }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/011.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/011.lua new file mode 100644 index 0000000000..bf4bf403be --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/011.lua @@ -0,0 +1,40 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 011 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Functions ]] +local function step(module_types, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = module_types + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { + appID = self.applications["Test Application"], + moduleTypes = module_types + }) + :Do(function() + -- self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + -- interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) + -- }) + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) + + commonTestCases:DelayedExp(11000) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) +runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/012.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/012.lua new file mode 100644 index 0000000000..1a36412752 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/012.lua @@ -0,0 +1,37 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 012 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function step(module_types, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = module_types + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { + appID = self.applications["Test Application"], + moduleTypes = module_types + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + interiorVehicleDataCapabilities = "fake_value" + }) + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) +runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/099_not_completed.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/099_not_completed.lua new file mode 100644 index 0000000000..de0f2e0057 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/099_not_completed.lua @@ -0,0 +1,59 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 099 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function step(id, module_types, self) + local session = commonRC.getMobileSession(self, id) + + local cid = session:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = module_types + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { + appID = self.applications[config["application" .. id].registerAppInterfaceParams.appID], + moduleTypes = module_types + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) + }) + end) + + session:ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS", + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) + }) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + moduleType = { "RADIO", "CLIMATE" }, + groups = { "Base-4" }, + groups_primaryRC = { "Base-4", "RemoteControl" }, + AppHMIType = { "REMOTE_CONTROL" } + } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE_App1", step, { 1, { "CLIMATE" } }) +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE_App2", step, { 2, { "CLIMATE" } }) +runner.Step("GetInteriorVehicleDataCapabilities_RADIO_App1", step, { 1, { "RADIO" } }) +runner.Step("GetInteriorVehicleDataCapabilities_RADIO_App2", step, { 2, { "RADIO" } }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/001.lua b/test_scripts/RC/OnInteriorVehicleData/001.lua new file mode 100644 index 0000000000..37dd05ec63 --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/001.lua @@ -0,0 +1,153 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 001 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function step1_1(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + isSubscribed = true, + moduleData = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone(), + climateControlData = commonRC.getClimateControlData() + } + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true }) +end + +local function step1_2(self) + local climateControlData = { + fanSpeed = 50, + currentTemp = 86, + desiredTemp = 75, + temperatureUnit = "FAHRENHEIT", + acEnable = true, + circulateAirEnable = true, + autoModeEnable = true, + defrostZone = "FRONT", + dualModeEnable = true + } + + self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + moduleData = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone(), + climateControlData = climateControlData + } + }) + + EXPECT_NOTIFICATION("OnInteriorVehicleData", { + moduleData = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone(), + climateControlData = climateControlData + } + }) +end + +local function step2_1(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + isSubscribed = true, + moduleData = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone(), + radioControlData = commonRC.getRadioControlData() + } + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true }) +end + +local function step2_2(self) + local radioControlData = { + frequencyInteger = 1, + frequencyFraction = 2, + band = "AM", + rdsData = { + PS = "ps", + RT = "rt", + CT = "123456789012345678901234", + PI = "pi", + PTY = 2, + TP = false, + TA = true, + REG = "US" + }, + availableHDs = 1, + hdChannel = 1, + signalStrength = 5, + signalChangeThreshold = 20, + radioEnable = true, + state = "ACQUIRING" + } + + self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + moduleData = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone(), + radioControlData = radioControlData + } + }) + + EXPECT_NOTIFICATION("OnInteriorVehicleData", { + moduleData = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone(), + radioControlData = radioControlData + } + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleData_CLIMATE", step1_1) +runner.Step("OnInteriorVehicleData_CLIMATE", step1_2) +runner.Step("GetInteriorVehicleData_RADIO", step2_1) +runner.Step("OnInteriorVehicleData_RADIO", step2_2) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/001b.lua b/test_scripts/RC/OnInteriorVehicleData/001b.lua new file mode 100644 index 0000000000..7b3bb2a31e --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/001b.lua @@ -0,0 +1,114 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 001 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Functions ]] +local function step1_1(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = false + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = false + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + isSubscribed = false, + moduleData = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone(), + climateControlData = commonRC.getClimateControlData() + } + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = false }) +end + +local function step1_2(self) + self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + moduleData = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone(), + climateControlData = commonRC.getRadioControlData() + } + }) + + EXPECT_NOTIFICATION("OnInteriorVehicleData") + :Times(0) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function step2_1(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = false + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = false + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + isSubscribed = false, + moduleData = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone(), + radioControlData = commonRC.getRadioControlData() + } + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = false }) +end + +local function step2_2(self) + self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + moduleData = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone(), + radioControlData = commonRC.getClimateControlData() + } + }) + + EXPECT_NOTIFICATION("OnInteriorVehicleData") + :Times(0) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleData_CLIMATE", step1_1) +runner.Step("OnInteriorVehicleData_CLIMATE", step1_2) +runner.Step("GetInteriorVehicleData_RADIO", step2_1) +runner.Step("OnInteriorVehicleData_RADIO", step2_2) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/002c.lua b/test_scripts/RC/OnInteriorVehicleData/002c.lua new file mode 100644 index 0000000000..d62c510911 --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/002c.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 002 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + isSubscribed = true, + moduleData = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone(), + climateControlData = commonRC.getClimateControlData() + } + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true }) +end + +local function step2(self) + self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + moduleData = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone(), + climateControlData = commonRC.getRadioControlData() + } + }) + + EXPECT_NOTIFICATION("OnInteriorVehicleData") + :Times(0) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Title("Test") +runner.Step("GetInteriorVehicleData_CLIMATE", step1) +runner.Step("OnInteriorVehicleData_CLIMATE", step2) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/002r.lua b/test_scripts/RC/OnInteriorVehicleData/002r.lua new file mode 100644 index 0000000000..6fd75d92aa --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/002r.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 002 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone() + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + isSubscribed = true, + moduleData = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone(), + radioControlData = commonRC.getRadioControlData() + } + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true }) +end + +local function step2(self) + self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + moduleData = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone(), + radioControlData = commonRC.getClimateControlData() + } + }) + + EXPECT_NOTIFICATION("OnInteriorVehicleData") + :Times(0) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Title("Test") +runner.Step("GetInteriorVehicleData_RADIO", step1) +runner.Step("OnInteriorVehicleData_RADIO", step2) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SetInteriorVehicleData/001.lua b/test_scripts/RC/SetInteriorVehicleData/001.lua new file mode 100644 index 0000000000..338bf2f232 --- /dev/null +++ b/test_scripts/RC/SetInteriorVehicleData/001.lua @@ -0,0 +1,79 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: SetInteriorVehicleData +-- Script: 001 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone(), + climateControlData = commonRC.getClimateControlData() + } + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone(), + climateControlData = commonRC.getClimateControlData() + } + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone(), + climateControlData = commonRC.getClimateControlData() + } + }) + end) + + self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function step2(self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone(), + radioControlData = commonRC.getRadioControlData() + } + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone(), + radioControlData = commonRC.getRadioControlData() + } + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone(), + radioControlData = commonRC.getRadioControlData() + } + }) + end) + + self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("SetInteriorVehicleData_CLIMATE", step1) +runner.Step("SetInteriorVehicleData_RADIO", step2) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SetInteriorVehicleData/002c.lua b/test_scripts/RC/SetInteriorVehicleData/002c.lua new file mode 100644 index 0000000000..988d1ae9e8 --- /dev/null +++ b/test_scripts/RC/SetInteriorVehicleData/002c.lua @@ -0,0 +1,40 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: SetInteriorVehicleData +-- Script: 002 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone(), + climateControlData = commonRC.getClimateControlData() + } + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Title("Test") +runner.Step("SetInteriorVehicleData_CLIMATE", step1) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SetInteriorVehicleData/002r.lua b/test_scripts/RC/SetInteriorVehicleData/002r.lua new file mode 100644 index 0000000000..cf65f768d4 --- /dev/null +++ b/test_scripts/RC/SetInteriorVehicleData/002r.lua @@ -0,0 +1,40 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: SetInteriorVehicleData +-- Script: 002 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone(), + radioControlData = commonRC.getRadioControlData() + } + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Title("Test") +runner.Step("SetInteriorVehicleData_RADIO", step1) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SetInteriorVehicleData/003.lua b/test_scripts/RC/SetInteriorVehicleData/003.lua new file mode 100644 index 0000000000..edcfeeb86b --- /dev/null +++ b/test_scripts/RC/SetInteriorVehicleData/003.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: SetInteriorVehicleData +-- Script: 003 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = { + moduleType = "CLIMATE", + moduleZone = commonRC.getInteriorZone(), + climateControlData = commonRC.getClimateControlData() + } + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function step2(self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = { + moduleType = "RADIO", + moduleZone = commonRC.getInteriorZone(), + radioControlData = commonRC.getRadioControlData() + } + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("SetInteriorVehicleData_CLIMATE", step1) +runner.Step("SetInteriorVehicleData_RADIO", step2) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua new file mode 100644 index 0000000000..ce19c40528 --- /dev/null +++ b/test_scripts/RC/commonRC.lua @@ -0,0 +1,362 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleData +-- Common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 +config.ValidateSchema = false +config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application2.registerAppInterfaceParams.appHMIType = nil + +--[[ Required Shared libraries ]] +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local mobile_session = require("mobile_session") +local json = require("modules/json") + +--[[ Local Variables ]] +local ptu_table = {} + +--[[ Local Functions ]] +local function insertFunctions() + local function_id = require("function_id") + function_id["ButtonPress"] = 100015 + function_id["GetInteriorVehicleDataCapabilities"] = 100016 + function_id["GetInteriorVehicleData"] = 100017 + function_id["SetInteriorVehicleData"] = 100018 + function_id["OnInteriorVehicleData"] = 100019 +end + +insertFunctions() + +local function initHMI(self) + local exp_waiter = commonFunctions:createMultipleExpectationsWaiter(self, "HMI initialization") + local function registerComponent(name, subscriptions) + local rid = self.hmiConnection:SendRequest("MB.registerComponent", { componentName = name }) + local exp = EXPECT_HMIRESPONSE(rid) + exp_waiter:AddExpectation(exp) + if subscriptions then + for _, s in ipairs(subscriptions) do + exp:Do(function() + rid = self.hmiConnection:SendRequest("MB.subscribeTo", { propertyName = s }) + exp = EXPECT_HMIRESPONSE(rid) + exp_waiter:AddExpectation(exp) + end) + end + end + end + + local web_socket_connected_event = EXPECT_HMIEVENT(events.connectedEvent, "Connected websocket") + :Do(function() + registerComponent("Buttons", {"Buttons.OnButtonSubscription"}) + registerComponent("TTS") + registerComponent("VR") + registerComponent("BasicCommunication", { + "BasicCommunication.OnPutFile", + "SDL.OnStatusUpdate", + "SDL.OnAppPermissionChanged", + "BasicCommunication.OnSDLPersistenceComplete", + "BasicCommunication.OnFileRemoved", + "BasicCommunication.OnAppRegistered", + "BasicCommunication.OnAppUnregistered", + "BasicCommunication.PlayTone", + "BasicCommunication.OnSDLClose", + "SDL.OnSDLConsentNeeded", + "BasicCommunication.OnResumeAudioSource" + }) + registerComponent("UI", { + "UI.OnRecordStart" + }) + registerComponent("VehicleInfo") + registerComponent("RC") + registerComponent("Navigation", { + "Navigation.OnAudioDataStreaming", + "Navigation.OnVideoDataStreaming" + }) + end) + exp_waiter:AddExpectation(web_socket_connected_event) + + self.hmiConnection:Connect() + return exp_waiter.expectation +end + +local function getPTUFromPTS(tbl) + tbl.policy_table.consumer_friendly_messages.messages = nil + tbl.policy_table.device_data = nil + tbl.policy_table.module_meta = nil + tbl.policy_table.usage_and_error_counts = nil + tbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + tbl.policy_table.module_config.preloaded_pt = nil + tbl.policy_table.module_config.preloaded_date = nil +end + +local function updatePTU(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + moduleType = { "RADIO", "CLIMATE" }, + groups = { "Base-4" }, + groups_primaryRC = { "Base-4", "RemoteControl" }, + AppHMIType = { "REMOTE_CONTROL" } + } + tbl.policy_table.functional_groupings["RemoteControl"] = { + rpcs = { + GetInteriorVehicleDataCapabilities = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED", "NONE" } + } + } + } +end + +local function jsonFileToTable(file_name) + local f = io.open(file_name, "r") + local content = f:read("*all") + f:close() + return json.decode(content) +end + +local function tableToJsonFile(tbl, file_name) + local f = io.open(file_name, "w") + f:write(json.encode(tbl)) + f:close() +end + +local function checkIfPTSIsSentAsBinary(bin_data) + if not (bin_data ~= nil and string.len(bin_data) > 0) then + commonFunctions:userPrint(31, "PTS was not sent to Mobile in payload of OnSystemRequest") + end +end + +local function ptu(self, ptu_update_func) + local policy_file_name = "PolicyTableUpdate" + local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + local ptu_file_name = os.tmpname() + local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) + EXPECT_HMIRESPONSE(requestId) + :Do(function() + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = pts_file_name }) + getPTUFromPTS(ptu_table) + updatePTU(ptu_table) + if ptu_update_func then + ptu_update_func(ptu_table) + end + tableToJsonFile(ptu_table, ptu_file_name) + self.mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :Do(function(_, d2) + checkIfPTSIsSentAsBinary(d2.binaryData) + local corIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, d3) + self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = policy_file_path .. "/" .. policy_file_name }) + end) + self.mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + end) + end) + os.remove(ptu_file_name) +end + +--[[ Module Functions ]] + +local commonRC = {} + +commonRC.timeout = 2000 + +function commonRC.preconditions() + commonFunctions:SDLForceStop() + commonSteps:DeletePolicyTable() + commonSteps:DeleteLogsFiles() +end + +function commonRC.start(self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady() + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + self:connectMobile() + :Do(function() + commonFunctions:userPrint(35, "Mobile connected") + self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) + self.mobileSession:StartService(7) + :Do(function() + commonFunctions:userPrint(35, "Session started") + end) + end) + end) + end) + end) +end + +function commonRC.rai_ptu(ptu_update_func, self) + self, ptu_update_func = commonRC.getSelfAndParams(ptu_update_func, self) + + local corId = self.mobileSession:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config.application1.registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + self.applications[config.application1.registerAppInterfaceParams.appID] = d1.params.application.appID + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :Do(function(_, d2) + self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptu_table = jsonFileToTable(d2.params.file) + ptu(self, ptu_update_func) + end) + end) + self.mobileSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self.mobileSession:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + self.mobileSession:ExpectNotification("OnPermissionsChange") + end) +end + +function commonRC.rai_n(id, self) + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + self.applications[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + end) + end) +end + +function commonRC.postconditions() + StopSDL() +end + +function commonRC.getInteriorZone() + return { + col = 0, + row = 0, + level = 0, + colspan = 2, + rowspan = 2, + levelspan = 1 + } +end + +function commonRC.getClimateControlData() + return { + fanSpeed = 50, + currentTemp = 30, + desiredTemp = 24, + temperatureUnit = "CELSIUS", + acEnable = true, + circulateAirEnable = true, + autoModeEnable = true, + defrostZone = "FRONT", + dualModeEnable = true + } +end + +function commonRC.getRadioControlData() + return { + frequencyInteger = 1, + frequencyFraction = 2, + band = "AM", + rdsData = { + PS = "ps", + RT = "rt", + CT = "123456789012345678901234", + PI = "pi", + PTY = 1, + TP = false, + TA = true, + REG = "US" + }, + availableHDs = 1, + hdChannel = 1, + signalStrength = 5, + signalChangeThreshold = 10, + radioEnable = true, + state = "ACQUIRING" + } +end + +function commonRC.getClimateControlCapabilities() + return { + name = "Climate control module", + fanSpeedAvailable = true, + desiredTemperatureAvailable = true, + acEnableAvailable = true, + acMaxEnableAvailable = true, + circulateAirEnableAvailable = true, + autoModeEnableAvailable = true, + dualModeEnableAvailable = true, + defrostZoneAvailable = true, + defrostZone = { "ALL" }, + ventilationModeAvailable = true, + ventilationMode = { "BOTH" } + } +end + +function commonRC.getRadioControlCapabilities() + return { + name = "Radio control module", + radioEnableAvailable = true, + radioBandAvailable = true, + radioFrequencyAvailable = true, + hdChannelAvailable = true, + rdsDataAvailable = true, + availableHDsAvailable = true, + stateAvailable = true, + signalStrengthAvailable = true, + signalChangeThresholdAvailable = true + } +end + +function commonRC.getInteriorVehicleDataCapabilities(module_types) + local out = { } + if not module_types then + return out + end + for _, v in pairs(module_types) do + if v == "CLIMATE" then + out.climateControlCapabilities = commonRC.getClimateControlCapabilities() + elseif v == "RADIO" then + out.radioControlCapabilities = commonRC.getRadioControlCapabilities() + end + end + return out +end + +function commonRC.getSelfAndParams(param, self) + if not self then + return param, nil + end + return self, param +end + +function commonRC.getMobileSession(self, id) + if id == 2 then + return self.mobileSession2 + end + return self.mobileSession +end + +function commonRC.consent(self) + EXPECT_HMICALL("RC.GetInteriorVehicleDataConsent") + :Times(1) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { allowed = true }) + end) +end + +return commonRC diff --git a/test_sets/rc_GetInteriorVehicleDataCapabilities.txt b/test_sets/rc_GetInteriorVehicleDataCapabilities.txt new file mode 100644 index 0000000000..be80213dce --- /dev/null +++ b/test_sets/rc_GetInteriorVehicleDataCapabilities.txt @@ -0,0 +1,12 @@ +./test_scripts/RC/GetInteriorVehicleDataCapabilities/001.lua +./test_scripts/RC/GetInteriorVehicleDataCapabilities/002.lua +./test_scripts/RC/GetInteriorVehicleDataCapabilities/003.lua +./test_scripts/RC/GetInteriorVehicleDataCapabilities/004.lua +./test_scripts/RC/GetInteriorVehicleDataCapabilities/005.lua +./test_scripts/RC/GetInteriorVehicleDataCapabilities/006.lua +./test_scripts/RC/GetInteriorVehicleDataCapabilities/007.lua +./test_scripts/RC/GetInteriorVehicleDataCapabilities/008.lua +./test_scripts/RC/GetInteriorVehicleDataCapabilities/009.lua +./test_scripts/RC/GetInteriorVehicleDataCapabilities/010.lua +./test_scripts/RC/GetInteriorVehicleDataCapabilities/011.lua +./test_scripts/RC/GetInteriorVehicleDataCapabilities/012.lua diff --git a/user_modules/script_runner.lua b/user_modules/script_runner.lua new file mode 100644 index 0000000000..ecaaacfd6d --- /dev/null +++ b/user_modules/script_runner.lua @@ -0,0 +1,94 @@ +local Test = require('user_modules/dummy_connecttest') +local commonFunctions = require('user_modules/shared_testcases/commonFunctions') + +local isPrintTitle = false +local title +local runner = {} + +--[ATF] +local function buildStepName(testStepName) + if type(testStepName) == "string" and testStepName ~= "" then + testStepName = testStepName:gsub("%W", "_") + while testStepName:match("^[%d_]") do + if #testStepName == 1 then + return error("Test step name is incorrect!") + end + testStepName = testStepName:sub(2) + end + if testStepName:match("^%l") then + testStepName = testStepName:sub(1, 1):upper() .. testStepName:sub(2) + end + return testStepName + elseif type(testStepName) == "number" then + return "Test_step_" .. testStepName + else + return error("Test step name is missing!") + end +end + +local function checkStepImplFunction(testStepImplFunction) + if type(testStepImplFunction) == "function" then + return testStepImplFunction + else + return error("Test step function is not specified!") + end +end + +local function addTestStep(testStepName, testStepImplFunction) + testStepName = buildStepName(testStepName) + testStepImplFunction = checkStepImplFunction(testStepImplFunction) + Test[testStepName] = testStepImplFunction +end + +local function extendedAddTestStep(testStepName, testStepImplFunction, paramsTable) + local implFunctionsListWithParams = {} + if isPrintTitle then + table.insert(implFunctionsListWithParams, {implFunc = commonFunctions.userPrint, params = {0, 32, title, "\n"}}) + isPrintTitle = false + end + if not paramsTable then + paramsTable = {} + end + table.insert(implFunctionsListWithParams, {implFunc = testStepImplFunction, params = paramsTable}) + local newTestStepImplFunction = function(self) + for _, func in pairs(implFunctionsListWithParams) do + table.insert(func.params, self) + func.implFunc(unpack(func.params)) + end + end + addTestStep(testStepName, newTestStepImplFunction) +end + +--[[ Title + Step approach]] +local function buildTitle(titleText) + local maxLength = 101 + local filler = "-" + local resultTable = {} + for line in titleText:gmatch("[^\n]+") do + local lineLength = #line + if lineLength >= maxLength then + table.insert(resultTable, line) + else + local tailLength = math.fmod(maxLength - lineLength, 2) + local emtyLineSideLength = math.floor((maxLength - lineLength) / 2) + table.insert(resultTable, filler:rep(emtyLineSideLength) .. line .. filler:rep(emtyLineSideLength + tailLength)) + end + end + return table.concat(resultTable, "\n") +end + +function runner.Title(titleText) + if isPrintTitle == true then + title = title .. "\n" .. titleText + else + title = titleText + isPrintTitle = true + end + title = buildTitle(title) +end + +function runner.Step(testStepName, testStepImplFunction, paramsTable) + extendedAddTestStep(testStepName, testStepImplFunction, paramsTable) +end + +return runner From b2970182b944455a3bf85f6c6de845d370d4ce7a Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Mon, 10 Jul 2017 10:03:24 +0300 Subject: [PATCH 003/681] Added 013 test with check GENERIC_ERROR resultCode in case HMI return READ_ONLY resultCode for GetInteriorVehicleDataCapabilities --- .../013.lua | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/013.lua diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/013.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/013.lua new file mode 100644 index 0000000000..179cf41a3b --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/013.lua @@ -0,0 +1,37 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 013 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function step(module_types, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = module_types + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { + appID = self.applications["Test Application"], + moduleTypes = module_types + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "READ_ONLY", { + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) + }) + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) +runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) From 90cee5bbd53f2855ccbb4f3807a46556a1a3c98c Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Mon, 10 Jul 2017 11:33:59 +0300 Subject: [PATCH 004/681] Common for RC functionality was updated with generation of capabilities parameters --- test_scripts/RC/commonRC.lua | 90 +++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 26 deletions(-) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index ce19c40528..8a38958ebc 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -17,6 +17,8 @@ local json = require("modules/json") --[[ Local Variables ]] local ptu_table = {} +local radioControlCapabilities; +local climateControlCapabilities; --[[ Local Functions ]] local function insertFunctions() @@ -30,6 +32,66 @@ end insertFunctions() +local function initRandom() + math.randomseed( os.time() ) + math.random() + math.random() + math.random() +end + +local function generateRandomValue(base) + if type(base) == "table" then + if base.values then + return base.values[math.random(#base.values)] + else + return math.random(base.min, base.max) + end + else + return error("Incorrect parameter, table expected") + end + +end + +local function generateRadioControlCapabilities() + return { + name = "Radio control module", + radioEnableAvailable = generateRandomValue({values = {true, false}}), + radioBandAvailable = generateRandomValue({values = {true, false}}), + radioFrequencyAvailable = generateRandomValue({values = {true, false}}), + hdChannelAvailable = generateRandomValue({values = {true, false}}), + rdsDataAvailable = generateRandomValue({values = {true, false}}), + availableHDsAvailable = generateRandomValue({values = {true, false}}), + stateAvailable = generateRandomValue({values = {true, false}}), + signalStrengthAvailable = generateRandomValue({values = {true, false}}), + signalChangeThresholdAvailable = generateRandomValue({values = {true, false}}) + } +end + +local function generateClimateControlCapabilities() + return { + name = "Climate control module", + fanSpeedAvailable = generateRandomValue({values = {true, false}}), + desiredTemperatureAvailable = generateRandomValue({values = {true, false}}), + acEnableAvailable = generateRandomValue({values = {true, false}}), + acMaxEnableAvailable = generateRandomValue({values = {true, false}}), + circulateAirEnableAvailable = generateRandomValue({values = {true, false}}), + autoModeEnableAvailable = generateRandomValue({values = {true, false}}), + dualModeEnableAvailable = generateRandomValue({values = {true, false}}), + defrostZoneAvailable = generateRandomValue({values = {true, false}}), + defrostZone = generateRandomValue({values = {"FRONT", "REAR", "ALL", "NONE"}}), + ventilationModeAvailable = generateRandomValue({values = {true, false}}), + ventilationMode = generateRandomValue({values = {"UPPER", "LOWER", "BOTH", "NONE"}}) + } +end + +local function initCommonRC() + initRandom() + radioControlCapabilities = generateRadioControlCapabilities() + climateControlCapabilities = generateClimateControlCapabilities() +end + +initCommonRC() + local function initHMI(self) local exp_waiter = commonFunctions:createMultipleExpectationsWaiter(self, "HMI initialization") local function registerComponent(name, subscriptions) @@ -291,35 +353,11 @@ function commonRC.getRadioControlData() end function commonRC.getClimateControlCapabilities() - return { - name = "Climate control module", - fanSpeedAvailable = true, - desiredTemperatureAvailable = true, - acEnableAvailable = true, - acMaxEnableAvailable = true, - circulateAirEnableAvailable = true, - autoModeEnableAvailable = true, - dualModeEnableAvailable = true, - defrostZoneAvailable = true, - defrostZone = { "ALL" }, - ventilationModeAvailable = true, - ventilationMode = { "BOTH" } - } + return climateControlCapabilities end function commonRC.getRadioControlCapabilities() - return { - name = "Radio control module", - radioEnableAvailable = true, - radioBandAvailable = true, - radioFrequencyAvailable = true, - hdChannelAvailable = true, - rdsDataAvailable = true, - availableHDsAvailable = true, - stateAvailable = true, - signalStrengthAvailable = true, - signalChangeThresholdAvailable = true - } + return radioControlCapabilities end function commonRC.getInteriorVehicleDataCapabilities(module_types) From 3acc6cce9a417649795a7c1b37696ed6c51d63d5 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Mon, 10 Jul 2017 12:26:13 +0300 Subject: [PATCH 005/681] Test set for GetInteriorVehicleDataCapabilities was updated --- test_sets/rc_GetInteriorVehicleDataCapabilities.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test_sets/rc_GetInteriorVehicleDataCapabilities.txt b/test_sets/rc_GetInteriorVehicleDataCapabilities.txt index be80213dce..46080f1315 100644 --- a/test_sets/rc_GetInteriorVehicleDataCapabilities.txt +++ b/test_sets/rc_GetInteriorVehicleDataCapabilities.txt @@ -10,3 +10,4 @@ ./test_scripts/RC/GetInteriorVehicleDataCapabilities/010.lua ./test_scripts/RC/GetInteriorVehicleDataCapabilities/011.lua ./test_scripts/RC/GetInteriorVehicleDataCapabilities/012.lua +./test_scripts/RC/GetInteriorVehicleDataCapabilities/013.lua From c744b6922a8c5de49552f81a673ad3ff318cc197 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Tue, 11 Jul 2017 15:02:04 +0300 Subject: [PATCH 006/681] Common for RC functionality was updated with function for creation of capabilities file. Created batch of tests for check functionality related default capabilities --- .../011.lua | 11 ++- .../012.lua | 11 ++- .../013.lua | 16 +++-- .../014.lua | 36 ++++++++++ .../015.lua | 64 ++++++++++++++++++ .../016.lua | 41 ++++++++++++ .../017.lua | 67 +++++++++++++++++++ .../018.lua | 54 +++++++++++++++ test_scripts/RC/commonRC.lua | 42 +++++++++++- 9 files changed, 335 insertions(+), 7 deletions(-) create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/014.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/015.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/016.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/017.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/018.lua diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/011.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/011.lua index bf4bf403be..c985cb5329 100644 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/011.lua +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/011.lua @@ -7,6 +7,10 @@ local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +--[[ Local Variables ]] +local interiorVehicleDataCapabilitiesTable = { + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities({"RADIO", "CLIMATE"}) +} --[[ Local Functions ]] local function step(module_types, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { @@ -23,7 +27,11 @@ local function step(module_types, self) -- }) end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) + EXPECT_RESPONSE(cid, { + success = true, + resultCode = "SUCCESS", + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) + }) commonTestCases:DelayedExp(11000) end @@ -31,6 +39,7 @@ end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Prepare InteriorVehicleDataCapabilities.json", commonRC.prepareInteriorVehicleDataCapabilitiesJson, {interiorVehicleDataCapabilitiesTable}) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) runner.Title("Test") diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/012.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/012.lua index 1a36412752..656819384b 100644 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/012.lua +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/012.lua @@ -6,6 +6,10 @@ local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +--[[ Local Variables ]] +local interiorVehicleDataCapabilitiesTable = { + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities({"RADIO", "CLIMATE"}) +} --[[ Local Functions ]] local function step(module_types, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { @@ -22,12 +26,17 @@ local function step(module_types, self) }) end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) + EXPECT_RESPONSE(cid, { + success = true, + resultCode = "SUCCESS", + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) + }) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Prepare InteriorVehicleDataCapabilities.json", commonRC.prepareInteriorVehicleDataCapabilitiesJson, {interiorVehicleDataCapabilitiesTable}) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) runner.Title("Test") diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/013.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/013.lua index 179cf41a3b..f5a92c2caa 100644 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/013.lua +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/013.lua @@ -6,6 +6,11 @@ local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +--[[ Local Variables ]] +local interiorVehicleDataCapabilitiesTable = { + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities({"RADIO", "CLIMATE"}) +} + --[[ Local Functions ]] local function step(module_types, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { @@ -17,17 +22,20 @@ local function step(module_types, self) moduleTypes = module_types }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "READ_ONLY", { - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) - }) + self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Read only parameters") end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) + EXPECT_RESPONSE(cid, { + success = true, + resultCode = "SUCCESS", + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) + }) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Prepare InteriorVehicleDataCapabilities.json", commonRC.prepareInteriorVehicleDataCapabilitiesJson, {interiorVehicleDataCapabilitiesTable}) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) runner.Title("Test") diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/014.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/014.lua new file mode 100644 index 0000000000..aa1cd39adb --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/014.lua @@ -0,0 +1,36 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 014 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function step(module_types, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = module_types + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { + appID = self.applications["Test Application"], + moduleTypes = module_types + }) + :Do(function(_, data) + self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Read only parameters") + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Remove InteriorVehicleDataCapabilities.json", commonRC.prepareInteriorVehicleDataCapabilitiesJson) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) +runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) \ No newline at end of file diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/015.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/015.lua new file mode 100644 index 0000000000..50513c7d1d --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/015.lua @@ -0,0 +1,64 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 015 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local interiorVehicleDataCapabilitiesTable = { + interiorVehicleDataCapabilities = { + climateVehicleCapabilities = { + circulateAirEnableAvailable = false, + defrostZone = "ALL", + defrostZoneAvailable = true, + desiredTemperatureAvailable = false, + dualModeEnableAvailable = true, + fanSpeedAvailable = false, + name = "Climate control module", + fake_param = "bad param", -- fake param + }, + radioControlCapabilities = { + availableHDsAvailable = false, + hdChannelAvailable = true, + name = "Radio control module", + radioBandAvailable = 128.3, -- wrong type + radioEnableAvailable = false, + radioFrequencyAvailable = false, + rdsDataAvailable = false, + signalChangeThresholdAvailable = "true", -- wrong type + signalStrengthAvailable = false, + stateAvailable = false + } + } +} + +--[[ Local Functions ]] +local function step(module_types, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = module_types + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { + appID = self.applications["Test Application"], + moduleTypes = module_types + }) + :Do(function(_, data) + self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Read only parameters") + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Prepare InteriorVehicleDataCapabilities.json", commonRC.prepareInteriorVehicleDataCapabilitiesJson, {interiorVehicleDataCapabilitiesTable}) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) +runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/016.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/016.lua new file mode 100644 index 0000000000..fe6b1e4cf7 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/016.lua @@ -0,0 +1,41 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 016 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Functions ]] +local function step(module_types, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = module_types + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { + appID = self.applications["Test Application"], + moduleTypes = module_types + }) + :Do(function() + -- self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + -- interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) + -- }) + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) + + commonTestCases:DelayedExp(11000) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Remove InteriorVehicleDataCapabilities.json", commonRC.prepareInteriorVehicleDataCapabilitiesJson) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) +runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) \ No newline at end of file diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/017.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/017.lua new file mode 100644 index 0000000000..7421836062 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/017.lua @@ -0,0 +1,67 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 017 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local interiorVehicleDataCapabilitiesTable = { + interiorVehicleDataCapabilities = { + climateVehicleCapabilities = { + circulateAirEnableAvailable = false, + defrostZone = "ALL", + defrostZoneAvailable = true, + desiredTemperatureAvailable = false, + dualModeEnableAvailable = true, + fanSpeedAvailable = false, + name = "Climate control module", + fake_param = "bad param", -- fake param + }, + radioControlCapabilities = { + availableHDsAvailable = false, + hdChannelAvailable = true, + name = "Radio control module", + radioBandAvailable = 128.3, -- wrong type + radioEnableAvailable = false, + radioFrequencyAvailable = false, + rdsDataAvailable = false, + signalChangeThresholdAvailable = "true", -- wrong type + signalStrengthAvailable = false, + stateAvailable = false + } + } +} + +--[[ Local Functions ]] +local function step(module_types, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = module_types + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { + appID = self.applications["Test Application"], + moduleTypes = module_types + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + interiorVehicleDataCapabilities = interiorVehicleDataCapabilitiesTable.interiorVehicleDataCapabilities + }) + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) + +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Remove InteriorVehicleDataCapabilities.json", commonRC.prepareInteriorVehicleDataCapabilitiesJson) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) +runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) \ No newline at end of file diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/018.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/018.lua new file mode 100644 index 0000000000..0edf04b7c0 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/018.lua @@ -0,0 +1,54 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleDataCapabilities +-- Script: 018 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") + +--[[ Local Variables ]] +local interiorVehicleDataCapabilitiesTable = { + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities({"RADIO", "CLIMATE"}) +} + +--[[ Local Functions ]] +local function step(module_types, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { + moduleTypes = module_types + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { + appID = self.applications["Test Application"], + moduleTypes = module_types + }) + :Do(function(_, data) + self.hmiConnection:SendError(data.id, data.method, "INVALID_DATA", "Invalid data") + end) + + EXPECT_RESPONSE(cid, { + success = true, + resultCode = "SUCCESS", + interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) + }) + +end + +local function setEmptyInteriorVDCapabilitiesFile() + commonFunctions:write_parameter_to_smart_device_link_ini("InteriorVDCapabilitiesFile", "") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Prepare InteriorVehicleDataCapabilities.json", + commonRC.prepareInteriorVehicleDataCapabilitiesJson, + {interiorVehicleDataCapabilitiesTable, "InteriorVehicleDataCapabilities.json"}) +runner.Step("Set empty InteriorVDCapabilitiesFile field in smartDeviceLink.ini", setEmptyInteriorVDCapabilitiesFile) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) +runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) \ No newline at end of file diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 8a38958ebc..9188e87a7d 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -10,6 +10,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application2.registerAppInterfaceParams.appHMIType = nil --[[ Required Shared libraries ]] +local commonPreconditions = require("user_modules/shared_testcases/commonPreconditions") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local mobile_session = require("mobile_session") @@ -18,7 +19,10 @@ local json = require("modules/json") --[[ Local Variables ]] local ptu_table = {} local radioControlCapabilities; -local climateControlCapabilities; +local climateControlCapabilities + +local backupedFiles = {} +local createdFiles = {} --[[ Local Functions ]] local function insertFunctions() @@ -234,6 +238,41 @@ function commonRC.preconditions() commonSteps:DeleteLogsFiles() end +function commonRC.prepareInteriorVehicleDataCapabilitiesJson(IVDCapabilitiesTable, IVDCapabilitiesFileName) + -- Validation check + if not IVDCapabilitiesTable.interiorVehicleDataCapabilities then IVDCapabilitiesTable = nil end + if not IVDCapabilitiesFileName or type(IVDCapabilitiesFileName) ~= "string" then IVDCapabilitiesFileName = "IVDCapabilities.json" end + + commonPreconditions:BackupFile("smartDeviceLink.ini") + table.insert(backupedFiles, "smartDeviceLink.ini") + local isBackuped = false + local sdlPath = commonPreconditions:GetPathToSDL() + local IVDCapabilitiesFilePath = commonFunctions:pathJoin(sdlPath, "plugins/" .. IVDCapabilitiesFileName) + commonFunctions:write_parameter_to_smart_device_link_ini("InteriorVDCapabilitiesFile", "./plugins/" .. IVDCapabilitiesFileName) + + if commonFunctions:File_exists(IVDCapabilitiesFilePath) then + commonPreconditions:BackupFile("plugins/" .. IVDCapabilitiesFileName) + table.insert(backupedFiles, "plugins/" .. IVDCapabilitiesFileName) + isBackuped = true + end + + if IVDCapabilitiesTable then + tableToJsonFile(IVDCapabilitiesTable, IVDCapabilitiesFilePath) + if not isBackuped then + table.insert(createdFiles, IVDCapabilitiesFilePath) + end + end +end + +function commonRC.restoreInteriorVehicleDataCapabilitiesJson() + for _,fileName in pairs(backupedFiles) do + commonPreconditions:RestoreFile(fileName) + end + for _,fileName in pairs(createdFiles) do + os.execute( " rm -f " .. fileName) + end +end + function commonRC.start(self) self:runSDL() commonFunctions:waitForSDLStart(self) @@ -300,6 +339,7 @@ function commonRC.rai_n(id, self) end function commonRC.postconditions() + commonRC.restoreInteriorVehicleDataCapabilitiesJson() StopSDL() end From 030fc6f0a56bd0d48a6e285ca4fb88097eff8a38 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Tue, 11 Jul 2017 15:03:12 +0300 Subject: [PATCH 007/681] Test set for GetInteriorVehicleDataCapabilities was updated --- test_sets/rc_GetInteriorVehicleDataCapabilities.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test_sets/rc_GetInteriorVehicleDataCapabilities.txt b/test_sets/rc_GetInteriorVehicleDataCapabilities.txt index 46080f1315..1c7d2811f6 100644 --- a/test_sets/rc_GetInteriorVehicleDataCapabilities.txt +++ b/test_sets/rc_GetInteriorVehicleDataCapabilities.txt @@ -11,3 +11,8 @@ ./test_scripts/RC/GetInteriorVehicleDataCapabilities/011.lua ./test_scripts/RC/GetInteriorVehicleDataCapabilities/012.lua ./test_scripts/RC/GetInteriorVehicleDataCapabilities/013.lua +./test_scripts/RC/GetInteriorVehicleDataCapabilities/014.lua +./test_scripts/RC/GetInteriorVehicleDataCapabilities/015.lua +./test_scripts/RC/GetInteriorVehicleDataCapabilities/016.lua +./test_scripts/RC/GetInteriorVehicleDataCapabilities/017.lua +./test_scripts/RC/GetInteriorVehicleDataCapabilities/018.lua From 3c0a8e48f72aa15c60bad1c895af9d7e83ee6dd1 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Wed, 12 Jul 2017 13:13:00 +0300 Subject: [PATCH 008/681] Fixed generation of arrays from list of values --- test_scripts/RC/commonRC.lua | 89 +++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 32 deletions(-) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 9188e87a7d..15183084a8 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -43,55 +43,80 @@ local function initRandom() math.random() end -local function generateRandomValue(base) - if type(base) == "table" then - if base.values then - return base.values[math.random(#base.values)] - else - return math.random(base.min, base.max) +local function generateRandomValueFromList(list) + return list[math.random(#list)] +end + +local function generateRandomValueFromIntInterval(min, max) + return math.random(min, max) +end + +local function generateRandomArrayFromList(list, isValUnique, min, max) + max = max or min + if max < min then + min, max = max, min end - else - return error("Incorrect parameter, table expected") - end + local isVariableLength = true + if min == max then isVariableLength = false end + local values = {table.unpack(list)} + + local count = min + if count > #values and isValUnique and not isVariableLength then + return error("Random array with " .. min .. " unique elements can not be generated from current list") + end + + if isVariableLength then + count = math.random(min, max) + end + + local result = {} + for _ = 1, count do + local randVal = math.random(#values) + table.insert(result, values[randVal]) + if isValUnique then + table.remove(values, randVal) + end + end + return result end local function generateRadioControlCapabilities() return { name = "Radio control module", - radioEnableAvailable = generateRandomValue({values = {true, false}}), - radioBandAvailable = generateRandomValue({values = {true, false}}), - radioFrequencyAvailable = generateRandomValue({values = {true, false}}), - hdChannelAvailable = generateRandomValue({values = {true, false}}), - rdsDataAvailable = generateRandomValue({values = {true, false}}), - availableHDsAvailable = generateRandomValue({values = {true, false}}), - stateAvailable = generateRandomValue({values = {true, false}}), - signalStrengthAvailable = generateRandomValue({values = {true, false}}), - signalChangeThresholdAvailable = generateRandomValue({values = {true, false}}) + radioEnableAvailable = generateRandomValueFromList({true, false}), + radioBandAvailable = generateRandomValueFromList({true, false}), + radioFrequencyAvailable = generateRandomValueFromList({true, false}), + hdChannelAvailable = generateRandomValueFromList({true, false}), + rdsDataAvailable = generateRandomValueFromList({true, false}), + availableHDsAvailable = generateRandomValueFromList({true, false}), + stateAvailable = generateRandomValueFromList({true, false}), + signalStrengthAvailable = generateRandomValueFromList({true, false}), + signalChangeThresholdAvailable = generateRandomValueFromList({true, false}) } end local function generateClimateControlCapabilities() return { name = "Climate control module", - fanSpeedAvailable = generateRandomValue({values = {true, false}}), - desiredTemperatureAvailable = generateRandomValue({values = {true, false}}), - acEnableAvailable = generateRandomValue({values = {true, false}}), - acMaxEnableAvailable = generateRandomValue({values = {true, false}}), - circulateAirEnableAvailable = generateRandomValue({values = {true, false}}), - autoModeEnableAvailable = generateRandomValue({values = {true, false}}), - dualModeEnableAvailable = generateRandomValue({values = {true, false}}), - defrostZoneAvailable = generateRandomValue({values = {true, false}}), - defrostZone = generateRandomValue({values = {"FRONT", "REAR", "ALL", "NONE"}}), - ventilationModeAvailable = generateRandomValue({values = {true, false}}), - ventilationMode = generateRandomValue({values = {"UPPER", "LOWER", "BOTH", "NONE"}}) + fanSpeedAvailable = generateRandomValueFromList({true, false}), + desiredTemperatureAvailable = generateRandomValueFromList({true, false}), + acEnableAvailable = generateRandomValueFromList({true, false}), + acMaxEnableAvailable = generateRandomValueFromList({true, false}), + circulateAirEnableAvailable = generateRandomValueFromList({true, false}), + autoModeEnableAvailable = generateRandomValueFromList({true, false}), + dualModeEnableAvailable = generateRandomValueFromList({true, false}), + defrostZoneAvailable = generateRandomValueFromList({true, false}), + defrostZone = generateRandomArrayFromList({"FRONT", "REAR", "ALL", "NONE"}, true, 1, 4), + ventilationModeAvailable = generateRandomValueFromList({true, false}), + ventilationMode = generateRandomArrayFromList({"UPPER", "LOWER", "BOTH", "NONE"}, true, 1, 4) } end local function initCommonRC() initRandom() - radioControlCapabilities = generateRadioControlCapabilities() - climateControlCapabilities = generateClimateControlCapabilities() + radioControlCapabilities = {generateRadioControlCapabilities()} + climateControlCapabilities = {generateClimateControlCapabilities()} end initCommonRC() @@ -339,7 +364,7 @@ function commonRC.rai_n(id, self) end function commonRC.postconditions() - commonRC.restoreInteriorVehicleDataCapabilitiesJson() + -- commonRC.restoreInteriorVehicleDataCapabilitiesJson() StopSDL() end From c783ab4ede07ba740fa835129e533c8abd4424bc Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Wed, 12 Jul 2017 13:15:48 +0300 Subject: [PATCH 009/681] Uncomment clean of environment after test --- test_scripts/RC/commonRC.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 15183084a8..5a4956b477 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -364,7 +364,7 @@ function commonRC.rai_n(id, self) end function commonRC.postconditions() - -- commonRC.restoreInteriorVehicleDataCapabilitiesJson() + commonRC.restoreInteriorVehicleDataCapabilitiesJson() StopSDL() end From b9d355c20f0927180fb1c637bcd42d6f31c88e57 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Wed, 12 Jul 2017 14:11:50 +0300 Subject: [PATCH 010/681] Add mock for OnHMIStatus during PTU --- test_scripts/RC/commonRC.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 5a4956b477..3b2bf01031 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -341,6 +341,7 @@ function commonRC.rai_ptu(ptu_update_func, self) self.mobileSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() self.mobileSession:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice self.mobileSession:ExpectNotification("OnPermissionsChange") end) end From 02fd4231619211af0c66913036e3e85f1463e7e7 Mon Sep 17 00:00:00 2001 From: AKalinich-Luxoft Date: Wed, 12 Jul 2017 17:57:48 +0300 Subject: [PATCH 011/681] Fix empty array sending The problem is that PTU generated by current script have moduleType value {} which is not correct and this is a reason of PTU failure. The correct one is []. This commit solves this issue. --- test_scripts/RC/GetInteriorVehicleDataCapabilities/008.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/008.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/008.lua index ff920227ff..110925d745 100644 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/008.lua +++ b/test_scripts/RC/GetInteriorVehicleDataCapabilities/008.lua @@ -5,6 +5,7 @@ --[[ Required Shared libraries ]] local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local json = require('modules/json') --[[ Local Functions ]] local function step(module_types, self) @@ -30,7 +31,7 @@ local function step(module_types, self) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { } + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY end --[[ Scenario ]] From e8a0d63fa5160c1db2e58a017d440e960b597a79 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Thu, 13 Jul 2017 09:35:59 +0300 Subject: [PATCH 012/681] Added new and updated exists tests for GetInteriorVehicleData. Extend policy permission for RC applications --- .../RC/GetInteriorVehicleData/001.lua | 34 ++- .../RC/GetInteriorVehicleData/002c.lua | 4 +- .../RC/GetInteriorVehicleData/002r.lua | 4 +- .../RC/GetInteriorVehicleData/003.lua | 8 +- .../RC/GetInteriorVehicleData/004.lua | 152 ++++++++++++++ .../RC/GetInteriorVehicleData/005.lua | 193 ++++++++++++++++++ .../RC/GetInteriorVehicleData/006.lua | 72 +++++++ .../RC/GetInteriorVehicleData/007.lua | 145 +++++++++++++ test_scripts/RC/commonRC.lua | 14 +- test_sets/rc_GetInteriorVehicleData.txt | 7 + 10 files changed, 614 insertions(+), 19 deletions(-) create mode 100644 test_scripts/RC/GetInteriorVehicleData/004.lua create mode 100644 test_scripts/RC/GetInteriorVehicleData/005.lua create mode 100644 test_scripts/RC/GetInteriorVehicleData/006.lua create mode 100644 test_scripts/RC/GetInteriorVehicleData/007.lua create mode 100644 test_sets/rc_GetInteriorVehicleData.txt diff --git a/test_scripts/RC/GetInteriorVehicleData/001.lua b/test_scripts/RC/GetInteriorVehicleData/001.lua index 2a429907d4..5c4d46da15 100644 --- a/test_scripts/RC/GetInteriorVehicleData/001.lua +++ b/test_scripts/RC/GetInteriorVehicleData/001.lua @@ -11,7 +11,7 @@ local function step1(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone() + moduleName = "Module Climate" }, subscribe = true }) @@ -20,29 +20,36 @@ local function step1(self) appID = self.applications["Test Application"], moduleDescription = { moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone() + moduleName = "Module Climate" }, subscribe = true }) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - isSubscribed = true, moduleData = { moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone(), + moduleName = "Module Climate", climateControlData = commonRC.getClimateControlData() - } + }, + isSubscribed = true }) end) - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true }) + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + isSubscribed = true, + moduleData = { + moduleType = "CLIMATE", + moduleName = "Module Climate", + climateControlData = commonRC.getClimateControlData() + } + }) end local function step2(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone() + moduleName = "Module Radio" }, subscribe = true }) @@ -51,7 +58,7 @@ local function step2(self) appID = self.applications["Test Application"], moduleDescription = { moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone() + moduleName = "Module Radio" }, subscribe = true }) @@ -60,13 +67,20 @@ local function step2(self) isSubscribed = true, moduleData = { moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone(), + moduleName = "Module Radio", radioControlData = commonRC.getRadioControlData() } }) end) - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true }) + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + isSubscribed = true, + moduleData = { + moduleType = "RADIO", + moduleName = "Module Radio", + radioControlData = commonRC.getRadioControlData() + } + }) end --[[ Scenario ]] diff --git a/test_scripts/RC/GetInteriorVehicleData/002c.lua b/test_scripts/RC/GetInteriorVehicleData/002c.lua index 818a786049..8b6f0595f7 100644 --- a/test_scripts/RC/GetInteriorVehicleData/002c.lua +++ b/test_scripts/RC/GetInteriorVehicleData/002c.lua @@ -12,9 +12,9 @@ local function step1(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone() + moduleName = " Climate Module" }, - subscribe = true + -- subscribe = true }) EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) diff --git a/test_scripts/RC/GetInteriorVehicleData/002r.lua b/test_scripts/RC/GetInteriorVehicleData/002r.lua index c1b1507d34..e4d21f2019 100644 --- a/test_scripts/RC/GetInteriorVehicleData/002r.lua +++ b/test_scripts/RC/GetInteriorVehicleData/002r.lua @@ -12,9 +12,9 @@ local function step1(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone() + moduleName = "Radio Module" }, - subscribe = true + -- subscribe = true }) EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) diff --git a/test_scripts/RC/GetInteriorVehicleData/003.lua b/test_scripts/RC/GetInteriorVehicleData/003.lua index e39decd740..9e5533b5a8 100644 --- a/test_scripts/RC/GetInteriorVehicleData/003.lua +++ b/test_scripts/RC/GetInteriorVehicleData/003.lua @@ -15,9 +15,9 @@ local function step1(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone() + moduleName = "Module Climate" }, - subscribe = true + -- subscribe = true }) EXPECT_HMICALL("RC.GetInteriorVehicleData") @@ -32,9 +32,9 @@ local function step2(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone() + moduleName = "Module Radio" }, - subscribe = true + -- subscribe = true }) EXPECT_HMICALL("RC.GetInteriorVehicleData") diff --git a/test_scripts/RC/GetInteriorVehicleData/004.lua b/test_scripts/RC/GetInteriorVehicleData/004.lua new file mode 100644 index 0000000000..eb23f9a455 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleData/004.lua @@ -0,0 +1,152 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleData +-- Script: 004 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function step1(pResultCode, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "CLIMATE", + moduleName = "Module Climate" + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "CLIMATE", + moduleName = "Module Climate" + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, pResultCode, { + moduleData = { + moduleType = "CLIMATE", + moduleName = "Module Climate", + climateControlData = commonRC.getClimateControlData() + } + -- isSubscribed = true + + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = pResultCode, + -- isSubscribed = true, + moduleData = { + moduleType = "CLIMATE", + moduleName = "Module Climate", + climateControlData = commonRC.getClimateControlData() + } + }) +end + +local function step2(pResultCode, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "RADIO", + moduleName = "Module Radio" + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "RADIO", + moduleName = "Module Radio" + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, pResultCode, { + -- isSubscribed = true, + moduleData = { + moduleType = "RADIO", + moduleName = "Module Radio", + radioControlData = commonRC.getRadioControlData() + } + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = pResultCode, + -- isSubscribed = true, + moduleData = { + moduleType = "RADIO", + moduleName = "Module Radio", + radioControlData = commonRC.getRadioControlData() + } + }) +end + +local function step1err(pResultCode, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "CLIMATE", + moduleName = "Module Climate" + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "CLIMATE", + moduleName = "Module Climate" + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = pResultCode}) +end + +local function step2err(pResultCode, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "RADIO", + moduleName = "Module Radio" + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "RADIO", + moduleName = "Module Radio" + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = pResultCode }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleData_CLIMATE with WARNINGS resultCode", step1, {"WARNINGS"}) +runner.Step("GetInteriorVehicleData_RADIO with WARNINGS resultCode", step2, {"WARNINGS"}) +runner.Step("GetInteriorVehicleData_CLIMATE with GENERIC_ERROR resultCode", step1err, {"GENERIC_ERROR"}) +runner.Step("GetInteriorVehicleData_RADIO with GENERIC_ERROR resultCode", step2err, {"GENERIC_ERROR"}) +runner.Step("GetInteriorVehicleData_CLIMATE with INVALID_DATA resultCode", step1err, {"INVALID_DATA"}) +runner.Step("GetInteriorVehicleData_RADIO with INVALID_DATA resultCode", step2err, {"INVALID_DATA"}) +runner.Step("GetInteriorVehicleData_CLIMATE with OUT_OF_MEMORY resultCode", step1err, {"OUT_OF_MEMORY"}) +runner.Step("GetInteriorVehicleData_RADIO with OUT_OF_MEMORY resultCode", step2err, {"OUT_OF_MEMORY"}) +runner.Step("GetInteriorVehicleData_CLIMATE with REJECTED resultCode", step1err, {"REJECTED"}) +runner.Step("GetInteriorVehicleData_RADIO with REJECTED resultCode", step2err, {"REJECTED"}) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/005.lua b/test_scripts/RC/GetInteriorVehicleData/005.lua new file mode 100644 index 0000000000..663f2f8bba --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleData/005.lua @@ -0,0 +1,193 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleData +-- Script: 005 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDecription = { -- invalid name of parameter + moduleType = "CLIMATE", + moduleName = "Module Climate" + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function step2(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDscription = { -- invalid name of parameter + moduleType = "RADIO", + moduleName = "Module Radio" + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function step3(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "CLIMATE", + moduleName = "Module Climate" + }, + subscribe = 17 -- invalid type of parameter + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function step4(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "RADIO", + moduleName = "Module Radio" + }, + subscribe = 21 -- invalid type of parameter + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function step5(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + -- moduleType = "CLIMATE", -- mandatory parameter absent + moduleName = "Module Climate" + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function step6(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + -- moduleType = "RADIO", -- mandatory parameter absent + moduleName = "Module Radio" + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function step7(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "CLIMATE", + moduleName = "Module Climate", + fakeParam = 7 + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "CLIMATE", + moduleName = "Module Climate" + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = { + moduleType = "CLIMATE", + moduleName = "Module Climate", + climateControlData = commonRC.getClimateControlData() + }, + isSubscribed = true + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + isSubscribed = true, + moduleData = { + moduleType = "CLIMATE", + moduleName = "Module Climate", + climateControlData = commonRC.getClimateControlData() + } + }) +end + +local function step8(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "RADIO", + moduleName = "Module Radio", + fakeParam = 7 + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "RADIO", + moduleName = "Module Radio" + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + isSubscribed = true, + moduleData = { + moduleType = "RADIO", + moduleName = "Module Radio", + radioControlData = commonRC.getRadioControlData() + } + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + isSubscribed = true, + moduleData = { + moduleType = "RADIO", + moduleName = "Module Radio", + radioControlData = commonRC.getRadioControlData() + } + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleData_CLIMATE (invalid name of parameter)", step1) +runner.Step("GetInteriorVehicleData_RADIO (invalid name of parameter)", step2) +runner.Step("GetInteriorVehicleData_CLIMATE (invalid type of parameter)", step3) +runner.Step("GetInteriorVehicleData_RADIO (invalid type of parameter)", step4) +runner.Step("GetInteriorVehicleData_CLIMATE (mandatory parameter absent)", step5) +runner.Step("GetInteriorVehicleData_RADIO (mandatory parameter absent)", step6) +runner.Step("GetInteriorVehicleData_CLIMATE (fake parameter)", step7) +runner.Step("GetInteriorVehicleData_RADIO (fake parameter)", step8) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/006.lua b/test_scripts/RC/GetInteriorVehicleData/006.lua new file mode 100644 index 0000000000..fd378f7abe --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleData/006.lua @@ -0,0 +1,72 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleData +-- Script: 006 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "CLIMATE", + moduleName = "Module Climate" + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "CLIMATE", + moduleName = "Module Climate" + }, + subscribe = true + }) + :Do(function(_, _) + -- HMI does not respond + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + + commonTestCases:DelayedExp(11000) +end + +local function step2(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "RADIO", + moduleName = "Module Radio" + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "RADIO", + moduleName = "Module Radio" + }, + subscribe = true + }) + :Do(function(_, _) + -- HMI does not respond + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + + commonTestCases:DelayedExp(11000) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleData_CLIMATE (HMI does not respond)", step1) +runner.Step("GetInteriorVehicleData_RADIO (HMI does not respond)", step2) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/007.lua b/test_scripts/RC/GetInteriorVehicleData/007.lua new file mode 100644 index 0000000000..bfaed8c02e --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleData/007.lua @@ -0,0 +1,145 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleData +-- Script: 006 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "CLIMATE", + moduleName = "Module Climate" + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "CLIMATE", + moduleName = "Module Climate" + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = { + moduleType = "CLIMATE", + moduleName = "Module Climate", + climateControlData = commonRC.getClimateControlData() + }, + isSubscribed = "yes" -- invalid type of parameter + }) + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) +end + +local function step2(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "RADIO", + moduleName = "Module Radio" + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "RADIO", + moduleName = "Module Radio" + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + isSubscribed = "yes", -- invalid type of parameter + moduleData = { + moduleType = "RADIO", + moduleName = "Module Radio", + radioControlData = commonRC.getRadioControlData() + } + }) + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) +end + +local function step3(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "CLIMATE", + moduleName = "Module Climate" + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "CLIMATE", + moduleName = "Module Climate" + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = { + moduleType = "CLIMATE", + moduleName = "Module Climate", + -- climateControlData = commonRC.getClimateControlData() -- missing mandatory parameter + }, + isSubscribed = true + }) + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) +end + +local function step4(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "RADIO", + moduleName = "Module Radio" + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "RADIO", + moduleName = "Module Radio" + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + isSubscribed = true, + moduleData = { + moduleType = "RADIO", + moduleName = "Module Radio", + -- radioControlData = commonRC.getRadioControlData() -- missing mandatory parameter + } + }) + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleData_CLIMATE (Invalid response from HMI-Invalid type of parameter)", step1) +runner.Step("GetInteriorVehicleData_RADIO (Invalid response from HMI-Invalid type of parameter)", step2) +runner.Step("GetInteriorVehicleData_CLIMATE (Invalid response from HMI-Missing mandatory parameter)", step3) +runner.Step("GetInteriorVehicleData_RADIO (Invalid response from HMI-Missing mandatory parameter)", step4) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 3b2bf01031..1c8cf0d8fc 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -197,7 +197,19 @@ local function updatePTU(tbl) rpcs = { GetInteriorVehicleDataCapabilities = { hmi_levels = { "BACKGROUND", "FULL", "LIMITED", "NONE" } - } + }, + GetInteriorVehicleData = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED", "NONE" } + }, + SetInteriorVehicleData = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED", "NONE" } + }, + ButtonPress = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED", "NONE" } + }, + OnInteriorVehicleData = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED", "NONE" } + }, } } end diff --git a/test_sets/rc_GetInteriorVehicleData.txt b/test_sets/rc_GetInteriorVehicleData.txt new file mode 100644 index 0000000000..6b4ce13ad9 --- /dev/null +++ b/test_sets/rc_GetInteriorVehicleData.txt @@ -0,0 +1,7 @@ +./test_scripts/RC/GetInteriorVehicleData/001.lua +./test_scripts/RC/GetInteriorVehicleData/002.lua +./test_scripts/RC/GetInteriorVehicleData/003.lua +./test_scripts/RC/GetInteriorVehicleData/004.lua +./test_scripts/RC/GetInteriorVehicleData/005.lua +./test_scripts/RC/GetInteriorVehicleData/006.lua +./test_scripts/RC/GetInteriorVehicleData/007.lua From 6c527450ab5c9b1d6dc2fa448512cb42b720498f Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Thu, 13 Jul 2017 12:09:08 +0300 Subject: [PATCH 013/681] Added test sets for RC RPC --- test_sets/rc_ButtonPress.txt | 4 ++++ test_sets/rc_GetInteriorVehicleData.txt | 3 ++- test_sets/rc_OnInteriorVehicleData.txt | 4 ++++ test_sets/rc_SetInteriorVehicleData.txt | 4 ++++ 4 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 test_sets/rc_ButtonPress.txt create mode 100644 test_sets/rc_OnInteriorVehicleData.txt create mode 100644 test_sets/rc_SetInteriorVehicleData.txt diff --git a/test_sets/rc_ButtonPress.txt b/test_sets/rc_ButtonPress.txt new file mode 100644 index 0000000000..e186c908ef --- /dev/null +++ b/test_sets/rc_ButtonPress.txt @@ -0,0 +1,4 @@ +./test_scripts/RC/ButtonPress/001.lua +./test_scripts/RC/ButtonPress/002c.lua +./test_scripts/RC/ButtonPress/002r.lua +./test_scripts/RC/ButtonPress/003.lua diff --git a/test_sets/rc_GetInteriorVehicleData.txt b/test_sets/rc_GetInteriorVehicleData.txt index 6b4ce13ad9..2691af13c0 100644 --- a/test_sets/rc_GetInteriorVehicleData.txt +++ b/test_sets/rc_GetInteriorVehicleData.txt @@ -1,5 +1,6 @@ ./test_scripts/RC/GetInteriorVehicleData/001.lua -./test_scripts/RC/GetInteriorVehicleData/002.lua +./test_scripts/RC/GetInteriorVehicleData/002r.lua +./test_scripts/RC/GetInteriorVehicleData/002c.lua ./test_scripts/RC/GetInteriorVehicleData/003.lua ./test_scripts/RC/GetInteriorVehicleData/004.lua ./test_scripts/RC/GetInteriorVehicleData/005.lua diff --git a/test_sets/rc_OnInteriorVehicleData.txt b/test_sets/rc_OnInteriorVehicleData.txt new file mode 100644 index 0000000000..ccf132d589 --- /dev/null +++ b/test_sets/rc_OnInteriorVehicleData.txt @@ -0,0 +1,4 @@ +./test_scripts/RC/ButtonPress/001.lua +./test_scripts/RC/ButtonPress/001b.lua +./test_scripts/RC/ButtonPress/002r.lua +./test_scripts/RC/ButtonPress/002c.lua diff --git a/test_sets/rc_SetInteriorVehicleData.txt b/test_sets/rc_SetInteriorVehicleData.txt new file mode 100644 index 0000000000..33a32d1b3b --- /dev/null +++ b/test_sets/rc_SetInteriorVehicleData.txt @@ -0,0 +1,4 @@ +./test_scripts/RC/GetInteriorVehicleData/001.lua +./test_scripts/RC/SetInteriorVehicleData/002c.lua +./test_scripts/RC/SetInteriorVehicleData/002r.lua +./test_scripts/RC/SetInteriorVehicleData/003.lua From bd7300679a127888e2243a442e0b87f91b54830f Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Thu, 13 Jul 2017 13:07:33 +0300 Subject: [PATCH 014/681] Removed moduleName parameter --- .../RC/GetInteriorVehicleData/001.lua | 16 +++------ .../RC/GetInteriorVehicleData/002c.lua | 3 +- .../RC/GetInteriorVehicleData/002r.lua | 3 +- .../RC/GetInteriorVehicleData/003.lua | 6 ++-- .../RC/GetInteriorVehicleData/004.lua | 24 ++++--------- .../RC/GetInteriorVehicleData/005.lua | 26 ++++---------- .../RC/GetInteriorVehicleData/006.lua | 12 +++---- .../RC/GetInteriorVehicleData/007.lua | 36 +++++++------------ 8 files changed, 36 insertions(+), 90 deletions(-) diff --git a/test_scripts/RC/GetInteriorVehicleData/001.lua b/test_scripts/RC/GetInteriorVehicleData/001.lua index 5c4d46da15..f71191a1a4 100644 --- a/test_scripts/RC/GetInteriorVehicleData/001.lua +++ b/test_scripts/RC/GetInteriorVehicleData/001.lua @@ -10,8 +10,7 @@ local runner = require('user_modules/script_runner') local function step1(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { - moduleType = "CLIMATE", - moduleName = "Module Climate" + moduleType = "CLIMATE" }, subscribe = true }) @@ -19,8 +18,7 @@ local function step1(self) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], moduleDescription = { - moduleType = "CLIMATE", - moduleName = "Module Climate" + moduleType = "CLIMATE" }, subscribe = true }) @@ -28,7 +26,6 @@ local function step1(self) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { moduleData = { moduleType = "CLIMATE", - moduleName = "Module Climate", climateControlData = commonRC.getClimateControlData() }, isSubscribed = true @@ -39,7 +36,6 @@ local function step1(self) isSubscribed = true, moduleData = { moduleType = "CLIMATE", - moduleName = "Module Climate", climateControlData = commonRC.getClimateControlData() } }) @@ -48,8 +44,7 @@ end local function step2(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { - moduleType = "RADIO", - moduleName = "Module Radio" + moduleType = "RADIO" }, subscribe = true }) @@ -57,8 +52,7 @@ local function step2(self) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], moduleDescription = { - moduleType = "RADIO", - moduleName = "Module Radio" + moduleType = "RADIO" }, subscribe = true }) @@ -67,7 +61,6 @@ local function step2(self) isSubscribed = true, moduleData = { moduleType = "RADIO", - moduleName = "Module Radio", radioControlData = commonRC.getRadioControlData() } }) @@ -77,7 +70,6 @@ local function step2(self) isSubscribed = true, moduleData = { moduleType = "RADIO", - moduleName = "Module Radio", radioControlData = commonRC.getRadioControlData() } }) diff --git a/test_scripts/RC/GetInteriorVehicleData/002c.lua b/test_scripts/RC/GetInteriorVehicleData/002c.lua index 8b6f0595f7..bd64b0fd71 100644 --- a/test_scripts/RC/GetInteriorVehicleData/002c.lua +++ b/test_scripts/RC/GetInteriorVehicleData/002c.lua @@ -11,8 +11,7 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local function step1(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { - moduleType = "CLIMATE", - moduleName = " Climate Module" + moduleType = "CLIMATE" }, -- subscribe = true }) diff --git a/test_scripts/RC/GetInteriorVehicleData/002r.lua b/test_scripts/RC/GetInteriorVehicleData/002r.lua index e4d21f2019..435e953c78 100644 --- a/test_scripts/RC/GetInteriorVehicleData/002r.lua +++ b/test_scripts/RC/GetInteriorVehicleData/002r.lua @@ -11,8 +11,7 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local function step1(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { - moduleType = "RADIO", - moduleName = "Radio Module" + moduleType = "RADIO" }, -- subscribe = true }) diff --git a/test_scripts/RC/GetInteriorVehicleData/003.lua b/test_scripts/RC/GetInteriorVehicleData/003.lua index 9e5533b5a8..98b1be87f6 100644 --- a/test_scripts/RC/GetInteriorVehicleData/003.lua +++ b/test_scripts/RC/GetInteriorVehicleData/003.lua @@ -14,8 +14,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } local function step1(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { - moduleType = "CLIMATE", - moduleName = "Module Climate" + moduleType = "CLIMATE" }, -- subscribe = true }) @@ -31,8 +30,7 @@ end local function step2(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { - moduleType = "RADIO", - moduleName = "Module Radio" + moduleType = "RADIO" }, -- subscribe = true }) diff --git a/test_scripts/RC/GetInteriorVehicleData/004.lua b/test_scripts/RC/GetInteriorVehicleData/004.lua index eb23f9a455..03f3165c57 100644 --- a/test_scripts/RC/GetInteriorVehicleData/004.lua +++ b/test_scripts/RC/GetInteriorVehicleData/004.lua @@ -10,8 +10,7 @@ local runner = require('user_modules/script_runner') local function step1(pResultCode, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { - moduleType = "CLIMATE", - moduleName = "Module Climate" + moduleType = "CLIMATE" }, subscribe = true }) @@ -19,8 +18,7 @@ local function step1(pResultCode, self) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], moduleDescription = { - moduleType = "CLIMATE", - moduleName = "Module Climate" + moduleType = "CLIMATE" }, subscribe = true }) @@ -28,7 +26,6 @@ local function step1(pResultCode, self) self.hmiConnection:SendResponse(data.id, data.method, pResultCode, { moduleData = { moduleType = "CLIMATE", - moduleName = "Module Climate", climateControlData = commonRC.getClimateControlData() } -- isSubscribed = true @@ -40,7 +37,6 @@ local function step1(pResultCode, self) -- isSubscribed = true, moduleData = { moduleType = "CLIMATE", - moduleName = "Module Climate", climateControlData = commonRC.getClimateControlData() } }) @@ -50,7 +46,6 @@ local function step2(pResultCode, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { moduleType = "RADIO", - moduleName = "Module Radio" }, subscribe = true }) @@ -59,7 +54,6 @@ local function step2(pResultCode, self) appID = self.applications["Test Application"], moduleDescription = { moduleType = "RADIO", - moduleName = "Module Radio" }, subscribe = true }) @@ -68,7 +62,6 @@ local function step2(pResultCode, self) -- isSubscribed = true, moduleData = { moduleType = "RADIO", - moduleName = "Module Radio", radioControlData = commonRC.getRadioControlData() } }) @@ -78,7 +71,6 @@ local function step2(pResultCode, self) -- isSubscribed = true, moduleData = { moduleType = "RADIO", - moduleName = "Module Radio", radioControlData = commonRC.getRadioControlData() } }) @@ -87,8 +79,7 @@ end local function step1err(pResultCode, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { - moduleType = "CLIMATE", - moduleName = "Module Climate" + moduleType = "CLIMATE" }, subscribe = true }) @@ -96,8 +87,7 @@ local function step1err(pResultCode, self) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], moduleDescription = { - moduleType = "CLIMATE", - moduleName = "Module Climate" + moduleType = "CLIMATE" }, subscribe = true }) @@ -111,8 +101,7 @@ end local function step2err(pResultCode, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { - moduleType = "RADIO", - moduleName = "Module Radio" + moduleType = "RADIO" }, subscribe = true }) @@ -120,8 +109,7 @@ local function step2err(pResultCode, self) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], moduleDescription = { - moduleType = "RADIO", - moduleName = "Module Radio" + moduleType = "RADIO" }, subscribe = true }) diff --git a/test_scripts/RC/GetInteriorVehicleData/005.lua b/test_scripts/RC/GetInteriorVehicleData/005.lua index 663f2f8bba..43dad206e4 100644 --- a/test_scripts/RC/GetInteriorVehicleData/005.lua +++ b/test_scripts/RC/GetInteriorVehicleData/005.lua @@ -10,8 +10,7 @@ local runner = require('user_modules/script_runner') local function step1(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDecription = { -- invalid name of parameter - moduleType = "CLIMATE", - moduleName = "Module Climate" + moduleType = "CLIMATE" }, subscribe = true }) @@ -25,8 +24,7 @@ end local function step2(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDscription = { -- invalid name of parameter - moduleType = "RADIO", - moduleName = "Module Radio" + moduleType = "RADIO" }, subscribe = true }) @@ -40,8 +38,7 @@ end local function step3(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { - moduleType = "CLIMATE", - moduleName = "Module Climate" + moduleType = "CLIMATE" }, subscribe = 17 -- invalid type of parameter }) @@ -55,8 +52,7 @@ end local function step4(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { - moduleType = "RADIO", - moduleName = "Module Radio" + moduleType = "RADIO" }, subscribe = 21 -- invalid type of parameter }) @@ -71,7 +67,6 @@ local function step5(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { -- moduleType = "CLIMATE", -- mandatory parameter absent - moduleName = "Module Climate" }, subscribe = true }) @@ -86,7 +81,6 @@ local function step6(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { -- moduleType = "RADIO", -- mandatory parameter absent - moduleName = "Module Radio" }, subscribe = true }) @@ -101,7 +95,6 @@ local function step7(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { moduleType = "CLIMATE", - moduleName = "Module Climate", fakeParam = 7 }, subscribe = true @@ -110,8 +103,7 @@ local function step7(self) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], moduleDescription = { - moduleType = "CLIMATE", - moduleName = "Module Climate" + moduleType = "CLIMATE" }, subscribe = true }) @@ -119,7 +111,6 @@ local function step7(self) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { moduleData = { moduleType = "CLIMATE", - moduleName = "Module Climate", climateControlData = commonRC.getClimateControlData() }, isSubscribed = true @@ -130,7 +121,6 @@ local function step7(self) isSubscribed = true, moduleData = { moduleType = "CLIMATE", - moduleName = "Module Climate", climateControlData = commonRC.getClimateControlData() } }) @@ -140,7 +130,6 @@ local function step8(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { moduleType = "RADIO", - moduleName = "Module Radio", fakeParam = 7 }, subscribe = true @@ -149,8 +138,7 @@ local function step8(self) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], moduleDescription = { - moduleType = "RADIO", - moduleName = "Module Radio" + moduleType = "RADIO" }, subscribe = true }) @@ -159,7 +147,6 @@ local function step8(self) isSubscribed = true, moduleData = { moduleType = "RADIO", - moduleName = "Module Radio", radioControlData = commonRC.getRadioControlData() } }) @@ -169,7 +156,6 @@ local function step8(self) isSubscribed = true, moduleData = { moduleType = "RADIO", - moduleName = "Module Radio", radioControlData = commonRC.getRadioControlData() } }) diff --git a/test_scripts/RC/GetInteriorVehicleData/006.lua b/test_scripts/RC/GetInteriorVehicleData/006.lua index fd378f7abe..812fda9eed 100644 --- a/test_scripts/RC/GetInteriorVehicleData/006.lua +++ b/test_scripts/RC/GetInteriorVehicleData/006.lua @@ -11,8 +11,7 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local function step1(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { - moduleType = "CLIMATE", - moduleName = "Module Climate" + moduleType = "CLIMATE" }, subscribe = true }) @@ -20,8 +19,7 @@ local function step1(self) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], moduleDescription = { - moduleType = "CLIMATE", - moduleName = "Module Climate" + moduleType = "CLIMATE" }, subscribe = true }) @@ -37,8 +35,7 @@ end local function step2(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { - moduleType = "RADIO", - moduleName = "Module Radio" + moduleType = "RADIO" }, subscribe = true }) @@ -46,8 +43,7 @@ local function step2(self) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], moduleDescription = { - moduleType = "RADIO", - moduleName = "Module Radio" + moduleType = "RADIO" }, subscribe = true }) diff --git a/test_scripts/RC/GetInteriorVehicleData/007.lua b/test_scripts/RC/GetInteriorVehicleData/007.lua index bfaed8c02e..31cb052f80 100644 --- a/test_scripts/RC/GetInteriorVehicleData/007.lua +++ b/test_scripts/RC/GetInteriorVehicleData/007.lua @@ -10,8 +10,7 @@ local runner = require('user_modules/script_runner') local function step1(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { - moduleType = "CLIMATE", - moduleName = "Module Climate" + moduleType = "CLIMATE" }, subscribe = true }) @@ -19,16 +18,14 @@ local function step1(self) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], moduleDescription = { - moduleType = "CLIMATE", - moduleName = "Module Climate" + moduleType = "CLIMATE" }, subscribe = true }) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { moduleData = { - moduleType = "CLIMATE", - moduleName = "Module Climate", + moduleType = "CLIMATE" climateControlData = commonRC.getClimateControlData() }, isSubscribed = "yes" -- invalid type of parameter @@ -41,8 +38,7 @@ end local function step2(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { - moduleType = "RADIO", - moduleName = "Module Radio" + moduleType = "RADIO" }, subscribe = true }) @@ -50,8 +46,7 @@ local function step2(self) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], moduleDescription = { - moduleType = "RADIO", - moduleName = "Module Radio" + moduleType = "RADIO" }, subscribe = true }) @@ -59,8 +54,7 @@ local function step2(self) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { isSubscribed = "yes", -- invalid type of parameter moduleData = { - moduleType = "RADIO", - moduleName = "Module Radio", + moduleType = "RADIO" radioControlData = commonRC.getRadioControlData() } }) @@ -72,8 +66,7 @@ end local function step3(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { - moduleType = "CLIMATE", - moduleName = "Module Climate" + moduleType = "CLIMATE" }, subscribe = true }) @@ -81,16 +74,14 @@ local function step3(self) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], moduleDescription = { - moduleType = "CLIMATE", - moduleName = "Module Climate" + moduleType = "CLIMATE" }, subscribe = true }) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { moduleData = { - moduleType = "CLIMATE", - moduleName = "Module Climate", + moduleType = "CLIMATE" -- climateControlData = commonRC.getClimateControlData() -- missing mandatory parameter }, isSubscribed = true @@ -103,8 +94,7 @@ end local function step4(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { - moduleType = "RADIO", - moduleName = "Module Radio" + moduleType = "RADIO" }, subscribe = true }) @@ -112,8 +102,7 @@ local function step4(self) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], moduleDescription = { - moduleType = "RADIO", - moduleName = "Module Radio" + moduleType = "RADIO" }, subscribe = true }) @@ -121,8 +110,7 @@ local function step4(self) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { isSubscribed = true, moduleData = { - moduleType = "RADIO", - moduleName = "Module Radio", + moduleType = "RADIO" -- radioControlData = commonRC.getRadioControlData() -- missing mandatory parameter } }) From 561fa3760ea7aeba7b043196e0a6887cbf69f386 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Fri, 14 Jul 2017 08:29:08 +0300 Subject: [PATCH 015/681] Added new tests for GetInteriorVehicleData --- .../RC/GetInteriorVehicleData/007.lua | 6 +- .../RC/GetInteriorVehicleData/008.lua | 92 ++++++++++++++++ .../RC/GetInteriorVehicleData/009.lua | 41 +++++++ .../RC/GetInteriorVehicleData/010.lua | 41 +++++++ .../RC/GetInteriorVehicleData/011.lua | 102 ++++++++++++++++++ .../RC/GetInteriorVehicleData/012.lua | 98 +++++++++++++++++ 6 files changed, 377 insertions(+), 3 deletions(-) create mode 100644 test_scripts/RC/GetInteriorVehicleData/008.lua create mode 100644 test_scripts/RC/GetInteriorVehicleData/009.lua create mode 100644 test_scripts/RC/GetInteriorVehicleData/010.lua create mode 100644 test_scripts/RC/GetInteriorVehicleData/011.lua create mode 100644 test_scripts/RC/GetInteriorVehicleData/012.lua diff --git a/test_scripts/RC/GetInteriorVehicleData/007.lua b/test_scripts/RC/GetInteriorVehicleData/007.lua index 31cb052f80..580c3a35b9 100644 --- a/test_scripts/RC/GetInteriorVehicleData/007.lua +++ b/test_scripts/RC/GetInteriorVehicleData/007.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- RPC: GetInteriorVehicleData --- Script: 006 +-- Script: 007 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local commonRC = require('test_scripts/RC/commonRC') @@ -25,7 +25,7 @@ local function step1(self) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { moduleData = { - moduleType = "CLIMATE" + moduleType = "CLIMATE", climateControlData = commonRC.getClimateControlData() }, isSubscribed = "yes" -- invalid type of parameter @@ -54,7 +54,7 @@ local function step2(self) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { isSubscribed = "yes", -- invalid type of parameter moduleData = { - moduleType = "RADIO" + moduleType = "RADIO", radioControlData = commonRC.getRadioControlData() } }) diff --git a/test_scripts/RC/GetInteriorVehicleData/008.lua b/test_scripts/RC/GetInteriorVehicleData/008.lua new file mode 100644 index 0000000000..4d442f4b5d --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleData/008.lua @@ -0,0 +1,92 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleData +-- Script: 001 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local json = require('modules/json') + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "CLIMATE" + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "CLIMATE" + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = { + moduleType = "CLIMATE", + climateControlData = commonRC.getClimateControlData() + }, + isSubscribed = true + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + isSubscribed = true, + moduleData = { + moduleType = "CLIMATE", + climateControlData = commonRC.getClimateControlData() + } + }) +end + +local function step2(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = "RADIO" + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = "RADIO" + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + isSubscribed = true, + moduleData = { + moduleType = "RADIO", + radioControlData = commonRC.getRadioControlData() + } + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + isSubscribed = true, + moduleData = { + moduleType = "RADIO", + radioControlData = commonRC.getRadioControlData() + } + }) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Title("Test") +runner.Step("GetInteriorVehicleData_CLIMATE", step1) +runner.Step("GetInteriorVehicleData_RADIO", step2) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/009.lua b/test_scripts/RC/GetInteriorVehicleData/009.lua new file mode 100644 index 0000000000..a095676828 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleData/009.lua @@ -0,0 +1,41 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleData +-- Script: 009 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local json = require('modules/json') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Functions ]] +local function step(module_type, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = module_type + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Title("Test") +runner.Step("GetInteriorVehicleData_CLIMATE", step, {"CLIMATE"}) +runner.Step("GetInteriorVehicleData_RADIO", step, {"RADIO"}) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/010.lua b/test_scripts/RC/GetInteriorVehicleData/010.lua new file mode 100644 index 0000000000..920e1e8b49 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleData/010.lua @@ -0,0 +1,41 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleData +-- Script: 010 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function step(module_type, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = module_type + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = module_type + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Read only parameters received") + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleData_CLIMATE_READ_ONLY", step, {"CLIMATE"}) +runner.Step("GetInteriorVehicleData_RADIO_READ_ONLY", step, {"RADIO"}) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/011.lua b/test_scripts/RC/GetInteriorVehicleData/011.lua new file mode 100644 index 0000000000..5347645b67 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleData/011.lua @@ -0,0 +1,102 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleData +-- Script: 011 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function getModuleControlData(moduleType) + if moduleType == "CLIMATE" then + return commonRC.getClimateControlData() + end + return commonRC.getRadioControlData() +end + +local function subscribeToModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = { + moduleType = pModuleType, + climateControlData = getModuleControlData(pModuleType) + }, + isSubscribed = true + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + moduleData = { + moduleType = pModuleType, + climateControlData = getModuleControlData(pModuleType) + }, + isSubscribed = true + }) +end + +local function step(pModuleType, isSubscriptionActive, pSubscribe, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = pSubscribe + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = pSubscribe + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = { + moduleType = pModuleType, + climateControlData = getModuleControlData(pModuleType) + }, + -- no isSubscribed parameter + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + isSubscribed = isSubscriptionActive, -- return current value of subscription + moduleData = { + moduleType = pModuleType, + climateControlData = getModuleControlData(pModuleType) + } + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleData_CLIMATE_NoSubscription_subscribe", step, {"CLIMATE", false, true}) +runner.Step("GetInteriorVehicleData_CLIMATE_NoSubscription_unsubscribe", step, {"CLIMATE", false, false}) +runner.Step("GetInteriorVehicleData_RADIO_NoSubscription_subscribe", step, {"RADIO", false, true}) +runner.Step("GetInteriorVehicleData_RADIO_NoSubscription_unsubscribe", step, {"RADIO", false, false}) +runner.Step("Subscribe app to CLIMATE", subscribeToModule, {"CLIMATE"}) +runner.Step("GetInteriorVehicleData_CLIMATE_ActiveSubscription_subscribe", step, {"CLIMATE", true, true}) +runner.Step("GetInteriorVehicleData_CLIMATE_ActiveSubscription_unsubscribe", step, {"CLIMATE", true, false}) +runner.Step("Subscribe app to RADIO", subscribeToModule, {"RADIO"}) +runner.Step("GetInteriorVehicleData_RADIO_ActiveSubscription_subscribe", step, {"RADIO", true, true}) +runner.Step("GetInteriorVehicleData_RADIO_ActiveSubscription_unsubscribe", step, {"RADIO", true, false}) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/012.lua b/test_scripts/RC/GetInteriorVehicleData/012.lua new file mode 100644 index 0000000000..33a0422e56 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleData/012.lua @@ -0,0 +1,98 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: GetInteriorVehicleData +-- Script: 012 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') + +--[[ Local Functions ]] +local function getModuleControlData(moduleType) + if moduleType == "CLIMATE" then + return commonRC.getClimateControlData() + end + return commonRC.getRadioControlData() +end + +local function subscribeToModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = { + moduleType = pModuleType, + climateControlData = getModuleControlData(pModuleType) + }, + isSubscribed = true + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + moduleData = { + moduleType = pModuleType, + climateControlData = getModuleControlData(pModuleType) + }, + isSubscribed = true + }) +end + +local function step(pModuleType, isSubscriptionActive, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + -- no subscribe parameter + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + } + -- no subscribe parameter + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = { + moduleType = pModuleType, + climateControlData = getModuleControlData(pModuleType) + }, + isSubscribed = isSubscriptionActive -- return current value of subscription + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + moduleData = { + moduleType = pModuleType, + climateControlData = getModuleControlData(pModuleType) + } + -- no isSubscribed parameter + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("GetInteriorVehicleData_CLIMATE_NoSubscription", step, {"CLIMATE", false}) +runner.Step("GetInteriorVehicleData_RADIO_NoSubscription", step, {"RADIO", false}) +runner.Step("Subscribe app to CLIMATE", subscribeToModule, {"CLIMATE"}) +runner.Step("GetInteriorVehicleData_CLIMATE_ActiveSubscription_subscribe", step, {"CLIMATE", true}) +runner.Step("Subscribe app to RADIO", subscribeToModule, {"RADIO"}) +runner.Step("GetInteriorVehicleData_RADIO_ActiveSubscription_subscribe", step, {"RADIO", true}) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) From 027baeeeb9e9b744b08cd12e9b2a60823c4456df Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Fri, 14 Jul 2017 12:08:17 +0300 Subject: [PATCH 016/681] Added check for info parameter for GENERIC_ERROR result code --- test_scripts/RC/GetInteriorVehicleData/007.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test_scripts/RC/GetInteriorVehicleData/007.lua b/test_scripts/RC/GetInteriorVehicleData/007.lua index 580c3a35b9..73814df974 100644 --- a/test_scripts/RC/GetInteriorVehicleData/007.lua +++ b/test_scripts/RC/GetInteriorVehicleData/007.lua @@ -32,7 +32,7 @@ local function step1(self) }) end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Invalid message received from vehicle"}) end local function step2(self) @@ -60,7 +60,7 @@ local function step2(self) }) end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Invalid message received from vehicle"}) end local function step3(self) @@ -88,7 +88,7 @@ local function step3(self) }) end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Invalid message received from vehicle"}) end local function step4(self) @@ -116,7 +116,7 @@ local function step4(self) }) end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Invalid message received from vehicle"}) end --[[ Scenario ]] From 3d48622e8290954c8eec8a75a7f67a83e42c2a43 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Fri, 14 Jul 2017 13:47:42 +0300 Subject: [PATCH 017/681] Fix mistake with moduleData --- .../RC/GetInteriorVehicleData/011.lua | 27 ++++++------------- .../RC/GetInteriorVehicleData/012.lua | 27 ++++++------------- 2 files changed, 16 insertions(+), 38 deletions(-) diff --git a/test_scripts/RC/GetInteriorVehicleData/011.lua b/test_scripts/RC/GetInteriorVehicleData/011.lua index 5347645b67..11ff01b279 100644 --- a/test_scripts/RC/GetInteriorVehicleData/011.lua +++ b/test_scripts/RC/GetInteriorVehicleData/011.lua @@ -7,14 +7,15 @@ local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') --[[ Local Functions ]] -local function getModuleControlData(moduleType) +local function getModuleData(moduleType) if moduleType == "CLIMATE" then - return commonRC.getClimateControlData() + return {moduleType = moduleType, climateControlData = commonRC.getClimateControlData()} end - return commonRC.getRadioControlData() + return {moduleType = moduleType, radioControlData = commonRC.getRadioControlData()} end local function subscribeToModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { moduleType = pModuleType @@ -31,19 +32,13 @@ local function subscribeToModule(pModuleType, self) }) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = { - moduleType = pModuleType, - climateControlData = getModuleControlData(pModuleType) - }, + moduleData = getModuleData(pModuleType), isSubscribed = true }) end) EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - moduleData = { - moduleType = pModuleType, - climateControlData = getModuleControlData(pModuleType) - }, + moduleData = getModuleData(pModuleType), isSubscribed = true }) end @@ -65,20 +60,14 @@ local function step(pModuleType, isSubscriptionActive, pSubscribe, self) }) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = { - moduleType = pModuleType, - climateControlData = getModuleControlData(pModuleType) - }, + moduleData = getModuleData(pModuleType), -- no isSubscribed parameter }) end) EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = isSubscriptionActive, -- return current value of subscription - moduleData = { - moduleType = pModuleType, - climateControlData = getModuleControlData(pModuleType) - } + moduleData = getModuleData(pModuleType) }) end diff --git a/test_scripts/RC/GetInteriorVehicleData/012.lua b/test_scripts/RC/GetInteriorVehicleData/012.lua index 33a0422e56..457f8ed80c 100644 --- a/test_scripts/RC/GetInteriorVehicleData/012.lua +++ b/test_scripts/RC/GetInteriorVehicleData/012.lua @@ -7,14 +7,15 @@ local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') --[[ Local Functions ]] -local function getModuleControlData(moduleType) +local function getModuleData(moduleType) if moduleType == "CLIMATE" then - return commonRC.getClimateControlData() + return {moduleType = moduleType, climateControlData = commonRC.getClimateControlData()} end - return commonRC.getRadioControlData() + return {moduleType = moduleType, radioControlData = commonRC.getRadioControlData()} end local function subscribeToModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { moduleType = pModuleType @@ -31,19 +32,13 @@ local function subscribeToModule(pModuleType, self) }) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = { - moduleType = pModuleType, - climateControlData = getModuleControlData(pModuleType) - }, + moduleData = getModuleData(pModuleType), isSubscribed = true }) end) EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - moduleData = { - moduleType = pModuleType, - climateControlData = getModuleControlData(pModuleType) - }, + moduleData = getModuleData(pModuleType), isSubscribed = true }) end @@ -65,19 +60,13 @@ local function step(pModuleType, isSubscriptionActive, self) }) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = { - moduleType = pModuleType, - climateControlData = getModuleControlData(pModuleType) - }, + moduleData = getModuleData(pModuleType), isSubscribed = isSubscriptionActive -- return current value of subscription }) end) EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - moduleData = { - moduleType = pModuleType, - climateControlData = getModuleControlData(pModuleType) - } + moduleData = getModuleData(pModuleType) -- no isSubscribed parameter }) end From ba537d016148cfdec34d3dd042b9840f7997198b Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Fri, 14 Jul 2017 14:20:58 +0300 Subject: [PATCH 018/681] Added tests for OnInteriorVehicleData and update test suites --- test_scripts/RC/OnInteriorVehicleData/001.lua | 162 +++++++----------- .../RC/OnInteriorVehicleData/001b.lua | 114 ------------ .../RC/OnInteriorVehicleData/002c.lua | 4 - .../RC/OnInteriorVehicleData/002r.lua | 4 - test_scripts/RC/OnInteriorVehicleData/003.lua | 102 +++++++++++ test_scripts/RC/OnInteriorVehicleData/004.lua | 101 +++++++++++ test_scripts/RC/OnInteriorVehicleData/005.lua | 107 ++++++++++++ test_scripts/RC/OnInteriorVehicleData/006.lua | 97 +++++++++++ test_sets/rc_GetInteriorVehicleData.txt | 5 + test_sets/rc_OnInteriorVehicleData.txt | 5 +- 10 files changed, 478 insertions(+), 223 deletions(-) delete mode 100644 test_scripts/RC/OnInteriorVehicleData/001b.lua create mode 100644 test_scripts/RC/OnInteriorVehicleData/003.lua create mode 100644 test_scripts/RC/OnInteriorVehicleData/004.lua create mode 100644 test_scripts/RC/OnInteriorVehicleData/005.lua create mode 100644 test_scripts/RC/OnInteriorVehicleData/006.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/001.lua b/test_scripts/RC/OnInteriorVehicleData/001.lua index 37dd05ec63..a6c20ae89e 100644 --- a/test_scripts/RC/OnInteriorVehicleData/001.lua +++ b/test_scripts/RC/OnInteriorVehicleData/001.lua @@ -5,41 +5,10 @@ --[[ Required Shared libraries ]] local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') ---[[ Local Functions ]] -local function step1_1(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone() - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone() - }, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - isSubscribed = true, - moduleData = { - moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone(), - climateControlData = commonRC.getClimateControlData() - } - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true }) -end - -local function step1_2(self) - local climateControlData = { +--[[ Local Valiables ]] +local climateControlData = { fanSpeed = 50, currentTemp = 86, desiredTemp = 75, @@ -49,58 +18,9 @@ local function step1_2(self) autoModeEnable = true, defrostZone = "FRONT", dualModeEnable = true - } - - self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { - moduleData = { - moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone(), - climateControlData = climateControlData - } - }) - - EXPECT_NOTIFICATION("OnInteriorVehicleData", { - moduleData = { - moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone(), - climateControlData = climateControlData - } - }) -end +} -local function step2_1(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone() - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone() - }, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - isSubscribed = true, - moduleData = { - moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone(), - radioControlData = commonRC.getRadioControlData() - } - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true }) -end - -local function step2_2(self) - local radioControlData = { +local radioControlData = { frequencyInteger = 1, frequencyFraction = 2, band = "AM", @@ -120,34 +40,76 @@ local function step2_2(self) signalChangeThreshold = 20, radioEnable = true, state = "ACQUIRING" - } +} +--[[ Local Functions ]] +local function getModuleData(moduleType, moduleControlData) + if moduleType == "CLIMATE" then + return {moduleType = moduleType, climateControlData = moduleControlData or commonRC.getClimateControlData()} + end + return {moduleType = moduleType, radioControlData = moduleControlData or commonRC.getRadioControlData()} +end + +local function subscriptionToModule(pModuleType, pSubscribe, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = pSubscribe + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = pSubscribe + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = getModuleData(pModuleType), + isSubscribed = pSubscribe + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + moduleData = getModuleData(pModuleType), + isSubscribed = pSubscribe + }) +end + +local function stepSubscribed(pModuleType, pModuleControlData, self) self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { - moduleData = { - moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone(), - radioControlData = radioControlData - } + moduleData = getModuleData(pModuleType, pModuleControlData) }) EXPECT_NOTIFICATION("OnInteriorVehicleData", { - moduleData = { - moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone(), - radioControlData = radioControlData - } + moduleData = getModuleData(pModuleType, pModuleControlData) }) end +local function stepUnsubscribed(pModuleType, pModuleControlData, self) + self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + moduleData = getModuleData(pModuleType, pModuleControlData) + }) + + EXPECT_NOTIFICATION("OnInteriorVehicleData", {}):Times(0) + commonTestCases:DelayedExp(commonRC.timeout) +end + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) runner.Title("Test") -runner.Step("GetInteriorVehicleData_CLIMATE", step1_1) -runner.Step("OnInteriorVehicleData_CLIMATE", step1_2) -runner.Step("GetInteriorVehicleData_RADIO", step2_1) -runner.Step("OnInteriorVehicleData_RADIO", step2_2) +runner.Step("Subscribe app to CLIMATE", subscriptionToModule, {"CLIMATE", true}) +runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App subscribed", stepSubscribed, {"CLIMATE", climateControlData}) +runner.Step("Subscribe app to RADIO", subscriptionToModule, {"RADIO", true}) +runner.Step("Send notification OnInteriorVehicleData_RADIO. App subscribed", stepSubscribed, {"RADIO", radioControlData}) +runner.Step("Unsubscribe app to CLIMATE", subscriptionToModule, {"CLIMATE", false}) +runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App unsubscribed", stepUnsubscribed, {"CLIMATE", climateControlData}) +runner.Step("Unsubscribe app to RADIO", subscriptionToModule, {"RADIO", false}) +runner.Step("Send notification OnInteriorVehicleData_RADIO. App unsubscribed", stepUnsubscribed, {"RADIO", radioControlData}) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/001b.lua b/test_scripts/RC/OnInteriorVehicleData/001b.lua deleted file mode 100644 index 7b3bb2a31e..0000000000 --- a/test_scripts/RC/OnInteriorVehicleData/001b.lua +++ /dev/null @@ -1,114 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData --- Script: 001 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') - ---[[ Local Functions ]] -local function step1_1(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone() - }, - subscribe = false - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone() - }, - subscribe = false - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - isSubscribed = false, - moduleData = { - moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone(), - climateControlData = commonRC.getClimateControlData() - } - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = false }) -end - -local function step1_2(self) - self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { - moduleData = { - moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone(), - climateControlData = commonRC.getRadioControlData() - } - }) - - EXPECT_NOTIFICATION("OnInteriorVehicleData") - :Times(0) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function step2_1(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone() - }, - subscribe = false - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone() - }, - subscribe = false - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - isSubscribed = false, - moduleData = { - moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone(), - radioControlData = commonRC.getRadioControlData() - } - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = false }) -end - -local function step2_2(self) - self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { - moduleData = { - moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone(), - radioControlData = commonRC.getClimateControlData() - } - }) - - EXPECT_NOTIFICATION("OnInteriorVehicleData") - :Times(0) - - commonTestCases:DelayedExp(commonRC.timeout) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Title("Test") -runner.Step("GetInteriorVehicleData_CLIMATE", step1_1) -runner.Step("OnInteriorVehicleData_CLIMATE", step1_2) -runner.Step("GetInteriorVehicleData_RADIO", step2_1) -runner.Step("OnInteriorVehicleData_RADIO", step2_2) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/002c.lua b/test_scripts/RC/OnInteriorVehicleData/002c.lua index d62c510911..90123945c8 100644 --- a/test_scripts/RC/OnInteriorVehicleData/002c.lua +++ b/test_scripts/RC/OnInteriorVehicleData/002c.lua @@ -12,7 +12,6 @@ local function step1(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone() }, subscribe = true }) @@ -21,7 +20,6 @@ local function step1(self) appID = self.applications["Test Application"], moduleDescription = { moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone() }, subscribe = true }) @@ -30,7 +28,6 @@ local function step1(self) isSubscribed = true, moduleData = { moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone(), climateControlData = commonRC.getClimateControlData() } }) @@ -43,7 +40,6 @@ local function step2(self) self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { moduleData = { moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone(), climateControlData = commonRC.getRadioControlData() } }) diff --git a/test_scripts/RC/OnInteriorVehicleData/002r.lua b/test_scripts/RC/OnInteriorVehicleData/002r.lua index 6fd75d92aa..e597a0c735 100644 --- a/test_scripts/RC/OnInteriorVehicleData/002r.lua +++ b/test_scripts/RC/OnInteriorVehicleData/002r.lua @@ -12,7 +12,6 @@ local function step1(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { moduleDescription = { moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone() }, subscribe = true }) @@ -21,7 +20,6 @@ local function step1(self) appID = self.applications["Test Application"], moduleDescription = { moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone() }, subscribe = true }) @@ -30,7 +28,6 @@ local function step1(self) isSubscribed = true, moduleData = { moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone(), radioControlData = commonRC.getRadioControlData() } }) @@ -43,7 +40,6 @@ local function step2(self) self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { moduleData = { moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone(), radioControlData = commonRC.getClimateControlData() } }) diff --git a/test_scripts/RC/OnInteriorVehicleData/003.lua b/test_scripts/RC/OnInteriorVehicleData/003.lua new file mode 100644 index 0000000000..a03c7459ab --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/003.lua @@ -0,0 +1,102 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 003 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Valiables ]] +local climateControlData = { + fanSpeed = 50, + currentTemp = 86, + desiredTemp = 75, + temperatureUnit = "FAHRENHEIT", + acEnable = true, + circulateAirEnable = true, + autoModeEnable = true, + defrostZone = "FRONT", + dualModeEnable = true +} + +local radioControlData = { + frequencyInteger = 1, + frequencyFraction = 2, + band = "AM", + rdsData = { + PS = "ps", + RT = "rt", + CT = "123456789012345678901234", + PI = "pi", + PTY = 2, + TP = false, + TA = true, + REG = "US" + }, + availableHDs = 1, + hdChannel = 1, + signalStrength = 5, + signalChangeThreshold = 20, + radioEnable = true, + state = "ACQUIRING" +} + +--[[ Local Functions ]] +local function getModuleData(moduleType, moduleControlData) + if moduleType == "CLIMATE" then + return {moduleType = moduleType, climateControlData = moduleControlData or commonRC.getClimateControlData()} + end + return {moduleType = moduleType, radioControlData = moduleControlData or commonRC.getRadioControlData()} +end + +local function subscriptionToModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = getModuleData(pModuleType), + isSubscribed = false -- not subscribe + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + moduleData = getModuleData(pModuleType), + isSubscribed = false + }) +end + + +local function stepUnsubscribed(pModuleType, pModuleControlData, self) + self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + moduleData = getModuleData(pModuleType, pModuleControlData) + }) + + EXPECT_NOTIFICATION("OnInteriorVehicleData", {}):Times(0) + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("Subscribe app to CLIMATE (unsuccessful)", subscriptionToModule, {"CLIMATE"}) +runner.Step("Subscribe app to RADIO (unsuccessful)", subscriptionToModule, {"RADIO"}) +runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App is not subscribed", stepUnsubscribed, {"CLIMATE", climateControlData}) +runner.Step("Send notification OnInteriorVehicleData_RADIO. App is not subscribed", stepUnsubscribed, {"RADIO", radioControlData}) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/004.lua b/test_scripts/RC/OnInteriorVehicleData/004.lua new file mode 100644 index 0000000000..d7f512d107 --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/004.lua @@ -0,0 +1,101 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 003 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Valiables ]] +local climateControlData = { + fanSpeed = 50, + currentTemp = 86, + desiredTemp = 75, + temperatureUnit = "FAHRENHEIT", + acEnable = true, + circulateAirEnable = true, + autoModeEnable = true, + defrostZone = "FRONT", + dualModeEnable = true +} + +local radioControlData = { + frequencyInteger = 1, + frequencyFraction = 2, + band = "AM", + rdsData = { + PS = "ps", + RT = "rt", + CT = "123456789012345678901234", + PI = "pi", + PTY = 2, + TP = false, + TA = true, + REG = "US" + }, + availableHDs = 1, + hdChannel = 1, + signalStrength = 5, + signalChangeThreshold = 20, + radioEnable = true, + state = "ACQUIRING" +} + +--[[ Local Functions ]] +local function getModuleData(moduleType, moduleControlData) + if moduleType == "CLIMATE" then + return {moduleType = moduleType, climateControlData = moduleControlData or commonRC.getClimateControlData()} + end + return {moduleType = moduleType, radioControlData = moduleControlData or commonRC.getRadioControlData()} +end + +local function subscriptionToModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = getModuleData(pModuleType), + -- no isSubscribed parameter + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + moduleData = getModuleData(pModuleType), + isSubscribed = false + }) +end + +local function stepUnsubscribed(pModuleType, pModuleControlData, self) + self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + moduleData = getModuleData(pModuleType, pModuleControlData) + }) + + EXPECT_NOTIFICATION("OnInteriorVehicleData", {}):Times(0) + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("Subscribe app to CLIMATE (no isSubscribed parameter)", subscriptionToModule, {"CLIMATE"}) +runner.Step("Subscribe app to RADIO (no isSubscribed parameter)", subscriptionToModule, {"RADIO"}) +runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App is not subscribed", stepUnsubscribed, {"CLIMATE", climateControlData}) +runner.Step("Send notification OnInteriorVehicleData_RADIO. App is not subscribed", stepUnsubscribed, {"RADIO", radioControlData}) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/005.lua b/test_scripts/RC/OnInteriorVehicleData/005.lua new file mode 100644 index 0000000000..6a34985dae --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/005.lua @@ -0,0 +1,107 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 004 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Valiables ]] +local climateControlData = { + fanSpeed = 50, + currentTemp = 86, + desiredTemp = 75, + temperatureUnit = "FAHRENHEIT", + acEnable = true, + circulateAirEnable = true, + autoModeEnable = true, + defrostZone = "FRONT", + dualModeEnable = true +} + +local radioControlData = { + frequencyInteger = 1, + frequencyFraction = 2, + band = "AM", + rdsData = { + PS = "ps", + RT = "rt", + CT = "123456789012345678901234", + PI = "pi", + PTY = 2, + TP = false, + TA = true, + REG = "US" + }, + availableHDs = 1, + hdChannel = 1, + signalStrength = 5, + signalChangeThreshold = 20, + radioEnable = true, + state = "ACQUIRING" +} + +--[[ Local Functions ]] +local function getModuleData(moduleType, moduleControlData) + if moduleType == "CLIMATE" then + return {moduleType = moduleType, climateControlData = moduleControlData or commonRC.getClimateControlData()} + end + return {moduleType = moduleType, radioControlData = moduleControlData or commonRC.getRadioControlData()} +end + +local function subscriptionToModule(pModuleType, pResultCode, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = pResultCode}) +end + +local function stepUnsubscribed(pModuleType, pModuleControlData, self) + self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + moduleData = getModuleData(pModuleType, pModuleControlData) + }) + + EXPECT_NOTIFICATION("OnInteriorVehicleData", {}):Times(0) + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("Subscribe app to CLIMATE (GENERIC_ERROR from HMI)", subscriptionToModule, {"CLIMATE", "GENERIC_ERROR"}) +runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App is not subscribed", stepUnsubscribed, {"CLIMATE", climateControlData}) +runner.Step("Subscribe app to CLIMATE (INVALID_DATA from HMI)", subscriptionToModule, {"CLIMATE", "INVALID_DATA"}) +runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App is not subscribed", stepUnsubscribed, {"CLIMATE", climateControlData}) +runner.Step("Subscribe app to CLIMATE (OUT_OF_MEMORY from HMI)", subscriptionToModule, {"CLIMATE", "OUT_OF_MEMORY"}) +runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App is not subscribed", stepUnsubscribed, {"CLIMATE", climateControlData}) +runner.Step("Subscribe app to CLIMATE (REJECTED from HMI)", subscriptionToModule, {"CLIMATE", "REJECTED"}) +runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App is not subscribed", stepUnsubscribed, {"CLIMATE", climateControlData}) +runner.Step("Subscribe app to RADIO (GENERIC_ERROR from HMI)", subscriptionToModule, {"RADIO", "GENERIC_ERROR"}) +runner.Step("Send notification OnInteriorVehicleData RADIO. App is not subscribed", stepUnsubscribed, {"RADIO", radioControlData}) +runner.Step("Subscribe app to RADIO (INVALID_DATA from HMI)", subscriptionToModule, {"RADIO", "INVALID_DATA"}) +runner.Step("Send notification OnInteriorVehicleData RADIO. App is not subscribed", stepUnsubscribed, {"RADIO", radioControlData}) +runner.Step("Subscribe app to RADIO (OUT_OF_MEMORY from HMI)", subscriptionToModule, {"RADIO", "OUT_OF_MEMORY"}) +runner.Step("Send notification OnInteriorVehicleData RADIO. App is not subscribed", stepUnsubscribed, {"RADIO", radioControlData}) +runner.Step("Subscribe app to RADIO (REJECTED from HMI)", subscriptionToModule, {"RADIO", "REJECTED"}) +runner.Step("Send notification OnInteriorVehicleData RADIO. App is not subscribed", stepUnsubscribed, {"RADIO", radioControlData}) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/006.lua b/test_scripts/RC/OnInteriorVehicleData/006.lua new file mode 100644 index 0000000000..cd3b2f73f0 --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/006.lua @@ -0,0 +1,97 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 004 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Valiables ]] +local climateControlData = { + fanSpeed = 50, + currentTemp = 86, + desiredTemp = 75, + temperatureUnit = "FAHRENHEIT", + acEnable = true, + circulateAirEnable = true, + autoModeEnable = true, + defrostZone = "FRONT", + dualModeEnable = true +} + +local radioControlData = { + frequencyInteger = 1, + frequencyFraction = 2, + band = "AM", + rdsData = { + PS = "ps", + RT = "rt", + CT = "123456789012345678901234", + PI = "pi", + PTY = 2, + TP = false, + TA = true, + REG = "US" + }, + availableHDs = 1, + hdChannel = 1, + signalStrength = 5, + signalChangeThreshold = 20, + radioEnable = true, + state = "ACQUIRING" +} + +--[[ Local Functions ]] +local function getModuleData(moduleType, moduleControlData) + if moduleType == "CLIMATE" then + return {moduleType = moduleType, climateControlData = moduleControlData or commonRC.getClimateControlData()} + end + return {moduleType = moduleType, radioControlData = moduleControlData or commonRC.getRadioControlData()} +end + +local function subscriptionToModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + :Do(function(_, _) + -- no response from HMI + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + + commonTestCases:DelayedExp(11000) +end + +local function stepUnsubscribed(pModuleType, pModuleControlData, self) + self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + moduleData = getModuleData(pModuleType, pModuleControlData) + }) + + EXPECT_NOTIFICATION("OnInteriorVehicleData", {}):Times(0) + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("Subscribe app to CLIMATE (no response from HMI)", subscriptionToModule, {"CLIMATE"}) +runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App is not subscribed", stepUnsubscribed, {"CLIMATE", climateControlData}) +runner.Step("Subscribe app to RADIO (no responsefrom HMI)", subscriptionToModule, {"RADIO"}) +runner.Step("Send notification OnInteriorVehicleData RADIO. App is not subscribed", stepUnsubscribed, {"RADIO", radioControlData}) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_GetInteriorVehicleData.txt b/test_sets/rc_GetInteriorVehicleData.txt index 2691af13c0..acbf5282f8 100644 --- a/test_sets/rc_GetInteriorVehicleData.txt +++ b/test_sets/rc_GetInteriorVehicleData.txt @@ -6,3 +6,8 @@ ./test_scripts/RC/GetInteriorVehicleData/005.lua ./test_scripts/RC/GetInteriorVehicleData/006.lua ./test_scripts/RC/GetInteriorVehicleData/007.lua +./test_scripts/RC/GetInteriorVehicleData/008.lua +./test_scripts/RC/GetInteriorVehicleData/009.lua +./test_scripts/RC/GetInteriorVehicleData/010.lua +./test_scripts/RC/GetInteriorVehicleData/011.lua +./test_scripts/RC/GetInteriorVehicleData/012.lua diff --git a/test_sets/rc_OnInteriorVehicleData.txt b/test_sets/rc_OnInteriorVehicleData.txt index ccf132d589..d0d8cff43b 100644 --- a/test_sets/rc_OnInteriorVehicleData.txt +++ b/test_sets/rc_OnInteriorVehicleData.txt @@ -1,4 +1,7 @@ ./test_scripts/RC/ButtonPress/001.lua -./test_scripts/RC/ButtonPress/001b.lua ./test_scripts/RC/ButtonPress/002r.lua ./test_scripts/RC/ButtonPress/002c.lua +./test_scripts/RC/ButtonPress/003.lua +./test_scripts/RC/ButtonPress/004.lua +./test_scripts/RC/ButtonPress/005.lua +./test_scripts/RC/ButtonPress/006.lua From dc7d12ae107008572eddc1138b2268a258913061 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Mon, 17 Jul 2017 15:12:01 +0300 Subject: [PATCH 019/681] Fix test set --- test_sets/rc_OnInteriorVehicleData.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test_sets/rc_OnInteriorVehicleData.txt b/test_sets/rc_OnInteriorVehicleData.txt index d0d8cff43b..b159c7ba9a 100644 --- a/test_sets/rc_OnInteriorVehicleData.txt +++ b/test_sets/rc_OnInteriorVehicleData.txt @@ -1,7 +1,7 @@ -./test_scripts/RC/ButtonPress/001.lua -./test_scripts/RC/ButtonPress/002r.lua -./test_scripts/RC/ButtonPress/002c.lua -./test_scripts/RC/ButtonPress/003.lua -./test_scripts/RC/ButtonPress/004.lua -./test_scripts/RC/ButtonPress/005.lua -./test_scripts/RC/ButtonPress/006.lua +./test_scripts/RC/OnInteriorVehicleData/001.lua +./test_scripts/RC/OnInteriorVehicleData/002r.lua +./test_scripts/RC/OnInteriorVehicleData/002c.lua +./test_scripts/RC/OnInteriorVehicleData/003.lua +./test_scripts/RC/OnInteriorVehicleData/004.lua +./test_scripts/RC/OnInteriorVehicleData/005.lua +./test_scripts/RC/OnInteriorVehicleData/006.lua From b73efc6a916f862b7d381758bce42d87fa77723b Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Mon, 17 Jul 2017 16:16:25 +0300 Subject: [PATCH 020/681] Fix obligation of parameter --- test_scripts/RC/GetInteriorVehicleData/007.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test_scripts/RC/GetInteriorVehicleData/007.lua b/test_scripts/RC/GetInteriorVehicleData/007.lua index 73814df974..510f75f34a 100644 --- a/test_scripts/RC/GetInteriorVehicleData/007.lua +++ b/test_scripts/RC/GetInteriorVehicleData/007.lua @@ -81,8 +81,8 @@ local function step3(self) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { moduleData = { - moduleType = "CLIMATE" - -- climateControlData = commonRC.getClimateControlData() -- missing mandatory parameter + -- moduleType = "CLIMATE" -- missing mandatory parameter + climateControlData = commonRC.getClimateControlData() }, isSubscribed = true }) @@ -110,8 +110,8 @@ local function step4(self) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { isSubscribed = true, moduleData = { - moduleType = "RADIO" - -- radioControlData = commonRC.getRadioControlData() -- missing mandatory parameter + -- moduleType = "RADIO" -- missing mandatory parameter + radioControlData = commonRC.getRadioControlData() } }) end) From 9606b6b2ab521f242b9738b7505d510233a09673 Mon Sep 17 00:00:00 2001 From: Alexandr Stasiuk Date: Tue, 18 Jul 2017 10:31:53 +0300 Subject: [PATCH 021/681] Deleted getinteriorZone function. --- test_scripts/RC/SetInteriorVehicleData/001.lua | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test_scripts/RC/SetInteriorVehicleData/001.lua b/test_scripts/RC/SetInteriorVehicleData/001.lua index 338bf2f232..05616643a9 100644 --- a/test_scripts/RC/SetInteriorVehicleData/001.lua +++ b/test_scripts/RC/SetInteriorVehicleData/001.lua @@ -11,7 +11,6 @@ local function step1(self) local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { moduleData = { moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone(), climateControlData = commonRC.getClimateControlData() } }) @@ -20,7 +19,6 @@ local function step1(self) appID = self.applications["Test Application"], moduleData = { moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone(), climateControlData = commonRC.getClimateControlData() } }) @@ -28,7 +26,6 @@ local function step1(self) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { moduleData = { moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone(), climateControlData = commonRC.getClimateControlData() } }) @@ -41,7 +38,6 @@ local function step2(self) local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { moduleData = { moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone(), radioControlData = commonRC.getRadioControlData() } }) @@ -50,7 +46,6 @@ local function step2(self) appID = self.applications["Test Application"], moduleData = { moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone(), radioControlData = commonRC.getRadioControlData() } }) @@ -58,7 +53,6 @@ local function step2(self) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { moduleData = { moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone(), radioControlData = commonRC.getRadioControlData() } }) From 04b887f015c14c975d08a58f7a82e349864f9329 Mon Sep 17 00:00:00 2001 From: "Dmytro Boltovskyi (GitHub)" Date: Tue, 18 Jul 2017 11:44:42 +0300 Subject: [PATCH 022/681] Add new scripts (#1558) * Add new scripts --- test_scripts/RC/OnInteriorVehicleData/001.lua | 114 +++-------------- .../RC/OnInteriorVehicleData/002c.lua | 55 ++------- .../RC/OnInteriorVehicleData/002r.lua | 55 ++------- test_scripts/RC/OnInteriorVehicleData/003.lua | 115 +++++------------ test_scripts/RC/OnInteriorVehicleData/004.lua | 116 ++++++------------ test_scripts/RC/OnInteriorVehicleData/005.lua | 115 +++++------------ test_scripts/RC/OnInteriorVehicleData/006.lua | 101 +++++---------- test_scripts/RC/OnInteriorVehicleData/007.lua | 52 ++++++++ test_scripts/RC/OnInteriorVehicleData/008.lua | 60 +++++++++ test_scripts/RC/OnInteriorVehicleData/009.lua | 60 +++++++++ test_scripts/RC/OnInteriorVehicleData/010.lua | 58 +++++++++ test_scripts/RC/OnInteriorVehicleData/011.lua | 63 ++++++++++ .../RC/OnInteriorVehicleData/012c.lua | 27 ++++ .../RC/OnInteriorVehicleData/012r.lua | 27 ++++ .../RC/OnInteriorVehicleData/013c.lua | 32 +++++ .../RC/OnInteriorVehicleData/013r.lua | 32 +++++ test_scripts/RC/commonRC.lua | 115 +++++++++++++++-- test_sets/rc_OnInteriorVehicleData.txt | 9 ++ 18 files changed, 683 insertions(+), 523 deletions(-) create mode 100644 test_scripts/RC/OnInteriorVehicleData/007.lua create mode 100644 test_scripts/RC/OnInteriorVehicleData/008.lua create mode 100644 test_scripts/RC/OnInteriorVehicleData/009.lua create mode 100644 test_scripts/RC/OnInteriorVehicleData/010.lua create mode 100644 test_scripts/RC/OnInteriorVehicleData/011.lua create mode 100644 test_scripts/RC/OnInteriorVehicleData/012c.lua create mode 100644 test_scripts/RC/OnInteriorVehicleData/012r.lua create mode 100644 test_scripts/RC/OnInteriorVehicleData/013c.lua create mode 100644 test_scripts/RC/OnInteriorVehicleData/013r.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/001.lua b/test_scripts/RC/OnInteriorVehicleData/001.lua index a6c20ae89e..e0aef5459a 100644 --- a/test_scripts/RC/OnInteriorVehicleData/001.lua +++ b/test_scripts/RC/OnInteriorVehicleData/001.lua @@ -3,113 +3,29 @@ -- Script: 001 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') - ---[[ Local Valiables ]] -local climateControlData = { - fanSpeed = 50, - currentTemp = 86, - desiredTemp = 75, - temperatureUnit = "FAHRENHEIT", - acEnable = true, - circulateAirEnable = true, - autoModeEnable = true, - defrostZone = "FRONT", - dualModeEnable = true -} - -local radioControlData = { - frequencyInteger = 1, - frequencyFraction = 2, - band = "AM", - rdsData = { - PS = "ps", - RT = "rt", - CT = "123456789012345678901234", - PI = "pi", - PTY = 2, - TP = false, - TA = true, - REG = "US" - }, - availableHDs = 1, - hdChannel = 1, - signalStrength = 5, - signalChangeThreshold = 20, - radioEnable = true, - state = "ACQUIRING" -} - ---[[ Local Functions ]] -local function getModuleData(moduleType, moduleControlData) - if moduleType == "CLIMATE" then - return {moduleType = moduleType, climateControlData = moduleControlData or commonRC.getClimateControlData()} - end - return {moduleType = moduleType, radioControlData = moduleControlData or commonRC.getRadioControlData()} -end - -local function subscriptionToModule(pModuleType, pSubscribe, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, - subscribe = pSubscribe - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, - subscribe = pSubscribe - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = getModuleData(pModuleType), - isSubscribed = pSubscribe - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - moduleData = getModuleData(pModuleType), - isSubscribed = pSubscribe - }) -end - -local function stepSubscribed(pModuleType, pModuleControlData, self) - self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { - moduleData = getModuleData(pModuleType, pModuleControlData) - }) - - EXPECT_NOTIFICATION("OnInteriorVehicleData", { - moduleData = getModuleData(pModuleType, pModuleControlData) - }) -end +local commonRC = require('test_scripts/RC/commonRC') -local function stepUnsubscribed(pModuleType, pModuleControlData, self) - self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { - moduleData = getModuleData(pModuleType, pModuleControlData) - }) - - EXPECT_NOTIFICATION("OnInteriorVehicleData", {}):Times(0) - commonTestCases:DelayedExp(commonRC.timeout) -end +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) + runner.Title("Test") -runner.Step("Subscribe app to CLIMATE", subscriptionToModule, {"CLIMATE", true}) -runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App subscribed", stepSubscribed, {"CLIMATE", climateControlData}) -runner.Step("Subscribe app to RADIO", subscriptionToModule, {"RADIO", true}) -runner.Step("Send notification OnInteriorVehicleData_RADIO. App subscribed", stepSubscribed, {"RADIO", radioControlData}) -runner.Step("Unsubscribe app to CLIMATE", subscriptionToModule, {"CLIMATE", false}) -runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App unsubscribed", stepUnsubscribed, {"CLIMATE", climateControlData}) -runner.Step("Unsubscribe app to RADIO", subscriptionToModule, {"RADIO", false}) -runner.Step("Send notification OnInteriorVehicleData_RADIO. App unsubscribed", stepUnsubscribed, {"RADIO", radioControlData}) + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", commonRC.isSubscribed, { mod }) +end + +for _, mod in pairs(modules) do + runner.Step("Unsubscribe app to " .. mod, commonRC.unSubscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is unsubscribed", commonRC.isUnsubscribed, { mod }) +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/002c.lua b/test_scripts/RC/OnInteriorVehicleData/002c.lua index 90123945c8..8a7f6e304b 100644 --- a/test_scripts/RC/OnInteriorVehicleData/002c.lua +++ b/test_scripts/RC/OnInteriorVehicleData/002c.lua @@ -3,55 +3,14 @@ -- Script: 002 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') - ---[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "CLIMATE", - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "CLIMATE", - }, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - isSubscribed = true, - moduleData = { - moduleType = "CLIMATE", - climateControlData = commonRC.getClimateControlData() - } - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true }) -end - -local function step2(self) - self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { - moduleData = { - moduleType = "RADIO", - climateControlData = commonRC.getRadioControlData() - } - }) - - EXPECT_NOTIFICATION("OnInteriorVehicleData") - :Times(0) +local commonRC = require('test_scripts/RC/commonRC') - commonTestCases:DelayedExp(commonRC.timeout) -end +--[[ Local Variables ]] +local mod = "CLIMATE" local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { mod } end --[[ Scenario ]] @@ -59,8 +18,10 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) + runner.Title("Test") -runner.Step("GetInteriorVehicleData_CLIMATE", step1) -runner.Step("OnInteriorVehicleData_CLIMATE", step2) +runner.Step("GetInteriorVehicleData " .. mod, commonRC.subscribeToModule, { mod }) +runner.Step("OnInteriorVehicleData " .. mod, commonRC.isUnsubscribed, { "RADIO" }) + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/002r.lua b/test_scripts/RC/OnInteriorVehicleData/002r.lua index e597a0c735..3c8cba3e71 100644 --- a/test_scripts/RC/OnInteriorVehicleData/002r.lua +++ b/test_scripts/RC/OnInteriorVehicleData/002r.lua @@ -3,55 +3,14 @@ -- Script: 002 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') - ---[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "RADIO", - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "RADIO", - }, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - isSubscribed = true, - moduleData = { - moduleType = "RADIO", - radioControlData = commonRC.getRadioControlData() - } - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true }) -end - -local function step2(self) - self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { - moduleData = { - moduleType = "CLIMATE", - radioControlData = commonRC.getClimateControlData() - } - }) - - EXPECT_NOTIFICATION("OnInteriorVehicleData") - :Times(0) +local commonRC = require('test_scripts/RC/commonRC') - commonTestCases:DelayedExp(commonRC.timeout) -end +--[[ Local Variables ]] +local mod = "RADIO" local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { mod } end --[[ Scenario ]] @@ -59,8 +18,10 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) + runner.Title("Test") -runner.Step("GetInteriorVehicleData_RADIO", step1) -runner.Step("OnInteriorVehicleData_RADIO", step2) +runner.Step("GetInteriorVehicleData " .. mod, commonRC.subscribeToModule, { mod }) +runner.Step("OnInteriorVehicleData " .. mod, commonRC.isUnsubscribed, { "CLIMATE" }) + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/003.lua b/test_scripts/RC/OnInteriorVehicleData/003.lua index a03c7459ab..1470927447 100644 --- a/test_scripts/RC/OnInteriorVehicleData/003.lua +++ b/test_scripts/RC/OnInteriorVehicleData/003.lua @@ -3,89 +3,39 @@ -- Script: 003 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') - ---[[ Local Valiables ]] -local climateControlData = { - fanSpeed = 50, - currentTemp = 86, - desiredTemp = 75, - temperatureUnit = "FAHRENHEIT", - acEnable = true, - circulateAirEnable = true, - autoModeEnable = true, - defrostZone = "FRONT", - dualModeEnable = true -} +local commonRC = require('test_scripts/RC/commonRC') -local radioControlData = { - frequencyInteger = 1, - frequencyFraction = 2, - band = "AM", - rdsData = { - PS = "ps", - RT = "rt", - CT = "123456789012345678901234", - PI = "pi", - PTY = 2, - TP = false, - TA = true, - REG = "US" - }, - availableHDs = 1, - hdChannel = 1, - signalStrength = 5, - signalChangeThreshold = 20, - radioEnable = true, - state = "ACQUIRING" -} +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] -local function getModuleData(moduleType, moduleControlData) - if moduleType == "CLIMATE" then - return {moduleType = moduleType, climateControlData = moduleControlData or commonRC.getClimateControlData()} - end - return {moduleType = moduleType, radioControlData = moduleControlData or commonRC.getRadioControlData()} -end - local function subscriptionToModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, - subscribe = true - }) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = getModuleData(pModuleType), - isSubscribed = false -- not subscribe - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - moduleData = getModuleData(pModuleType), - isSubscribed = false - }) -end - - -local function stepUnsubscribed(pModuleType, pModuleControlData, self) - self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { - moduleData = getModuleData(pModuleType, pModuleControlData) - }) - - EXPECT_NOTIFICATION("OnInteriorVehicleData", {}):Times(0) - commonTestCases:DelayedExp(commonRC.timeout) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = false -- not subscribe + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = false + }) end --[[ Scenario ]] @@ -93,10 +43,13 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) + runner.Title("Test") -runner.Step("Subscribe app to CLIMATE (unsuccessful)", subscriptionToModule, {"CLIMATE"}) -runner.Step("Subscribe app to RADIO (unsuccessful)", subscriptionToModule, {"RADIO"}) -runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App is not subscribed", stepUnsubscribed, {"CLIMATE", climateControlData}) -runner.Step("Send notification OnInteriorVehicleData_RADIO. App is not subscribed", stepUnsubscribed, {"RADIO", radioControlData}) + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, subscriptionToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", commonRC.isUnsubscribed, { mod }) +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/004.lua b/test_scripts/RC/OnInteriorVehicleData/004.lua index d7f512d107..8a1df979dd 100644 --- a/test_scripts/RC/OnInteriorVehicleData/004.lua +++ b/test_scripts/RC/OnInteriorVehicleData/004.lua @@ -1,90 +1,41 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 003 +-- Script: 004 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') - ---[[ Local Valiables ]] -local climateControlData = { - fanSpeed = 50, - currentTemp = 86, - desiredTemp = 75, - temperatureUnit = "FAHRENHEIT", - acEnable = true, - circulateAirEnable = true, - autoModeEnable = true, - defrostZone = "FRONT", - dualModeEnable = true -} +local commonRC = require('test_scripts/RC/commonRC') -local radioControlData = { - frequencyInteger = 1, - frequencyFraction = 2, - band = "AM", - rdsData = { - PS = "ps", - RT = "rt", - CT = "123456789012345678901234", - PI = "pi", - PTY = 2, - TP = false, - TA = true, - REG = "US" - }, - availableHDs = 1, - hdChannel = 1, - signalStrength = 5, - signalChangeThreshold = 20, - radioEnable = true, - state = "ACQUIRING" -} +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] -local function getModuleData(moduleType, moduleControlData) - if moduleType == "CLIMATE" then - return {moduleType = moduleType, climateControlData = moduleControlData or commonRC.getClimateControlData()} - end - return {moduleType = moduleType, radioControlData = moduleControlData or commonRC.getRadioControlData()} -end - local function subscriptionToModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, - subscribe = true - }) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = getModuleData(pModuleType), - -- no isSubscribed parameter - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - moduleData = getModuleData(pModuleType), - isSubscribed = false - }) -end - -local function stepUnsubscribed(pModuleType, pModuleControlData, self) - self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { - moduleData = getModuleData(pModuleType, pModuleControlData) - }) - - EXPECT_NOTIFICATION("OnInteriorVehicleData", {}):Times(0) - commonTestCases:DelayedExp(commonRC.timeout) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + -- no isSubscribed parameter + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = false + }) end --[[ Scenario ]] @@ -92,10 +43,13 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) + runner.Title("Test") -runner.Step("Subscribe app to CLIMATE (no isSubscribed parameter)", subscriptionToModule, {"CLIMATE"}) -runner.Step("Subscribe app to RADIO (no isSubscribed parameter)", subscriptionToModule, {"RADIO"}) -runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App is not subscribed", stepUnsubscribed, {"CLIMATE", climateControlData}) -runner.Step("Send notification OnInteriorVehicleData_RADIO. App is not subscribed", stepUnsubscribed, {"RADIO", radioControlData}) + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, subscriptionToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", commonRC.isUnsubscribed, { mod }) +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/005.lua b/test_scripts/RC/OnInteriorVehicleData/005.lua index 6a34985dae..322288f08d 100644 --- a/test_scripts/RC/OnInteriorVehicleData/005.lua +++ b/test_scripts/RC/OnInteriorVehicleData/005.lua @@ -1,84 +1,36 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 004 +-- Script: 005 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +local commonRC = require('test_scripts/RC/commonRC') --[[ Local Valiables ]] -local climateControlData = { - fanSpeed = 50, - currentTemp = 86, - desiredTemp = 75, - temperatureUnit = "FAHRENHEIT", - acEnable = true, - circulateAirEnable = true, - autoModeEnable = true, - defrostZone = "FRONT", - dualModeEnable = true -} - -local radioControlData = { - frequencyInteger = 1, - frequencyFraction = 2, - band = "AM", - rdsData = { - PS = "ps", - RT = "rt", - CT = "123456789012345678901234", - PI = "pi", - PTY = 2, - TP = false, - TA = true, - REG = "US" - }, - availableHDs = 1, - hdChannel = 1, - signalStrength = 5, - signalChangeThreshold = 20, - radioEnable = true, - state = "ACQUIRING" -} +local modules = { "CLIMATE", "RADIO" } +local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } --[[ Local Functions ]] -local function getModuleData(moduleType, moduleControlData) - if moduleType == "CLIMATE" then - return {moduleType = moduleType, climateControlData = moduleControlData or commonRC.getClimateControlData()} - end - return {moduleType = moduleType, radioControlData = moduleControlData or commonRC.getRadioControlData()} -end - local function subscriptionToModule(pModuleType, pResultCode, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, - subscribe = true - }) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") - end) + self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") + end) - EXPECT_RESPONSE(cid, { success = false, resultCode = pResultCode}) -end - -local function stepUnsubscribed(pModuleType, pModuleControlData, self) - self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { - moduleData = getModuleData(pModuleType, pModuleControlData) - }) - - EXPECT_NOTIFICATION("OnInteriorVehicleData", {}):Times(0) - commonTestCases:DelayedExp(commonRC.timeout) + EXPECT_RESPONSE(cid, { success = false, resultCode = pResultCode }) end --[[ Scenario ]] @@ -86,22 +38,15 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) + runner.Title("Test") -runner.Step("Subscribe app to CLIMATE (GENERIC_ERROR from HMI)", subscriptionToModule, {"CLIMATE", "GENERIC_ERROR"}) -runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App is not subscribed", stepUnsubscribed, {"CLIMATE", climateControlData}) -runner.Step("Subscribe app to CLIMATE (INVALID_DATA from HMI)", subscriptionToModule, {"CLIMATE", "INVALID_DATA"}) -runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App is not subscribed", stepUnsubscribed, {"CLIMATE", climateControlData}) -runner.Step("Subscribe app to CLIMATE (OUT_OF_MEMORY from HMI)", subscriptionToModule, {"CLIMATE", "OUT_OF_MEMORY"}) -runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App is not subscribed", stepUnsubscribed, {"CLIMATE", climateControlData}) -runner.Step("Subscribe app to CLIMATE (REJECTED from HMI)", subscriptionToModule, {"CLIMATE", "REJECTED"}) -runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App is not subscribed", stepUnsubscribed, {"CLIMATE", climateControlData}) -runner.Step("Subscribe app to RADIO (GENERIC_ERROR from HMI)", subscriptionToModule, {"RADIO", "GENERIC_ERROR"}) -runner.Step("Send notification OnInteriorVehicleData RADIO. App is not subscribed", stepUnsubscribed, {"RADIO", radioControlData}) -runner.Step("Subscribe app to RADIO (INVALID_DATA from HMI)", subscriptionToModule, {"RADIO", "INVALID_DATA"}) -runner.Step("Send notification OnInteriorVehicleData RADIO. App is not subscribed", stepUnsubscribed, {"RADIO", radioControlData}) -runner.Step("Subscribe app to RADIO (OUT_OF_MEMORY from HMI)", subscriptionToModule, {"RADIO", "OUT_OF_MEMORY"}) -runner.Step("Send notification OnInteriorVehicleData RADIO. App is not subscribed", stepUnsubscribed, {"RADIO", radioControlData}) -runner.Step("Subscribe app to RADIO (REJECTED from HMI)", subscriptionToModule, {"RADIO", "REJECTED"}) -runner.Step("Send notification OnInteriorVehicleData RADIO. App is not subscribed", stepUnsubscribed, {"RADIO", radioControlData}) + +for _, mod in pairs(modules) do + for _, err in pairs(error_codes) do + runner.Step("Subscribe app to " .. mod .. " (" .. err .. " from HMI)", subscriptionToModule, { mod, err }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", commonRC.isUnsubscribed, { mod }) + end +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/006.lua b/test_scripts/RC/OnInteriorVehicleData/006.lua index cd3b2f73f0..0b04f12ecf 100644 --- a/test_scripts/RC/OnInteriorVehicleData/006.lua +++ b/test_scripts/RC/OnInteriorVehicleData/006.lua @@ -1,86 +1,38 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 004 +-- Script: 006 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ Local Valiables ]] -local climateControlData = { - fanSpeed = 50, - currentTemp = 86, - desiredTemp = 75, - temperatureUnit = "FAHRENHEIT", - acEnable = true, - circulateAirEnable = true, - autoModeEnable = true, - defrostZone = "FRONT", - dualModeEnable = true -} - -local radioControlData = { - frequencyInteger = 1, - frequencyFraction = 2, - band = "AM", - rdsData = { - PS = "ps", - RT = "rt", - CT = "123456789012345678901234", - PI = "pi", - PTY = 2, - TP = false, - TA = true, - REG = "US" - }, - availableHDs = 1, - hdChannel = 1, - signalStrength = 5, - signalChangeThreshold = 20, - radioEnable = true, - state = "ACQUIRING" -} +local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] -local function getModuleData(moduleType, moduleControlData) - if moduleType == "CLIMATE" then - return {moduleType = moduleType, climateControlData = moduleControlData or commonRC.getClimateControlData()} - end - return {moduleType = moduleType, radioControlData = moduleControlData or commonRC.getRadioControlData()} -end - local function subscriptionToModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, - subscribe = true - }) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) :Do(function(_, _) - -- no response from HMI - end) + -- no response from HMI + end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) - commonTestCases:DelayedExp(11000) -end - -local function stepUnsubscribed(pModuleType, pModuleControlData, self) - self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { - moduleData = getModuleData(pModuleType, pModuleControlData) - }) - - EXPECT_NOTIFICATION("OnInteriorVehicleData", {}):Times(0) - commonTestCases:DelayedExp(commonRC.timeout) + commonTestCases:DelayedExp(11000) end --[[ Scenario ]] @@ -88,10 +40,13 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) + runner.Title("Test") -runner.Step("Subscribe app to CLIMATE (no response from HMI)", subscriptionToModule, {"CLIMATE"}) -runner.Step("Send notification OnInteriorVehicleData_CLIMATE. App is not subscribed", stepUnsubscribed, {"CLIMATE", climateControlData}) -runner.Step("Subscribe app to RADIO (no responsefrom HMI)", subscriptionToModule, {"RADIO"}) -runner.Step("Send notification OnInteriorVehicleData RADIO. App is not subscribed", stepUnsubscribed, {"RADIO", radioControlData}) + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, subscriptionToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", commonRC.isUnsubscribed, { mod }) +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/007.lua b/test_scripts/RC/OnInteriorVehicleData/007.lua new file mode 100644 index 0000000000..69a06e123e --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/007.lua @@ -0,0 +1,52 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 007 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Valiables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function subscriptionToModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = 123, -- invalid data + isSubscribed = true + }) + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, subscriptionToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", commonRC.isUnsubscribed, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/008.lua b/test_scripts/RC/OnInteriorVehicleData/008.lua new file mode 100644 index 0000000000..5d499110f6 --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/008.lua @@ -0,0 +1,60 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 008 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function unSubscriptionToModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = false + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = false + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = true -- HMI responds with true + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = true + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", commonRC.isSubscribed, { mod }) +end + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, unSubscriptionToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App still subscribed", commonRC.isSubscribed, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/009.lua b/test_scripts/RC/OnInteriorVehicleData/009.lua new file mode 100644 index 0000000000..d39c655fe2 --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/009.lua @@ -0,0 +1,60 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 009 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function unSubscriptionToModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = false + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = false + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + -- no isSubscribed parameter + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = true + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", commonRC.isSubscribed, { mod }) +end + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, unSubscriptionToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App still subscribed", commonRC.isSubscribed, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/010.lua b/test_scripts/RC/OnInteriorVehicleData/010.lua new file mode 100644 index 0000000000..f4d8f00dcf --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/010.lua @@ -0,0 +1,58 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 010 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } + +--[[ Local Functions ]] +local function unSubscriptionToModule(pModuleType, pResultCode, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = false + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = false + }) + :Do(function(_, data) + self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") + -- no isSubscribed parameter + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = pResultCode }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App subscribed", commonRC.isSubscribed, { mod }) +end + +runner.Title("Test") + +for _, mod in pairs(modules) do + for _, err in pairs(error_codes) do + runner.Step("Unsubscribe app to " .. mod .. " (" .. err .. " from HMI)", unSubscriptionToModule, { mod, err }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App still subscribed", commonRC.isSubscribed, { mod }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/011.lua b/test_scripts/RC/OnInteriorVehicleData/011.lua new file mode 100644 index 0000000000..47ff3855d0 --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/011.lua @@ -0,0 +1,63 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 011 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local error_codes = { + { name = "GENERIC_ERROR", id = 22 }, + { name = "INVALID_DATA", id = 11 }, + { name = "OUT_OF_MEMORY", id = 17 }, + { name = "REJECTED", id = 4 } +} + +--[[ Local Functions ]] +local function unSubscriptionToModule(pModuleType, pResultCodeName, pResultCodeId, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = false + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = false + }) + :Do(function(_, data) + self.hmiConnection:Send('{"error":{"data":{"method":"' .. data.method .. '"},"params":{"isSubscribed":false},' + .. '"message":"error message","code":' .. pResultCodeId .. '},"jsonrpc":"2.0","id":' .. data.id .. '}') + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = pResultCodeName }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App subscribed", commonRC.isSubscribed, { mod }) +end + +runner.Title("Test") + +for _, mod in pairs(modules) do + for _, err in pairs(error_codes) do + runner.Step("Unsubscribe app to " .. mod .. " (" .. err.name .. " from HMI)", unSubscriptionToModule, { mod, err.name, err.id }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App still subscribed", commonRC.isSubscribed, { mod }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/012c.lua b/test_scripts/RC/OnInteriorVehicleData/012c.lua new file mode 100644 index 0000000000..164a8d27b6 --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/012c.lua @@ -0,0 +1,27 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 012 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local mod1 = "CLIMATE" +local mod2 = "RADIO" + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +runner.Title("Test") + +runner.Step("Subscribe app to " .. mod1, commonRC.subscribeToModule, { mod1 }) +runner.Step("Send notification OnInteriorVehicleData " .. mod1 .. ". App is subscribed", commonRC.isSubscribed, { mod1 }) + +runner.Step("Send notification OnInteriorVehicleData " .. mod2 .. ". App is not subscribed", commonRC.isUnsubscribed, { mod2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/012r.lua b/test_scripts/RC/OnInteriorVehicleData/012r.lua new file mode 100644 index 0000000000..47f2f71cce --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/012r.lua @@ -0,0 +1,27 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 012 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local mod1 = "RADIO" +local mod2 = "CLIMATE" + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +runner.Title("Test") + +runner.Step("Subscribe app to " .. mod1, commonRC.subscribeToModule, { mod1 }) +runner.Step("Send notification OnInteriorVehicleData " .. mod1 .. ". App is subscribed", commonRC.isSubscribed, { mod1 }) + +runner.Step("Send notification OnInteriorVehicleData " .. mod2 .. ". App is not subscribed", commonRC.isUnsubscribed, { mod2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/013c.lua b/test_scripts/RC/OnInteriorVehicleData/013c.lua new file mode 100644 index 0000000000..4a5f704c3d --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/013c.lua @@ -0,0 +1,32 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 012 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local mod1 = "RADIO" +local mod2 = "CLIMATE" + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", commonRC.isSubscribed, { mod }) +end + +runner.Title("Test") + +runner.Step("Unsubscribe app to " .. mod1, commonRC.unSubscribeToModule, { mod1 }) +runner.Step("Send notification OnInteriorVehicleData " .. mod1 .. ". App is unsubscribed", commonRC.isUnsubscribed, { mod1 }) +runner.Step("Send notification OnInteriorVehicleData " .. mod2 .. ". App is still subscribed", commonRC.isSubscribed, { mod2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/013r.lua b/test_scripts/RC/OnInteriorVehicleData/013r.lua new file mode 100644 index 0000000000..61158ee9a3 --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/013r.lua @@ -0,0 +1,32 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 012 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local mod1 = "CLIMATE" +local mod2 = "RADIO" + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", commonRC.isSubscribed, { mod }) +end + +runner.Title("Test") + +runner.Step("Unsubscribe app to " .. mod1, commonRC.unSubscribeToModule, { mod1 }) +runner.Step("Send notification OnInteriorVehicleData " .. mod1 .. ". App is unsubscribed", commonRC.isUnsubscribed, { mod1 }) +runner.Step("Send notification OnInteriorVehicleData " .. mod2 .. ". App is still subscribed", commonRC.isSubscribed, { mod2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 1c8cf0d8fc..adb4763888 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleData --- Common module +-- RC common module --------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" @@ -13,6 +12,7 @@ config.application2.registerAppInterfaceParams.appHMIType = nil local commonPreconditions = require("user_modules/shared_testcases/commonPreconditions") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") local mobile_session = require("mobile_session") local json = require("modules/json") @@ -47,10 +47,6 @@ local function generateRandomValueFromList(list) return list[math.random(#list)] end -local function generateRandomValueFromIntInterval(min, max) - return math.random(min, max) -end - local function generateRandomArrayFromList(list, isValUnique, min, max) max = max or min if max < min then @@ -430,6 +426,58 @@ function commonRC.getRadioControlData() } end +function commonRC.getModuleControlData(module_type) + local out = { moduleType = module_type } + if module_type == "CLIMATE" then + out.climateControlData = commonRC.getClimateControlData() + elseif module_type == "RADIO" then + out.radioControlData = commonRC.getRadioControlData() + end + return out +end + +function commonRC.getAnotherModuleControlData(module_type) + local out = { moduleType = module_type } + local climateControlData = { + fanSpeed = 50, + currentTemp = 86, + desiredTemp = 75, + temperatureUnit = "FAHRENHEIT", + acEnable = true, + circulateAirEnable = true, + autoModeEnable = true, + defrostZone = "FRONT", + dualModeEnable = true + } + local radioControlData = { + frequencyInteger = 1, + frequencyFraction = 2, + band = "AM", + rdsData = { + PS = "ps", + RT = "rt", + CT = "123456789012345678901234", + PI = "pi", + PTY = 2, + TP = false, + TA = true, + REG = "US" + }, + availableHDs = 1, + hdChannel = 1, + signalStrength = 5, + signalChangeThreshold = 20, + radioEnable = true, + state = "ACQUIRING" + } + if module_type == "CLIMATE" then + out.climateControlData = climateControlData + elseif module_type == "RADIO" then + out.radioControlData = radioControlData + end + return out +end + function commonRC.getClimateControlCapabilities() return climateControlCapabilities end @@ -467,12 +515,59 @@ function commonRC.getMobileSession(self, id) return self.mobileSession end -function commonRC.consent(self) - EXPECT_HMICALL("RC.GetInteriorVehicleDataConsent") - :Times(1) +local function subscriptionToModule(pModuleType, pSubscribe, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = pSubscribe + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = pSubscribe + }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { allowed = true }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = pSubscribe + }) end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = pSubscribe + }) +end + +function commonRC.subscribeToModule(pModuleType, self) + subscriptionToModule(pModuleType, true, self) +end + +function commonRC.unSubscribeToModule(pModuleType, self) + subscriptionToModule(pModuleType, false, self) +end + +function commonRC.isSubscribed(pModuleType, self) + self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + moduleData = commonRC.getAnotherModuleControlData(pModuleType) + }) + + EXPECT_NOTIFICATION("OnInteriorVehicleData", { + moduleData = commonRC.getAnotherModuleControlData(pModuleType) + }) +end + +function commonRC.isUnsubscribed(pModuleType, self) + self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + moduleData = commonRC.getAnotherModuleControlData(pModuleType) + }) + + EXPECT_NOTIFICATION("OnInteriorVehicleData", {}):Times(0) + commonTestCases:DelayedExp(commonRC.timeout) end return commonRC diff --git a/test_sets/rc_OnInteriorVehicleData.txt b/test_sets/rc_OnInteriorVehicleData.txt index b159c7ba9a..e6ea47bd63 100644 --- a/test_sets/rc_OnInteriorVehicleData.txt +++ b/test_sets/rc_OnInteriorVehicleData.txt @@ -5,3 +5,12 @@ ./test_scripts/RC/OnInteriorVehicleData/004.lua ./test_scripts/RC/OnInteriorVehicleData/005.lua ./test_scripts/RC/OnInteriorVehicleData/006.lua +./test_scripts/RC/OnInteriorVehicleData/007.lua +./test_scripts/RC/OnInteriorVehicleData/008.lua +./test_scripts/RC/OnInteriorVehicleData/009.lua +./test_scripts/RC/OnInteriorVehicleData/010.lua +./test_scripts/RC/OnInteriorVehicleData/011.lua +./test_scripts/RC/OnInteriorVehicleData/012c.lua +./test_scripts/RC/OnInteriorVehicleData/012r.lua +./test_scripts/RC/OnInteriorVehicleData/013c.lua +./test_scripts/RC/OnInteriorVehicleData/013r.lua From ad45d6fe18df1a8141cfb1b1c26acbc9b9e7bf7b Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Tue, 18 Jul 2017 14:19:23 +0300 Subject: [PATCH 023/681] Remove GetInteriorVehicleDataCapabilities --- .../001.lua | 51 ------ .../002.lua | 47 ------ .../003.lua | 47 ------ .../004.lua | 36 ----- .../005.lua | 36 ----- .../006.lua | 40 ----- .../007.lua | 43 ------ .../008.lua | 46 ------ .../009.lua | 37 ----- .../010.lua | 30 ---- .../011.lua | 49 ------ .../012.lua | 46 ------ .../013.lua | 45 ------ .../014.lua | 36 ----- .../015.lua | 64 -------- .../016.lua | 41 ----- .../017.lua | 67 -------- .../018.lua | 54 ------- .../099_not_completed.lua | 59 ------- test_scripts/RC/commonRC.lua | 146 ------------------ .../rc_GetInteriorVehicleDataCapabilities.txt | 18 --- 21 files changed, 1038 deletions(-) delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/001.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/002.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/003.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/004.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/005.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/006.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/007.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/008.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/009.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/010.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/011.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/012.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/013.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/014.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/015.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/016.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/017.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/018.lua delete mode 100644 test_scripts/RC/GetInteriorVehicleDataCapabilities/099_not_completed.lua delete mode 100644 test_sets/rc_GetInteriorVehicleDataCapabilities.txt diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/001.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/001.lua deleted file mode 100644 index 0102b50186..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/001.lua +++ /dev/null @@ -1,51 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 001 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') - ---[[ Local Functions ]] -local function step(module_types, self) - self, module_types = commonRC.getSelfAndParams(module_types, self) - - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = module_types - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { - appID = self.applications["Test Application"], - moduleTypes = module_types - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) - }) - end) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataConsent") - :Times(0) - - EXPECT_RESPONSE(cid, { - success = true, - resultCode = "SUCCESS", - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) - }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) -runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE_RADIO", step, { { "CLIMATE", "RADIO" } }) -runner.Step("GetInteriorVehicleDataCapabilities_absent", step, { nil }) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/002.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/002.lua deleted file mode 100644 index 89adfd5c49..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/002.lua +++ /dev/null @@ -1,47 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 002 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') - ---[[ Local Functions ]] -local function step(module_types, self) - self, module_types = commonRC.getSelfAndParams(module_types, self) - - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = module_types - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { - appID = self.applications["Test Application"], - moduleTypes = { "CLIMATE" } - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities({ "CLIMATE" }) - }) - end) - - EXPECT_RESPONSE(cid, { - success = true, - resultCode = "SUCCESS", - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities({ "CLIMATE" }) - }) -end - -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE_both", step, { { "CLIMATE", "RADIO" } }) -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE_absent", step, { nil }) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/003.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/003.lua deleted file mode 100644 index 61281884ae..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/003.lua +++ /dev/null @@ -1,47 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 003 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') - ---[[ Local Functions ]] -local function step(module_types, self) - self, module_types = commonRC.getSelfAndParams(module_types, self) - - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = module_types - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { - appID = self.applications["Test Application"], - moduleTypes = { "RADIO" } - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities({ "RADIO" }) - }) - end) - - EXPECT_RESPONSE(cid, { - success = true, - resultCode = "SUCCESS", - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities({ "RADIO" }) - }) -end - -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_RADIO_both", step, { { "CLIMATE", "RADIO" } }) -runner.Step("GetInteriorVehicleDataCapabilities_RADIO_absent", step, { nil }) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/004.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/004.lua deleted file mode 100644 index ce4ed6fd4f..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/004.lua +++ /dev/null @@ -1,36 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 004 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') - ---[[ Local Functions ]] -local function step(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = { "CLIMATE" } - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", {}) - :Times(0) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/005.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/005.lua deleted file mode 100644 index a0a4570884..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/005.lua +++ /dev/null @@ -1,36 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 005 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') - ---[[ Local Functions ]] -local function step(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = { "RADIO" } - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", {}) - :Times(0) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/006.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/006.lua deleted file mode 100644 index b0903ae6b9..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/006.lua +++ /dev/null @@ -1,40 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 006 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') - ---[[ General configuration parameters ]] -config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } - ---[[ Local Functions ]] -local function step(module_types, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = module_types - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities") - :Times(0) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].AppHMIType = { "DEFAULT" } -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) -runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/007.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/007.lua deleted file mode 100644 index 602b0628ee..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/007.lua +++ /dev/null @@ -1,43 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 007 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') - ---[[ Local Functions ]] -local function step(module_types, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = { "CLIMATE", "RADIO" } - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { - appID = self.applications["Test Application"], - moduleTypes = { "CLIMATE", "RADIO" } - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "WARNINGS", { - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types), - info = "Radio module is not available" - }) - end) - - EXPECT_RESPONSE(cid, { - success = true, - resultCode = "WARNINGS", - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types), - info = "Radio module is not available" - }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) -runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/008.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/008.lua deleted file mode 100644 index 110925d745..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/008.lua +++ /dev/null @@ -1,46 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 008 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') -local json = require('modules/json') - ---[[ Local Functions ]] -local function step(module_types, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = module_types - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { - appID = self.applications["Test Application"], - moduleTypes = module_types - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) - }) - end) - - EXPECT_RESPONSE(cid, { - success = true, - resultCode = "SUCCESS", - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) - }) -end - -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) -runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/009.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/009.lua deleted file mode 100644 index 616d049bba..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/009.lua +++ /dev/null @@ -1,37 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 009 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') - ---[[ Local Functions ]] -local function step(module_types, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = module_types - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", {}) - :Times(0) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) -runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/010.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/010.lua deleted file mode 100644 index d3dc0a64cc..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/010.lua +++ /dev/null @@ -1,30 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 010 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') - ---[[ Local Functions ]] -local function step(module_types, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = module_types - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", {}) - :Times(0) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_fake_value", step, { { "FAKE_VALUE" } }) -runner.Step("GetInteriorVehicleDataCapabilities_invalid_type", step, { 1 }) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/011.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/011.lua deleted file mode 100644 index c985cb5329..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/011.lua +++ /dev/null @@ -1,49 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 011 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') - ---[[ Local Variables ]] -local interiorVehicleDataCapabilitiesTable = { - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities({"RADIO", "CLIMATE"}) -} ---[[ Local Functions ]] -local function step(module_types, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = module_types - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { - appID = self.applications["Test Application"], - moduleTypes = module_types - }) - :Do(function() - -- self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - -- interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) - -- }) - end) - - EXPECT_RESPONSE(cid, { - success = true, - resultCode = "SUCCESS", - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) - }) - - commonTestCases:DelayedExp(11000) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Prepare InteriorVehicleDataCapabilities.json", commonRC.prepareInteriorVehicleDataCapabilitiesJson, {interiorVehicleDataCapabilitiesTable}) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) -runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/012.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/012.lua deleted file mode 100644 index 656819384b..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/012.lua +++ /dev/null @@ -1,46 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 012 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') - ---[[ Local Variables ]] -local interiorVehicleDataCapabilitiesTable = { - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities({"RADIO", "CLIMATE"}) -} ---[[ Local Functions ]] -local function step(module_types, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = module_types - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { - appID = self.applications["Test Application"], - moduleTypes = module_types - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - interiorVehicleDataCapabilities = "fake_value" - }) - end) - - EXPECT_RESPONSE(cid, { - success = true, - resultCode = "SUCCESS", - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) - }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Prepare InteriorVehicleDataCapabilities.json", commonRC.prepareInteriorVehicleDataCapabilitiesJson, {interiorVehicleDataCapabilitiesTable}) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) -runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/013.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/013.lua deleted file mode 100644 index f5a92c2caa..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/013.lua +++ /dev/null @@ -1,45 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 013 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') - ---[[ Local Variables ]] -local interiorVehicleDataCapabilitiesTable = { - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities({"RADIO", "CLIMATE"}) -} - ---[[ Local Functions ]] -local function step(module_types, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = module_types - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { - appID = self.applications["Test Application"], - moduleTypes = module_types - }) - :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Read only parameters") - end) - - EXPECT_RESPONSE(cid, { - success = true, - resultCode = "SUCCESS", - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) - }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Prepare InteriorVehicleDataCapabilities.json", commonRC.prepareInteriorVehicleDataCapabilitiesJson, {interiorVehicleDataCapabilitiesTable}) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) -runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/014.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/014.lua deleted file mode 100644 index aa1cd39adb..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/014.lua +++ /dev/null @@ -1,36 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 014 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') - ---[[ Local Functions ]] -local function step(module_types, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = module_types - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { - appID = self.applications["Test Application"], - moduleTypes = module_types - }) - :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Read only parameters") - end) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Remove InteriorVehicleDataCapabilities.json", commonRC.prepareInteriorVehicleDataCapabilitiesJson) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) -runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) \ No newline at end of file diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/015.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/015.lua deleted file mode 100644 index 50513c7d1d..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/015.lua +++ /dev/null @@ -1,64 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 015 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') - ---[[ Local Variables ]] -local interiorVehicleDataCapabilitiesTable = { - interiorVehicleDataCapabilities = { - climateVehicleCapabilities = { - circulateAirEnableAvailable = false, - defrostZone = "ALL", - defrostZoneAvailable = true, - desiredTemperatureAvailable = false, - dualModeEnableAvailable = true, - fanSpeedAvailable = false, - name = "Climate control module", - fake_param = "bad param", -- fake param - }, - radioControlCapabilities = { - availableHDsAvailable = false, - hdChannelAvailable = true, - name = "Radio control module", - radioBandAvailable = 128.3, -- wrong type - radioEnableAvailable = false, - radioFrequencyAvailable = false, - rdsDataAvailable = false, - signalChangeThresholdAvailable = "true", -- wrong type - signalStrengthAvailable = false, - stateAvailable = false - } - } -} - ---[[ Local Functions ]] -local function step(module_types, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = module_types - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { - appID = self.applications["Test Application"], - moduleTypes = module_types - }) - :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Read only parameters") - end) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Prepare InteriorVehicleDataCapabilities.json", commonRC.prepareInteriorVehicleDataCapabilitiesJson, {interiorVehicleDataCapabilitiesTable}) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) -runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/016.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/016.lua deleted file mode 100644 index fe6b1e4cf7..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/016.lua +++ /dev/null @@ -1,41 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 016 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') - ---[[ Local Functions ]] -local function step(module_types, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = module_types - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { - appID = self.applications["Test Application"], - moduleTypes = module_types - }) - :Do(function() - -- self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - -- interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) - -- }) - end) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) - - commonTestCases:DelayedExp(11000) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Remove InteriorVehicleDataCapabilities.json", commonRC.prepareInteriorVehicleDataCapabilitiesJson) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) -runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) \ No newline at end of file diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/017.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/017.lua deleted file mode 100644 index 7421836062..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/017.lua +++ /dev/null @@ -1,67 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 017 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') - ---[[ Local Variables ]] -local interiorVehicleDataCapabilitiesTable = { - interiorVehicleDataCapabilities = { - climateVehicleCapabilities = { - circulateAirEnableAvailable = false, - defrostZone = "ALL", - defrostZoneAvailable = true, - desiredTemperatureAvailable = false, - dualModeEnableAvailable = true, - fanSpeedAvailable = false, - name = "Climate control module", - fake_param = "bad param", -- fake param - }, - radioControlCapabilities = { - availableHDsAvailable = false, - hdChannelAvailable = true, - name = "Radio control module", - radioBandAvailable = 128.3, -- wrong type - radioEnableAvailable = false, - radioFrequencyAvailable = false, - rdsDataAvailable = false, - signalChangeThresholdAvailable = "true", -- wrong type - signalStrengthAvailable = false, - stateAvailable = false - } - } -} - ---[[ Local Functions ]] -local function step(module_types, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = module_types - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { - appID = self.applications["Test Application"], - moduleTypes = module_types - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - interiorVehicleDataCapabilities = interiorVehicleDataCapabilitiesTable.interiorVehicleDataCapabilities - }) - end) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) - -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Remove InteriorVehicleDataCapabilities.json", commonRC.prepareInteriorVehicleDataCapabilitiesJson) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) -runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) \ No newline at end of file diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/018.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/018.lua deleted file mode 100644 index 0edf04b7c0..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/018.lua +++ /dev/null @@ -1,54 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 018 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') -local commonFunctions = require("user_modules/shared_testcases/commonFunctions") - ---[[ Local Variables ]] -local interiorVehicleDataCapabilitiesTable = { - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities({"RADIO", "CLIMATE"}) -} - ---[[ Local Functions ]] -local function step(module_types, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = module_types - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { - appID = self.applications["Test Application"], - moduleTypes = module_types - }) - :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, "INVALID_DATA", "Invalid data") - end) - - EXPECT_RESPONSE(cid, { - success = true, - resultCode = "SUCCESS", - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) - }) - -end - -local function setEmptyInteriorVDCapabilitiesFile() - commonFunctions:write_parameter_to_smart_device_link_ini("InteriorVDCapabilitiesFile", "") -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Prepare InteriorVehicleDataCapabilities.json", - commonRC.prepareInteriorVehicleDataCapabilitiesJson, - {interiorVehicleDataCapabilitiesTable, "InteriorVehicleDataCapabilities.json"}) -runner.Step("Set empty InteriorVDCapabilitiesFile field in smartDeviceLink.ini", setEmptyInteriorVDCapabilitiesFile) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE", step, { { "CLIMATE" } }) -runner.Step("GetInteriorVehicleDataCapabilities_RADIO", step, { { "RADIO" } }) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) \ No newline at end of file diff --git a/test_scripts/RC/GetInteriorVehicleDataCapabilities/099_not_completed.lua b/test_scripts/RC/GetInteriorVehicleDataCapabilities/099_not_completed.lua deleted file mode 100644 index de0f2e0057..0000000000 --- a/test_scripts/RC/GetInteriorVehicleDataCapabilities/099_not_completed.lua +++ /dev/null @@ -1,59 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleDataCapabilities --- Script: 099 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') -local runner = require('user_modules/script_runner') - ---[[ Local Functions ]] -local function step(id, module_types, self) - local session = commonRC.getMobileSession(self, id) - - local cid = session:SendRPC("GetInteriorVehicleDataCapabilities", { - moduleTypes = module_types - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleDataCapabilities", { - appID = self.applications[config["application" .. id].registerAppInterfaceParams.appID], - moduleTypes = module_types - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) - }) - end) - - session:ExpectResponse(cid, { - success = true, - resultCode = "SUCCESS", - interiorVehicleDataCapabilities = commonRC.getInteriorVehicleDataCapabilities(module_types) - }) -end - -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = { - keep_context = false, - steal_focus = false, - priority = "NONE", - default_hmi = "NONE", - moduleType = { "RADIO", "CLIMATE" }, - groups = { "Base-4" }, - groups_primaryRC = { "Base-4", "RemoteControl" }, - AppHMIType = { "REMOTE_CONTROL" } - } -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Title("Test") -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE_App1", step, { 1, { "CLIMATE" } }) -runner.Step("GetInteriorVehicleDataCapabilities_CLIMATE_App2", step, { 2, { "CLIMATE" } }) -runner.Step("GetInteriorVehicleDataCapabilities_RADIO_App1", step, { 1, { "RADIO" } }) -runner.Step("GetInteriorVehicleDataCapabilities_RADIO_App2", step, { 2, { "RADIO" } }) -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index adb4763888..5dc45bd21b 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -9,7 +9,6 @@ config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application2.registerAppInterfaceParams.appHMIType = nil --[[ Required Shared libraries ]] -local commonPreconditions = require("user_modules/shared_testcases/commonPreconditions") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") @@ -18,11 +17,6 @@ local json = require("modules/json") --[[ Local Variables ]] local ptu_table = {} -local radioControlCapabilities; -local climateControlCapabilities - -local backupedFiles = {} -local createdFiles = {} --[[ Local Functions ]] local function insertFunctions() @@ -36,87 +30,6 @@ end insertFunctions() -local function initRandom() - math.randomseed( os.time() ) - math.random() - math.random() - math.random() -end - -local function generateRandomValueFromList(list) - return list[math.random(#list)] -end - -local function generateRandomArrayFromList(list, isValUnique, min, max) - max = max or min - if max < min then - min, max = max, min - end - - local isVariableLength = true - if min == max then isVariableLength = false end - local values = {table.unpack(list)} - - local count = min - if count > #values and isValUnique and not isVariableLength then - return error("Random array with " .. min .. " unique elements can not be generated from current list") - end - - if isVariableLength then - count = math.random(min, max) - end - - local result = {} - for _ = 1, count do - local randVal = math.random(#values) - table.insert(result, values[randVal]) - if isValUnique then - table.remove(values, randVal) - end - end - return result -end - -local function generateRadioControlCapabilities() - return { - name = "Radio control module", - radioEnableAvailable = generateRandomValueFromList({true, false}), - radioBandAvailable = generateRandomValueFromList({true, false}), - radioFrequencyAvailable = generateRandomValueFromList({true, false}), - hdChannelAvailable = generateRandomValueFromList({true, false}), - rdsDataAvailable = generateRandomValueFromList({true, false}), - availableHDsAvailable = generateRandomValueFromList({true, false}), - stateAvailable = generateRandomValueFromList({true, false}), - signalStrengthAvailable = generateRandomValueFromList({true, false}), - signalChangeThresholdAvailable = generateRandomValueFromList({true, false}) - } -end - -local function generateClimateControlCapabilities() - return { - name = "Climate control module", - fanSpeedAvailable = generateRandomValueFromList({true, false}), - desiredTemperatureAvailable = generateRandomValueFromList({true, false}), - acEnableAvailable = generateRandomValueFromList({true, false}), - acMaxEnableAvailable = generateRandomValueFromList({true, false}), - circulateAirEnableAvailable = generateRandomValueFromList({true, false}), - autoModeEnableAvailable = generateRandomValueFromList({true, false}), - dualModeEnableAvailable = generateRandomValueFromList({true, false}), - defrostZoneAvailable = generateRandomValueFromList({true, false}), - defrostZone = generateRandomArrayFromList({"FRONT", "REAR", "ALL", "NONE"}, true, 1, 4), - ventilationModeAvailable = generateRandomValueFromList({true, false}), - ventilationMode = generateRandomArrayFromList({"UPPER", "LOWER", "BOTH", "NONE"}, true, 1, 4) - } -end - -local function initCommonRC() - initRandom() - radioControlCapabilities = {generateRadioControlCapabilities()} - climateControlCapabilities = {generateClimateControlCapabilities()} -end - -initCommonRC() - local function initHMI(self) local exp_waiter = commonFunctions:createMultipleExpectationsWaiter(self, "HMI initialization") local function registerComponent(name, subscriptions) @@ -271,41 +184,6 @@ function commonRC.preconditions() commonSteps:DeleteLogsFiles() end -function commonRC.prepareInteriorVehicleDataCapabilitiesJson(IVDCapabilitiesTable, IVDCapabilitiesFileName) - -- Validation check - if not IVDCapabilitiesTable.interiorVehicleDataCapabilities then IVDCapabilitiesTable = nil end - if not IVDCapabilitiesFileName or type(IVDCapabilitiesFileName) ~= "string" then IVDCapabilitiesFileName = "IVDCapabilities.json" end - - commonPreconditions:BackupFile("smartDeviceLink.ini") - table.insert(backupedFiles, "smartDeviceLink.ini") - local isBackuped = false - local sdlPath = commonPreconditions:GetPathToSDL() - local IVDCapabilitiesFilePath = commonFunctions:pathJoin(sdlPath, "plugins/" .. IVDCapabilitiesFileName) - commonFunctions:write_parameter_to_smart_device_link_ini("InteriorVDCapabilitiesFile", "./plugins/" .. IVDCapabilitiesFileName) - - if commonFunctions:File_exists(IVDCapabilitiesFilePath) then - commonPreconditions:BackupFile("plugins/" .. IVDCapabilitiesFileName) - table.insert(backupedFiles, "plugins/" .. IVDCapabilitiesFileName) - isBackuped = true - end - - if IVDCapabilitiesTable then - tableToJsonFile(IVDCapabilitiesTable, IVDCapabilitiesFilePath) - if not isBackuped then - table.insert(createdFiles, IVDCapabilitiesFilePath) - end - end -end - -function commonRC.restoreInteriorVehicleDataCapabilitiesJson() - for _,fileName in pairs(backupedFiles) do - commonPreconditions:RestoreFile(fileName) - end - for _,fileName in pairs(createdFiles) do - os.execute( " rm -f " .. fileName) - end -end - function commonRC.start(self) self:runSDL() commonFunctions:waitForSDLStart(self) @@ -373,7 +251,6 @@ function commonRC.rai_n(id, self) end function commonRC.postconditions() - commonRC.restoreInteriorVehicleDataCapabilitiesJson() StopSDL() end @@ -478,29 +355,6 @@ function commonRC.getAnotherModuleControlData(module_type) return out end -function commonRC.getClimateControlCapabilities() - return climateControlCapabilities -end - -function commonRC.getRadioControlCapabilities() - return radioControlCapabilities -end - -function commonRC.getInteriorVehicleDataCapabilities(module_types) - local out = { } - if not module_types then - return out - end - for _, v in pairs(module_types) do - if v == "CLIMATE" then - out.climateControlCapabilities = commonRC.getClimateControlCapabilities() - elseif v == "RADIO" then - out.radioControlCapabilities = commonRC.getRadioControlCapabilities() - end - end - return out -end - function commonRC.getSelfAndParams(param, self) if not self then return param, nil diff --git a/test_sets/rc_GetInteriorVehicleDataCapabilities.txt b/test_sets/rc_GetInteriorVehicleDataCapabilities.txt deleted file mode 100644 index 1c7d2811f6..0000000000 --- a/test_sets/rc_GetInteriorVehicleDataCapabilities.txt +++ /dev/null @@ -1,18 +0,0 @@ -./test_scripts/RC/GetInteriorVehicleDataCapabilities/001.lua -./test_scripts/RC/GetInteriorVehicleDataCapabilities/002.lua -./test_scripts/RC/GetInteriorVehicleDataCapabilities/003.lua -./test_scripts/RC/GetInteriorVehicleDataCapabilities/004.lua -./test_scripts/RC/GetInteriorVehicleDataCapabilities/005.lua -./test_scripts/RC/GetInteriorVehicleDataCapabilities/006.lua -./test_scripts/RC/GetInteriorVehicleDataCapabilities/007.lua -./test_scripts/RC/GetInteriorVehicleDataCapabilities/008.lua -./test_scripts/RC/GetInteriorVehicleDataCapabilities/009.lua -./test_scripts/RC/GetInteriorVehicleDataCapabilities/010.lua -./test_scripts/RC/GetInteriorVehicleDataCapabilities/011.lua -./test_scripts/RC/GetInteriorVehicleDataCapabilities/012.lua -./test_scripts/RC/GetInteriorVehicleDataCapabilities/013.lua -./test_scripts/RC/GetInteriorVehicleDataCapabilities/014.lua -./test_scripts/RC/GetInteriorVehicleDataCapabilities/015.lua -./test_scripts/RC/GetInteriorVehicleDataCapabilities/016.lua -./test_scripts/RC/GetInteriorVehicleDataCapabilities/017.lua -./test_scripts/RC/GetInteriorVehicleDataCapabilities/018.lua From ca485a2acdb2e35bdf3b90e3375b0a5ddf1082b0 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Tue, 18 Jul 2017 15:39:24 +0300 Subject: [PATCH 024/681] Refactoring of test scripts for GetInteriorVehicleData --- .../RC/GetInteriorVehicleData/001.lua | 80 +------ .../RC/GetInteriorVehicleData/002c.lua | 32 +-- .../RC/GetInteriorVehicleData/002r.lua | 33 +-- .../RC/GetInteriorVehicleData/003.lua | 50 ++-- .../RC/GetInteriorVehicleData/004.lua | 174 +++++--------- .../RC/GetInteriorVehicleData/005.lua | 222 ++++++------------ .../RC/GetInteriorVehicleData/006.lua | 81 +++---- .../RC/GetInteriorVehicleData/007.lua | 164 +++++-------- .../RC/GetInteriorVehicleData/008.lua | 107 +++------ .../RC/GetInteriorVehicleData/009.lua | 38 +-- .../RC/GetInteriorVehicleData/010.lua | 53 +++-- .../RC/GetInteriorVehicleData/011.lua | 114 ++++----- .../RC/GetInteriorVehicleData/012.lua | 108 ++++----- 13 files changed, 456 insertions(+), 800 deletions(-) diff --git a/test_scripts/RC/GetInteriorVehicleData/001.lua b/test_scripts/RC/GetInteriorVehicleData/001.lua index f71191a1a4..4ab9db49a0 100644 --- a/test_scripts/RC/GetInteriorVehicleData/001.lua +++ b/test_scripts/RC/GetInteriorVehicleData/001.lua @@ -3,85 +3,23 @@ -- Script: 001 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "CLIMATE" - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "CLIMATE" - }, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = { - moduleType = "CLIMATE", - climateControlData = commonRC.getClimateControlData() - }, - isSubscribed = true - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - isSubscribed = true, - moduleData = { - moduleType = "CLIMATE", - climateControlData = commonRC.getClimateControlData() - } - }) -end - -local function step2(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "RADIO" - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "RADIO" - }, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - isSubscribed = true, - moduleData = { - moduleType = "RADIO", - radioControlData = commonRC.getRadioControlData() - } - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - isSubscribed = true, - moduleData = { - moduleType = "RADIO", - radioControlData = commonRC.getRadioControlData() - } - }) -end +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) + runner.Title("Test") -runner.Step("GetInteriorVehicleData_CLIMATE", step1) -runner.Step("GetInteriorVehicleData_RADIO", step2) + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod, commonRC.subscribeToModule, { mod }) +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/002c.lua b/test_scripts/RC/GetInteriorVehicleData/002c.lua index bd64b0fd71..62878e8de8 100644 --- a/test_scripts/RC/GetInteriorVehicleData/002c.lua +++ b/test_scripts/RC/GetInteriorVehicleData/002c.lua @@ -3,29 +3,31 @@ -- Script: 002 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +--[[ Local Variables ]] +local mod = "CLIMATE" + --[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "CLIMATE" - }, - -- subscribe = true - }) +local function getDataForModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + } + }) - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) - commonTestCases:DelayedExp(commonRC.timeout) + commonTestCases:DelayedExp(commonRC.timeout) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } end --[[ Scenario ]] @@ -33,7 +35,9 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) + runner.Title("Test") -runner.Step("GetInteriorVehicleData_CLIMATE", step1) +runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/002r.lua b/test_scripts/RC/GetInteriorVehicleData/002r.lua index 435e953c78..d116254da2 100644 --- a/test_scripts/RC/GetInteriorVehicleData/002r.lua +++ b/test_scripts/RC/GetInteriorVehicleData/002r.lua @@ -3,29 +3,31 @@ -- Script: 002 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +--[[ Local Variables ]] +local mod = "RADIO" + --[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "RADIO" - }, - -- subscribe = true - }) +local function getDataForModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + } + }) - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) - commonTestCases:DelayedExp(commonRC.timeout) + commonTestCases:DelayedExp(commonRC.timeout) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } end --[[ Scenario ]] @@ -33,7 +35,10 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) + runner.Title("Test") -runner.Step("GetInteriorVehicleData_RADIO", step1) +runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) + diff --git a/test_scripts/RC/GetInteriorVehicleData/003.lua b/test_scripts/RC/GetInteriorVehicleData/003.lua index 98b1be87f6..2ca1e7ddc3 100644 --- a/test_scripts/RC/GetInteriorVehicleData/003.lua +++ b/test_scripts/RC/GetInteriorVehicleData/003.lua @@ -3,44 +3,30 @@ -- Script: 003 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ General configuration parameters ]] config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } ---[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "CLIMATE" - }, - -- subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData") - :Times(0) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } -local function step2(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "RADIO" - }, - -- subscribe = true - }) +--[[ Local Functions ]] +local function getDataForModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + } + }) - EXPECT_HMICALL("RC.GetInteriorVehicleData") - :Times(0) + EXPECT_HMICALL("RC.GetInteriorVehicleData") + :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) - commonTestCases:DelayedExp(commonRC.timeout) + commonTestCases:DelayedExp(commonRC.timeout) end --[[ Scenario ]] @@ -48,8 +34,12 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) + runner.Title("Test") -runner.Step("GetInteriorVehicleData_CLIMATE", step1) -runner.Step("GetInteriorVehicleData_RADIO", step2) + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/004.lua b/test_scripts/RC/GetInteriorVehicleData/004.lua index 03f3165c57..4a0e2f708a 100644 --- a/test_scripts/RC/GetInteriorVehicleData/004.lua +++ b/test_scripts/RC/GetInteriorVehicleData/004.lua @@ -3,121 +3,63 @@ -- Script: 004 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local success_codes = { "WARNINGS" } +local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } --[[ Local Functions ]] -local function step1(pResultCode, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "CLIMATE" - }, - subscribe = true - }) +local function stepSuccessfull(pModuleType, pResultCode, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "CLIMATE" - }, - subscribe = true - }) + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, pResultCode, { - moduleData = { - moduleType = "CLIMATE", - climateControlData = commonRC.getClimateControlData() - } - -- isSubscribed = true + self.hmiConnection:SendResponse(data.id, data.method, pResultCode, { + moduleData = commonRC.getModuleControlData(pModuleType) + -- isSubscribed = true + }) + end) - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = pResultCode, - -- isSubscribed = true, - moduleData = { - moduleType = "CLIMATE", - climateControlData = commonRC.getClimateControlData() - } - }) + EXPECT_RESPONSE(cid, { success = true, resultCode = pResultCode, + -- isSubscribed = true, + moduleData = commonRC.getModuleControlData(pModuleType) + }) end -local function step2(pResultCode, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "RADIO", - }, - subscribe = true - }) +local function stepUnsuccessfull(pModuleType, pResultCode, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "RADIO", - }, - subscribe = true - }) + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, pResultCode, { - -- isSubscribed = true, - moduleData = { - moduleType = "RADIO", - radioControlData = commonRC.getRadioControlData() - } - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = pResultCode, - -- isSubscribed = true, - moduleData = { - moduleType = "RADIO", - radioControlData = commonRC.getRadioControlData() - } - }) -end - -local function step1err(pResultCode, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "CLIMATE" - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "CLIMATE" - }, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") - end) - - EXPECT_RESPONSE(cid, { success = false, resultCode = pResultCode}) -end - -local function step2err(pResultCode, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "RADIO" - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "RADIO" - }, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") - end) + self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") + end) - EXPECT_RESPONSE(cid, { success = false, resultCode = pResultCode }) + EXPECT_RESPONSE(cid, { success = false, resultCode = pResultCode}) end --[[ Scenario ]] @@ -125,16 +67,20 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) + runner.Title("Test") -runner.Step("GetInteriorVehicleData_CLIMATE with WARNINGS resultCode", step1, {"WARNINGS"}) -runner.Step("GetInteriorVehicleData_RADIO with WARNINGS resultCode", step2, {"WARNINGS"}) -runner.Step("GetInteriorVehicleData_CLIMATE with GENERIC_ERROR resultCode", step1err, {"GENERIC_ERROR"}) -runner.Step("GetInteriorVehicleData_RADIO with GENERIC_ERROR resultCode", step2err, {"GENERIC_ERROR"}) -runner.Step("GetInteriorVehicleData_CLIMATE with INVALID_DATA resultCode", step1err, {"INVALID_DATA"}) -runner.Step("GetInteriorVehicleData_RADIO with INVALID_DATA resultCode", step2err, {"INVALID_DATA"}) -runner.Step("GetInteriorVehicleData_CLIMATE with OUT_OF_MEMORY resultCode", step1err, {"OUT_OF_MEMORY"}) -runner.Step("GetInteriorVehicleData_RADIO with OUT_OF_MEMORY resultCode", step2err, {"OUT_OF_MEMORY"}) -runner.Step("GetInteriorVehicleData_CLIMATE with REJECTED resultCode", step1err, {"REJECTED"}) -runner.Step("GetInteriorVehicleData_RADIO with REJECTED resultCode", step2err, {"REJECTED"}) + +for _, mod in pairs(modules) do + for _, code in pairs(success_codes) do + runner.Step("GetInteriorVehicleData " .. mod .. " with " .. code .. " resultCode", stepSuccessfull, { mod, code }) + end +end + +for _, mod in pairs(modules) do + for _, code in pairs(error_codes) do + runner.Step("GetInteriorVehicleData " .. mod .. " with " .. code .. " resultCode", stepUnsuccessfull, { mod, code }) + end +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/005.lua b/test_scripts/RC/GetInteriorVehicleData/005.lua index 43dad206e4..e5c225fc54 100644 --- a/test_scripts/RC/GetInteriorVehicleData/005.lua +++ b/test_scripts/RC/GetInteriorVehicleData/005.lua @@ -3,162 +3,82 @@ -- Script: 005 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDecription = { -- invalid name of parameter - moduleType = "CLIMATE" - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) -end - -local function step2(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDscription = { -- invalid name of parameter - moduleType = "RADIO" - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) -end - -local function step3(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "CLIMATE" - }, - subscribe = 17 -- invalid type of parameter - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) -end - -local function step4(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "RADIO" - }, - subscribe = 21 -- invalid type of parameter - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) +--[[ Local Functions ]] +local function invalidParamName(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDecription = { -- invalid name of parameter + moduleType = pModuleType + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) end -local function step5(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - -- moduleType = "CLIMATE", -- mandatory parameter absent - }, - subscribe = true - }) +local function invalidParamType(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = 17 -- invalid type of parameter + }) - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) end -local function step6(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - -- moduleType = "RADIO", -- mandatory parameter absent - }, - subscribe = true - }) +local function missingMandatoryParam(self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + -- moduleType = "CLIMATE", -- mandatory parameter absent + }, + subscribe = true + }) - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) -end - -local function step7(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "CLIMATE", - fakeParam = 7 - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "CLIMATE" - }, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = { - moduleType = "CLIMATE", - climateControlData = commonRC.getClimateControlData() - }, - isSubscribed = true - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - isSubscribed = true, - moduleData = { - moduleType = "CLIMATE", - climateControlData = commonRC.getClimateControlData() - } - }) + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) end -local function step8(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "RADIO", - fakeParam = 7 - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "RADIO" - }, - subscribe = true - }) +local function fakeParam(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType, + fakeParam = 7 + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - isSubscribed = true, - moduleData = { - moduleType = "RADIO", - radioControlData = commonRC.getRadioControlData() - } - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - isSubscribed = true, - moduleData = { - moduleType = "RADIO", - radioControlData = commonRC.getRadioControlData() - } - }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = true + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + isSubscribed = true, + moduleData = commonRC.getModuleControlData(pModuleType) + }) end --[[ Scenario ]] @@ -166,14 +86,16 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) + runner.Title("Test") -runner.Step("GetInteriorVehicleData_CLIMATE (invalid name of parameter)", step1) -runner.Step("GetInteriorVehicleData_RADIO (invalid name of parameter)", step2) -runner.Step("GetInteriorVehicleData_CLIMATE (invalid type of parameter)", step3) -runner.Step("GetInteriorVehicleData_RADIO (invalid type of parameter)", step4) -runner.Step("GetInteriorVehicleData_CLIMATE (mandatory parameter absent)", step5) -runner.Step("GetInteriorVehicleData_RADIO (mandatory parameter absent)", step6) -runner.Step("GetInteriorVehicleData_CLIMATE (fake parameter)", step7) -runner.Step("GetInteriorVehicleData_RADIO (fake parameter)", step8) + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod .. " invalid name of parameter", invalidParamName, { mod }) + runner.Step("GetInteriorVehicleData " .. mod .. " invalid type of parameter", invalidParamType, { mod }) + runner.Step("GetInteriorVehicleData " .. mod .. " fake parameter", fakeParam, { mod }) +end + +runner.Step("GetInteriorVehicleData (mandatory parameter absent)", missingMandatoryParam) + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/006.lua b/test_scripts/RC/GetInteriorVehicleData/006.lua index 812fda9eed..71600e85d6 100644 --- a/test_scripts/RC/GetInteriorVehicleData/006.lua +++ b/test_scripts/RC/GetInteriorVehicleData/006.lua @@ -3,57 +3,36 @@ -- Script: 006 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') ---[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "CLIMATE" - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "CLIMATE" - }, - subscribe = true - }) - :Do(function(_, _) - -- HMI does not respond - end) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) - - commonTestCases:DelayedExp(11000) -end - -local function step2(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "RADIO" - }, - subscribe = true - }) +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "RADIO" - }, - subscribe = true - }) - :Do(function(_, _) - -- HMI does not respond - end) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) - - commonTestCases:DelayedExp(11000) +--[[ Local Functions ]] +local function getDataForModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + :Do(function(_, _) + -- HMI does not respond + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + + commonTestCases:DelayedExp(11000) end --[[ Scenario ]] @@ -61,8 +40,12 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) + runner.Title("Test") -runner.Step("GetInteriorVehicleData_CLIMATE (HMI does not respond)", step1) -runner.Step("GetInteriorVehicleData_RADIO (HMI does not respond)", step2) + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod .. " HMI does not respond", getDataForModule, { mod }) +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/007.lua b/test_scripts/RC/GetInteriorVehicleData/007.lua index 510f75f34a..e66989af6e 100644 --- a/test_scripts/RC/GetInteriorVehicleData/007.lua +++ b/test_scripts/RC/GetInteriorVehicleData/007.lua @@ -3,120 +3,63 @@ -- Script: 007 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "CLIMATE" - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "CLIMATE" - }, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = { - moduleType = "CLIMATE", - climateControlData = commonRC.getClimateControlData() - }, - isSubscribed = "yes" -- invalid type of parameter - }) - end) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Invalid message received from vehicle"}) -end - -local function step2(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "RADIO" - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "RADIO" - }, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - isSubscribed = "yes", -- invalid type of parameter - moduleData = { - moduleType = "RADIO", - radioControlData = commonRC.getRadioControlData() - } - }) - end) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Invalid message received from vehicle"}) -end +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } -local function step3(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "CLIMATE" - }, - subscribe = true - }) +--[[ Local Functions ]] +local function invalidParamType(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "CLIMATE" - }, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = { - -- moduleType = "CLIMATE" -- missing mandatory parameter - climateControlData = commonRC.getClimateControlData() - }, - isSubscribed = true - }) - end) + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = "yes" -- invalid type of parameter + }) + end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Invalid message received from vehicle"}) + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Invalid message received from vehicle"}) end -local function step4(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "RADIO" - }, - subscribe = true - }) +local function missingMandatoryParam(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "RADIO" - }, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - isSubscribed = true, - moduleData = { - -- moduleType = "RADIO" -- missing mandatory parameter - radioControlData = commonRC.getRadioControlData() - } - }) - end) + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + :Do(function(_, data) + local moduleData = commonRC.getModuleControlData(pModuleType) + moduleData.moduleType = nil -- missing mandatory parameter + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = moduleData, + isSubscribed = true + }) + end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Invalid message received from vehicle"}) + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Invalid message received from vehicle"}) end --[[ Scenario ]] @@ -124,10 +67,13 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) + runner.Title("Test") -runner.Step("GetInteriorVehicleData_CLIMATE (Invalid response from HMI-Invalid type of parameter)", step1) -runner.Step("GetInteriorVehicleData_RADIO (Invalid response from HMI-Invalid type of parameter)", step2) -runner.Step("GetInteriorVehicleData_CLIMATE (Invalid response from HMI-Missing mandatory parameter)", step3) -runner.Step("GetInteriorVehicleData_RADIO (Invalid response from HMI-Missing mandatory parameter)", step4) + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod .. " Invalid response from HMI-Invalid type of parameter", invalidParamType, { mod }) + runner.Step("GetInteriorVehicleData " .. mod .. " Invalid response from HMI-Missing mandatory parameter", missingMandatoryParam, { mod }) +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/008.lua b/test_scripts/RC/GetInteriorVehicleData/008.lua index 4d442f4b5d..eedb9e1307 100644 --- a/test_scripts/RC/GetInteriorVehicleData/008.lua +++ b/test_scripts/RC/GetInteriorVehicleData/008.lua @@ -1,83 +1,46 @@ --------------------------------------------------------------------------------------------------- -- RPC: GetInteriorVehicleData --- Script: 001 +-- Script: 008 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') local json = require('modules/json') ---[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "CLIMATE" - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "CLIMATE" - }, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = { - moduleType = "CLIMATE", - climateControlData = commonRC.getClimateControlData() - }, - isSubscribed = true - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - isSubscribed = true, - moduleData = { - moduleType = "CLIMATE", - climateControlData = commonRC.getClimateControlData() - } - }) -end - -local function step2(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = "RADIO" - }, - subscribe = true - }) +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = "RADIO" - }, - subscribe = true - }) +--[[ Local Functions ]] +local function getDataForModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = true + }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - isSubscribed = true, - moduleData = { - moduleType = "RADIO", - radioControlData = commonRC.getRadioControlData() - } - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - isSubscribed = true, - moduleData = { - moduleType = "RADIO", - radioControlData = commonRC.getRadioControlData() - } - }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = true + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + isSubscribed = true, + moduleData = commonRC.getModuleControlData(pModuleType) + }) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY end --[[ Scenario ]] @@ -85,8 +48,12 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) + runner.Title("Test") -runner.Step("GetInteriorVehicleData_CLIMATE", step1) -runner.Step("GetInteriorVehicleData_RADIO", step2) + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/009.lua b/test_scripts/RC/GetInteriorVehicleData/009.lua index a095676828..8bc347f7fa 100644 --- a/test_scripts/RC/GetInteriorVehicleData/009.lua +++ b/test_scripts/RC/GetInteriorVehicleData/009.lua @@ -3,30 +3,32 @@ -- Script: 009 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') -local json = require('modules/json') +local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + --[[ Local Functions ]] -local function step(module_type, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = module_type - }, - subscribe = true - }) +local function getDataForModule(module_type, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = module_type + }, + subscribe = true + }) - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) - commonTestCases:DelayedExp(commonRC.timeout) + commonTestCases:DelayedExp(commonRC.timeout) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil end --[[ Scenario ]] @@ -34,8 +36,12 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) + runner.Title("Test") -runner.Step("GetInteriorVehicleData_CLIMATE", step, {"CLIMATE"}) -runner.Step("GetInteriorVehicleData_RADIO", step, {"RADIO"}) + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/010.lua b/test_scripts/RC/GetInteriorVehicleData/010.lua index 920e1e8b49..bc04ff5d22 100644 --- a/test_scripts/RC/GetInteriorVehicleData/010.lua +++ b/test_scripts/RC/GetInteriorVehicleData/010.lua @@ -3,30 +3,33 @@ -- Script: 010 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] -local function step(module_type, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = module_type - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = module_type - }, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Read only parameters received") - end) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) +local function getDataForModule(module_type, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = module_type + }, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = module_type + }, + subscribe = true + }) + :Do(function(_, data) + self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Read only parameters received") + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) end --[[ Scenario ]] @@ -34,8 +37,12 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) + runner.Title("Test") -runner.Step("GetInteriorVehicleData_CLIMATE_READ_ONLY", step, {"CLIMATE"}) -runner.Step("GetInteriorVehicleData_RADIO_READ_ONLY", step, {"RADIO"}) + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/011.lua b/test_scripts/RC/GetInteriorVehicleData/011.lua index 11ff01b279..f16cb4e801 100644 --- a/test_scripts/RC/GetInteriorVehicleData/011.lua +++ b/test_scripts/RC/GetInteriorVehicleData/011.lua @@ -3,72 +3,39 @@ -- Script: 011 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Functions ]] -local function getModuleData(moduleType) - if moduleType == "CLIMATE" then - return {moduleType = moduleType, climateControlData = commonRC.getClimateControlData()} - end - return {moduleType = moduleType, radioControlData = commonRC.getRadioControlData()} -end - -local function subscribeToModule(pModuleType, self) - - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = getModuleData(pModuleType), - isSubscribed = true - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - moduleData = getModuleData(pModuleType), - isSubscribed = true - }) -end - -local function step(pModuleType, isSubscriptionActive, pSubscribe, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, - subscribe = pSubscribe - }) +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, - subscribe = pSubscribe - }) +--[[ Local Functions ]] +local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + subscribe = pSubscribe + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + }, + subscribe = pSubscribe + }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = getModuleData(pModuleType), - -- no isSubscribed parameter - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - isSubscribed = isSubscriptionActive, -- return current value of subscription - moduleData = getModuleData(pModuleType) - }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + -- no isSubscribed parameter + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + isSubscribed = isSubscriptionActive, -- return current value of subscription + moduleData = commonRC.getModuleControlData(pModuleType) + }) end --[[ Scenario ]] @@ -76,16 +43,19 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) + runner.Title("Test") -runner.Step("GetInteriorVehicleData_CLIMATE_NoSubscription_subscribe", step, {"CLIMATE", false, true}) -runner.Step("GetInteriorVehicleData_CLIMATE_NoSubscription_unsubscribe", step, {"CLIMATE", false, false}) -runner.Step("GetInteriorVehicleData_RADIO_NoSubscription_subscribe", step, {"RADIO", false, true}) -runner.Step("GetInteriorVehicleData_RADIO_NoSubscription_unsubscribe", step, {"RADIO", false, false}) -runner.Step("Subscribe app to CLIMATE", subscribeToModule, {"CLIMATE"}) -runner.Step("GetInteriorVehicleData_CLIMATE_ActiveSubscription_subscribe", step, {"CLIMATE", true, true}) -runner.Step("GetInteriorVehicleData_CLIMATE_ActiveSubscription_unsubscribe", step, {"CLIMATE", true, false}) -runner.Step("Subscribe app to RADIO", subscribeToModule, {"RADIO"}) -runner.Step("GetInteriorVehicleData_RADIO_ActiveSubscription_subscribe", step, {"RADIO", true, true}) -runner.Step("GetInteriorVehicleData_RADIO_ActiveSubscription_unsubscribe", step, {"RADIO", true, false}) + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription_subscribe", getDataForModule, { mod, false, true }) + runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription_unsubscribe", getDataForModule, { mod, false, false }) +end + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) + runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true, true }) + runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_unsubscribe", getDataForModule, { mod, true, false }) +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleData/012.lua b/test_scripts/RC/GetInteriorVehicleData/012.lua index 457f8ed80c..c85ae2ff82 100644 --- a/test_scripts/RC/GetInteriorVehicleData/012.lua +++ b/test_scripts/RC/GetInteriorVehicleData/012.lua @@ -3,72 +3,39 @@ -- Script: 012 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Functions ]] -local function getModuleData(moduleType) - if moduleType == "CLIMATE" then - return {moduleType = moduleType, climateControlData = commonRC.getClimateControlData()} - end - return {moduleType = moduleType, radioControlData = commonRC.getRadioControlData()} -end - -local function subscribeToModule(pModuleType, self) - - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = getModuleData(pModuleType), - isSubscribed = true - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - moduleData = getModuleData(pModuleType), - isSubscribed = true - }) -end - -local function step(pModuleType, isSubscriptionActive, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, - -- no subscribe parameter - }) +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - } - -- no subscribe parameter - }) +--[[ Local Functions ]] +local function getDataForModule(pModuleType, isSubscriptionActive, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleDescription = { + moduleType = pModuleType + }, + -- no subscribe parameter + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleDescription = { + moduleType = pModuleType + } + -- no subscribe parameter + }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = getModuleData(pModuleType), - isSubscribed = isSubscriptionActive -- return current value of subscription - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - moduleData = getModuleData(pModuleType) - -- no isSubscribed parameter - }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = isSubscriptionActive -- return current value of subscription + }) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + moduleData = commonRC.getModuleControlData(pModuleType) + -- no isSubscribed parameter + }) end --[[ Scenario ]] @@ -76,12 +43,17 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) + runner.Title("Test") -runner.Step("GetInteriorVehicleData_CLIMATE_NoSubscription", step, {"CLIMATE", false}) -runner.Step("GetInteriorVehicleData_RADIO_NoSubscription", step, {"RADIO", false}) -runner.Step("Subscribe app to CLIMATE", subscribeToModule, {"CLIMATE"}) -runner.Step("GetInteriorVehicleData_CLIMATE_ActiveSubscription_subscribe", step, {"CLIMATE", true}) -runner.Step("Subscribe app to RADIO", subscribeToModule, {"RADIO"}) -runner.Step("GetInteriorVehicleData_RADIO_ActiveSubscription_subscribe", step, {"RADIO", true}) + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription", getDataForModule, { mod, false }) +end + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) + runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true }) +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) From 3b7ca37f7380f7b4e563db24a267b7fa9c3e9e20 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Tue, 18 Jul 2017 17:06:41 +0300 Subject: [PATCH 025/681] OnInteriorVehicleData: add new script --- test_scripts/RC/OnInteriorVehicleData/014.lua | 73 +++++++++++++++++++ test_sets/rc_OnInteriorVehicleData.txt | 1 + 2 files changed, 74 insertions(+) create mode 100644 test_scripts/RC/OnInteriorVehicleData/014.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/014.lua b/test_scripts/RC/OnInteriorVehicleData/014.lua new file mode 100644 index 0000000000..f1ef0a21a3 --- /dev/null +++ b/test_scripts/RC/OnInteriorVehicleData/014.lua @@ -0,0 +1,73 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: OnInteriorVehicleData +-- Script: 014 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function invalidParamName(pModuleType, self) + self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + modduleData = commonRC.getAnotherModuleControlData(pModuleType) -- invalid name of parameter + }) + + EXPECT_NOTIFICATION("OnInteriorVehicleData") + :Times(0) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function invalidParamType(pModuleType, self) + local moduleData = commonRC.getAnotherModuleControlData(pModuleType) + moduleData.moduleType = {} -- invalid type of parameter + + self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + moduleData = moduleData + }) + + EXPECT_NOTIFICATION("OnInteriorVehicleData") + :Times(0) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function missingMandatoryParam(pModuleType, self) + local moduleData = commonRC.getAnotherModuleControlData(pModuleType) + moduleData.moduleType = nil -- mandatory parameter missing + + self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + moduleData = moduleData + }) + + EXPECT_NOTIFICATION("OnInteriorVehicleData") + :Times(0) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", commonRC.isSubscribed, { mod }) +end + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("OnInteriorVehicleData " .. mod .. " invalid name of parameter", invalidParamName, { mod }) + runner.Step("OnInteriorVehicleData " .. mod .. " invalid type of parameter", invalidParamType, { mod }) + runner.Step("OnInteriorVehicleData " .. mod .. " mandatory parameter missing", missingMandatoryParam, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_OnInteriorVehicleData.txt b/test_sets/rc_OnInteriorVehicleData.txt index e6ea47bd63..63d494267b 100644 --- a/test_sets/rc_OnInteriorVehicleData.txt +++ b/test_sets/rc_OnInteriorVehicleData.txt @@ -14,3 +14,4 @@ ./test_scripts/RC/OnInteriorVehicleData/012r.lua ./test_scripts/RC/OnInteriorVehicleData/013c.lua ./test_scripts/RC/OnInteriorVehicleData/013r.lua +./test_scripts/RC/OnInteriorVehicleData/014.lua From 188a88ae3833be776dc742f6fbb3c43895f369bd Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Tue, 18 Jul 2017 18:14:18 +0300 Subject: [PATCH 026/681] Update according to latest API changes --- test_scripts/RC/commonRC.lua | 119 ++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 58 deletions(-) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 5dc45bd21b..16fe23b72d 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -254,53 +254,49 @@ function commonRC.postconditions() StopSDL() end -function commonRC.getInteriorZone() - return { - col = 0, - row = 0, - level = 0, - colspan = 2, - rowspan = 2, - levelspan = 1 - } -end - function commonRC.getClimateControlData() return { - fanSpeed = 50, - currentTemp = 30, - desiredTemp = 24, - temperatureUnit = "CELSIUS", - acEnable = true, - circulateAirEnable = true, - autoModeEnable = true, - defrostZone = "FRONT", - dualModeEnable = true - } + fanSpeed = 50, + currentTemperature = { + unit = "FAHRENHEIT", + value = 20.1 + }, + desiredTemperature = { + unit = "CELSIUS", + value = 10.5 + }, + acEnable = true, + circulateAirEnable = true, + autoModeEnable = true, + defrostZone = "FRONT", + dualModeEnable = true, + acMaxEnable = true, + ventilationMode = "BOTH" + } end function commonRC.getRadioControlData() return { - frequencyInteger = 1, - frequencyFraction = 2, - band = "AM", - rdsData = { - PS = "ps", - RT = "rt", - CT = "123456789012345678901234", - PI = "pi", - PTY = 1, - TP = false, - TA = true, - REG = "US" - }, - availableHDs = 1, - hdChannel = 1, - signalStrength = 5, - signalChangeThreshold = 10, - radioEnable = true, - state = "ACQUIRING" - } + frequencyInteger = 1, + frequencyFraction = 2, + band = "AM", + rdsData = { + PS = "ps", + RT = "rt", + CT = "123456789012345678901234", + PI = "pi", + PTY = 1, + TP = false, + TA = true, + REG = "US" + }, + availableHDs = 1, + hdChannel = 1, + signalStrength = 5, + signalChangeThreshold = 10, + radioEnable = true, + state = "ACQUIRING" + } end function commonRC.getModuleControlData(module_type) @@ -316,30 +312,37 @@ end function commonRC.getAnotherModuleControlData(module_type) local out = { moduleType = module_type } local climateControlData = { - fanSpeed = 50, - currentTemp = 86, - desiredTemp = 75, - temperatureUnit = "FAHRENHEIT", - acEnable = true, - circulateAirEnable = true, + fanSpeed = 65, + currentTemperature = { + unit = "FAHRENHEIT", + value = 44.3 + }, + desiredTemperature = { + unit = "CELSIUS", + value = 22.6 + }, + acEnable = false, + circulateAirEnable = false, autoModeEnable = true, - defrostZone = "FRONT", - dualModeEnable = true + defrostZone = "ALL", + dualModeEnable = true, + acMaxEnable = false, + ventilationMode = "UPPER" } local radioControlData = { frequencyInteger = 1, frequencyFraction = 2, band = "AM", rdsData = { - PS = "ps", - RT = "rt", - CT = "123456789012345678901234", - PI = "pi", - PTY = 2, - TP = false, - TA = true, - REG = "US" - }, + PS = "ps", + RT = "rt", + CT = "123456789012345678901234", + PI = "pi", + PTY = 2, + TP = false, + TA = true, + REG = "US" + }, availableHDs = 1, hdChannel = 1, signalStrength = 5, From 3c82b4736f8af3e8ed62ab9db794d12238b0e481 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Tue, 18 Jul 2017 19:48:55 +0300 Subject: [PATCH 027/681] SetInteriorVehicleData: Refactoring of scripts --- .../RC/SetInteriorVehicleData/001.lua | 57 ++---- .../RC/SetInteriorVehicleData/002c.lua | 17 +- .../RC/SetInteriorVehicleData/002r.lua | 29 +-- .../RC/SetInteriorVehicleData/003.lua | 38 ++-- test_scripts/RC/commonRC.lua | 166 ++++++++---------- 5 files changed, 128 insertions(+), 179 deletions(-) diff --git a/test_scripts/RC/SetInteriorVehicleData/001.lua b/test_scripts/RC/SetInteriorVehicleData/001.lua index 05616643a9..eb95532183 100644 --- a/test_scripts/RC/SetInteriorVehicleData/001.lua +++ b/test_scripts/RC/SetInteriorVehicleData/001.lua @@ -3,58 +3,25 @@ -- Script: 001 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = { - moduleType = "CLIMATE", - climateControlData = commonRC.getClimateControlData() - } - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleData = { - moduleType = "CLIMATE", - climateControlData = commonRC.getClimateControlData() - } - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = { - moduleType = "CLIMATE", - climateControlData = commonRC.getClimateControlData() - } - }) - end) - - self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } -local function step2(self) +--[[ Local Functions ]] +local function setVehicleData(pModuleType, self) local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = { - moduleType = "RADIO", - radioControlData = commonRC.getRadioControlData() - } + moduleData = commonRC.getModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleData = { - moduleType = "RADIO", - radioControlData = commonRC.getRadioControlData() - } + moduleData = commonRC.getModuleControlData(pModuleType) }) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = { - moduleType = "RADIO", - radioControlData = commonRC.getRadioControlData() - } + moduleData = commonRC.getModuleControlData(pModuleType) }) end) @@ -66,8 +33,12 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) + runner.Title("Test") -runner.Step("SetInteriorVehicleData_CLIMATE", step1) -runner.Step("SetInteriorVehicleData_RADIO", step2) + +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SetInteriorVehicleData/002c.lua b/test_scripts/RC/SetInteriorVehicleData/002c.lua index 988d1ae9e8..e30f68b75c 100644 --- a/test_scripts/RC/SetInteriorVehicleData/002c.lua +++ b/test_scripts/RC/SetInteriorVehicleData/002c.lua @@ -3,18 +3,17 @@ -- Script: 002 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +--[[ Local Variables ]] +local mod = "CLIMATE" + --[[ Local Functions ]] -local function step1(self) +local function setVehicleData(pModuleType, self) local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = { - moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone(), - climateControlData = commonRC.getClimateControlData() - } + moduleData = commonRC.getModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData") @@ -34,7 +33,9 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) + runner.Title("Test") -runner.Step("SetInteriorVehicleData_CLIMATE", step1) +runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SetInteriorVehicleData/002r.lua b/test_scripts/RC/SetInteriorVehicleData/002r.lua index cf65f768d4..8e9666b716 100644 --- a/test_scripts/RC/SetInteriorVehicleData/002r.lua +++ b/test_scripts/RC/SetInteriorVehicleData/002r.lua @@ -3,26 +3,25 @@ -- Script: 002 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +--[[ Local Variables ]] +local mod = "RADIO" + --[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = { - moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone(), - radioControlData = commonRC.getRadioControlData() - } - }) +local function setVehicleData(pModuleType, self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getModuleControlData(pModuleType) + }) - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) - commonTestCases:DelayedExp(commonRC.timeout) + commonTestCases:DelayedExp(commonRC.timeout) end local function ptu_update_func(tbl) @@ -34,7 +33,9 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) + runner.Title("Test") -runner.Step("SetInteriorVehicleData_RADIO", step1) +runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SetInteriorVehicleData/003.lua b/test_scripts/RC/SetInteriorVehicleData/003.lua index edcfeeb86b..c0eb3c7c9b 100644 --- a/test_scripts/RC/SetInteriorVehicleData/003.lua +++ b/test_scripts/RC/SetInteriorVehicleData/003.lua @@ -3,38 +3,20 @@ -- Script: 003 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ General configuration parameters ]] config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } ---[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = { - moduleType = "CLIMATE", - moduleZone = commonRC.getInteriorZone(), - climateControlData = commonRC.getClimateControlData() - } - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) - - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function step2(self) +--[[ Local Functions ]] +local function setVehicleData(pModuleType, self) local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = { - moduleType = "RADIO", - moduleZone = commonRC.getInteriorZone(), - radioControlData = commonRC.getRadioControlData() - } + moduleData = commonRC.getModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData") @@ -50,8 +32,12 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) + runner.Title("Test") -runner.Step("SetInteriorVehicleData_CLIMATE", step1) -runner.Step("SetInteriorVehicleData_RADIO", step2) + +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 16fe23b72d..c31a5c5ad1 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -254,106 +254,96 @@ function commonRC.postconditions() StopSDL() end -function commonRC.getClimateControlData() - return { - fanSpeed = 50, - currentTemperature = { - unit = "FAHRENHEIT", - value = 20.1 - }, - desiredTemperature = { - unit = "CELSIUS", - value = 10.5 - }, - acEnable = true, - circulateAirEnable = true, - autoModeEnable = true, - defrostZone = "FRONT", - dualModeEnable = true, - acMaxEnable = true, - ventilationMode = "BOTH" - } -end - -function commonRC.getRadioControlData() - return { - frequencyInteger = 1, - frequencyFraction = 2, - band = "AM", - rdsData = { - PS = "ps", - RT = "rt", - CT = "123456789012345678901234", - PI = "pi", - PTY = 1, - TP = false, - TA = true, - REG = "US" - }, - availableHDs = 1, - hdChannel = 1, - signalStrength = 5, - signalChangeThreshold = 10, - radioEnable = true, - state = "ACQUIRING" - } -end - function commonRC.getModuleControlData(module_type) local out = { moduleType = module_type } if module_type == "CLIMATE" then - out.climateControlData = commonRC.getClimateControlData() + out.climateControlData = { + fanSpeed = 50, + currentTemperature = { + unit = "FAHRENHEIT", + value = 20.1 + }, + desiredTemperature = { + unit = "CELSIUS", + value = 10.5 + }, + acEnable = true, + circulateAirEnable = true, + autoModeEnable = true, + defrostZone = "FRONT", + dualModeEnable = true, + acMaxEnable = true, + ventilationMode = "BOTH" + } elseif module_type == "RADIO" then - out.radioControlData = commonRC.getRadioControlData() + out.radioControlData = { + frequencyInteger = 1, + frequencyFraction = 2, + band = "AM", + rdsData = { + PS = "ps", + RT = "rt", + CT = "123456789012345678901234", + PI = "pi", + PTY = 1, + TP = false, + TA = true, + REG = "US" + }, + availableHDs = 1, + hdChannel = 1, + signalStrength = 5, + signalChangeThreshold = 10, + radioEnable = true, + state = "ACQUIRING" + } end return out end function commonRC.getAnotherModuleControlData(module_type) local out = { moduleType = module_type } - local climateControlData = { - fanSpeed = 65, - currentTemperature = { - unit = "FAHRENHEIT", - value = 44.3 - }, - desiredTemperature = { - unit = "CELSIUS", - value = 22.6 - }, - acEnable = false, - circulateAirEnable = false, - autoModeEnable = true, - defrostZone = "ALL", - dualModeEnable = true, - acMaxEnable = false, - ventilationMode = "UPPER" - } - local radioControlData = { - frequencyInteger = 1, - frequencyFraction = 2, - band = "AM", - rdsData = { - PS = "ps", - RT = "rt", - CT = "123456789012345678901234", - PI = "pi", - PTY = 2, - TP = false, - TA = true, - REG = "US" - }, - availableHDs = 1, - hdChannel = 1, - signalStrength = 5, - signalChangeThreshold = 20, - radioEnable = true, - state = "ACQUIRING" - } if module_type == "CLIMATE" then - out.climateControlData = climateControlData + out.climateControlData = { + fanSpeed = 65, + currentTemperature = { + unit = "FAHRENHEIT", + value = 44.3 + }, + desiredTemperature = { + unit = "CELSIUS", + value = 22.6 + }, + acEnable = false, + circulateAirEnable = false, + autoModeEnable = true, + defrostZone = "ALL", + dualModeEnable = true, + acMaxEnable = false, + ventilationMode = "UPPER" + } elseif module_type == "RADIO" then - out.radioControlData = radioControlData + out.radioControlData = { + frequencyInteger = 1, + frequencyFraction = 2, + band = "AM", + rdsData = { + PS = "ps", + RT = "rt", + CT = "123456789012345678901234", + PI = "pi", + PTY = 2, + TP = false, + TA = true, + REG = "US" + }, + availableHDs = 1, + hdChannel = 1, + signalStrength = 5, + signalChangeThreshold = 20, + radioEnable = true, + state = "ACQUIRING" + } end return out end From 59c92722912f03122c3d77433304c031507af82d Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Tue, 18 Jul 2017 20:22:44 +0300 Subject: [PATCH 028/681] SetInteriorVehicleData: Add new scripts --- .../RC/SetInteriorVehicleData/006.lua | 94 +++++++++++++++++++ .../RC/SetInteriorVehicleData/007.lua | 49 ++++++++++ .../RC/SetInteriorVehicleData/008.lua | 44 +++++++++ test_sets/rc_SetInteriorVehicleData.txt | 3 + 4 files changed, 190 insertions(+) create mode 100644 test_scripts/RC/SetInteriorVehicleData/006.lua create mode 100644 test_scripts/RC/SetInteriorVehicleData/007.lua create mode 100644 test_scripts/RC/SetInteriorVehicleData/008.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/006.lua b/test_scripts/RC/SetInteriorVehicleData/006.lua new file mode 100644 index 0000000000..6cccdb9711 --- /dev/null +++ b/test_scripts/RC/SetInteriorVehicleData/006.lua @@ -0,0 +1,94 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: SetInteriorVehicleData +-- Script: 006 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function invalidParamName(pModuleType, self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleDData = commonRC.getModuleControlData(pModuleType) -- invalid name of parameter + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function invalidParamType(pModuleType, self) + local moduleData = commonRC.getAnotherModuleControlData(pModuleType) + moduleData.moduleType = {} -- invalid type of parameter + + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + modduleData = moduleData + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function missingMandatoryParam(pModuleType, self) + local moduleData = commonRC.getAnotherModuleControlData(pModuleType) + moduleData.moduleType = nil -- mandatory parameter missing + + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + modduleData = moduleData + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function fakeParam(pModuleType, self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getModuleControlData(pModuleType), + fakeParam = 6 + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = commonRC.getModuleControlData(pModuleType) + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType) + }) + end) + + self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod .. " invalid name of parameter", invalidParamName, { mod }) + runner.Step("SetInteriorVehicleData " .. mod .. " invalid type of parameter", invalidParamType, { mod }) + runner.Step("SetInteriorVehicleData " .. mod .. " fake parameter", fakeParam, { mod }) + runner.Step("SetInteriorVehicleData " .. mod .. " missing mandatory parameter", missingMandatoryParam, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SetInteriorVehicleData/007.lua b/test_scripts/RC/SetInteriorVehicleData/007.lua new file mode 100644 index 0000000000..8a81329bc0 --- /dev/null +++ b/test_scripts/RC/SetInteriorVehicleData/007.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: SetInteriorVehicleData +-- Script: 007 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local json = require('modules/json') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function setVehicleData(pModuleType, self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = commonRC.getModuleControlData(pModuleType) + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType) + }) + end) + + self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SetInteriorVehicleData/008.lua b/test_scripts/RC/SetInteriorVehicleData/008.lua new file mode 100644 index 0000000000..d6c3272cdf --- /dev/null +++ b/test_scripts/RC/SetInteriorVehicleData/008.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: SetInteriorVehicleData +-- Script: 008 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function setVehicleData(pModuleType, self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_SetInteriorVehicleData.txt b/test_sets/rc_SetInteriorVehicleData.txt index 33a32d1b3b..864f0c0a1e 100644 --- a/test_sets/rc_SetInteriorVehicleData.txt +++ b/test_sets/rc_SetInteriorVehicleData.txt @@ -2,3 +2,6 @@ ./test_scripts/RC/SetInteriorVehicleData/002c.lua ./test_scripts/RC/SetInteriorVehicleData/002r.lua ./test_scripts/RC/SetInteriorVehicleData/003.lua +./test_scripts/RC/SetInteriorVehicleData/006.lua +./test_scripts/RC/SetInteriorVehicleData/007.lua +./test_scripts/RC/SetInteriorVehicleData/008.lua From 3fd943fd2c3c5da9de9f7b7a8731965267885b23 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 19 Jul 2017 16:59:38 +0300 Subject: [PATCH 029/681] SetInteriorVehicleData: Add new script --- .../RC/SetInteriorVehicleData/004.lua | 50 +++++++++++++++++++ test_sets/rc_SetInteriorVehicleData.txt | 1 + 2 files changed, 51 insertions(+) create mode 100644 test_scripts/RC/SetInteriorVehicleData/004.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/004.lua b/test_scripts/RC/SetInteriorVehicleData/004.lua new file mode 100644 index 0000000000..a36074bf1a --- /dev/null +++ b/test_scripts/RC/SetInteriorVehicleData/004.lua @@ -0,0 +1,50 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: SetInteriorVehicleData +-- Script: 004 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function setVehicleData(pModuleType, self) + local moduleType2 = nil + if pModuleType == "CLIMATE" then + moduleType2 = "RADIO" + elseif pModuleType == "RADIO" then + moduleType2 = "CLIMATE" + end + + local moduleData = commonRC.getModuleControlData(moduleType2) + moduleData.moduleType = pModuleType + + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = moduleData + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod .. "_gets_INVALID_DATA", setVehicleData, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_SetInteriorVehicleData.txt b/test_sets/rc_SetInteriorVehicleData.txt index 864f0c0a1e..31c6c4a3d8 100644 --- a/test_sets/rc_SetInteriorVehicleData.txt +++ b/test_sets/rc_SetInteriorVehicleData.txt @@ -2,6 +2,7 @@ ./test_scripts/RC/SetInteriorVehicleData/002c.lua ./test_scripts/RC/SetInteriorVehicleData/002r.lua ./test_scripts/RC/SetInteriorVehicleData/003.lua +./test_scripts/RC/SetInteriorVehicleData/004.lua ./test_scripts/RC/SetInteriorVehicleData/006.lua ./test_scripts/RC/SetInteriorVehicleData/007.lua ./test_scripts/RC/SetInteriorVehicleData/008.lua From d6f167b28f49f8b0a356525998cb3230d0a2697d Mon Sep 17 00:00:00 2001 From: Ira Lytvynenko Date: Wed, 19 Jul 2017 17:09:13 +0300 Subject: [PATCH 030/681] Update scripts --- test_scripts/RC/ButtonPress/001.lua | 4 --- test_scripts/RC/ButtonPress/002c.lua | 1 - test_scripts/RC/ButtonPress/002r.lua | 1 - test_scripts/RC/ButtonPress/003.lua | 2 -- test_scripts/RC/ButtonPress/004.lua | 51 ++++++++++++++++++++++++++++ test_sets/rc_ButtonPress.txt | 1 + 6 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 test_scripts/RC/ButtonPress/004.lua diff --git a/test_scripts/RC/ButtonPress/001.lua b/test_scripts/RC/ButtonPress/001.lua index fcad59566a..d8270c55d0 100644 --- a/test_scripts/RC/ButtonPress/001.lua +++ b/test_scripts/RC/ButtonPress/001.lua @@ -9,7 +9,6 @@ local runner = require('user_modules/script_runner') --[[ Local Functions ]] local function step1(self) local cid = self.mobileSession:SendRPC("ButtonPress", { - zone = commonRC.getInteriorZone(), moduleType = "CLIMATE", buttonName = "AC", buttonPressMode = "SHORT" @@ -17,7 +16,6 @@ local function step1(self) EXPECT_HMICALL("Buttons.ButtonPress", { appID = self.applications["Test Application"], - zone = commonRC.getInteriorZone(), moduleType = "CLIMATE", buttonName = "AC", buttonPressMode = "SHORT" @@ -31,7 +29,6 @@ end local function step2(self) local cid = self.mobileSession:SendRPC("ButtonPress", { - zone = commonRC.getInteriorZone(), moduleType = "RADIO", buttonName = "VOLUME_UP", buttonPressMode = "LONG" @@ -39,7 +36,6 @@ local function step2(self) EXPECT_HMICALL("Buttons.ButtonPress", { appID = self.applications["Test Application"], - zone = commonRC.getInteriorZone(), moduleType = "RADIO", buttonName = "VOLUME_UP", buttonPressMode = "LONG" diff --git a/test_scripts/RC/ButtonPress/002c.lua b/test_scripts/RC/ButtonPress/002c.lua index 42fd23fcd9..72172c994d 100644 --- a/test_scripts/RC/ButtonPress/002c.lua +++ b/test_scripts/RC/ButtonPress/002c.lua @@ -10,7 +10,6 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ Local Functions ]] local function step1(self) local cid = self.mobileSession:SendRPC("ButtonPress", { - zone = commonRC.getInteriorZone(), moduleType = "CLIMATE", buttonName = "AC", buttonPressMode = "SHORT" diff --git a/test_scripts/RC/ButtonPress/002r.lua b/test_scripts/RC/ButtonPress/002r.lua index ed7d8a7008..a53c0c420a 100644 --- a/test_scripts/RC/ButtonPress/002r.lua +++ b/test_scripts/RC/ButtonPress/002r.lua @@ -10,7 +10,6 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ Local Functions ]] local function step1(self) local cid = self.mobileSession:SendRPC("ButtonPress", { - zone = commonRC.getInteriorZone(), moduleType = "RADIO", buttonName = "VOLUME_UP", buttonPressMode = "LONG" diff --git a/test_scripts/RC/ButtonPress/003.lua b/test_scripts/RC/ButtonPress/003.lua index e5af93f72e..d6034f8677 100644 --- a/test_scripts/RC/ButtonPress/003.lua +++ b/test_scripts/RC/ButtonPress/003.lua @@ -13,7 +13,6 @@ config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } --[[ Local Functions ]] local function step1(self) local cid = self.mobileSession:SendRPC("ButtonPress", { - zone = commonRC.getInteriorZone(), moduleType = "CLIMATE", buttonName = "AC", buttonPressMode = "SHORT" @@ -29,7 +28,6 @@ end local function step2(self) local cid = self.mobileSession:SendRPC("ButtonPress", { - zone = commonRC.getInteriorZone(), moduleType = "RADIO", buttonName = "VOLUME_UP", buttonPressMode = "LONG" diff --git a/test_scripts/RC/ButtonPress/004.lua b/test_scripts/RC/ButtonPress/004.lua new file mode 100644 index 0000000000..ca37907d31 --- /dev/null +++ b/test_scripts/RC/ButtonPress/004.lua @@ -0,0 +1,51 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: ButtonPress +-- Script: 004 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + + +--[[ Local Functions ]] +local function step1(self) + local cid = self.mobileSession:SendRPC("ButtonPress", { + moduleType = "CLIMATE", + buttonName = "VOLUME_UP", + buttonPressMode = "SHORT" + }) + + EXPECT_HMICALL("Buttons.ButtonPress") + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function step2(self) + local cid = self.mobileSession:SendRPC("ButtonPress", { + moduleType = "RADIO", + buttonName = "AC", + buttonPressMode = "LONG" + }) + + EXPECT_HMICALL("Buttons.ButtonPress") + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("ButtonPress_CLIMATE", step1) +runner.Step("ButtonPress_RADIO", step2) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_ButtonPress.txt b/test_sets/rc_ButtonPress.txt index e186c908ef..3889e7617e 100644 --- a/test_sets/rc_ButtonPress.txt +++ b/test_sets/rc_ButtonPress.txt @@ -2,3 +2,4 @@ ./test_scripts/RC/ButtonPress/002c.lua ./test_scripts/RC/ButtonPress/002r.lua ./test_scripts/RC/ButtonPress/003.lua +./test_scripts/RC/ButtonPress/004.lua From ebfff36dabc7701ce18b223dff79b2d44b20b283 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 19 Jul 2017 20:28:53 +0300 Subject: [PATCH 031/681] ButtonPress: Add new scripts --- test_scripts/RC/ButtonPress/008.lua | 51 +++++++++++++++++++++++++++++ test_scripts/RC/ButtonPress/009.lua | 46 ++++++++++++++++++++++++++ test_scripts/RC/ButtonPress/010.lua | 46 ++++++++++++++++++++++++++ test_scripts/RC/ButtonPress/011.lua | 49 +++++++++++++++++++++++++++ test_scripts/RC/ButtonPress/012.lua | 46 ++++++++++++++++++++++++++ test_scripts/RC/commonRC.lua | 19 +++++------ test_sets/rc_ButtonPress.txt | 5 +++ 7 files changed, 251 insertions(+), 11 deletions(-) create mode 100644 test_scripts/RC/ButtonPress/008.lua create mode 100644 test_scripts/RC/ButtonPress/009.lua create mode 100644 test_scripts/RC/ButtonPress/010.lua create mode 100644 test_scripts/RC/ButtonPress/011.lua create mode 100644 test_scripts/RC/ButtonPress/012.lua diff --git a/test_scripts/RC/ButtonPress/008.lua b/test_scripts/RC/ButtonPress/008.lua new file mode 100644 index 0000000000..b698d00862 --- /dev/null +++ b/test_scripts/RC/ButtonPress/008.lua @@ -0,0 +1,51 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: ButtonPress +-- Script: 008 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local json = require('modules/json') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("ButtonPress", { + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + + EXPECT_HMICALL("Buttons.ButtonPress", { + appID = self.applications["Test Application"], + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("ButtonPress " .. mod, getDataForModule, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/ButtonPress/009.lua b/test_scripts/RC/ButtonPress/009.lua new file mode 100644 index 0000000000..35a3461feb --- /dev/null +++ b/test_scripts/RC/ButtonPress/009.lua @@ -0,0 +1,46 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: ButtonPress +-- Script: 009 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("ButtonPress", { + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("ButtonPress " .. mod, getDataForModule, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/ButtonPress/010.lua b/test_scripts/RC/ButtonPress/010.lua new file mode 100644 index 0000000000..2f1ef9c97d --- /dev/null +++ b/test_scripts/RC/ButtonPress/010.lua @@ -0,0 +1,46 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: ButtonPress +-- Script: 010 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("ButtonPress", { + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function ptu_update_func(tbl) + tbl.policy_table.functional_groupings["RemoteControl"].rpcs.ButtonPress = nil +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("ButtonPress " .. mod, getDataForModule, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/ButtonPress/011.lua b/test_scripts/RC/ButtonPress/011.lua new file mode 100644 index 0000000000..8e54c08333 --- /dev/null +++ b/test_scripts/RC/ButtonPress/011.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: ButtonPress +-- Script: 011 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("ButtonPress", { + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + + EXPECT_HMICALL("Buttons.ButtonPress", { + appID = self.applications["Test Application"], + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + :Do(function(_, _) + -- HMI does not respond + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + + commonTestCases:DelayedExp(11000) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("ButtonPress " .. mod, getDataForModule, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/ButtonPress/012.lua b/test_scripts/RC/ButtonPress/012.lua new file mode 100644 index 0000000000..3e518a7437 --- /dev/null +++ b/test_scripts/RC/ButtonPress/012.lua @@ -0,0 +1,46 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: ButtonPress +-- Script: 012 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("ButtonPress", { + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + + EXPECT_HMICALL("Buttons.ButtonPress", { + appID = self.applications["Test Application"], + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + :Do(function(_, data) + self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Read only parameters received") + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("ButtonPress " .. mod, getDataForModule, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index c31a5c5ad1..942bfd95e9 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -19,17 +19,6 @@ local json = require("modules/json") local ptu_table = {} --[[ Local Functions ]] -local function insertFunctions() - local function_id = require("function_id") - function_id["ButtonPress"] = 100015 - function_id["GetInteriorVehicleDataCapabilities"] = 100016 - function_id["GetInteriorVehicleData"] = 100017 - function_id["SetInteriorVehicleData"] = 100018 - function_id["OnInteriorVehicleData"] = 100019 -end - -insertFunctions() - local function initHMI(self) local exp_waiter = commonFunctions:createMultipleExpectationsWaiter(self, "HMI initialization") local function registerComponent(name, subscriptions) @@ -417,4 +406,12 @@ function commonRC.isUnsubscribed(pModuleType, self) commonTestCases:DelayedExp(commonRC.timeout) end +function commonRC.getButtonNameByModule(pModuleType) + if pModuleType == "CLIMATE" then + return "FAN_UP" + elseif pModuleType == "RADIO" then + return "VOLUME_UP" + end +end + return commonRC diff --git a/test_sets/rc_ButtonPress.txt b/test_sets/rc_ButtonPress.txt index 3889e7617e..8fc244353b 100644 --- a/test_sets/rc_ButtonPress.txt +++ b/test_sets/rc_ButtonPress.txt @@ -3,3 +3,8 @@ ./test_scripts/RC/ButtonPress/002r.lua ./test_scripts/RC/ButtonPress/003.lua ./test_scripts/RC/ButtonPress/004.lua +./test_scripts/RC/ButtonPress/008.lua +./test_scripts/RC/ButtonPress/009.lua +./test_scripts/RC/ButtonPress/010.lua +./test_scripts/RC/ButtonPress/011.lua +./test_scripts/RC/ButtonPress/012.lua From 4f68ac8d3220c2f7a0e3aa481c2615f52bd0119b Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Thu, 20 Jul 2017 10:48:58 +0300 Subject: [PATCH 032/681] GetInteriorVehicleData: Add additional waiting timeout --- test_scripts/RC/GetInteriorVehicleData/005.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test_scripts/RC/GetInteriorVehicleData/005.lua b/test_scripts/RC/GetInteriorVehicleData/005.lua index e5c225fc54..592351efac 100644 --- a/test_scripts/RC/GetInteriorVehicleData/005.lua +++ b/test_scripts/RC/GetInteriorVehicleData/005.lua @@ -5,6 +5,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ Local Variables ]] local modules = { "CLIMATE", "RADIO" } @@ -22,6 +23,8 @@ local function invalidParamName(pModuleType, self) :Times(0) EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + + commonTestCases:DelayedExp(commonRC.timeout) end local function invalidParamType(pModuleType, self) @@ -36,6 +39,8 @@ local function invalidParamType(pModuleType, self) :Times(0) EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + + commonTestCases:DelayedExp(commonRC.timeout) end local function missingMandatoryParam(self) @@ -50,6 +55,8 @@ local function missingMandatoryParam(self) :Times(0) EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + + commonTestCases:DelayedExp(commonRC.timeout) end local function fakeParam(pModuleType, self) From 2a90971fd821ec8a28bcc488782d70cc52169e5f Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Thu, 20 Jul 2017 17:31:36 +0300 Subject: [PATCH 033/681] SetInteriorVehicleData: Add additional scripts to check fake parameters --- .../RC/SetInteriorVehicleData/009.lua | 44 ++++++++++++++++ .../RC/SetInteriorVehicleData/010.lua | 51 +++++++++++++++++++ test_sets/rc_SetInteriorVehicleData.txt | 2 + 3 files changed, 97 insertions(+) create mode 100644 test_scripts/RC/SetInteriorVehicleData/009.lua create mode 100644 test_scripts/RC/SetInteriorVehicleData/010.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/009.lua b/test_scripts/RC/SetInteriorVehicleData/009.lua new file mode 100644 index 0000000000..1f318ec6ec --- /dev/null +++ b/test_scripts/RC/SetInteriorVehicleData/009.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: SetInteriorVehicleData +-- Script: 009 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function setVehicleData(pModuleType, self) + local moduleData = commonRC.getModuleControlData(pModuleType) + moduleData.fakeParam = 123 + self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = moduleData + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = commonRC.getModuleControlData(pModuleType) + }) + :ValidIf(function(_, data) + if data.params.moduleData.fakeParam then + return false, 'Fake parameter is not cut-off ("fakeParam":' .. tostring(data.params.moduleData.fakeParam) .. ")" + end + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SetInteriorVehicleData/010.lua b/test_scripts/RC/SetInteriorVehicleData/010.lua new file mode 100644 index 0000000000..ca62233ab1 --- /dev/null +++ b/test_scripts/RC/SetInteriorVehicleData/010.lua @@ -0,0 +1,51 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: SetInteriorVehicleData +-- Script: 010 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function setVehicleData(pModuleType, self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = commonRC.getModuleControlData(pModuleType) + }) + :Do(function(_, data) + local moduleData = commonRC.getModuleControlData(pModuleType) + moduleData.fakeParam = 123 + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = moduleData + }) + end) + + self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + :ValidIf(function(_, data) + if data.payload.moduleData.fakeParam then + return false, 'Fake parameter is not cut-off ("fakeParam":' .. tostring(data.payload.moduleData.fakeParam) .. ")" + end + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_SetInteriorVehicleData.txt b/test_sets/rc_SetInteriorVehicleData.txt index 31c6c4a3d8..db5e9b5b89 100644 --- a/test_sets/rc_SetInteriorVehicleData.txt +++ b/test_sets/rc_SetInteriorVehicleData.txt @@ -6,3 +6,5 @@ ./test_scripts/RC/SetInteriorVehicleData/006.lua ./test_scripts/RC/SetInteriorVehicleData/007.lua ./test_scripts/RC/SetInteriorVehicleData/008.lua +./test_scripts/RC/SetInteriorVehicleData/009.lua +./test_scripts/RC/SetInteriorVehicleData/010.lua From 06d4d32330c2489d441bb7eef3704c8741ceb36f Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Thu, 20 Jul 2017 18:14:00 +0300 Subject: [PATCH 034/681] GetInteriorVehicleData: Minor fix --- test_scripts/RC/GetInteriorVehicleData/005.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/RC/GetInteriorVehicleData/005.lua b/test_scripts/RC/GetInteriorVehicleData/005.lua index 592351efac..ffabd6078b 100644 --- a/test_scripts/RC/GetInteriorVehicleData/005.lua +++ b/test_scripts/RC/GetInteriorVehicleData/005.lua @@ -102,7 +102,7 @@ for _, mod in pairs(modules) do runner.Step("GetInteriorVehicleData " .. mod .. " fake parameter", fakeParam, { mod }) end -runner.Step("GetInteriorVehicleData (mandatory parameter absent)", missingMandatoryParam) +runner.Step("GetInteriorVehicleData mandatory parameter absent", missingMandatoryParam) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) From e45c3cc38c8644da32949461a3e014ddc872c96b Mon Sep 17 00:00:00 2001 From: Igor Kovalenko Date: Thu, 20 Jul 2017 15:07:33 +0300 Subject: [PATCH 035/681] 005.lua check for RPC ButtonPress parameters --- test_scripts/RC/ButtonPress/005.lua | 58 +++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 test_scripts/RC/ButtonPress/005.lua diff --git a/test_scripts/RC/ButtonPress/005.lua b/test_scripts/RC/ButtonPress/005.lua new file mode 100644 index 0000000000..95588b7f3e --- /dev/null +++ b/test_scripts/RC/ButtonPress/005.lua @@ -0,0 +1,58 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: ButtonPress +-- Script: 005 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local runner = require('user_modules/script_runner') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +-- Climate Buttons +-- "AC_MAX" +-- "AC" +-- "RECIRCULATE" +-- "FAN_UP" +-- "FAN_DOWN" +-- "TEMP_UP" +-- "TEMP_DOWN" +-- "DEFROST_MAX" +-- "DEFROST" +-- "DEFROST_REAR" +-- "UPPER_VENT" +-- "LOWER_VENT" + +local climate_params = { + moduleType = "CLIMATE", + buttonName = "VOLUME_UP", + buttonPressMode = "SHORT" -- LONG, SHORT +} + +local radio_params = { + moduleType = "RADIO", + buttonName = "AC", + buttonPressMode = "LONG" +} + + +--[[ Local Functions ]] +local function SendButtonPress(button_press_params, self) + local cid = self.mobileSession:SendRPC("ButtonPress", button_press_params) + + EXPECT_HMICALL("Buttons.ButtonPress") + :Times(0) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test") +runner.Step("ButtonPress_CLIMATE", SendButtonPress, {climate_params}) +runner.Step("ButtonPress_RADIO", SendButtonPress, {radio_params}) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) From b8b738eaf1f6fc1d5205f2b7272d5a13401f0a3f Mon Sep 17 00:00:00 2001 From: Igor Kovalenko Date: Fri, 21 Jul 2017 11:27:10 +0300 Subject: [PATCH 036/681] modified 005 - ButtonPress --- test_scripts/RC/ButtonPress/005.lua | 81 ++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 19 deletions(-) diff --git a/test_scripts/RC/ButtonPress/005.lua b/test_scripts/RC/ButtonPress/005.lua index 95588b7f3e..f5cdbdd64e 100644 --- a/test_scripts/RC/ButtonPress/005.lua +++ b/test_scripts/RC/ButtonPress/005.lua @@ -7,19 +7,30 @@ local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --- Climate Buttons --- "AC_MAX" --- "AC" --- "RECIRCULATE" --- "FAN_UP" --- "FAN_DOWN" --- "TEMP_UP" --- "TEMP_DOWN" --- "DEFROST_MAX" --- "DEFROST" --- "DEFROST_REAR" --- "UPPER_VENT" --- "LOWER_VENT" +--[[ Local variables for tests ]] +local climate_button_names = { + "AC_MAX", + "AC", + "RECIRCULATE", + "FAN_UP", + "FAN_DOWN", + "TEMP_UP", + "TEMP_DOWN", + "DEFROST_MAX", + "DEFROST", + "DEFROST_REAR", + "UPPER_VENT", + "LOWER_VENT" +} + +local radio_button_names = { + "VOLUME_UP", + "VOLUME_DOWN", + "EJECT", + "SOURCE", + "SHUFFLE", + "REPEAT", +} local climate_params = { moduleType = "CLIMATE", @@ -33,9 +44,27 @@ local radio_params = { buttonPressMode = "LONG" } - --[[ Local Functions ]] -local function SendButtonPress(button_press_params, self) +local function SendButtonPressPositive(button_press_params, self) + local cid = self.mobileSession:SendRPC("ButtonPress", button_press_params) + + EXPECT_HMICALL("Buttons.ButtonPress", { + appID = self.applications["Test Application"], + moduleType = button_press_params.moduleType, + buttonName = button_press_params.buttonName, + buttonPressMode = button_press_params.buttonPressMode + }) + :Times(1) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "SUCCESS" }) + + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function SendButtonPressNegative(button_press_params, self) local cid = self.mobileSession:SendRPC("ButtonPress", button_press_params) EXPECT_HMICALL("Buttons.ButtonPress") @@ -46,13 +75,27 @@ local function SendButtonPress(button_press_params, self) commonTestCases:DelayedExp(commonRC.timeout) end ---[[ Scenario ]] +--[[ Positive Scenario - check all positive climate names params]] +for _, button_name_value in pairs( climate_button_names ) do + climate_params.buttonPressMode = "SHORT" + runner.Title("Preconditions") + runner.Step("Clean environment", commonRC.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) + runner.Step("RAI, PTU", commonRC.rai_ptu) + runner.Title("Test - ButtonPress with buttonName " .. button_name_value) + runner.Step("ButtonPress_CLIMATE", SendButtonPressPositive, {climate_params}) + runner.Step("ButtonPress_RADIO", SendButtonPressNegative, {radio_params}) + runner.Title("Postconditions") + runner.Step("Stop SDL", commonRC.postconditions) +end + +--[[ Negative Scenario - not matched params in mobile request]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Title("Test") -runner.Step("ButtonPress_CLIMATE", SendButtonPress, {climate_params}) -runner.Step("ButtonPress_RADIO", SendButtonPress, {radio_params}) +runner.Title("Test - negative, not matched params in mobile request") +runner.Step("ButtonPress_CLIMATE", SendButtonPressNegative, {climate_params}) +runner.Step("ButtonPress_RADIO", SendButtonPressNegative, {radio_params}) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) From 5abb0173da4b731bca1454a7a8bf97530aad22cf Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 21 Jul 2017 12:12:47 +0300 Subject: [PATCH 037/681] Rename scripts --- .../{001.lua => 001_Success_flow.lua} | 1 - ...> 002_Disallow_flow_by_policy_CLIMATE.lua} | 1 - ... => 003_Disallow_flow_by_policy_RADIO.lua} | 1 - ...case_appHMIType_is_not_REMOTE_CONTROL.lua} | 1 - ...ansfering_of_HMI_resultCode_to_mobile.lua} | 1 - ...{005.lua => 006_RPC_parameters_values.lua} | 1 - ...RIC_ERROR_in_case_HMI_did_not_respond.lua} | 1 - ...in_case_HMI_respond_with_invalid_data.lua} | 1 - ...e_moduleType_is_an_empty_array_in_LPT.lua} | 1 - ...w_in_case_moduleType_is_absent_in_LPT.lua} | 1 - ...OR_in_case_HMI_respond_with_READ_ONLY.lua} | 1 - ...esponse_from_HMI_without_isSubscribed.lua} | 1 - ...t_response_from_HMI_with_isSubscribed.lua} | 1 - .../{001.lua => 001_Success_flow.lua} | 1 - ...> 002_Disallow_flow_by_policy_CLIMATE.lua} | 1 - ... => 003_Disallow_flow_by_policy_RADIO.lua} | 1 - ...ibing_with_isSubscribe_false_from_HMI.lua} | 1 - ...scribing_without_isSubscribe_from_HMI.lua} | 1 - ...se_of_subscribing_with_error_from_HMI.lua} | 1 - ...subscribing_with_no_response_from_HMI.lua} | 1 - ...ribing_with_invalid_response_from_HMI.lua} | 1 - ...ribing_with_isSubscribe_true_from_HMI.lua} | 1 - ...scribing_without_isSubscribe_from_HMI.lua} | 1 - ...ibing_with_isSubscribe_false_from_HMI.lua} | 1 - ...scribing_without_isSubscribe_from_HMI.lua} | 1 - ...mate_and_without_one_for_module_Radio.lua} | 1 - ...io_and_without_one_for_module_Climate.lua} | 1 - ...d_after_unsubscribe_from_module_Radio.lua} | 1 - ...after_unsubscribe_from_module_Climate.lua} | 1 - ...{014.lua => 017_RPC_parameters_values.lua} | 1 - test_sets/rc_GetInteriorVehicleData.txt | 26 +++++++------- test_sets/rc_OnInteriorVehicleData.txt | 34 +++++++++---------- 32 files changed, 30 insertions(+), 60 deletions(-) rename test_scripts/RC/GetInteriorVehicleData/{001.lua => 001_Success_flow.lua} (98%) rename test_scripts/RC/GetInteriorVehicleData/{002c.lua => 002_Disallow_flow_by_policy_CLIMATE.lua} (98%) rename test_scripts/RC/GetInteriorVehicleData/{002r.lua => 003_Disallow_flow_by_policy_RADIO.lua} (98%) rename test_scripts/RC/GetInteriorVehicleData/{003.lua => 004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua} (98%) rename test_scripts/RC/GetInteriorVehicleData/{004.lua => 005_Transfering_of_HMI_resultCode_to_mobile.lua} (99%) rename test_scripts/RC/GetInteriorVehicleData/{005.lua => 006_RPC_parameters_values.lua} (99%) rename test_scripts/RC/GetInteriorVehicleData/{006.lua => 007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua} (99%) rename test_scripts/RC/GetInteriorVehicleData/{007.lua => 008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua} (99%) rename test_scripts/RC/GetInteriorVehicleData/{008.lua => 009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua} (99%) rename test_scripts/RC/GetInteriorVehicleData/{009.lua => 010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua} (99%) rename test_scripts/RC/GetInteriorVehicleData/{010.lua => 011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua} (99%) rename test_scripts/RC/GetInteriorVehicleData/{011.lua => 012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua} (99%) rename test_scripts/RC/GetInteriorVehicleData/{012.lua => 013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua} (99%) rename test_scripts/RC/OnInteriorVehicleData/{001.lua => 001_Success_flow.lua} (98%) rename test_scripts/RC/OnInteriorVehicleData/{002c.lua => 002_Disallow_flow_by_policy_CLIMATE.lua} (98%) rename test_scripts/RC/OnInteriorVehicleData/{002r.lua => 003_Disallow_flow_by_policy_RADIO.lua} (98%) rename test_scripts/RC/OnInteriorVehicleData/{003.lua => 004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua} (99%) rename test_scripts/RC/OnInteriorVehicleData/{004.lua => 005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua} (99%) rename test_scripts/RC/OnInteriorVehicleData/{005.lua => 006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua} (99%) rename test_scripts/RC/OnInteriorVehicleData/{006.lua => 007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua} (99%) rename test_scripts/RC/OnInteriorVehicleData/{007.lua => 008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua} (99%) rename test_scripts/RC/OnInteriorVehicleData/{008.lua => 009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua} (99%) rename test_scripts/RC/OnInteriorVehicleData/{009.lua => 010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua} (99%) rename test_scripts/RC/OnInteriorVehicleData/{011.lua => 011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua} (99%) rename test_scripts/RC/OnInteriorVehicleData/{010.lua => 012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua} (99%) rename test_scripts/RC/OnInteriorVehicleData/{012c.lua => 013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua} (98%) rename test_scripts/RC/OnInteriorVehicleData/{012r.lua => 014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua} (98%) rename test_scripts/RC/OnInteriorVehicleData/{013c.lua => 015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua} (98%) rename test_scripts/RC/OnInteriorVehicleData/{013r.lua => 016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua} (98%) rename test_scripts/RC/OnInteriorVehicleData/{014.lua => 017_RPC_parameters_values.lua} (99%) diff --git a/test_scripts/RC/GetInteriorVehicleData/001.lua b/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua similarity index 98% rename from test_scripts/RC/GetInteriorVehicleData/001.lua rename to test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua index 4ab9db49a0..5b7201e5e5 100644 --- a/test_scripts/RC/GetInteriorVehicleData/001.lua +++ b/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: GetInteriorVehicleData --- Script: 001 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/002c.lua b/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua similarity index 98% rename from test_scripts/RC/GetInteriorVehicleData/002c.lua rename to test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 62878e8de8..362baefcee 100644 --- a/test_scripts/RC/GetInteriorVehicleData/002c.lua +++ b/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: GetInteriorVehicleData --- Script: 002 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/002r.lua b/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua similarity index 98% rename from test_scripts/RC/GetInteriorVehicleData/002r.lua rename to test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index d116254da2..77f94fec3a 100644 --- a/test_scripts/RC/GetInteriorVehicleData/002r.lua +++ b/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: GetInteriorVehicleData --- Script: 002 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/003.lua b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua similarity index 98% rename from test_scripts/RC/GetInteriorVehicleData/003.lua rename to test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 2ca1e7ddc3..4aade2f664 100644 --- a/test_scripts/RC/GetInteriorVehicleData/003.lua +++ b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: GetInteriorVehicleData --- Script: 003 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/004.lua b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua similarity index 99% rename from test_scripts/RC/GetInteriorVehicleData/004.lua rename to test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua index 4a0e2f708a..9d49d9c800 100644 --- a/test_scripts/RC/GetInteriorVehicleData/004.lua +++ b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: GetInteriorVehicleData --- Script: 004 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/005.lua b/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua similarity index 99% rename from test_scripts/RC/GetInteriorVehicleData/005.lua rename to test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua index ffabd6078b..c6a2351941 100644 --- a/test_scripts/RC/GetInteriorVehicleData/005.lua +++ b/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: GetInteriorVehicleData --- Script: 005 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/006.lua b/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua similarity index 99% rename from test_scripts/RC/GetInteriorVehicleData/006.lua rename to test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index 71600e85d6..790ed72c5a 100644 --- a/test_scripts/RC/GetInteriorVehicleData/006.lua +++ b/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: GetInteriorVehicleData --- Script: 006 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/007.lua b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua similarity index 99% rename from test_scripts/RC/GetInteriorVehicleData/007.lua rename to test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index e66989af6e..09383c04fc 100644 --- a/test_scripts/RC/GetInteriorVehicleData/007.lua +++ b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: GetInteriorVehicleData --- Script: 007 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/008.lua b/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua similarity index 99% rename from test_scripts/RC/GetInteriorVehicleData/008.lua rename to test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index eedb9e1307..17e4249014 100644 --- a/test_scripts/RC/GetInteriorVehicleData/008.lua +++ b/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: GetInteriorVehicleData --- Script: 008 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/009.lua b/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua similarity index 99% rename from test_scripts/RC/GetInteriorVehicleData/009.lua rename to test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 8bc347f7fa..0feee4e2a6 100644 --- a/test_scripts/RC/GetInteriorVehicleData/009.lua +++ b/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: GetInteriorVehicleData --- Script: 009 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/010.lua b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua similarity index 99% rename from test_scripts/RC/GetInteriorVehicleData/010.lua rename to test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua index bc04ff5d22..b86b27da77 100644 --- a/test_scripts/RC/GetInteriorVehicleData/010.lua +++ b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: GetInteriorVehicleData --- Script: 010 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/011.lua b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua similarity index 99% rename from test_scripts/RC/GetInteriorVehicleData/011.lua rename to test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua index f16cb4e801..200f17bdec 100644 --- a/test_scripts/RC/GetInteriorVehicleData/011.lua +++ b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: GetInteriorVehicleData --- Script: 011 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/012.lua b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua similarity index 99% rename from test_scripts/RC/GetInteriorVehicleData/012.lua rename to test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index c85ae2ff82..db034984df 100644 --- a/test_scripts/RC/GetInteriorVehicleData/012.lua +++ b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: GetInteriorVehicleData --- Script: 012 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/001.lua b/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua similarity index 98% rename from test_scripts/RC/OnInteriorVehicleData/001.lua rename to test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua index e0aef5459a..ac6f87dcbe 100644 --- a/test_scripts/RC/OnInteriorVehicleData/001.lua +++ b/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 001 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/002c.lua b/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua similarity index 98% rename from test_scripts/RC/OnInteriorVehicleData/002c.lua rename to test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 8a7f6e304b..dbe90482b0 100644 --- a/test_scripts/RC/OnInteriorVehicleData/002c.lua +++ b/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 002 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/002r.lua b/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua similarity index 98% rename from test_scripts/RC/OnInteriorVehicleData/002r.lua rename to test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index 3c8cba3e71..2fe8d2dd59 100644 --- a/test_scripts/RC/OnInteriorVehicleData/002r.lua +++ b/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 002 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/003.lua b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua similarity index 99% rename from test_scripts/RC/OnInteriorVehicleData/003.lua rename to test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua index 1470927447..6cdb90221c 100644 --- a/test_scripts/RC/OnInteriorVehicleData/003.lua +++ b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 003 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/004.lua b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua similarity index 99% rename from test_scripts/RC/OnInteriorVehicleData/004.lua rename to test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua index 8a1df979dd..bbcb4acd56 100644 --- a/test_scripts/RC/OnInteriorVehicleData/004.lua +++ b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 004 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/005.lua b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua similarity index 99% rename from test_scripts/RC/OnInteriorVehicleData/005.lua rename to test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua index 322288f08d..624c10ac2c 100644 --- a/test_scripts/RC/OnInteriorVehicleData/005.lua +++ b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 005 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/006.lua b/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua similarity index 99% rename from test_scripts/RC/OnInteriorVehicleData/006.lua rename to test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua index 0b04f12ecf..c957979e9a 100644 --- a/test_scripts/RC/OnInteriorVehicleData/006.lua +++ b/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 006 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/007.lua b/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua similarity index 99% rename from test_scripts/RC/OnInteriorVehicleData/007.lua rename to test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua index 69a06e123e..ecd5f48891 100644 --- a/test_scripts/RC/OnInteriorVehicleData/007.lua +++ b/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 007 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/008.lua b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua similarity index 99% rename from test_scripts/RC/OnInteriorVehicleData/008.lua rename to test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua index 5d499110f6..c4b6781a4d 100644 --- a/test_scripts/RC/OnInteriorVehicleData/008.lua +++ b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 008 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/009.lua b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua similarity index 99% rename from test_scripts/RC/OnInteriorVehicleData/009.lua rename to test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua index d39c655fe2..f6965d1d2f 100644 --- a/test_scripts/RC/OnInteriorVehicleData/009.lua +++ b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 009 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/011.lua b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua similarity index 99% rename from test_scripts/RC/OnInteriorVehicleData/011.lua rename to test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua index 47ff3855d0..1fca515606 100644 --- a/test_scripts/RC/OnInteriorVehicleData/011.lua +++ b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 011 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/010.lua b/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua similarity index 99% rename from test_scripts/RC/OnInteriorVehicleData/010.lua rename to test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua index f4d8f00dcf..1853969cad 100644 --- a/test_scripts/RC/OnInteriorVehicleData/010.lua +++ b/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 010 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/012c.lua b/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua similarity index 98% rename from test_scripts/RC/OnInteriorVehicleData/012c.lua rename to test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua index 164a8d27b6..595fdae8ef 100644 --- a/test_scripts/RC/OnInteriorVehicleData/012c.lua +++ b/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 012 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/012r.lua b/test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua similarity index 98% rename from test_scripts/RC/OnInteriorVehicleData/012r.lua rename to test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua index 47f2f71cce..bcd4991568 100644 --- a/test_scripts/RC/OnInteriorVehicleData/012r.lua +++ b/test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 012 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/013c.lua b/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua similarity index 98% rename from test_scripts/RC/OnInteriorVehicleData/013c.lua rename to test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua index 4a5f704c3d..dfa9b0321d 100644 --- a/test_scripts/RC/OnInteriorVehicleData/013c.lua +++ b/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 012 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/013r.lua b/test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua similarity index 98% rename from test_scripts/RC/OnInteriorVehicleData/013r.lua rename to test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua index 61158ee9a3..2772d05f21 100644 --- a/test_scripts/RC/OnInteriorVehicleData/013r.lua +++ b/test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 012 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/014.lua b/test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua similarity index 99% rename from test_scripts/RC/OnInteriorVehicleData/014.lua rename to test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua index f1ef0a21a3..be601a5411 100644 --- a/test_scripts/RC/OnInteriorVehicleData/014.lua +++ b/test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua @@ -1,6 +1,5 @@ --------------------------------------------------------------------------------------------------- -- RPC: OnInteriorVehicleData --- Script: 014 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_sets/rc_GetInteriorVehicleData.txt b/test_sets/rc_GetInteriorVehicleData.txt index acbf5282f8..d8c41b442b 100644 --- a/test_sets/rc_GetInteriorVehicleData.txt +++ b/test_sets/rc_GetInteriorVehicleData.txt @@ -1,13 +1,13 @@ -./test_scripts/RC/GetInteriorVehicleData/001.lua -./test_scripts/RC/GetInteriorVehicleData/002r.lua -./test_scripts/RC/GetInteriorVehicleData/002c.lua -./test_scripts/RC/GetInteriorVehicleData/003.lua -./test_scripts/RC/GetInteriorVehicleData/004.lua -./test_scripts/RC/GetInteriorVehicleData/005.lua -./test_scripts/RC/GetInteriorVehicleData/006.lua -./test_scripts/RC/GetInteriorVehicleData/007.lua -./test_scripts/RC/GetInteriorVehicleData/008.lua -./test_scripts/RC/GetInteriorVehicleData/009.lua -./test_scripts/RC/GetInteriorVehicleData/010.lua -./test_scripts/RC/GetInteriorVehicleData/011.lua -./test_scripts/RC/GetInteriorVehicleData/012.lua +./test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +./test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +./test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua +./test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua +./test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +./test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +./test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua diff --git a/test_sets/rc_OnInteriorVehicleData.txt b/test_sets/rc_OnInteriorVehicleData.txt index 63d494267b..9fccba9097 100644 --- a/test_sets/rc_OnInteriorVehicleData.txt +++ b/test_sets/rc_OnInteriorVehicleData.txt @@ -1,17 +1,17 @@ -./test_scripts/RC/OnInteriorVehicleData/001.lua -./test_scripts/RC/OnInteriorVehicleData/002r.lua -./test_scripts/RC/OnInteriorVehicleData/002c.lua -./test_scripts/RC/OnInteriorVehicleData/003.lua -./test_scripts/RC/OnInteriorVehicleData/004.lua -./test_scripts/RC/OnInteriorVehicleData/005.lua -./test_scripts/RC/OnInteriorVehicleData/006.lua -./test_scripts/RC/OnInteriorVehicleData/007.lua -./test_scripts/RC/OnInteriorVehicleData/008.lua -./test_scripts/RC/OnInteriorVehicleData/009.lua -./test_scripts/RC/OnInteriorVehicleData/010.lua -./test_scripts/RC/OnInteriorVehicleData/011.lua -./test_scripts/RC/OnInteriorVehicleData/012c.lua -./test_scripts/RC/OnInteriorVehicleData/012r.lua -./test_scripts/RC/OnInteriorVehicleData/013c.lua -./test_scripts/RC/OnInteriorVehicleData/013r.lua -./test_scripts/RC/OnInteriorVehicleData/014.lua +./test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +./test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +./test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +./test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua +./test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua +./test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua +./test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +./test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua +./test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua +./test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua +./test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua +./test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua +./test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua From 4843fc2d9393ff1db2da3f4053aa2c9ee21a8b84 Mon Sep 17 00:00:00 2001 From: Igor Kovalenko Date: Fri, 21 Jul 2017 13:57:34 +0300 Subject: [PATCH 038/681] finished 005 script --- test_scripts/RC/ButtonPress/005.lua | 70 ++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/test_scripts/RC/ButtonPress/005.lua b/test_scripts/RC/ButtonPress/005.lua index f5cdbdd64e..157e7d968f 100644 --- a/test_scripts/RC/ButtonPress/005.lua +++ b/test_scripts/RC/ButtonPress/005.lua @@ -34,17 +34,27 @@ local radio_button_names = { local climate_params = { moduleType = "CLIMATE", - buttonName = "VOLUME_UP", + buttonName = "AC_MAX", buttonPressMode = "SHORT" -- LONG, SHORT } local radio_params = { moduleType = "RADIO", - buttonName = "AC", + buttonName = "VOLUME_UP", buttonPressMode = "LONG" } +commonRC.timeout = 1000 + --[[ Local Functions ]] +local function reset_climate_params( ... ) + return {moduleType = "CLIMATE", buttonName = "AC", buttonPressMode = "SHORT"} +end + +local function reset_radio_params( ... ) + return {moduleType = "RADIO", buttonName = "VOLUME_UP", buttonPressMode = "SHORT"} +end + local function SendButtonPressPositive(button_press_params, self) local cid = self.mobileSession:SendRPC("ButtonPress", button_press_params) @@ -59,7 +69,7 @@ local function SendButtonPressPositive(button_press_params, self) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "SUCCESS" }) + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) commonTestCases:DelayedExp(commonRC.timeout) end @@ -76,24 +86,54 @@ local function SendButtonPressNegative(button_press_params, self) end --[[ Positive Scenario - check all positive climate names params]] +climate_params = reset_climate_params() +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) for _, button_name_value in pairs( climate_button_names ) do climate_params.buttonPressMode = "SHORT" - runner.Title("Preconditions") - runner.Step("Clean environment", commonRC.preconditions) - runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) - runner.Step("RAI, PTU", commonRC.rai_ptu) + climate_params.buttonName = button_name_value + runner.Title("Test - ButtonPress with buttonName " .. button_name_value) + runner.Step("ButtonPress_CLIMATE_" .. button_name_value .. "_SHORT", SendButtonPressPositive, {climate_params}) + climate_params.buttonPressMode = "LONG" + runner.Step("ButtonPress_CLIMATE_" .. button_name_value .. "_LONG", SendButtonPressPositive, {climate_params}) +end + +--[[ Positive Scenario - check all positive radio names params]] +radio_params = reset_radio_params() +for _, button_name_value in pairs( radio_button_names ) do + radio_params.buttonPressMode = "SHORT" + radio_params.buttonName = button_name_value runner.Title("Test - ButtonPress with buttonName " .. button_name_value) - runner.Step("ButtonPress_CLIMATE", SendButtonPressPositive, {climate_params}) - runner.Step("ButtonPress_RADIO", SendButtonPressNegative, {radio_params}) - runner.Title("Postconditions") - runner.Step("Stop SDL", commonRC.postconditions) + runner.Step("ButtonPress_RADIO_" .. button_name_value .. "_SHORT", SendButtonPressPositive, {radio_params}) + radio_params.buttonPressMode = "LONG" + runner.Step("ButtonPress_RADIO_" .. button_name_value .. "_LONG", SendButtonPressPositive, {radio_params}) end +--[[ Negative Scenario - invalid value of buttonName in mobile request]] +climate_params = reset_climate_params() +radio_params = reset_radio_params() +climate_params.buttonName = "invalid_name" +radio_params.buttonName = "invalid_name" +runner.Title("Test - negative, invalid value of buttonName in mobile request") +runner.Step("ButtonPress_CLIMATE", SendButtonPressNegative, {climate_params}) +runner.Step("ButtonPress_RADIO", SendButtonPressNegative, {radio_params}) +climate_params = reset_climate_params() +radio_params = reset_radio_params() + +--[[ Negative Scenario - invalid value of buttonPressMode in mobile request]] +climate_params.buttonPressMode = "invalid_name" +radio_params.buttonPressMode = "invalid_name" +runner.Title("Test - negative, invalid value of buttonPressMode in mobile request") +runner.Step("ButtonPress_CLIMATE", SendButtonPressNegative, {climate_params}) +runner.Step("ButtonPress_RADIO", SendButtonPressNegative, {radio_params}) +climate_params = reset_climate_params() +radio_params = reset_radio_params() + --[[ Negative Scenario - not matched params in mobile request]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) +climate_params.buttonName = "VOLUME_UP" +radio_params.buttonName = "AC" runner.Title("Test - negative, not matched params in mobile request") runner.Step("ButtonPress_CLIMATE", SendButtonPressNegative, {climate_params}) runner.Step("ButtonPress_RADIO", SendButtonPressNegative, {radio_params}) From f73e53e26e8635753bcb0666044607a9d53e7c29 Mon Sep 17 00:00:00 2001 From: Igor Kovalenko Date: Fri, 21 Jul 2017 14:17:56 +0300 Subject: [PATCH 039/681] renamed ButtonPress scripts for more readable format --- .../{001.lua => 001_success_flow_for_climate_and_radio.lua} | 0 .../{002c.lua => 002_disallow_flow_by_policy_for_climate.lua} | 0 .../{002r.lua => 002_disallow_flow_by_policy_for_radio.lua} | 0 ...03.lua => 003_check_processing_button_press_for_nonRC_App.lua} | 0 ..._matached_buttonName_and_moduleType_for_radio_and_climate.lua} | 0 .../{005.lua => 005_check_rpc_paramters_for_button_press.lua} | 0 ...08.lua => 008_button_press_allowed_if_moduleType_is_empty.lua} | 0 ...ua => 009_button_press_disallowed_if_moduleType_is_absent.lua} | 0 ..._press_disallowed_if_moduleType_is_disallowed_by_policies.lua} | 0 .../{011.lua => 011_generic_error_if_no_response_from_hmi.lua} | 0 ...a => 012_generic_error_if_read_only_reponse_come_from_hmi.lua} | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename test_scripts/RC/ButtonPress/{001.lua => 001_success_flow_for_climate_and_radio.lua} (100%) rename test_scripts/RC/ButtonPress/{002c.lua => 002_disallow_flow_by_policy_for_climate.lua} (100%) rename test_scripts/RC/ButtonPress/{002r.lua => 002_disallow_flow_by_policy_for_radio.lua} (100%) rename test_scripts/RC/ButtonPress/{003.lua => 003_check_processing_button_press_for_nonRC_App.lua} (100%) rename test_scripts/RC/ButtonPress/{004.lua => 004_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua} (100%) rename test_scripts/RC/ButtonPress/{005.lua => 005_check_rpc_paramters_for_button_press.lua} (100%) rename test_scripts/RC/ButtonPress/{008.lua => 008_button_press_allowed_if_moduleType_is_empty.lua} (100%) rename test_scripts/RC/ButtonPress/{009.lua => 009_button_press_disallowed_if_moduleType_is_absent.lua} (100%) rename test_scripts/RC/ButtonPress/{010.lua => 010_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua} (100%) rename test_scripts/RC/ButtonPress/{011.lua => 011_generic_error_if_no_response_from_hmi.lua} (100%) rename test_scripts/RC/ButtonPress/{012.lua => 012_generic_error_if_read_only_reponse_come_from_hmi.lua} (100%) diff --git a/test_scripts/RC/ButtonPress/001.lua b/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua similarity index 100% rename from test_scripts/RC/ButtonPress/001.lua rename to test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua diff --git a/test_scripts/RC/ButtonPress/002c.lua b/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua similarity index 100% rename from test_scripts/RC/ButtonPress/002c.lua rename to test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua diff --git a/test_scripts/RC/ButtonPress/002r.lua b/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_radio.lua similarity index 100% rename from test_scripts/RC/ButtonPress/002r.lua rename to test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_radio.lua diff --git a/test_scripts/RC/ButtonPress/003.lua b/test_scripts/RC/ButtonPress/003_check_processing_button_press_for_nonRC_App.lua similarity index 100% rename from test_scripts/RC/ButtonPress/003.lua rename to test_scripts/RC/ButtonPress/003_check_processing_button_press_for_nonRC_App.lua diff --git a/test_scripts/RC/ButtonPress/004.lua b/test_scripts/RC/ButtonPress/004_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua similarity index 100% rename from test_scripts/RC/ButtonPress/004.lua rename to test_scripts/RC/ButtonPress/004_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua diff --git a/test_scripts/RC/ButtonPress/005.lua b/test_scripts/RC/ButtonPress/005_check_rpc_paramters_for_button_press.lua similarity index 100% rename from test_scripts/RC/ButtonPress/005.lua rename to test_scripts/RC/ButtonPress/005_check_rpc_paramters_for_button_press.lua diff --git a/test_scripts/RC/ButtonPress/008.lua b/test_scripts/RC/ButtonPress/008_button_press_allowed_if_moduleType_is_empty.lua similarity index 100% rename from test_scripts/RC/ButtonPress/008.lua rename to test_scripts/RC/ButtonPress/008_button_press_allowed_if_moduleType_is_empty.lua diff --git a/test_scripts/RC/ButtonPress/009.lua b/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_absent.lua similarity index 100% rename from test_scripts/RC/ButtonPress/009.lua rename to test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_absent.lua diff --git a/test_scripts/RC/ButtonPress/010.lua b/test_scripts/RC/ButtonPress/010_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua similarity index 100% rename from test_scripts/RC/ButtonPress/010.lua rename to test_scripts/RC/ButtonPress/010_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua diff --git a/test_scripts/RC/ButtonPress/011.lua b/test_scripts/RC/ButtonPress/011_generic_error_if_no_response_from_hmi.lua similarity index 100% rename from test_scripts/RC/ButtonPress/011.lua rename to test_scripts/RC/ButtonPress/011_generic_error_if_no_response_from_hmi.lua diff --git a/test_scripts/RC/ButtonPress/012.lua b/test_scripts/RC/ButtonPress/012_generic_error_if_read_only_reponse_come_from_hmi.lua similarity index 100% rename from test_scripts/RC/ButtonPress/012.lua rename to test_scripts/RC/ButtonPress/012_generic_error_if_read_only_reponse_come_from_hmi.lua From b4f76da576e577944521d50663b84a1780ffa2cb Mon Sep 17 00:00:00 2001 From: Igor Kovalenko Date: Fri, 21 Jul 2017 15:19:35 +0300 Subject: [PATCH 040/681] fix issues according to pull request comments --- ...5_check_rpc_paramters_for_button_press.lua | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/test_scripts/RC/ButtonPress/005_check_rpc_paramters_for_button_press.lua b/test_scripts/RC/ButtonPress/005_check_rpc_paramters_for_button_press.lua index 157e7d968f..ce6add7097 100644 --- a/test_scripts/RC/ButtonPress/005_check_rpc_paramters_for_button_press.lua +++ b/test_scripts/RC/ButtonPress/005_check_rpc_paramters_for_button_press.lua @@ -32,26 +32,12 @@ local radio_button_names = { "REPEAT", } -local climate_params = { - moduleType = "CLIMATE", - buttonName = "AC_MAX", - buttonPressMode = "SHORT" -- LONG, SHORT -} - -local radio_params = { - moduleType = "RADIO", - buttonName = "VOLUME_UP", - buttonPressMode = "LONG" -} - -commonRC.timeout = 1000 - --[[ Local Functions ]] -local function reset_climate_params( ... ) +local function reset_climate_params() return {moduleType = "CLIMATE", buttonName = "AC", buttonPressMode = "SHORT"} end -local function reset_radio_params( ... ) +local function reset_radio_params() return {moduleType = "RADIO", buttonName = "VOLUME_UP", buttonPressMode = "SHORT"} end @@ -70,8 +56,6 @@ local function SendButtonPressPositive(button_press_params, self) end) EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) - - commonTestCases:DelayedExp(commonRC.timeout) end local function SendButtonPressNegative(button_press_params, self) @@ -86,7 +70,7 @@ local function SendButtonPressNegative(button_press_params, self) end --[[ Positive Scenario - check all positive climate names params]] -climate_params = reset_climate_params() +local climate_params = reset_climate_params() runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) @@ -101,7 +85,7 @@ for _, button_name_value in pairs( climate_button_names ) do end --[[ Positive Scenario - check all positive radio names params]] -radio_params = reset_radio_params() +local radio_params = reset_radio_params() for _, button_name_value in pairs( radio_button_names ) do radio_params.buttonPressMode = "SHORT" radio_params.buttonName = button_name_value From aabf070a85f944de0194ca580cc19b147cde8e17 Mon Sep 17 00:00:00 2001 From: Igor Kovalenko Date: Fri, 21 Jul 2017 15:27:49 +0300 Subject: [PATCH 041/681] removed redundant scenario, updated test set --- ...5_check_rpc_paramters_for_button_press.lua | 9 -------- test_sets/rc_ButtonPress.txt | 21 ++++++++++--------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/test_scripts/RC/ButtonPress/005_check_rpc_paramters_for_button_press.lua b/test_scripts/RC/ButtonPress/005_check_rpc_paramters_for_button_press.lua index ce6add7097..e5fc6005a6 100644 --- a/test_scripts/RC/ButtonPress/005_check_rpc_paramters_for_button_press.lua +++ b/test_scripts/RC/ButtonPress/005_check_rpc_paramters_for_button_press.lua @@ -112,14 +112,5 @@ radio_params.buttonPressMode = "invalid_name" runner.Title("Test - negative, invalid value of buttonPressMode in mobile request") runner.Step("ButtonPress_CLIMATE", SendButtonPressNegative, {climate_params}) runner.Step("ButtonPress_RADIO", SendButtonPressNegative, {radio_params}) -climate_params = reset_climate_params() -radio_params = reset_radio_params() - ---[[ Negative Scenario - not matched params in mobile request]] -climate_params.buttonName = "VOLUME_UP" -radio_params.buttonName = "AC" -runner.Title("Test - negative, not matched params in mobile request") -runner.Step("ButtonPress_CLIMATE", SendButtonPressNegative, {climate_params}) -runner.Step("ButtonPress_RADIO", SendButtonPressNegative, {radio_params}) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_ButtonPress.txt b/test_sets/rc_ButtonPress.txt index 8fc244353b..14dc15fbe7 100644 --- a/test_sets/rc_ButtonPress.txt +++ b/test_sets/rc_ButtonPress.txt @@ -1,10 +1,11 @@ -./test_scripts/RC/ButtonPress/001.lua -./test_scripts/RC/ButtonPress/002c.lua -./test_scripts/RC/ButtonPress/002r.lua -./test_scripts/RC/ButtonPress/003.lua -./test_scripts/RC/ButtonPress/004.lua -./test_scripts/RC/ButtonPress/008.lua -./test_scripts/RC/ButtonPress/009.lua -./test_scripts/RC/ButtonPress/010.lua -./test_scripts/RC/ButtonPress/011.lua -./test_scripts/RC/ButtonPress/012.lua +./test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua +./test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua +./test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_radio.lua +./test_scripts/RC/ButtonPress/003_check_processing_button_press_for_nonRC_App.lua +./test_scripts/RC/ButtonPress/004_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua +./test_scripts/RC/ButtonPress/005_check_rpc_paramters_for_button_press.lua +./test_scripts/RC/ButtonPress/008_button_press_allowed_if_moduleType_is_empty.lua +./test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_absent.lua +./test_scripts/RC/ButtonPress/010_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua +./test_scripts/RC/ButtonPress/011_generic_error_if_no_response_from_hmi.lua +./test_scripts/RC/ButtonPress/012_generic_error_if_read_only_reponse_come_from_hmi.lua From 1540ea1549e0a8cedbc2f3920c3b5dc9993b5272 Mon Sep 17 00:00:00 2001 From: Igor Kovalenko Date: Fri, 21 Jul 2017 15:36:16 +0300 Subject: [PATCH 042/681] renamed 005 and 012 screen, misprints --- ...on_press.lua => 005_check_rpc_parameters_for_button_press.lua} | 0 ... => 012_generic_error_if_read_only_response_come_from_hmi.lua} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename test_scripts/RC/ButtonPress/{005_check_rpc_paramters_for_button_press.lua => 005_check_rpc_parameters_for_button_press.lua} (100%) rename test_scripts/RC/ButtonPress/{012_generic_error_if_read_only_reponse_come_from_hmi.lua => 012_generic_error_if_read_only_response_come_from_hmi.lua} (100%) diff --git a/test_scripts/RC/ButtonPress/005_check_rpc_paramters_for_button_press.lua b/test_scripts/RC/ButtonPress/005_check_rpc_parameters_for_button_press.lua similarity index 100% rename from test_scripts/RC/ButtonPress/005_check_rpc_paramters_for_button_press.lua rename to test_scripts/RC/ButtonPress/005_check_rpc_parameters_for_button_press.lua diff --git a/test_scripts/RC/ButtonPress/012_generic_error_if_read_only_reponse_come_from_hmi.lua b/test_scripts/RC/ButtonPress/012_generic_error_if_read_only_response_come_from_hmi.lua similarity index 100% rename from test_scripts/RC/ButtonPress/012_generic_error_if_read_only_reponse_come_from_hmi.lua rename to test_scripts/RC/ButtonPress/012_generic_error_if_read_only_response_come_from_hmi.lua From 51a3c085ee657b0fc37de8d8ff0fb51458d90e2b Mon Sep 17 00:00:00 2001 From: Igor Kovalenko Date: Fri, 21 Jul 2017 15:39:17 +0300 Subject: [PATCH 043/681] updated test set content according to updates in file names --- test_sets/rc_ButtonPress.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_sets/rc_ButtonPress.txt b/test_sets/rc_ButtonPress.txt index 14dc15fbe7..bf81d4ea76 100644 --- a/test_sets/rc_ButtonPress.txt +++ b/test_sets/rc_ButtonPress.txt @@ -3,9 +3,9 @@ ./test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_radio.lua ./test_scripts/RC/ButtonPress/003_check_processing_button_press_for_nonRC_App.lua ./test_scripts/RC/ButtonPress/004_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua -./test_scripts/RC/ButtonPress/005_check_rpc_paramters_for_button_press.lua +./test_scripts/RC/ButtonPress/005_check_rpc_parameters_for_button_press.lua ./test_scripts/RC/ButtonPress/008_button_press_allowed_if_moduleType_is_empty.lua ./test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_absent.lua ./test_scripts/RC/ButtonPress/010_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua ./test_scripts/RC/ButtonPress/011_generic_error_if_no_response_from_hmi.lua -./test_scripts/RC/ButtonPress/012_generic_error_if_read_only_reponse_come_from_hmi.lua +./test_scripts/RC/ButtonPress/012_generic_error_if_read_only_response_come_from_hmi.lua From 16d12ee241b4d57a026170bd70fe1a610abc9fcc Mon Sep 17 00:00:00 2001 From: JackLivio Date: Fri, 21 Jul 2017 09:59:34 -0400 Subject: [PATCH 044/681] GetSystemCapability Success --- test_scripts/API/ATF_GetSystemCapability.lua | 85 ++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 test_scripts/API/ATF_GetSystemCapability.lua diff --git a/test_scripts/API/ATF_GetSystemCapability.lua b/test_scripts/API/ATF_GetSystemCapability.lua new file mode 100644 index 0000000000..4cf43e25d6 --- /dev/null +++ b/test_scripts/API/ATF_GetSystemCapability.lua @@ -0,0 +1,85 @@ +--------------------------------------------------------------------------------------------- +-- Requirement summary: +-- Name(s) of requirement that is covered. +-- Name(s) of additional non-functional requirement(s) if applicable +-- +-- Description: +-- Describe correctly the CASE of requirement that is covered, conditions that will be used. +-- 1. Used preconditions(if applicable) +-- 2. Performed steps +-- +-- Expected result: +-- Expected SDL behaviour +--------------------------------------------------------------------------------------------- + +--[[ General configuration parameters ]] +config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" + +--[[ Required Shared libraries ]] +local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') + +--[[ Local Variables ]] +-- if not applicable remove this section + +--[[ Local Functions ]] +-- if not applicable remove this section + +-- if applicable shortly describe the purpose of function and used parameters +--[[ @Example: the function gets.... +--! @parameters: +--! func_param ]] +local function Example(func_param) + -- body +end + +--[[ General Precondition before ATF start ]] +-- General precondition for restoring configuration files of SDL: +commonFunctions:SDLForceStop() + +--[[ General Settings for configuration ]] +-- if not applicable remove this section +-- This part is under clarification, based on section for using common functions +Test = require('connecttest') +require('user_modules/AppTypes') + +--[[ Test ]] +commonFunctions:newTestCasesGroup("Test") +-- Each Test will be separate and defined as one or few TestSteps +function Test:TestStep_GetNavCapability() + local CorIdGetSystemCapability = self.mobileSession:SendRPC( + "GetSystemCapability", + { + systemCapabilityType = 0 + }) + + --mobile response + EXPECT_RESPONSE(CorIdGetSystemCapability, { + success = true, + resultCode = "SUCCESS", + systemCapability={navigationCapability={getWayPointsEnabled=true,sendLocationEnabled=true},systemCapabilityType="NAVIGATION"}}) + :Timeout(12000) +end + +function Test:TestStep_GetPhoneCapability() + local CorIdGetSystemCapability = self.mobileSession:SendRPC( + "GetSystemCapability", + { + systemCapabilityType = 1 + }) + + --mobile response + EXPECT_RESPONSE(CorIdGetSystemCapability, { + success = true, + resultCode = "SUCCESS", + systemCapability={phoneCapability={dialNumberEnabled=true},systemCapabilityType="PHONE_CALL"}}) + :Timeout(12000) +end + +--[[ Postconditions ]] +-- if not applicable remove this section +commonFunctions:newTestCasesGroup("Postconditions") +function Test:Postcondition_Stop() + StopSDL() +end + +return Test From cd93088418f94a4bb0d75e3336e3333f8c6df560 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 21 Jul 2017 17:10:28 +0300 Subject: [PATCH 045/681] GetInteriorVehicleData: Add descriptions for test scripts --- .../RC/GetInteriorVehicleData/001_Success_flow.lua | 7 ++++++- .../002_Disallow_flow_by_policy_CLIMATE.lua | 7 ++++++- .../003_Disallow_flow_by_policy_RADIO.lua | 8 ++++++-- ...w_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua | 7 ++++++- .../005_Transfering_of_HMI_resultCode_to_mobile.lua | 7 ++++++- .../006_RPC_parameters_values.lua | 10 +++++++++- .../007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua | 7 ++++++- ...RIC_ERROR_in_case_HMI_respond_with_invalid_data.lua | 9 ++++++++- ...low_in_case_moduleType_is_an_empty_array_in_LPT.lua | 7 ++++++- ...sallow_flow_in_case_moduleType_is_absent_in_LPT.lua | 7 ++++++- ...ENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua | 7 ++++++- ...eter_but_response_from_HMI_without_isSubscribed.lua | 8 +++++++- ...rameter_but_response_from_HMI_with_isSubscribed.lua | 8 +++++++- 13 files changed, 85 insertions(+), 14 deletions(-) diff --git a/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua index 5b7201e5e5..54be00a9f7 100644 --- a/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua @@ -1,5 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleData +-- Description +-- In case: +-- 1) RC app sends valid and allowed by policies GetInteriorVehicleData request +-- 2) and SDL received response with successful result code and current module data from HMI +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with provided from HMI current module data for allowed module and control items --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 362baefcee..24f884f399 100644 --- a/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -1,5 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleData +-- Description +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received GetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index 77f94fec3a..fd79d65485 100644 --- a/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -1,5 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleData +-- Description +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received GetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -40,4 +45,3 @@ runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) - diff --git a/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 4aade2f664..54bcf40e15 100644 --- a/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -1,5 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleData +-- Description +-- In case: +-- 1) Non remote-control application is registered on SDL +-- 2) and SDL received GetInteriorVehicleData request from this App +-- SDL must: +-- 1) Disallow remote-control RPCs for this app (success:false, "DISALLOWED") --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua index 9d49d9c800..4542b24978 100644 --- a/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua @@ -1,5 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleData +-- Description +-- In case: +-- 1) RC app sends valid and allowed by policies GetInteriorvehicleData request +-- 2) and SDL received GetInteriorVehicledata response with successful result code and current module data from HMI +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with provided from HMI current module data for allowed module and control items --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua index c6a2351941..416355b55c 100644 --- a/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua @@ -1,5 +1,13 @@ --------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleData +-- Description +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with invalid parameters +-- - invalid parameter name +-- - invalid parameter type +-- - missing mandatory parameter +-- SDL must: +-- 1) Do not transfer request to HMI +-- 2) Respond with success:false, "INVALID_DATA" --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index 790ed72c5a..26fba24ffe 100644 --- a/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -1,5 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleData +-- Description +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with valid parameters +-- 2) and HMI didn't respond within default timeout +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index 09383c04fc..c2e74a2d14 100644 --- a/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -1,5 +1,12 @@ --------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleData +-- Description +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with valid parameters +-- 2) and HMI responds with invalid data: +-- - invalid type of parameter +-- - missing mandatory parameter +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 17e4249014..f6dd4954a5 100644 --- a/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -1,5 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleData +-- Description +-- In case: +-- 1) "moduleType" in app's assigned policies has an empty array +-- 2) and RC app sends GetInteriorVehicleData request with valid parameters +-- SDL must: +-- 1) Allow this RPC to be processed --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 0feee4e2a6..d4bca17cce 100644 --- a/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -1,5 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleData +-- Description +-- In case: +-- 1) "moduleType" does not exist in app's assigned policies +-- 2) and RC app sends GetInteriorVehicleData request with valid parameters +-- SDL must: +-- 1) Disallow this RPC to be processed (success:false, "DISALLOWED") --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua index b86b27da77..0aba2f7fb7 100644 --- a/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +++ b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -1,5 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleData +-- Description +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with valid parameters +-- 2) and SDL gets response (resultCode: READ_ONLY) from HMI +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua index 200f17bdec..ef3c20fded 100644 --- a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -1,5 +1,11 @@ --------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleData +-- Description +-- In case: +-- 1) RC app sends valid and allowed by policies GetInteriorVehicleData request with "subscribe" parameter +-- 2) and SDL received GetInteriorVehicledata response with "resultCode:" and without "isSubscribed" parameter from HMI +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with provided from HMI current module data +-- and with added "isSubscribed: " to the related app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index db034984df..6246b9f3de 100644 --- a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -1,5 +1,11 @@ --------------------------------------------------------------------------------------------------- --- RPC: GetInteriorVehicleData +-- Description +-- In case: +-- 1) RC app sends valid and allowed by policies GetInteriorvehicleData request without "subscribe" parameter +-- 2) and SDL received GetInteriorVehicledata response with "resultCode:" and with "isSubscribed" parameter from HMI +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with provided from HMI current module data +-- and without "isSubscribed" parameter to the related app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') From 4d7e1a77c072d3022fd2339dd168db3d84f5b91a Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 21 Jul 2017 18:10:46 +0300 Subject: [PATCH 046/681] OnInteriorVehicleData: Add descriptions for test scripts --- .../001_Success_flow.lua | 21 ++++++++++++++++++- .../002_Disallow_flow_by_policy_CLIMATE.lua | 8 ++++++- .../003_Disallow_flow_by_policy_RADIO.lua | 8 ++++++- ...ribing_with_isSubscribe_false_from_HMI.lua | 9 +++++++- ...bscribing_without_isSubscribe_from_HMI.lua | 9 +++++++- ...ase_of_subscribing_with_error_from_HMI.lua | 9 +++++++- ..._subscribing_with_no_response_from_HMI.lua | 9 +++++++- ...cribing_with_invalid_response_from_HMI.lua | 9 +++++++- ...cribing_with_isSubscribe_true_from_HMI.lua | 10 ++++++++- ...bscribing_without_isSubscribe_from_HMI.lua | 10 ++++++++- ...ribing_with_isSubscribe_false_from_HMI.lua | 11 +++++++++- ...bscribing_without_isSubscribe_from_HMI.lua | 11 +++++++++- ...imate_and_without_one_for_module_Radio.lua | 7 ++++++- ...dio_and_without_one_for_module_Climate.lua | 7 ++++++- ...nd_after_unsubscribe_from_module_Radio.lua | 9 +++++++- ..._after_unsubscribe_from_module_Climate.lua | 9 +++++++- .../017_RPC_parameters_values.lua | 10 ++++++++- 17 files changed, 149 insertions(+), 17 deletions(-) diff --git a/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua index ac6f87dcbe..a9bb1191db 100644 --- a/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua @@ -1,5 +1,24 @@ --------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData +-- Description #1 +-- In case: +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter +-- 2) and SDL received GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS" from HMI +-- 3) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Internally subscribe this application for requested +-- 2) Transfer GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS", "success:true" to the related app +-- 3) Re-send OnInteriorVehicleData notification to the related app + +-- Description #2 +-- In case: +-- 1) RC app is subscribed to "" +-- 2) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS" from HMI +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Internally un-subscribe this application for requested +-- 2) Transfer GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS", "success:true" to the related app +-- 3) Does not re-send OnInteriorVehicleData notification to the related app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index dbe90482b0..21ce70c66a 100644 --- a/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -1,5 +1,11 @@ --------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData +-- Description +-- In case: +-- 1) A set of module(s) is defined in policies for particular RC app +-- 2) and this RC app is subscribed to one of the module from the list +-- 3) and then SDL received OnInteriorVehicleData notification for module not in list +-- SDL must: +-- 1) Does not re-send OnInteriorVehicleData notification to the related app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index 2fe8d2dd59..1573596546 100644 --- a/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -1,5 +1,11 @@ --------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData +-- Description +-- In case: +-- 1) A set of module(s) is defined in policies for particular RC app +-- 2) and this RC app is subscribed to one of the module from the list +-- 3) and then SDL received OnInteriorVehicleData notification for module not in list +-- SDL must: +-- 1) Does not re-send OnInteriorVehicleData notification to the related app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua index 6cdb90221c..68f9b2a175 100644 --- a/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -1,5 +1,12 @@ --------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData +-- Description +-- In case: +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter +-- 2) and SDL received GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS" from HMI +-- 3) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS", "success:true" to the related app +-- 2) Does not re-send OnInteriorVehicleData notification to the app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua index bbcb4acd56..0483494e6b 100644 --- a/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua @@ -1,5 +1,12 @@ --------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData +-- Description +-- In case: +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter +-- 2) and SDL received GetInteriorVehicleData response without "isSubscribed" parameter, "resultCode: SUCCESS" from HMI +-- 3) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS", "success:true" to the related app +-- 2) Does not re-send OnInteriorVehicleData notification to the app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua index 624c10ac2c..412fa0997a 100644 --- a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua @@ -1,5 +1,12 @@ --------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData +-- Description +-- In case: +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter +-- 2) and SDL received GetInteriorVehicleData response with "resultCode: " from HMI +-- 3) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "resultCode: " and without "isSubscribed" param to the related app +-- 2) Does not re-send OnInteriorVehicleData notification to the app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua index c957979e9a..5fa04cdd78 100644 --- a/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua @@ -1,5 +1,12 @@ --------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData +-- Description +-- In case: +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter +-- 2) and HMI didn't respond within default timeout +-- 3) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" +-- 2) Does not re-send OnInteriorVehicleData notification to the app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua index ecd5f48891..12d7b24f07 100644 --- a/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua @@ -1,5 +1,12 @@ --------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData +-- Description +-- In case: +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter +-- 2) and HMI responds with invalid data +-- 3) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" +-- 2) Does not re-send OnInteriorVehicleData notification to the app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua index c4b6781a4d..feb8257d98 100644 --- a/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua @@ -1,5 +1,13 @@ --------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData +-- Description +-- In case: +-- 1) RC app is subscribed to "" +-- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS" from HMI +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS", "success:true" to the related app +-- 2) Re-send OnInteriorVehicleData notification to the app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua index f6965d1d2f..d908cba2aa 100644 --- a/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -1,5 +1,13 @@ --------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData +-- Description +-- In case: +-- 1) RC app is subscribed to "" +-- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response without "isSubscribed" parameter, "resultCode: SUCCESS" from HMI +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS", "success:true" to the related app +-- 2) Re-send OnInteriorVehicleData notification to the app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua index 1fca515606..d6f671f80f 100644 --- a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua @@ -1,5 +1,14 @@ --------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData +-- Description +-- In case: +-- 1) RC app is subscribed to "" +-- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response with "resultCode: " from HMI +-- and with "isSubscribed" parameter +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "resultCode: " and without "isSubscribed" param to the related app +-- 2) Re-send OnInteriorVehicleData notification to the app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua index 1853969cad..733eec206c 100644 --- a/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -1,5 +1,14 @@ --------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData +-- Description +-- In case: +-- 1) RC app is subscribed to "" +-- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response with "resultCode: " from HMI +-- and without "isSubscribed" parameter +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "resultCode: " and without "isSubscribed" param to the related app +-- 2) Re-send OnInteriorVehicleData notification to the app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua b/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua index 595fdae8ef..c7a0214b2e 100644 --- a/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua +++ b/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua @@ -1,5 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData +-- Description +-- In case: +-- 1) RC app is subscribed to one of the RC module +-- 2) and then SDL received OnInteriorVehicleData notification for another module +-- SDL must: +-- 1) Does not re-send OnInteriorVehicleData notification to the related app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua b/test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua index bcd4991568..4b3324a7a4 100644 --- a/test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua +++ b/test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua @@ -1,5 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData +-- Description +-- In case: +-- 1) RC app is subscribed to one of the RC module +-- 2) and then SDL received OnInteriorVehicleData notification for another module +-- SDL must: +-- 1) Does not re-send OnInteriorVehicleData notification to the related app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua b/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua index dfa9b0321d..6d17fdfe49 100644 --- a/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua +++ b/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua @@ -1,5 +1,12 @@ --------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData +-- Description +-- In case: +-- 1) RC app is subscribed to a few RC modules +-- 2) and then RC app is unsubscribed to one of the module +-- 3) and then SDL received OnInteriorVehicleData notification for another module +-- SDL must: +-- 1) Does not re-send OnInteriorVehicleData notification to the related app for unsubscribed module +-- 2) Re-send OnInteriorVehicleData notification to the related app for subscribed module --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua b/test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua index 2772d05f21..0a4d0cce42 100644 --- a/test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua +++ b/test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua @@ -1,5 +1,12 @@ --------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData +-- Description +-- In case: +-- 1) RC app is subscribed to a few RC modules +-- 2) and then RC app is unsubscribed to one of the module +-- 3) and then SDL received OnInteriorVehicleData notification for another module +-- SDL must: +-- 1) Does not re-send OnInteriorVehicleData notification to the related app for unsubscribed module +-- 2) Re-send OnInteriorVehicleData notification to the related app for subscribed module --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua b/test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua index be601a5411..9a812c494e 100644 --- a/test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua +++ b/test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua @@ -1,5 +1,13 @@ --------------------------------------------------------------------------------------------------- --- RPC: OnInteriorVehicleData +-- Description +-- In case: +-- 1) RC app is subscribed to a RC module +-- 2) and then SDL received OnInteriorVehicleData notification for this module with invalid data +-- - invalid parameter name +-- - invalid parameter type +-- - missing mandatory parameter +-- SDL must: +-- 1) Does not re-send OnInteriorVehicleData notification to the related app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') From 3624c27a15cbd944859ac099ef52c9b62e2872de Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 21 Jul 2017 18:38:56 +0300 Subject: [PATCH 047/681] SetInteriorVehicleData: Rename scripts --- .../{001.lua => 001_Success_flow.lua} | 0 ...> 002_Disallow_flow_by_policy_CLIMATE.lua} | 0 ... => 003_Disallow_flow_by_policy_RADIO.lua} | 0 ...case_appHMIType_is_not_REMOTE_CONTROL.lua} | 0 ...ams_does_not_correspond_to_moduleType.lua} | 0 ...{006.lua => 006_RPC_parameters_values.lua} | 0 ...e_moduleType_is_an_empty_array_in_LPT.lua} | 0 ...w_in_case_moduleType_is_absent_in_LPT.lua} | 0 ...9_Cut-off_of_fake_parameters_from_App.lua} | 0 ...0_Cut-off_of_fake_parameters_from_HMI.lua} | 0 test_sets/rc_SetInteriorVehicleData.txt | 20 +++++++++---------- 11 files changed, 10 insertions(+), 10 deletions(-) rename test_scripts/RC/SetInteriorVehicleData/{001.lua => 001_Success_flow.lua} (100%) rename test_scripts/RC/SetInteriorVehicleData/{002c.lua => 002_Disallow_flow_by_policy_CLIMATE.lua} (100%) rename test_scripts/RC/SetInteriorVehicleData/{002r.lua => 003_Disallow_flow_by_policy_RADIO.lua} (100%) rename test_scripts/RC/SetInteriorVehicleData/{003.lua => 004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua} (100%) rename test_scripts/RC/SetInteriorVehicleData/{004.lua => 005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua} (100%) rename test_scripts/RC/SetInteriorVehicleData/{006.lua => 006_RPC_parameters_values.lua} (100%) rename test_scripts/RC/SetInteriorVehicleData/{007.lua => 007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua} (100%) rename test_scripts/RC/SetInteriorVehicleData/{008.lua => 008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua} (100%) rename test_scripts/RC/SetInteriorVehicleData/{009.lua => 009_Cut-off_of_fake_parameters_from_App.lua} (100%) rename test_scripts/RC/SetInteriorVehicleData/{010.lua => 010_Cut-off_of_fake_parameters_from_HMI.lua} (100%) diff --git a/test_scripts/RC/SetInteriorVehicleData/001.lua b/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/001.lua rename to test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/002c.lua b/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/002c.lua rename to test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/002r.lua b/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/002r.lua rename to test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/003.lua b/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/003.lua rename to test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/004.lua b/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/004.lua rename to test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/006.lua b/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/006.lua rename to test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/007.lua b/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/007.lua rename to test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/008.lua b/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/008.lua rename to test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/009.lua b/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/009.lua rename to test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/010.lua b/test_scripts/RC/SetInteriorVehicleData/010_Cut-off_of_fake_parameters_from_HMI.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/010.lua rename to test_scripts/RC/SetInteriorVehicleData/010_Cut-off_of_fake_parameters_from_HMI.lua diff --git a/test_sets/rc_SetInteriorVehicleData.txt b/test_sets/rc_SetInteriorVehicleData.txt index db5e9b5b89..0db16374de 100644 --- a/test_sets/rc_SetInteriorVehicleData.txt +++ b/test_sets/rc_SetInteriorVehicleData.txt @@ -1,10 +1,10 @@ -./test_scripts/RC/GetInteriorVehicleData/001.lua -./test_scripts/RC/SetInteriorVehicleData/002c.lua -./test_scripts/RC/SetInteriorVehicleData/002r.lua -./test_scripts/RC/SetInteriorVehicleData/003.lua -./test_scripts/RC/SetInteriorVehicleData/004.lua -./test_scripts/RC/SetInteriorVehicleData/006.lua -./test_scripts/RC/SetInteriorVehicleData/007.lua -./test_scripts/RC/SetInteriorVehicleData/008.lua -./test_scripts/RC/SetInteriorVehicleData/009.lua -./test_scripts/RC/SetInteriorVehicleData/010.lua +./test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +./test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +./test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua +./test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua +./test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua +./test_scripts/RC/SetInteriorVehicleData/010_Cut-off_of_fake_parameters_from_HMI.lua From d9ce4d18b4fc72343ae27a410d2f9d0dbaa51cc3 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Sun, 23 Jul 2017 00:13:25 +0300 Subject: [PATCH 048/681] GetInteriorVehicleData: Remove moduleDescription structure according to last APIs --- .../002_Disallow_flow_by_policy_CLIMATE.lua | 4 +--- .../003_Disallow_flow_by_policy_RADIO.lua | 4 +--- ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 4 +--- ...ransfering_of_HMI_resultCode_to_mobile.lua | 16 ++++---------- .../006_RPC_parameters_values.lua | 22 +++++-------------- ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 8 ++----- ..._in_case_HMI_respond_with_invalid_data.lua | 16 ++++---------- ...se_moduleType_is_an_empty_array_in_LPT.lua | 8 ++----- ...ow_in_case_moduleType_is_absent_in_LPT.lua | 4 +--- ...ROR_in_case_HMI_respond_with_READ_ONLY.lua | 8 ++----- ...response_from_HMI_without_isSubscribed.lua | 8 ++----- ...ut_response_from_HMI_with_isSubscribed.lua | 8 ++----- test_scripts/RC/commonRC.lua | 8 ++----- 13 files changed, 30 insertions(+), 88 deletions(-) diff --git a/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 24f884f399..89331b16fe 100644 --- a/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -17,9 +17,7 @@ local mod = "CLIMATE" --[[ Local Functions ]] local function getDataForModule(pModuleType, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - } + moduleType = pModuleType }) EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) diff --git a/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index fd79d65485..5e6a5ecd0e 100644 --- a/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -17,9 +17,7 @@ local mod = "RADIO" --[[ Local Functions ]] local function getDataForModule(pModuleType, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - } + moduleType = pModuleType }) EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) diff --git a/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 54bcf40e15..c7828452c8 100644 --- a/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -20,9 +20,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(pModuleType, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - } + moduleType = pModuleType }) EXPECT_HMICALL("RC.GetInteriorVehicleData") diff --git a/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua index 4542b24978..fb05de6b61 100644 --- a/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua @@ -18,17 +18,13 @@ local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTE --[[ Local Functions ]] local function stepSuccessfull(pModuleType, pResultCode, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) :Do(function(_, data) @@ -46,17 +42,13 @@ end local function stepUnsuccessfull(pModuleType, pResultCode, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) :Do(function(_, data) diff --git a/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua index 416355b55c..f2ad31d768 100644 --- a/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua @@ -20,9 +20,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function invalidParamName(pModuleType, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDecription = { -- invalid name of parameter - moduleType = pModuleType - }, + modduleType = pModuleType, -- invalid name of parameter subscribe = true }) @@ -36,9 +34,7 @@ end local function invalidParamType(pModuleType, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = 17 -- invalid type of parameter }) @@ -52,9 +48,7 @@ end local function missingMandatoryParam(self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - -- moduleType = "CLIMATE", -- mandatory parameter absent - }, + -- moduleType = "CLIMATE", -- mandatory parameter absent subscribe = true }) @@ -68,18 +62,14 @@ end local function fakeParam(pModuleType, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType, - fakeParam = 7 - }, + moduleType = pModuleType, + fakeParam = 7, subscribe = true }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) :Do(function(_, data) diff --git a/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index 26fba24ffe..4e37699ec3 100644 --- a/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -17,17 +17,13 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(pModuleType, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) :Do(function(_, _) diff --git a/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index c2e74a2d14..40353866ee 100644 --- a/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -18,17 +18,13 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function invalidParamType(pModuleType, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) :Do(function(_, data) @@ -43,17 +39,13 @@ end local function missingMandatoryParam(pModuleType, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) :Do(function(_, data) diff --git a/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index f6dd4954a5..9db9d298a3 100644 --- a/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -17,17 +17,13 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(pModuleType, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) :Do(function(_, data) diff --git a/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index d4bca17cce..3b9ef14c4e 100644 --- a/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -17,9 +17,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(module_type, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = module_type - }, + moduleType = module_type, subscribe = true }) diff --git a/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua index 0aba2f7fb7..9f5c4c33d1 100644 --- a/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +++ b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -16,17 +16,13 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(module_type, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = module_type - }, + moduleType = module_type, subscribe = true }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = module_type - }, + moduleType = module_type, subscribe = true }) :Do(function(_, data) diff --git a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua index ef3c20fded..114723169c 100644 --- a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -17,17 +17,13 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = pSubscribe }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = pSubscribe }) :Do(function(_, data) diff --git a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index 6246b9f3de..4af7ae2fb0 100644 --- a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -17,17 +17,13 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(pModuleType, isSubscriptionActive, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType -- no subscribe parameter }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - } + moduleType = pModuleType -- no subscribe parameter }) :Do(function(_, data) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 942bfd95e9..c6c921cb3d 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -353,17 +353,13 @@ end local function subscriptionToModule(pModuleType, pSubscribe, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = pSubscribe }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = pSubscribe }) :Do(function(_, data) From 4fb51917008e69fb302597600db3318274ba0b08 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Sun, 23 Jul 2017 00:19:00 +0300 Subject: [PATCH 049/681] OnInteriorVehicleData: Remove moduleDescription structure according to last APIs --- ...ssfull_subscribing_with_isSubscribe_false_from_HMI.lua | 8 ++------ ...ccessfull_subscribing_without_isSubscribe_from_HMI.lua | 8 ++------ ...f_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua | 8 ++------ ...D_in_case_of_subscribing_with_no_response_from_HMI.lua | 8 ++------ ...case_of_subscribing_with_invalid_response_from_HMI.lua | 8 ++------ ...sfull_unsubscribing_with_isSubscribe_true_from_HMI.lua | 8 ++------ ...essfull_unsubscribing_without_isSubscribe_from_HMI.lua | 8 ++------ ...full_unsubscribing_with_isSubscribe_false_from_HMI.lua | 8 ++------ ...essfull_unsubscribing_without_isSubscribe_from_HMI.lua | 8 ++------ 9 files changed, 18 insertions(+), 54 deletions(-) diff --git a/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua index 68f9b2a175..94ea213696 100644 --- a/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -18,17 +18,13 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function subscriptionToModule(pModuleType, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) :Do(function(_, data) diff --git a/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua index 0483494e6b..6d8728ea21 100644 --- a/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua @@ -18,17 +18,13 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function subscriptionToModule(pModuleType, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) :Do(function(_, data) diff --git a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua index 412fa0997a..fc7bae4b95 100644 --- a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua @@ -19,17 +19,13 @@ local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTE --[[ Local Functions ]] local function subscriptionToModule(pModuleType, pResultCode, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) :Do(function(_, data) diff --git a/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua index 5fa04cdd78..3aa4f9b3a6 100644 --- a/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua @@ -19,17 +19,13 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function subscriptionToModule(pModuleType, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) :Do(function(_, _) diff --git a/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua index 12d7b24f07..d6de35f073 100644 --- a/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua @@ -18,17 +18,13 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function subscriptionToModule(pModuleType, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = true }) :Do(function(_, data) diff --git a/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua index feb8257d98..7e27dbe64d 100644 --- a/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua @@ -19,17 +19,13 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function unSubscriptionToModule(pModuleType, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = false }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = false }) :Do(function(_, data) diff --git a/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua index d908cba2aa..ee33f7c2f0 100644 --- a/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -19,17 +19,13 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function unSubscriptionToModule(pModuleType, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = false }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = false }) :Do(function(_, data) diff --git a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua index d6f671f80f..1e5fe84ff1 100644 --- a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua @@ -26,17 +26,13 @@ local error_codes = { --[[ Local Functions ]] local function unSubscriptionToModule(pModuleType, pResultCodeName, pResultCodeId, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = false }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = false }) :Do(function(_, data) diff --git a/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua index 733eec206c..aea6cc3151 100644 --- a/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -21,17 +21,13 @@ local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTE --[[ Local Functions ]] local function unSubscriptionToModule(pModuleType, pResultCode, self) local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = false }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleDescription = { - moduleType = pModuleType - }, + moduleType = pModuleType, subscribe = false }) :Do(function(_, data) From 311222702793975b8fbbe9b49504cb8aa0bffe68 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Mon, 24 Jul 2017 10:19:39 +0300 Subject: [PATCH 050/681] Fix returning of true for positive case --- .../009_Cut-off_of_fake_parameters_from_App.lua | 1 + .../010_Cut-off_of_fake_parameters_from_HMI.lua | 1 + 2 files changed, 2 insertions(+) diff --git a/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua b/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua index 1f318ec6ec..3ae12334fc 100644 --- a/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua +++ b/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua @@ -25,6 +25,7 @@ local function setVehicleData(pModuleType, self) if data.params.moduleData.fakeParam then return false, 'Fake parameter is not cut-off ("fakeParam":' .. tostring(data.params.moduleData.fakeParam) .. ")" end + return true end) end diff --git a/test_scripts/RC/SetInteriorVehicleData/010_Cut-off_of_fake_parameters_from_HMI.lua b/test_scripts/RC/SetInteriorVehicleData/010_Cut-off_of_fake_parameters_from_HMI.lua index ca62233ab1..2ba606c67b 100644 --- a/test_scripts/RC/SetInteriorVehicleData/010_Cut-off_of_fake_parameters_from_HMI.lua +++ b/test_scripts/RC/SetInteriorVehicleData/010_Cut-off_of_fake_parameters_from_HMI.lua @@ -32,6 +32,7 @@ local function setVehicleData(pModuleType, self) if data.payload.moduleData.fakeParam then return false, 'Fake parameter is not cut-off ("fakeParam":' .. tostring(data.payload.moduleData.fakeParam) .. ")" end + return true end) end From 7f22a089cb5b82f08acbc6e6f3b7100c86126e69 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Mon, 24 Jul 2017 11:32:15 +0300 Subject: [PATCH 051/681] Remove script --- ...10_Cut-off_of_fake_parameters_from_HMI.lua | 52 ------------------- test_sets/rc_SetInteriorVehicleData.txt | 1 - 2 files changed, 53 deletions(-) delete mode 100644 test_scripts/RC/SetInteriorVehicleData/010_Cut-off_of_fake_parameters_from_HMI.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/010_Cut-off_of_fake_parameters_from_HMI.lua b/test_scripts/RC/SetInteriorVehicleData/010_Cut-off_of_fake_parameters_from_HMI.lua deleted file mode 100644 index 2ba606c67b..0000000000 --- a/test_scripts/RC/SetInteriorVehicleData/010_Cut-off_of_fake_parameters_from_HMI.lua +++ /dev/null @@ -1,52 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RPC: SetInteriorVehicleData --- Script: 010 ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/commonRC') - ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } - ---[[ Local Functions ]] -local function setVehicleData(pModuleType, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleData = commonRC.getModuleControlData(pModuleType) - }) - :Do(function(_, data) - local moduleData = commonRC.getModuleControlData(pModuleType) - moduleData.fakeParam = 123 - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = moduleData - }) - end) - - self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) - :ValidIf(function(_, data) - if data.payload.moduleData.fakeParam then - return false, 'Fake parameter is not cut-off ("fakeParam":' .. tostring(data.payload.moduleData.fakeParam) .. ")" - end - return true - end) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) - -runner.Title("Test") - -for _, mod in pairs(modules) do - runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) -end - -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_SetInteriorVehicleData.txt b/test_sets/rc_SetInteriorVehicleData.txt index 0db16374de..f4f462c41e 100644 --- a/test_sets/rc_SetInteriorVehicleData.txt +++ b/test_sets/rc_SetInteriorVehicleData.txt @@ -7,4 +7,3 @@ ./test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua ./test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua ./test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua -./test_scripts/RC/SetInteriorVehicleData/010_Cut-off_of_fake_parameters_from_HMI.lua From f6491e1f781587c55332e750ac3383861d297b5b Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Mon, 24 Jul 2017 12:45:14 +0300 Subject: [PATCH 052/681] SetInteriorVehicleData: Add descriptions for test scripts --- .../RC/SetInteriorVehicleData/001_Success_flow.lua | 9 +++++++-- .../002_Disallow_flow_by_policy_CLIMATE.lua | 8 ++++++-- .../003_Disallow_flow_by_policy_RADIO.lua | 8 ++++++-- ..._flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua | 8 ++++++-- ..._case_params_does_not_correspond_to_moduleType.lua | 8 ++++++-- .../006_RPC_parameters_values.lua | 11 +++++++++-- ...ow_in_case_moduleType_is_an_empty_array_in_LPT.lua | 8 ++++++-- ...allow_flow_in_case_moduleType_is_absent_in_LPT.lua | 8 ++++++-- .../009_Cut-off_of_fake_parameters_from_App.lua | 8 ++++++-- 9 files changed, 58 insertions(+), 18 deletions(-) diff --git a/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua index eb95532183..fb5bfef3eb 100644 --- a/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua @@ -1,6 +1,11 @@ --------------------------------------------------------------------------------------------------- --- RPC: SetInteriorVehicleData --- Script: 001 +-- Description +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) and sends valid SetInteriorVehicleData RPC with <"moduleType"> and "<*ControlData>" parameters +-- SDL must: +-- 1) Transfer this request to HMI +-- 2) Respond with received from HMI --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index e30f68b75c..77f5794c24 100644 --- a/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -1,6 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: SetInteriorVehicleData --- Script: 002 +-- Description +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received SetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index 8e9666b716..25252cf821 100644 --- a/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -1,6 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: SetInteriorVehicleData --- Script: 002 +-- Description +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received SetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index c0eb3c7c9b..479f529289 100644 --- a/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -1,6 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: SetInteriorVehicleData --- Script: 003 +-- Description +-- In case: +-- 1) Non remote-control application is registered on SDL +-- 2) and SDL received SetInteriorVehicleData request from this App +-- SDL must: +-- 1) Disallow remote-control RPCs for this app (success:false, "DISALLOWED") --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua b/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua index a36074bf1a..acdb7370dc 100644 --- a/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua +++ b/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua @@ -1,6 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: SetInteriorVehicleData --- Script: 004 +-- Description #1 +-- In case: +-- 1) Application registered with REMOTE_CONTROL AppHMIType and sends SetInteriorVehicleData RPC +-- 2) (with "climateControlData" and RADIO moduleType) OR (with "radioControlData" and CLIMATE moduleType) +-- SDL must: +-- 1) Respond with "resultCode: INVALID_DATA, success: false" to this mobile app, not transferring this RPC to the vehicle --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua index 6cccdb9711..4970296a53 100644 --- a/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua @@ -1,6 +1,13 @@ --------------------------------------------------------------------------------------------------- --- RPC: SetInteriorVehicleData --- Script: 006 +-- Description +-- In case: +-- 1) RC app sends SetInteriorVehicleData request with invalid parameters +-- - invalid parameter name +-- - invalid parameter type +-- - missing mandatory parameter +-- SDL must: +-- 1) Do not transfer request to HMI +-- 2) Respond with success:false, "INVALID_DATA" --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 8a81329bc0..da55786c44 100644 --- a/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -1,6 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: SetInteriorVehicleData --- Script: 007 +-- Description +-- In case: +-- 1) "moduleType" in app's assigned policies has an empty array +-- 2) and RC app sends SetInteriorVehicleData request with valid parameters +-- SDL must: +-- 1) Allow this RPC to be processed --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index d6c3272cdf..c7f8950d21 100644 --- a/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -1,6 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: SetInteriorVehicleData --- Script: 008 +-- Description +-- In case: +-- 1) "moduleType" does not exist in app's assigned policies +-- 2) and RC app sends SetInteriorVehicleData request with valid parameters +-- SDL must: +-- 1) Disallow this RPC to be processed (success:false, "DISALLOWED") --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua b/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua index 3ae12334fc..b0087d4d25 100644 --- a/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua +++ b/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua @@ -1,6 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: SetInteriorVehicleData --- Script: 009 +-- Description +-- In case: +-- 1) Mobile app send SetInteriorVehicleData with moduleType that matches with controlData structure +-- 2) and control data structure has fake parameters (in this case related to another module or unknown) +-- SDL must: +-- 1) Cut off these parameters and forward to HMI only parameters of controlData that are related to requested moduleType --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') From f04d516b0f7d4907bb2c7bfcfc1bb37271a6c104 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Mon, 24 Jul 2017 13:06:11 +0300 Subject: [PATCH 053/681] SetInteriorVehicleData: Minor fix in description --- test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua index fb5bfef3eb..139b7d1402 100644 --- a/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua @@ -2,7 +2,7 @@ -- Description -- In case: -- 1) Application is registered with REMOTE_CONTROL appHMIType --- 2) and sends valid SetInteriorVehicleData RPC with <"moduleType"> and "<*ControlData>" parameters +-- 2) and sends valid SetInteriorVehicleData RPC with valid parameters -- SDL must: -- 1) Transfer this request to HMI -- 2) Respond with received from HMI From efffbe8d11c5f1346c17d36569c64af3274bdc98 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Mon, 24 Jul 2017 13:24:14 +0300 Subject: [PATCH 054/681] ButtonPress: Add descriptions for test scripts --- .../001_success_flow_for_climate_and_radio.lua | 9 +++++++-- .../002_disallow_flow_by_policy_for_climate.lua | 8 ++++++-- .../002_disallow_flow_by_policy_for_radio.lua | 8 ++++++-- .../003_check_processing_button_press_for_nonRC_App.lua | 8 ++++++-- ...d_buttonName_and_moduleType_for_radio_and_climate.lua | 8 ++++++-- .../005_check_rpc_parameters_for_button_press.lua | 8 ++++++-- .../008_button_press_allowed_if_moduleType_is_empty.lua | 8 ++++++-- ...9_button_press_disallowed_if_moduleType_is_absent.lua | 8 ++++++-- ...isallowed_if_moduleType_is_disallowed_by_policies.lua | 8 ++++++-- .../011_generic_error_if_no_response_from_hmi.lua | 8 ++++++-- ...generic_error_if_read_only_response_come_from_hmi.lua | 7 +++++-- 11 files changed, 66 insertions(+), 22 deletions(-) diff --git a/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua b/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua index d8270c55d0..d1b7bfae60 100644 --- a/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua +++ b/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua @@ -1,6 +1,11 @@ --------------------------------------------------------------------------------------------------- --- RPC: ButtonPress --- Script: 001 +-- Description +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) and sends valid ButtonPress RPC with valid parameters +-- SDL must: +-- 1) Transfer this request to HMI +-- 2) Respond with received from HMI --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local commonRC = require('test_scripts/RC/commonRC') diff --git a/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua b/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua index 72172c994d..e16475dae3 100644 --- a/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua +++ b/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua @@ -1,6 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: ButtonPress --- Script: 002 +-- Description +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received ButtonPress request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local commonRC = require('test_scripts/RC/commonRC') diff --git a/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_radio.lua b/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_radio.lua index a53c0c420a..122e31f31d 100644 --- a/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_radio.lua +++ b/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_radio.lua @@ -1,6 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: ButtonPress --- Script: 002 +-- Description +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received ButtonPress request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local commonRC = require('test_scripts/RC/commonRC') diff --git a/test_scripts/RC/ButtonPress/003_check_processing_button_press_for_nonRC_App.lua b/test_scripts/RC/ButtonPress/003_check_processing_button_press_for_nonRC_App.lua index d6034f8677..764f5da10f 100644 --- a/test_scripts/RC/ButtonPress/003_check_processing_button_press_for_nonRC_App.lua +++ b/test_scripts/RC/ButtonPress/003_check_processing_button_press_for_nonRC_App.lua @@ -1,6 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: ButtonPress --- Script: 003 +-- Description +-- In case: +-- 1) Non remote-control application is registered on SDL +-- 2) and SDL received ButtonPress request from this App +-- SDL must: +-- 1) Disallow remote-control RPCs for this app (success:false, "DISALLOWED") --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local commonRC = require('test_scripts/RC/commonRC') diff --git a/test_scripts/RC/ButtonPress/004_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua b/test_scripts/RC/ButtonPress/004_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua index ca37907d31..3820aecc93 100644 --- a/test_scripts/RC/ButtonPress/004_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua +++ b/test_scripts/RC/ButtonPress/004_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua @@ -1,6 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: ButtonPress --- Script: 004 +-- Description +-- In case: +-- 1) Application registered with REMOTE_CONTROL AppHMIType sends ButtonPress RPC +-- 2) (with and RADIO moduleType) OR (with and CLIMATE moduleType) +-- SDL must: +-- 1) Respond with "resultCode: INVALID_DATA, success: false" to this mobile app, not transferring this RPC to the vehicle --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local commonRC = require('test_scripts/RC/commonRC') diff --git a/test_scripts/RC/ButtonPress/005_check_rpc_parameters_for_button_press.lua b/test_scripts/RC/ButtonPress/005_check_rpc_parameters_for_button_press.lua index e5fc6005a6..bcec980b74 100644 --- a/test_scripts/RC/ButtonPress/005_check_rpc_parameters_for_button_press.lua +++ b/test_scripts/RC/ButtonPress/005_check_rpc_parameters_for_button_press.lua @@ -1,6 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: ButtonPress --- Script: 005 +-- Description +-- In case: +-- 1) RC app sends ButtonPress request with invalid parameters +-- SDL must: +-- 1) Do not transfer request to HMI +-- 2) Respond with success:false, "INVALID_DATA" --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local commonRC = require('test_scripts/RC/commonRC') diff --git a/test_scripts/RC/ButtonPress/008_button_press_allowed_if_moduleType_is_empty.lua b/test_scripts/RC/ButtonPress/008_button_press_allowed_if_moduleType_is_empty.lua index b698d00862..236c4c65fc 100644 --- a/test_scripts/RC/ButtonPress/008_button_press_allowed_if_moduleType_is_empty.lua +++ b/test_scripts/RC/ButtonPress/008_button_press_allowed_if_moduleType_is_empty.lua @@ -1,6 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: ButtonPress --- Script: 008 +-- Description +-- In case: +-- 1) "moduleType" in app's assigned policies has an empty array +-- 2) and RC app sends ButtonPress request with valid parameters +-- SDL must: +-- 1) Allow this RPC to be processed --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_absent.lua b/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_absent.lua index 35a3461feb..c9222b6ef9 100644 --- a/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_absent.lua +++ b/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_absent.lua @@ -1,6 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: ButtonPress --- Script: 009 +-- Description +-- In case: +-- 1) "moduleType" does not exist in app's assigned policies +-- 2) and RC app sends ButtonPress request with valid parameters +-- SDL must: +-- 1) Disallow this RPC to be processed (success:false, "DISALLOWED") --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/ButtonPress/010_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua b/test_scripts/RC/ButtonPress/010_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua index 2f1ef9c97d..12305b8725 100644 --- a/test_scripts/RC/ButtonPress/010_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua +++ b/test_scripts/RC/ButtonPress/010_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua @@ -1,6 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: ButtonPress --- Script: 010 +-- Description +-- In case: +-- 1) ButtonPress RPC does not exist in app's assigned policies +-- 2) and RC app sends ButtonPress request with valid parameters +-- SDL must: +-- 1) Disallow this RPC to be processed (success:false, "DISALLOWED") --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/ButtonPress/011_generic_error_if_no_response_from_hmi.lua b/test_scripts/RC/ButtonPress/011_generic_error_if_no_response_from_hmi.lua index 8e54c08333..fddcd7ce21 100644 --- a/test_scripts/RC/ButtonPress/011_generic_error_if_no_response_from_hmi.lua +++ b/test_scripts/RC/ButtonPress/011_generic_error_if_no_response_from_hmi.lua @@ -1,6 +1,10 @@ --------------------------------------------------------------------------------------------------- --- RPC: ButtonPress --- Script: 011 +-- Description +-- In case: +-- 1) RC app sends ButtonPress request with valid parameters +-- 2) and HMI didn't respond within default timeout +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/ButtonPress/012_generic_error_if_read_only_response_come_from_hmi.lua b/test_scripts/RC/ButtonPress/012_generic_error_if_read_only_response_come_from_hmi.lua index 3e518a7437..6ca81773f9 100644 --- a/test_scripts/RC/ButtonPress/012_generic_error_if_read_only_response_come_from_hmi.lua +++ b/test_scripts/RC/ButtonPress/012_generic_error_if_read_only_response_come_from_hmi.lua @@ -1,6 +1,9 @@ --------------------------------------------------------------------------------------------------- --- RPC: ButtonPress --- Script: 012 +-- In case: +-- 1) RC app sends ButtonPress request with valid parameters +-- 2) and SDL gets response (resultCode: READ_ONLY) from HMI +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') From c3872959a4ff47c1744fcabde00ad4d21829e9d7 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Mon, 24 Jul 2017 13:38:47 +0300 Subject: [PATCH 055/681] ButtonPress: Renaming test scripts --- ... 003_disallow_flow_by_policy_for_radio.lua} | 0 ..._processing_button_press_for_nonRC_App.lua} | 0 ...e_and_moduleType_for_radio_and_climate.lua} | 0 ..._check_rpc_parameters_for_button_press.lua} | 0 ...n_press_allowed_if_moduleType_is_empty.lua} | 0 ...ess_disallowed_if_moduleType_is_absent.lua} | 0 ...f_moduleType_is_disallowed_by_policies.lua} | 0 ..._generic_error_if_no_response_from_hmi.lua} | 0 ...or_if_read_only_response_come_from_hmi.lua} | 0 test_sets/rc_ButtonPress.txt | 18 +++++++++--------- 10 files changed, 9 insertions(+), 9 deletions(-) rename test_scripts/RC/ButtonPress/{002_disallow_flow_by_policy_for_radio.lua => 003_disallow_flow_by_policy_for_radio.lua} (100%) rename test_scripts/RC/ButtonPress/{003_check_processing_button_press_for_nonRC_App.lua => 004_check_processing_button_press_for_nonRC_App.lua} (100%) rename test_scripts/RC/ButtonPress/{004_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua => 005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua} (100%) rename test_scripts/RC/ButtonPress/{005_check_rpc_parameters_for_button_press.lua => 006_check_rpc_parameters_for_button_press.lua} (100%) rename test_scripts/RC/ButtonPress/{008_button_press_allowed_if_moduleType_is_empty.lua => 007_button_press_allowed_if_moduleType_is_empty.lua} (100%) rename test_scripts/RC/ButtonPress/{009_button_press_disallowed_if_moduleType_is_absent.lua => 008_button_press_disallowed_if_moduleType_is_absent.lua} (100%) rename test_scripts/RC/ButtonPress/{010_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua => 009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua} (100%) rename test_scripts/RC/ButtonPress/{011_generic_error_if_no_response_from_hmi.lua => 010_generic_error_if_no_response_from_hmi.lua} (100%) rename test_scripts/RC/ButtonPress/{012_generic_error_if_read_only_response_come_from_hmi.lua => 011_generic_error_if_read_only_response_come_from_hmi.lua} (100%) diff --git a/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_radio.lua b/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua similarity index 100% rename from test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_radio.lua rename to test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua diff --git a/test_scripts/RC/ButtonPress/003_check_processing_button_press_for_nonRC_App.lua b/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua similarity index 100% rename from test_scripts/RC/ButtonPress/003_check_processing_button_press_for_nonRC_App.lua rename to test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua diff --git a/test_scripts/RC/ButtonPress/004_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua b/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua similarity index 100% rename from test_scripts/RC/ButtonPress/004_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua rename to test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua diff --git a/test_scripts/RC/ButtonPress/005_check_rpc_parameters_for_button_press.lua b/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua similarity index 100% rename from test_scripts/RC/ButtonPress/005_check_rpc_parameters_for_button_press.lua rename to test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua diff --git a/test_scripts/RC/ButtonPress/008_button_press_allowed_if_moduleType_is_empty.lua b/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua similarity index 100% rename from test_scripts/RC/ButtonPress/008_button_press_allowed_if_moduleType_is_empty.lua rename to test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua diff --git a/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_absent.lua b/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua similarity index 100% rename from test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_absent.lua rename to test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua diff --git a/test_scripts/RC/ButtonPress/010_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua b/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua similarity index 100% rename from test_scripts/RC/ButtonPress/010_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua rename to test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua diff --git a/test_scripts/RC/ButtonPress/011_generic_error_if_no_response_from_hmi.lua b/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua similarity index 100% rename from test_scripts/RC/ButtonPress/011_generic_error_if_no_response_from_hmi.lua rename to test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua diff --git a/test_scripts/RC/ButtonPress/012_generic_error_if_read_only_response_come_from_hmi.lua b/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua similarity index 100% rename from test_scripts/RC/ButtonPress/012_generic_error_if_read_only_response_come_from_hmi.lua rename to test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua diff --git a/test_sets/rc_ButtonPress.txt b/test_sets/rc_ButtonPress.txt index bf81d4ea76..0095372caa 100644 --- a/test_sets/rc_ButtonPress.txt +++ b/test_sets/rc_ButtonPress.txt @@ -1,11 +1,11 @@ ./test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua ./test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua -./test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_radio.lua -./test_scripts/RC/ButtonPress/003_check_processing_button_press_for_nonRC_App.lua -./test_scripts/RC/ButtonPress/004_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua -./test_scripts/RC/ButtonPress/005_check_rpc_parameters_for_button_press.lua -./test_scripts/RC/ButtonPress/008_button_press_allowed_if_moduleType_is_empty.lua -./test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_absent.lua -./test_scripts/RC/ButtonPress/010_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua -./test_scripts/RC/ButtonPress/011_generic_error_if_no_response_from_hmi.lua -./test_scripts/RC/ButtonPress/012_generic_error_if_read_only_response_come_from_hmi.lua +./test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua +./test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua +./test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua +./test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua +./test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua +./test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua +./test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua +./test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua +./test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua From 14bdb85cc444b1d58d9c463a0074c956e23eb023 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Mon, 24 Jul 2017 16:11:21 +0300 Subject: [PATCH 056/681] SetInteriorVehicleData: Add script --- ...read-only_and_not_read-only_parameters.lua | 88 +++++++++++++++++++ test_scripts/RC/commonRC.lua | 31 +++++++ test_sets/rc_SetInteriorVehicleData.txt | 1 + 3 files changed, 120 insertions(+) create mode 100644 test_scripts/RC/SetInteriorVehicleData/011_Check_cut-off_read-only_parameters_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/011_Check_cut-off_read-only_parameters_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters.lua b/test_scripts/RC/SetInteriorVehicleData/011_Check_cut-off_read-only_parameters_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters.lua new file mode 100644 index 0000000000..88672d2095 --- /dev/null +++ b/test_scripts/RC/SetInteriorVehicleData/011_Check_cut-off_read-only_parameters_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters.lua @@ -0,0 +1,88 @@ +--------------------------------------------------------------------------------------------------- +-- Description +-- In case: +-- 1) Application sends valid SetInteriorVehicleData with read-only parameters +-- 2) and one or more settable parameters in "radioControlData" struct, for moduleType: RADIO, +-- SDL must: +-- 1) Cut the read-only parameters off and process this RPC as assigned +-- (that is, check policies, send to HMI, and etc. per existing requirements) +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonFunctions = require('user_modules/shared_testcases/commonFunctions') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function getNonReadOnlyParams(pModuleType) + if pModuleType == "CLIMATE" then + return { fanSpeed = 55 } + elseif pModuleType == "RADIO" then + return { band = "FM" } + end +end + +local function getModuleParams(pModuleData) + if pModuleData.climateControlData then + return pModuleData.climateControlData + elseif pModuleData.radioControlData then + return pModuleData.radioControlData + end +end + +local function setVehicleData(pModuleType, self) + local moduleDataReadOnly = commonRC.getReadOnlyParamsByModule(pModuleType) + local moduleDataCombined = commonFunctions:cloneTable(moduleDataReadOnly) + + for k, v in pairs(getNonReadOnlyParams(pModuleType)) do + getModuleParams(moduleDataCombined)[k] = v + end + + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = moduleDataCombined + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = moduleDataReadOnly + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = moduleDataReadOnly + }) + end) + :ValidIf(function(_, data) + local isFalse = false + for k1, _ in pairs(getModuleParams(commonRC.getReadOnlyParamsByModule(pModuleType))) do + for k2, _ in pairs(getModuleParams(data.params.moduleData)) do + if k1 == k2 then + isFalse = true + commonFunctions:userPrint(36, "Unexpected read-only parameter: " .. k1) + end + end + end + if isFalse then + return false, "Test step failed, see prints" + end + return true + end) + + self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index c6c921cb3d..38193c2478 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -410,4 +410,35 @@ function commonRC.getButtonNameByModule(pModuleType) end end +function commonRC.getReadOnlyParamsByModule(pModuleType) + local out = { moduleType = pModuleType } + if pModuleType == "CLIMATE" then + out.climateControlData = { + currentTemperature = { + unit = "FAHRENHEIT", + value = 32.6 + } + } + elseif pModuleType == "RADIO" then + out.radioControlData = { + rdsData = { + PS = "ps", + RT = "rt", + CT = "123456789012345678901234", + PI = "pi", + PTY = 2, + TP = false, + TA = true, + REG = "US" + }, + availableHDs = 2, + signalStrength = 4, + signalChangeThreshold = 22, + radioEnable = true, + state = "MULTICAST" + } + end + return out +end + return commonRC diff --git a/test_sets/rc_SetInteriorVehicleData.txt b/test_sets/rc_SetInteriorVehicleData.txt index f4f462c41e..d2cdee2a06 100644 --- a/test_sets/rc_SetInteriorVehicleData.txt +++ b/test_sets/rc_SetInteriorVehicleData.txt @@ -7,3 +7,4 @@ ./test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua ./test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua ./test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua +./test_scripts/RC/SetInteriorVehicleData/011_Check_cut-off_read-only_parameters_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters.lua From d6b8a6191ea5e0b281e89dcaacf47a8f0aa22580 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Mon, 24 Jul 2017 16:36:53 +0300 Subject: [PATCH 057/681] SetInteriorVehicleData: Minor fix of parameter names --- ...mobile_with_read-only_and_not_read-only_parameters.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test_scripts/RC/SetInteriorVehicleData/011_Check_cut-off_read-only_parameters_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters.lua b/test_scripts/RC/SetInteriorVehicleData/011_Check_cut-off_read-only_parameters_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters.lua index 88672d2095..6f213c2a59 100644 --- a/test_scripts/RC/SetInteriorVehicleData/011_Check_cut-off_read-only_parameters_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters.lua +++ b/test_scripts/RC/SetInteriorVehicleData/011_Check_cut-off_read-only_parameters_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters.lua @@ -55,11 +55,11 @@ local function setVehicleData(pModuleType, self) end) :ValidIf(function(_, data) local isFalse = false - for k1, _ in pairs(getModuleParams(commonRC.getReadOnlyParamsByModule(pModuleType))) do - for k2, _ in pairs(getModuleParams(data.params.moduleData)) do - if k1 == k2 then + for param_readonly, _ in pairs(getModuleParams(commonRC.getReadOnlyParamsByModule(pModuleType))) do + for param_actual, _ in pairs(getModuleParams(data.params.moduleData)) do + if param_readonly == param_actual then isFalse = true - commonFunctions:userPrint(36, "Unexpected read-only parameter: " .. k1) + commonFunctions:userPrint(36, "Unexpected read-only parameter: " .. param_readonly) end end end From da24daedae2a8e575a875a5500b016a055a26374 Mon Sep 17 00:00:00 2001 From: Igor Kovalenko Date: Mon, 24 Jul 2017 13:31:09 +0300 Subject: [PATCH 058/681] created new test for READ_ONLY for Climate params --- ...cle_data_if_read_only_params_requested.lua | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua b/test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua new file mode 100644 index 0000000000..6395342ef3 --- /dev/null +++ b/test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------------------------------- +-- RPC: SetInteriorVehicleData +-- Description +-- In case: +-- application sends valid SetInteriorVehicleData with just read-only parameters in "climateControlData" struct, for muduleType: CLIMATE, +-- SDL must +-- respond with "resultCode: READ_ONLY, success:false" to this application and do not process this RPC. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Variables ]] +local module_data_climate = { + moduleType = "CLIMATE", + climateControlData = { + currentTemperature = { + unit = "CELSIUS", + value = 21.5 + } + } +} + +--[[ Local Functions ]] +local function setVehicleData(module_data, self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", {moduleData = module_data}) + + EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) + + self.mobileSession:ExpectResponse(cid, { success = false, resultCode = "READ_ONLY" }) + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Title("Test: SDL respond with READ_ONLY if SetInteriorVehicleData is sent with read_only params") +runner.Step("Send SetInteriorVehicleData with currentTemperature only", setVehicleData, { module_data_climate }) +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) From f1f517d6b8cd3ecbeb88ebd573f6cb8cd02981e5 Mon Sep 17 00:00:00 2001 From: Igor Kovalenko Date: Mon, 24 Jul 2017 16:45:41 +0300 Subject: [PATCH 059/681] added 010 to test set --- ...icle_data_if_read_only_params_requested.lua | 18 ++++++++++++++++++ test_sets/rc_SetInteriorVehicleData.txt | 1 + 2 files changed, 19 insertions(+) diff --git a/test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua b/test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua index 6395342ef3..d6c538222b 100644 --- a/test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +++ b/test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua @@ -22,6 +22,15 @@ local module_data_climate = { } } +local read_only_radio_params = { + rdsData = {PS = "103.2FM"}, + availableHDs = 2, + signalStrength = 70, + signalChangeThreshold = 50, + radioEnable = true, + state = "ACQUIRED" +} + --[[ Local Functions ]] local function setVehicleData(module_data, self) local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", {moduleData = module_data}) @@ -39,5 +48,14 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) runner.Title("Test: SDL respond with READ_ONLY if SetInteriorVehicleData is sent with read_only params") runner.Step("Send SetInteriorVehicleData with currentTemperature only", setVehicleData, { module_data_climate }) + +for k, v in pairs( read_only_radio_params ) do + local module_data_radio = { + moduleType = "RADIO", + radioControlData = {[k] = v} + } + runner.Step("Send SetInteriorVehicleData with " .. tostring( k ) .. " only", setVehicleData, { module_data_radio }) +end + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_SetInteriorVehicleData.txt b/test_sets/rc_SetInteriorVehicleData.txt index d2cdee2a06..32bb648833 100644 --- a/test_sets/rc_SetInteriorVehicleData.txt +++ b/test_sets/rc_SetInteriorVehicleData.txt @@ -7,4 +7,5 @@ ./test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua ./test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua ./test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua +./test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua ./test_scripts/RC/SetInteriorVehicleData/011_Check_cut-off_read-only_parameters_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters.lua From 33529205dcbe8ad623b403721ca329efdbdf1db2 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Mon, 24 Jul 2017 17:42:33 +0300 Subject: [PATCH 060/681] SetInteriorVehicleData: Add script --- ...y_parameters_and_HMI_returns_READ_ONLY.lua | 46 +++++++++++++++++++ test_sets/rc_SetInteriorVehicleData.txt | 1 + 2 files changed, 47 insertions(+) create mode 100644 test_scripts/RC/SetInteriorVehicleData/012_Check_READ_ONLY_resultCode_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/012_Check_READ_ONLY_resultCode_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua b/test_scripts/RC/SetInteriorVehicleData/012_Check_READ_ONLY_resultCode_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua new file mode 100644 index 0000000000..50fd0ff540 --- /dev/null +++ b/test_scripts/RC/SetInteriorVehicleData/012_Check_READ_ONLY_resultCode_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua @@ -0,0 +1,46 @@ +--------------------------------------------------------------------------------------------------- +-- Description +-- In case: +-- 1) SDL has sent SetInteriorVehicleData with one or more settable parameters in "moduleData" struct +-- 2) and HMI responds with "resultCode: READ_ONLY" +-- SDL must: +-- 1) Send "resultCode: READ_ONLY, success:false" to the related mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function setVehicleData(pModuleType, self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = commonRC.getModuleControlData(pModuleType) + }) + :Do(function(_, data) + self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Read only parameters received") + end) + + self.mobileSession:ExpectResponse(cid, { success = false, resultCode = "READ_ONLY" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_SetInteriorVehicleData.txt b/test_sets/rc_SetInteriorVehicleData.txt index d2cdee2a06..32c3a8c18c 100644 --- a/test_sets/rc_SetInteriorVehicleData.txt +++ b/test_sets/rc_SetInteriorVehicleData.txt @@ -8,3 +8,4 @@ ./test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua ./test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua ./test_scripts/RC/SetInteriorVehicleData/011_Check_cut-off_read-only_parameters_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters.lua +./test_scripts/RC/SetInteriorVehicleData/012_Check_READ_ONLY_resultCode_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua From c4011c36b44e54c349adab26422152e477c38752 Mon Sep 17 00:00:00 2001 From: Igor Kovalenko Date: Mon, 24 Jul 2017 17:47:01 +0300 Subject: [PATCH 061/681] refactored to use common function to get read_only parameters --- ...cle_data_if_read_only_params_requested.lua | 48 +++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua b/test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua index d6c538222b..08ce582f27 100644 --- a/test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +++ b/test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua @@ -2,7 +2,8 @@ -- RPC: SetInteriorVehicleData -- Description -- In case: --- application sends valid SetInteriorVehicleData with just read-only parameters in "climateControlData" struct, for muduleType: CLIMATE, +-- 1) application sends valid SetInteriorVehicleData with just read-only parameters in "climateControlData" struct for muduleType: CLIMATE, +-- 2) application sends valid SetInteriorVehicleData with just read-only parameters in "radioControlData" struct for muduleType: RADIO -- SDL must -- respond with "resultCode: READ_ONLY, success:false" to this application and do not process this RPC. --------------------------------------------------------------------------------------------------- @@ -12,24 +13,8 @@ local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ Local Variables ]] -local module_data_climate = { - moduleType = "CLIMATE", - climateControlData = { - currentTemperature = { - unit = "CELSIUS", - value = 21.5 - } - } -} - -local read_only_radio_params = { - rdsData = {PS = "103.2FM"}, - availableHDs = 2, - signalStrength = 70, - signalChangeThreshold = 50, - radioEnable = true, - state = "ACQUIRED" -} +local module_data_climate = commonRC.getReadOnlyParamsByModule("CLIMATE") +local module_data_radio = commonRC.getReadOnlyParamsByModule("RADIO") --[[ Local Functions ]] local function setVehicleData(module_data, self) @@ -47,14 +32,27 @@ runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) runner.Title("Test: SDL respond with READ_ONLY if SetInteriorVehicleData is sent with read_only params") -runner.Step("Send SetInteriorVehicleData with currentTemperature only", setVehicleData, { module_data_climate }) -for k, v in pairs( read_only_radio_params ) do - local module_data_radio = { - moduleType = "RADIO", - radioControlData = {[k] = v} +for parameter_name, parameter_value in pairs(module_data_climate.climateControlData) do + local climate_read_only_parameters = { + moduleType = module_data_climate.moduleType, + climateControlData = {[parameter_name] = parameter_value} + } + runner.Step( + "Send SetInteriorVehicleData with " .. tostring(parameter_name) .." only", + setVehicleData, + {climate_read_only_parameters}) +end + +for parameter_name, parameter_value in pairs(module_data_radio.radioControlData) do + local radio_read_only_parameters = { + moduleType = module_data_radio.moduleType, + radioControlData = {[parameter_name] = parameter_value} } - runner.Step("Send SetInteriorVehicleData with " .. tostring( k ) .. " only", setVehicleData, { module_data_radio }) + runner.Step( + "Send SetInteriorVehicleData with " .. tostring(parameter_name) .. " only", + setVehicleData, + {radio_read_only_parameters}) end runner.Title("Postconditions") From 01c7f37e1a3a78bae309d73bb3c6da43af8d5e4e Mon Sep 17 00:00:00 2001 From: Igor Kovalenko Date: Mon, 24 Jul 2017 18:09:48 +0300 Subject: [PATCH 062/681] corrected description of 010 script --- ..._set_interior_vehicle_data_if_read_only_params_requested.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua b/test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua index 08ce582f27..78a5bd066d 100644 --- a/test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +++ b/test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua @@ -1,8 +1,8 @@ --------------------------------------------------------------------------------------------------- --- RPC: SetInteriorVehicleData -- Description -- In case: -- 1) application sends valid SetInteriorVehicleData with just read-only parameters in "climateControlData" struct for muduleType: CLIMATE, +-- OR -- 2) application sends valid SetInteriorVehicleData with just read-only parameters in "radioControlData" struct for muduleType: RADIO -- SDL must -- respond with "resultCode: READ_ONLY, success:false" to this application and do not process this RPC. From c5f47d8e0232f38d14ed04cd22da1ebf1b74de31 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Tue, 25 Jul 2017 14:53:24 +0300 Subject: [PATCH 063/681] SetInteriorVehicleData: Rename scripts --- ...interior_vehicle_data_if_read_only_params_requested.lua} | 0 ...request_with_read-only_and_not_read-only_parameters.lua} | 0 ..._not_read-only_parameters_and_HMI_returns_READ_ONLY.lua} | 0 test_sets/rc_SetInteriorVehicleData.txt | 6 +++--- 4 files changed, 3 insertions(+), 3 deletions(-) rename test_scripts/RC/SetInteriorVehicleData/{010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua => 010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua} (100%) rename test_scripts/RC/SetInteriorVehicleData/{011_Check_cut-off_read-only_parameters_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters.lua => 011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua} (100%) rename test_scripts/RC/SetInteriorVehicleData/{012_Check_READ_ONLY_resultCode_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua => 012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua} (100%) diff --git a/test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua b/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua rename to test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/011_Check_cut-off_read-only_parameters_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters.lua b/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/011_Check_cut-off_read-only_parameters_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters.lua rename to test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/012_Check_READ_ONLY_resultCode_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua b/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/012_Check_READ_ONLY_resultCode_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua rename to test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua diff --git a/test_sets/rc_SetInteriorVehicleData.txt b/test_sets/rc_SetInteriorVehicleData.txt index dfe58bf33c..62d271ccb6 100644 --- a/test_sets/rc_SetInteriorVehicleData.txt +++ b/test_sets/rc_SetInteriorVehicleData.txt @@ -7,6 +7,6 @@ ./test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua ./test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua ./test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua -./test_scripts/RC/SetInteriorVehicleData/010_read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua -./test_scripts/RC/SetInteriorVehicleData/011_Check_cut-off_read-only_parameters_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters.lua -./test_scripts/RC/SetInteriorVehicleData/012_Check_READ_ONLY_resultCode_in_case_request_SetInteriorVehicleData_from_mobile_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua +./test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +./test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua +./test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua From beaffbfe1cdeffaafd0ce0dc9a7a38f4eebed48d Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Tue, 25 Jul 2017 17:40:26 +0300 Subject: [PATCH 064/681] SetInteriorVehicleData: Add additional cases into script --- ...read-only_and_not_read-only_parameters.lua | 41 +++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua b/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua index 6f213c2a59..61031f4cc7 100644 --- a/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua +++ b/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua @@ -15,15 +15,6 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') --[[ Local Variables ]] local modules = { "CLIMATE", "RADIO" } ---[[ Local Functions ]] -local function getNonReadOnlyParams(pModuleType) - if pModuleType == "CLIMATE" then - return { fanSpeed = 55 } - elseif pModuleType == "RADIO" then - return { band = "FM" } - end -end - local function getModuleParams(pModuleData) if pModuleData.climateControlData then return pModuleData.climateControlData @@ -32,11 +23,29 @@ local function getModuleParams(pModuleData) end end -local function setVehicleData(pModuleType, self) +local function getNonReadOnlyParams(pModuleType) + local params_all = getModuleParams(commonRC.getModuleControlData(pModuleType)) + local params_read_only = getModuleParams(commonRC.getReadOnlyParamsByModule(pModuleType)) + local params_settable = { } + for p, v in pairs(params_all) do + local isSettable = true + for p_read_only, _ in pairs(params_read_only) do + if p == p_read_only then + isSettable = false + end + end + if isSettable then + params_settable[p] = v + end + end + return params_settable +end + +local function setVehicleData(pModuleType, pParams, self) local moduleDataReadOnly = commonRC.getReadOnlyParamsByModule(pModuleType) local moduleDataCombined = commonFunctions:cloneTable(moduleDataReadOnly) - for k, v in pairs(getNonReadOnlyParams(pModuleType)) do + for k, v in pairs(pParams) do getModuleParams(moduleDataCombined)[k] = v end @@ -80,8 +89,16 @@ runner.Step("RAI, PTU", commonRC.rai_ptu) runner.Title("Test") +-- one settable parameter +for _, mod in pairs(modules) do + for param, value in pairs(getNonReadOnlyParams(mod)) do + runner.Step("SetInteriorVehicleData " .. mod .. "_one_settable_param_" .. param, setVehicleData, { mod, { [param] = value } }) + end +end + +-- all settable parameters for _, mod in pairs(modules) do - runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) + runner.Step("SetInteriorVehicleData " .. mod .. "_all_settable_params", setVehicleData, { mod, getNonReadOnlyParams(mod) }) end runner.Title("Postconditions") From efb728e2ba633c7d611a7fb434c2959333d95b50 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 26 Jul 2017 11:36:07 +0300 Subject: [PATCH 065/681] Fix ListFiles step: implement unsorted check --- test_scripts/smoke_api.lua | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/test_scripts/smoke_api.lua b/test_scripts/smoke_api.lua index 8f3b28fc7a..742a0b06b1 100644 --- a/test_scripts/smoke_api.lua +++ b/test_scripts/smoke_api.lua @@ -1222,14 +1222,20 @@ end function Test:ListFiles() local cid = self.mobileSession:SendRPC("ListFiles", {} ) - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - spaceAvailable = 103878520, - filenames = { " SpaceBefore", strMaxLengthFileName255, "icon.png" } + spaceAvailable = 103878520 }) + :ValidIf(function(_, data) + local files_expected = { " SpaceBefore", strMaxLengthFileName255, "icon.png" } + if not commonFunctions:is_table_equal(data.payload.filenames, files_expected) then + return false, "\nExpected files:\n" .. commonFunctions:convertTableToString(files_expected, 1) + .. "\nActual files:\n" .. commonFunctions:convertTableToString(data.payload.filenames, 1) + end + return true + end) end -- End Test case 1.11 From 617edf102ccda2a0bfd903db51f0a1730824a08a Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 26 Jul 2017 12:06:37 +0300 Subject: [PATCH 066/681] Fix ListFiles step: implement unsorted check --- test_scripts/smoke_api.lua | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/test_scripts/smoke_api.lua b/test_scripts/smoke_api.lua index 8f3b28fc7a..742a0b06b1 100644 --- a/test_scripts/smoke_api.lua +++ b/test_scripts/smoke_api.lua @@ -1222,14 +1222,20 @@ end function Test:ListFiles() local cid = self.mobileSession:SendRPC("ListFiles", {} ) - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - spaceAvailable = 103878520, - filenames = { " SpaceBefore", strMaxLengthFileName255, "icon.png" } + spaceAvailable = 103878520 }) + :ValidIf(function(_, data) + local files_expected = { " SpaceBefore", strMaxLengthFileName255, "icon.png" } + if not commonFunctions:is_table_equal(data.payload.filenames, files_expected) then + return false, "\nExpected files:\n" .. commonFunctions:convertTableToString(files_expected, 1) + .. "\nActual files:\n" .. commonFunctions:convertTableToString(data.payload.filenames, 1) + end + return true + end) end -- End Test case 1.11 From 5186604ccdec17ef5e2dc08b1a9a3f99b9194daf Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 26 Jul 2017 13:31:03 +0300 Subject: [PATCH 067/681] Fix path to scripts in test set --- test_sets/policies_smoke.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test_sets/policies_smoke.txt b/test_sets/policies_smoke.txt index 1626c21e92..45b5000202 100644 --- a/test_sets/policies_smoke.txt +++ b/test_sets/policies_smoke.txt @@ -1,12 +1,12 @@ -./test_scripts/Polices/App_Permissions/026_ATF_DISALLOWED_App_Which_Name_Does_Not_Match_With_Nickname_In_PT.lua -./test_scripts/Polices/appID_Management/045_ATF_Register_App_Interface_Assign_Default_Policies_To_Application_Which_Appid_Does_Not_Exist_In_LPT.lua -./test_scripts/Polices/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua -./test_scripts/Polices/build_options/048_ATF_SDL_Build_Flag_DEXTENDED_POLICY_PROPRIETARY.lua -./test_scripts/Polices/build_options/089_ATF_Check_SDL_respond_GetURLs_Request_fromHMI_PROPRIETARY.lua -./test_scripts/Polices/build_options/094_ATF_PTS_creation_rule_PROPRIETARY.lua -./test_scripts/Polices/build_options/100_ATF_PTU_Transfer_Several_Apps_Different_HMI_Levels_PROPRIETARY.lua -./test_scripts/Polices/build_options/103_ATF_Timeout_wait_response_PTU_PROPRIETARY.lua -./test_scripts/Polices/build_options/105_ATF_PM_change_status_UPDATE_NEEDED_after_timeout_expired_PROPRIETARY.lua -./test_scripts/Polices/build_options/108_ATF_PTU_Trigger_days_PROPRIETARY.lua -./test_scripts/Polices/build_options/109_ATF_PTU_Trigger_IGN_cycles_PROPRIETARY.lua -./test_scripts/Polices/build_options/110_ATF_PTU_Trigger_kilometers_PROPRIETARY.lua +./test_scripts/Policies/App_Permissions/026_ATF_DISALLOWED_App_Which_Name_Does_Not_Match_With_Nickname_In_PT.lua +./test_scripts/Policies/appID_Management/045_ATF_Register_App_Interface_Assign_Default_Policies_To_Application_Which_Appid_Does_Not_Exist_In_LPT.lua +./test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua +./test_scripts/Policies/build_options/048_ATF_SDL_Build_Flag_DEXTENDED_POLICY_PROPRIETARY.lua +./test_scripts/Policies/build_options/089_ATF_Check_SDL_respond_GetURLs_Request_fromHMI_PROPRIETARY.lua +./test_scripts/Policies/build_options/094_ATF_PTS_creation_rule_PROPRIETARY.lua +./test_scripts/Policies/build_options/100_ATF_PTU_Transfer_Several_Apps_Different_HMI_Levels_PROPRIETARY.lua +./test_scripts/Policies/build_options/103_ATF_Timeout_wait_response_PTU_PROPRIETARY.lua +./test_scripts/Policies/build_options/105_ATF_PM_change_status_UPDATE_NEEDED_after_timeout_expired_PROPRIETARY.lua +./test_scripts/Policies/build_options/108_ATF_PTU_Trigger_days_PROPRIETARY.lua +./test_scripts/Policies/build_options/109_ATF_PTU_Trigger_IGN_cycles_PROPRIETARY.lua +./test_scripts/Policies/build_options/110_ATF_PTU_Trigger_kilometers_PROPRIETARY.lua From 29a3e56582fd7d77e23daf77d709d85a40d885db Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 26 Jul 2017 13:36:30 +0300 Subject: [PATCH 068/681] SetInteriorVehicleData: Refactoring of scripts --- ...read-only_and_not_read-only_parameters.lua | 38 ++++--------------- test_scripts/RC/commonRC.lua | 23 +++++++++++ 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua b/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua index 61031f4cc7..0c52b1e14f 100644 --- a/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua +++ b/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua @@ -15,38 +15,12 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') --[[ Local Variables ]] local modules = { "CLIMATE", "RADIO" } -local function getModuleParams(pModuleData) - if pModuleData.climateControlData then - return pModuleData.climateControlData - elseif pModuleData.radioControlData then - return pModuleData.radioControlData - end -end - -local function getNonReadOnlyParams(pModuleType) - local params_all = getModuleParams(commonRC.getModuleControlData(pModuleType)) - local params_read_only = getModuleParams(commonRC.getReadOnlyParamsByModule(pModuleType)) - local params_settable = { } - for p, v in pairs(params_all) do - local isSettable = true - for p_read_only, _ in pairs(params_read_only) do - if p == p_read_only then - isSettable = false - end - end - if isSettable then - params_settable[p] = v - end - end - return params_settable -end - local function setVehicleData(pModuleType, pParams, self) local moduleDataReadOnly = commonRC.getReadOnlyParamsByModule(pModuleType) local moduleDataCombined = commonFunctions:cloneTable(moduleDataReadOnly) for k, v in pairs(pParams) do - getModuleParams(moduleDataCombined)[k] = v + commonRC.getModuleParams(moduleDataCombined)[k] = v end local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { @@ -64,8 +38,8 @@ local function setVehicleData(pModuleType, pParams, self) end) :ValidIf(function(_, data) local isFalse = false - for param_readonly, _ in pairs(getModuleParams(commonRC.getReadOnlyParamsByModule(pModuleType))) do - for param_actual, _ in pairs(getModuleParams(data.params.moduleData)) do + for param_readonly, _ in pairs(commonRC.getModuleParams(commonRC.getReadOnlyParamsByModule(pModuleType))) do + for param_actual, _ in pairs(commonRC.getModuleParams(data.params.moduleData)) do if param_readonly == param_actual then isFalse = true commonFunctions:userPrint(36, "Unexpected read-only parameter: " .. param_readonly) @@ -91,14 +65,16 @@ runner.Title("Test") -- one settable parameter for _, mod in pairs(modules) do - for param, value in pairs(getNonReadOnlyParams(mod)) do + local settableParams = commonRC.getModuleParams(commonRC.getSettableModuleControlData(mod)) + for param, value in pairs(settableParams) do runner.Step("SetInteriorVehicleData " .. mod .. "_one_settable_param_" .. param, setVehicleData, { mod, { [param] = value } }) end end -- all settable parameters for _, mod in pairs(modules) do - runner.Step("SetInteriorVehicleData " .. mod .. "_all_settable_params", setVehicleData, { mod, getNonReadOnlyParams(mod) }) + local settableParams = commonRC.getModuleParams(commonRC.getSettableModuleControlData(mod)) + runner.Step("SetInteriorVehicleData " .. mod .. "_all_settable_params", setVehicleData, { mod, settableParams }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 38193c2478..fbe1de83bb 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -441,4 +441,27 @@ function commonRC.getReadOnlyParamsByModule(pModuleType) return out end +function commonRC.getModuleParams(pModuleData) + if pModuleData.moduleType == "CLIMATE" then + if not pModuleData.climateControlData then + pModuleData.climateControlData = { } + end + return pModuleData.climateControlData + elseif pModuleData.moduleType == "RADIO" then + if not pModuleData.radioControlData then + pModuleData.radioControlData = { } + end + return pModuleData.radioControlData + end +end + +function commonRC.getSettableModuleControlData(pModuleType) + local out = commonRC.getModuleControlData(pModuleType) + local params_read_only = commonRC.getModuleParams(commonRC.getReadOnlyParamsByModule(pModuleType)) + for p_read_only in pairs(params_read_only) do + commonRC.getModuleParams(out)[p_read_only] = nil + end + return out +end + return commonRC From 773750072c53da093f13d31a35501697dfc2db00 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 26 Jul 2017 13:38:45 +0300 Subject: [PATCH 069/681] Fix path to scripts in test set --- test_sets/policies_smoke.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test_sets/policies_smoke.txt b/test_sets/policies_smoke.txt index 1626c21e92..45b5000202 100644 --- a/test_sets/policies_smoke.txt +++ b/test_sets/policies_smoke.txt @@ -1,12 +1,12 @@ -./test_scripts/Polices/App_Permissions/026_ATF_DISALLOWED_App_Which_Name_Does_Not_Match_With_Nickname_In_PT.lua -./test_scripts/Polices/appID_Management/045_ATF_Register_App_Interface_Assign_Default_Policies_To_Application_Which_Appid_Does_Not_Exist_In_LPT.lua -./test_scripts/Polices/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua -./test_scripts/Polices/build_options/048_ATF_SDL_Build_Flag_DEXTENDED_POLICY_PROPRIETARY.lua -./test_scripts/Polices/build_options/089_ATF_Check_SDL_respond_GetURLs_Request_fromHMI_PROPRIETARY.lua -./test_scripts/Polices/build_options/094_ATF_PTS_creation_rule_PROPRIETARY.lua -./test_scripts/Polices/build_options/100_ATF_PTU_Transfer_Several_Apps_Different_HMI_Levels_PROPRIETARY.lua -./test_scripts/Polices/build_options/103_ATF_Timeout_wait_response_PTU_PROPRIETARY.lua -./test_scripts/Polices/build_options/105_ATF_PM_change_status_UPDATE_NEEDED_after_timeout_expired_PROPRIETARY.lua -./test_scripts/Polices/build_options/108_ATF_PTU_Trigger_days_PROPRIETARY.lua -./test_scripts/Polices/build_options/109_ATF_PTU_Trigger_IGN_cycles_PROPRIETARY.lua -./test_scripts/Polices/build_options/110_ATF_PTU_Trigger_kilometers_PROPRIETARY.lua +./test_scripts/Policies/App_Permissions/026_ATF_DISALLOWED_App_Which_Name_Does_Not_Match_With_Nickname_In_PT.lua +./test_scripts/Policies/appID_Management/045_ATF_Register_App_Interface_Assign_Default_Policies_To_Application_Which_Appid_Does_Not_Exist_In_LPT.lua +./test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua +./test_scripts/Policies/build_options/048_ATF_SDL_Build_Flag_DEXTENDED_POLICY_PROPRIETARY.lua +./test_scripts/Policies/build_options/089_ATF_Check_SDL_respond_GetURLs_Request_fromHMI_PROPRIETARY.lua +./test_scripts/Policies/build_options/094_ATF_PTS_creation_rule_PROPRIETARY.lua +./test_scripts/Policies/build_options/100_ATF_PTU_Transfer_Several_Apps_Different_HMI_Levels_PROPRIETARY.lua +./test_scripts/Policies/build_options/103_ATF_Timeout_wait_response_PTU_PROPRIETARY.lua +./test_scripts/Policies/build_options/105_ATF_PM_change_status_UPDATE_NEEDED_after_timeout_expired_PROPRIETARY.lua +./test_scripts/Policies/build_options/108_ATF_PTU_Trigger_days_PROPRIETARY.lua +./test_scripts/Policies/build_options/109_ATF_PTU_Trigger_IGN_cycles_PROPRIETARY.lua +./test_scripts/Policies/build_options/110_ATF_PTU_Trigger_kilometers_PROPRIETARY.lua From b80b1f55b02c9487f3a8a505f39d8ea3ddbf792a Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 26 Jul 2017 15:33:25 +0300 Subject: [PATCH 070/681] Add verification on 'info' parameter --- .../011_generic_error_if_read_only_response_come_from_hmi.lua | 4 ++-- .../011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua | 4 ++-- ...and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua b/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua index 6ca81773f9..fca04a54a5 100644 --- a/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua +++ b/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua @@ -27,10 +27,10 @@ local function getDataForModule(pModuleType, self) buttonPressMode = "SHORT" }) :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Read only parameters received") + self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Info message") end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Info message" }) end --[[ Scenario ]] diff --git a/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua index 9f5c4c33d1..71c3dbd08f 100644 --- a/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +++ b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -26,10 +26,10 @@ local function getDataForModule(module_type, self) subscribe = true }) :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Read only parameters received") + self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Info message") end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Info message" }) end --[[ Scenario ]] diff --git a/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua b/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua index 50fd0ff540..ace75096fd 100644 --- a/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua +++ b/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua @@ -24,10 +24,10 @@ local function setVehicleData(pModuleType, self) moduleData = commonRC.getModuleControlData(pModuleType) }) :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Read only parameters received") + self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Info message") end) - self.mobileSession:ExpectResponse(cid, { success = false, resultCode = "READ_ONLY" }) + self.mobileSession:ExpectResponse(cid, { success = false, resultCode = "READ_ONLY", info = "Info message" }) end --[[ Scenario ]] From 6bedf02d3de1913f91dc0cb2c80eed056ddc226f Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 26 Jul 2017 16:48:43 +0300 Subject: [PATCH 071/681] SetInteriorVehicleData: fix issues in script --- ...read-only_and_not_read-only_parameters.lua | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua b/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua index 0c52b1e14f..cfed345c85 100644 --- a/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua +++ b/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua @@ -15,44 +15,54 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') --[[ Local Variables ]] local modules = { "CLIMATE", "RADIO" } -local function setVehicleData(pModuleType, pParams, self) - local moduleDataReadOnly = commonRC.getReadOnlyParamsByModule(pModuleType) - local moduleDataCombined = commonFunctions:cloneTable(moduleDataReadOnly) +local function isModuleDataCorrect(pModuleType, actualModuleData) + local isFalse = false + for param_readonly, _ in pairs(commonRC.getModuleParams(commonRC.getReadOnlyParamsByModule(pModuleType))) do + for param_actual, _ in pairs(commonRC.getModuleParams(actualModuleData)) do + if param_readonly == param_actual then + isFalse = true + commonFunctions:userPrint(36, "Unexpected read-only parameter: " .. param_readonly) + end + end + end + if isFalse then + return false + end + return true +end +local function setVehicleData(pModuleType, pParams, self) + local moduleDataCombined = commonRC.getReadOnlyParamsByModule(pModuleType) + local moduleDataSettable = { moduleType = pModuleType } for k, v in pairs(pParams) do commonRC.getModuleParams(moduleDataCombined)[k] = v + commonRC.getModuleParams(moduleDataSettable)[k] = v end local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { moduleData = moduleDataCombined }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleData = moduleDataReadOnly - }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = self.applications["Test Application"] }) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = moduleDataReadOnly + moduleData = moduleDataSettable }) end) :ValidIf(function(_, data) - local isFalse = false - for param_readonly, _ in pairs(commonRC.getModuleParams(commonRC.getReadOnlyParamsByModule(pModuleType))) do - for param_actual, _ in pairs(commonRC.getModuleParams(data.params.moduleData)) do - if param_readonly == param_actual then - isFalse = true - commonFunctions:userPrint(36, "Unexpected read-only parameter: " .. param_readonly) - end - end - end - if isFalse then + if not isModuleDataCorrect(pModuleType, data.params.moduleData) then return false, "Test step failed, see prints" end return true end) self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + :ValidIf(function(_, data) + if not isModuleDataCorrect(pModuleType, data.payload.moduleData) then + return false, "Test step failed, see prints" + end + return true + end) end --[[ Scenario ]] From 86b5b525d1a81f49224e7bc9efe8d568043f8dac Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 26 Jul 2017 17:00:22 +0300 Subject: [PATCH 072/681] SetInteriorVehicleData: update for settable parameters --- .../RC/SetInteriorVehicleData/001_Success_flow.lua | 6 +++--- .../002_Disallow_flow_by_policy_CLIMATE.lua | 2 +- .../003_Disallow_flow_by_policy_RADIO.lua | 2 +- ...flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua | 2 +- ...case_params_does_not_correspond_to_moduleType.lua | 2 +- .../006_RPC_parameters_values.lua | 12 ++++++------ ...w_in_case_moduleType_is_an_empty_array_in_LPT.lua | 6 +++--- ...llow_flow_in_case_moduleType_is_absent_in_LPT.lua | 2 +- .../009_Cut-off_of_fake_parameters_from_App.lua | 4 ++-- ...ead-only_parameters_and_HMI_returns_READ_ONLY.lua | 4 ++-- 10 files changed, 21 insertions(+), 21 deletions(-) diff --git a/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua index 139b7d1402..0057ec901f 100644 --- a/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua @@ -17,16 +17,16 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function setVehicleData(pModuleType, self) local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = commonRC.getSettableModuleControlData(pModuleType) }) end) diff --git a/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 77f5794c24..d924f1fbc1 100644 --- a/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -17,7 +17,7 @@ local mod = "CLIMATE" --[[ Local Functions ]] local function setVehicleData(pModuleType, self) local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData") diff --git a/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index 25252cf821..f358174e1d 100644 --- a/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -17,7 +17,7 @@ local mod = "RADIO" --[[ Local Functions ]] local function setVehicleData(pModuleType, self) local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData") diff --git a/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 479f529289..fb0fe6e003 100644 --- a/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -20,7 +20,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function setVehicleData(pModuleType, self) local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData") diff --git a/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua b/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua index acdb7370dc..cd006d8eb8 100644 --- a/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua +++ b/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua @@ -23,7 +23,7 @@ local function setVehicleData(pModuleType, self) moduleType2 = "CLIMATE" end - local moduleData = commonRC.getModuleControlData(moduleType2) + local moduleData = commonRC.getSettableModuleControlData(moduleType2) moduleData.moduleType = pModuleType local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { diff --git a/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua index 4970296a53..b591f95cb7 100644 --- a/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua @@ -20,7 +20,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function invalidParamName(pModuleType, self) local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { - moduleDData = commonRC.getModuleControlData(pModuleType) -- invalid name of parameter + moduleDData = commonRC.getSettableModuleControlData(pModuleType) -- invalid name of parameter }) EXPECT_HMICALL("RC.SetInteriorVehicleData", {}) @@ -32,7 +32,7 @@ local function invalidParamName(pModuleType, self) end local function invalidParamType(pModuleType, self) - local moduleData = commonRC.getAnotherModuleControlData(pModuleType) + local moduleData = commonRC.getSettableModuleControlData(pModuleType) moduleData.moduleType = {} -- invalid type of parameter local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { @@ -48,7 +48,7 @@ local function invalidParamType(pModuleType, self) end local function missingMandatoryParam(pModuleType, self) - local moduleData = commonRC.getAnotherModuleControlData(pModuleType) + local moduleData = commonRC.getSettableModuleControlData(pModuleType) moduleData.moduleType = nil -- mandatory parameter missing local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { @@ -65,17 +65,17 @@ end local function fakeParam(pModuleType, self) local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = commonRC.getSettableModuleControlData(pModuleType), fakeParam = 6 }) EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = commonRC.getSettableModuleControlData(pModuleType) }) end) diff --git a/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index da55786c44..f80b47cb22 100644 --- a/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -17,16 +17,16 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function setVehicleData(pModuleType, self) local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = commonRC.getSettableModuleControlData(pModuleType) }) end) diff --git a/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index c7f8950d21..1438703581 100644 --- a/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -17,7 +17,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function setVehicleData(pModuleType, self) local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData") diff --git a/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua b/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua index b0087d4d25..44985083a2 100644 --- a/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua +++ b/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua @@ -15,7 +15,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function setVehicleData(pModuleType, self) - local moduleData = commonRC.getModuleControlData(pModuleType) + local moduleData = commonRC.getSettableModuleControlData(pModuleType) moduleData.fakeParam = 123 self.mobileSession:SendRPC("SetInteriorVehicleData", { moduleData = moduleData @@ -23,7 +23,7 @@ local function setVehicleData(pModuleType, self) EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :ValidIf(function(_, data) if data.params.moduleData.fakeParam then diff --git a/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua b/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua index ace75096fd..b049754cd6 100644 --- a/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua +++ b/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua @@ -16,12 +16,12 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function setVehicleData(pModuleType, self) local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :Do(function(_, data) self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Info message") From 2f25a60f2e7c30bf0c0bd672338cac24900aeac1 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 26 Jul 2017 18:03:36 +0300 Subject: [PATCH 073/681] Add req-ts into descriptions of scripts --- .../001_success_flow_for_climate_and_radio.lua | 5 ++++- .../002_disallow_flow_by_policy_for_climate.lua | 6 +++++- .../003_disallow_flow_by_policy_for_radio.lua | 6 +++++- .../004_check_processing_button_press_for_nonRC_App.lua | 5 ++++- ...d_buttonName_and_moduleType_for_radio_and_climate.lua | 5 ++++- .../006_check_rpc_parameters_for_button_press.lua | 5 ++++- .../007_button_press_allowed_if_moduleType_is_empty.lua | 6 +++++- ...8_button_press_disallowed_if_moduleType_is_absent.lua | 6 +++++- ...isallowed_if_moduleType_is_disallowed_by_policies.lua | 6 +++++- .../010_generic_error_if_no_response_from_hmi.lua | 5 ++++- ...generic_error_if_read_only_response_come_from_hmi.lua | 4 ++++ .../RC/GetInteriorVehicleData/001_Success_flow.lua | 5 ++++- .../002_Disallow_flow_by_policy_CLIMATE.lua | 6 +++++- .../003_Disallow_flow_by_policy_RADIO.lua | 6 +++++- ...low_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua | 5 ++++- .../005_Transfering_of_HMI_resultCode_to_mobile.lua | 5 ++++- .../GetInteriorVehicleData/006_RPC_parameters_values.lua | 5 ++++- .../007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua | 5 ++++- ...NERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua | 5 ++++- ..._flow_in_case_moduleType_is_an_empty_array_in_LPT.lua | 6 +++++- ...Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua | 6 +++++- ..._GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua | 5 ++++- ...ameter_but_response_from_HMI_without_isSubscribed.lua | 5 ++++- ...parameter_but_response_from_HMI_with_isSubscribed.lua | 5 ++++- .../RC/OnInteriorVehicleData/001_Success_flow.lua | 9 ++++++--- .../002_Disallow_flow_by_policy_CLIMATE.lua | 6 +++++- .../003_Disallow_flow_by_policy_RADIO.lua | 6 +++++- ...sfull_subscribing_with_isSubscribe_false_from_HMI.lua | 5 ++++- ...cessfull_subscribing_without_isSubscribe_from_HMI.lua | 5 ++++- ..._OnIVD_in_case_of_subscribing_with_error_from_HMI.lua | 5 ++++- ..._in_case_of_subscribing_with_no_response_from_HMI.lua | 5 ++++- ...ase_of_subscribing_with_invalid_response_from_HMI.lua | 5 ++++- ...full_unsubscribing_with_isSubscribe_true_from_HMI.lua | 5 ++++- ...ssfull_unsubscribing_without_isSubscribe_from_HMI.lua | 5 ++++- ...ull_unsubscribing_with_isSubscribe_false_from_HMI.lua | 5 ++++- ...ssfull_unsubscribing_without_isSubscribe_from_HMI.lua | 5 ++++- ...r_module_Climate_and_without_one_for_module_Radio.lua | 6 +++++- ...r_module_Radio_and_without_one_for_module_Climate.lua | 6 +++++- ...e_Climate_and_after_unsubscribe_from_module_Radio.lua | 5 ++++- ...e_Radio_and_after_unsubscribe_from_module_Climate.lua | 5 ++++- .../OnInteriorVehicleData/017_RPC_parameters_values.lua | 6 +++++- .../RC/SetInteriorVehicleData/001_Success_flow.lua | 5 ++++- .../002_Disallow_flow_by_policy_CLIMATE.lua | 6 +++++- .../003_Disallow_flow_by_policy_RADIO.lua | 6 +++++- ...low_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua | 5 ++++- ..._in_case_params_does_not_correspond_to_moduleType.lua | 5 ++++- .../SetInteriorVehicleData/006_RPC_parameters_values.lua | 5 ++++- ..._flow_in_case_moduleType_is_an_empty_array_in_LPT.lua | 6 +++++- ...Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua | 6 +++++- .../009_Cut-off_of_fake_parameters_from_App.lua | 5 ++++- ...terior_vehicle_data_if_read_only_params_requested.lua | 5 ++++- ...quest_with_read-only_and_not_read-only_parameters.lua | 5 ++++- ...ot_read-only_parameters_and_HMI_returns_READ_ONLY.lua | 5 ++++- 53 files changed, 232 insertions(+), 54 deletions(-) diff --git a/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua b/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua index d1b7bfae60..5281397b70 100644 --- a/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua +++ b/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Button press event emulation Requirement +-- +-- Description: -- In case: -- 1) Application is registered with REMOTE_CONTROL appHMIType -- 2) and sends valid ButtonPress RPC with valid parameters diff --git a/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua b/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua index e16475dae3..98dea7b8d0 100644 --- a/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua +++ b/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Button press event emulation Requirement +-- [SDL_RC] Policy support of basic RC functionality Requirement +-- +-- Description: -- In case: -- 1) "moduleType" in app's assigned policies has one or more valid values -- 2) and SDL received ButtonPress request from App with moduleType not in list diff --git a/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua b/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua index 122e31f31d..56897caf86 100644 --- a/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua +++ b/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Button press event emulation Requirement +-- [SDL_RC] Policy support of basic RC functionality Requirement +-- +-- Description: -- In case: -- 1) "moduleType" in app's assigned policies has one or more valid values -- 2) and SDL received ButtonPress request from App with moduleType not in list diff --git a/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua b/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua index 764f5da10f..3ec4ef5501 100644 --- a/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua +++ b/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Button press event emulation Requirement +-- +-- Description: -- In case: -- 1) Non remote-control application is registered on SDL -- 2) and SDL received ButtonPress request from this App diff --git a/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua b/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua index 3820aecc93..82dfc5a1e2 100644 --- a/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua +++ b/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Button press event emulation Requirement +-- +-- Description: -- In case: -- 1) Application registered with REMOTE_CONTROL AppHMIType sends ButtonPress RPC -- 2) (with and RADIO moduleType) OR (with and CLIMATE moduleType) diff --git a/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua b/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua index bcec980b74..1742b3e05d 100644 --- a/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua +++ b/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Button press event emulation Requirement +-- +-- Description: -- In case: -- 1) RC app sends ButtonPress request with invalid parameters -- SDL must: diff --git a/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua b/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua index 236c4c65fc..97bf56270d 100644 --- a/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua +++ b/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Button press event emulation Requirement +-- [SDL_RC] Policy support of basic RC functionality Requirement +-- +-- Description: -- In case: -- 1) "moduleType" in app's assigned policies has an empty array -- 2) and RC app sends ButtonPress request with valid parameters diff --git a/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua b/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua index c9222b6ef9..0abf6de02c 100644 --- a/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua +++ b/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Button press event emulation Requirement +-- [SDL_RC] Policy support of basic RC functionality Requirement +-- +-- Description: -- In case: -- 1) "moduleType" does not exist in app's assigned policies -- 2) and RC app sends ButtonPress request with valid parameters diff --git a/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua b/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua index 12305b8725..2eac2cc0c5 100644 --- a/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua +++ b/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Button press event emulation Requirement +-- [SDL_RC] Policy support of basic RC functionality Requirement +-- +-- Description: -- In case: -- 1) ButtonPress RPC does not exist in app's assigned policies -- 2) and RC app sends ButtonPress request with valid parameters diff --git a/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua b/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua index fddcd7ce21..62a32c7708 100644 --- a/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua +++ b/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Button press event emulation Requirement +-- +-- Description: -- In case: -- 1) RC app sends ButtonPress request with valid parameters -- 2) and HMI didn't respond within default timeout diff --git a/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua b/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua index fca04a54a5..9109ef6a5e 100644 --- a/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua +++ b/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Button press event emulation Requirement +-- +-- Description: -- In case: -- 1) RC app sends ButtonPress request with valid parameters -- 2) and SDL gets response (resultCode: READ_ONLY) from HMI diff --git a/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua index 54be00a9f7..e0a8bc4a89 100644 --- a/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- +-- Description: -- In case: -- 1) RC app sends valid and allowed by policies GetInteriorVehicleData request -- 2) and SDL received response with successful result code and current module data from HMI diff --git a/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 89331b16fe..8a8f97ed75 100644 --- a/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- [SDL_RC] Policy support of basic RC functionality Requirement +-- +-- Description: -- In case: -- 1) "moduleType" in app's assigned policies has one or more valid values -- 2) and SDL received GetInteriorVehicleData request from App with moduleType not in list diff --git a/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index 5e6a5ecd0e..6a7306076a 100644 --- a/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- [SDL_RC] Policy support of basic RC functionality Requirement +-- +-- Description: -- In case: -- 1) "moduleType" in app's assigned policies has one or more valid values -- 2) and SDL received GetInteriorVehicleData request from App with moduleType not in list diff --git a/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index c7828452c8..d271a9bd4a 100644 --- a/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- +-- Description: -- In case: -- 1) Non remote-control application is registered on SDL -- 2) and SDL received GetInteriorVehicleData request from this App diff --git a/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua index fb05de6b61..ddd0828cbe 100644 --- a/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- +-- Description: -- In case: -- 1) RC app sends valid and allowed by policies GetInteriorvehicleData request -- 2) and SDL received GetInteriorVehicledata response with successful result code and current module data from HMI diff --git a/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua index f2ad31d768..5231394783 100644 --- a/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- +-- Description: -- In case: -- 1) RC app sends GetInteriorVehicleData request with invalid parameters -- - invalid parameter name diff --git a/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index 4e37699ec3..233a185d78 100644 --- a/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- +-- Description: -- In case: -- 1) RC app sends GetInteriorVehicleData request with valid parameters -- 2) and HMI didn't respond within default timeout diff --git a/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index 40353866ee..c08fa73e77 100644 --- a/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- +-- Description: -- In case: -- 1) RC app sends GetInteriorVehicleData request with valid parameters -- 2) and HMI responds with invalid data: diff --git a/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 9db9d298a3..6934e83469 100644 --- a/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- [SDL_RC] Policy support of basic RC functionality Requirement +-- +-- Description: -- In case: -- 1) "moduleType" in app's assigned policies has an empty array -- 2) and RC app sends GetInteriorVehicleData request with valid parameters diff --git a/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 3b9ef14c4e..dba0026eb0 100644 --- a/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- [SDL_RC] Policy support of basic RC functionality Requirement +-- +-- Description: -- In case: -- 1) "moduleType" does not exist in app's assigned policies -- 2) and RC app sends GetInteriorVehicleData request with valid parameters diff --git a/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua index 71c3dbd08f..f12a9c985d 100644 --- a/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +++ b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- +-- Description: -- In case: -- 1) RC app sends GetInteriorVehicleData request with valid parameters -- 2) and SDL gets response (resultCode: READ_ONLY) from HMI diff --git a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua index 114723169c..423469f8fe 100644 --- a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- +-- Description: -- In case: -- 1) RC app sends valid and allowed by policies GetInteriorVehicleData request with "subscribe" parameter -- 2) and SDL received GetInteriorVehicledata response with "resultCode:" and without "isSubscribed" parameter from HMI diff --git a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index 4af7ae2fb0..c793da2f2a 100644 --- a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- +-- Description: -- In case: -- 1) RC app sends valid and allowed by policies GetInteriorvehicleData request without "subscribe" parameter -- 2) and SDL received GetInteriorVehicledata response with "resultCode:" and with "isSubscribed" parameter from HMI diff --git a/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua index a9bb1191db..dc74d9b280 100644 --- a/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua @@ -1,5 +1,7 @@ --------------------------------------------------------------------------------------------------- --- Description #1 +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification Requirement +-- Description: -- In case: -- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter -- 2) and SDL received GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS" from HMI @@ -8,8 +10,9 @@ -- 1) Internally subscribe this application for requested -- 2) Transfer GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS", "success:true" to the related app -- 3) Re-send OnInteriorVehicleData notification to the related app - --- Description #2 +-- +-- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- Description: -- In case: -- 1) RC app is subscribed to "" -- 2) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter diff --git a/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 21ce70c66a..dbb32b0c45 100644 --- a/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification Requirement +-- [SDL_RC] Policy support of basic RC functionality Requirement +-- +-- Description: -- In case: -- 1) A set of module(s) is defined in policies for particular RC app -- 2) and this RC app is subscribed to one of the module from the list diff --git a/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index 1573596546..60484273c6 100644 --- a/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification Requirement +-- [SDL_RC] Policy support of basic RC functionality Requirement +-- +-- Description: -- In case: -- 1) A set of module(s) is defined in policies for particular RC app -- 2) and this RC app is subscribed to one of the module from the list diff --git a/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua index 94ea213696..e88f91c0b1 100644 --- a/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification Requirement +-- +-- Description: -- In case: -- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter -- 2) and SDL received GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS" from HMI diff --git a/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua index 6d8728ea21..0f00adcdd0 100644 --- a/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification Requirement +-- +-- Description: -- In case: -- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter -- 2) and SDL received GetInteriorVehicleData response without "isSubscribed" parameter, "resultCode: SUCCESS" from HMI diff --git a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua index fc7bae4b95..e561e44bc5 100644 --- a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification Requirement +-- +-- Description: -- In case: -- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter -- 2) and SDL received GetInteriorVehicleData response with "resultCode: " from HMI diff --git a/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua index 3aa4f9b3a6..cec61a423a 100644 --- a/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification Requirement +-- +-- Description: -- In case: -- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter -- 2) and HMI didn't respond within default timeout diff --git a/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua index d6de35f073..f6b0c98a54 100644 --- a/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification Requirement +-- +-- Description: -- In case: -- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter -- 2) and HMI responds with invalid data diff --git a/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua index 7e27dbe64d..5669fa91dc 100644 --- a/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- +-- Description: -- In case: -- 1) RC app is subscribed to "" -- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter diff --git a/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua index ee33f7c2f0..bef8c74de2 100644 --- a/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- +-- Description: -- In case: -- 1) RC app is subscribed to "" -- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter diff --git a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua index 1e5fe84ff1..a677adf515 100644 --- a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- +-- Description: -- In case: -- 1) RC app is subscribed to "" -- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter diff --git a/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua index aea6cc3151..df2bc1835f 100644 --- a/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- +-- Description: -- In case: -- 1) RC app is subscribed to "" -- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter diff --git a/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua b/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua index c7a0214b2e..0af0f342ca 100644 --- a/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua +++ b/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification Requirement +-- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- +-- Description: -- In case: -- 1) RC app is subscribed to one of the RC module -- 2) and then SDL received OnInteriorVehicleData notification for another module diff --git a/test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua b/test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua index 4b3324a7a4..d6833bfb3e 100644 --- a/test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua +++ b/test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification Requirement +-- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- +-- Description: -- In case: -- 1) RC app is subscribed to one of the RC module -- 2) and then SDL received OnInteriorVehicleData notification for another module diff --git a/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua b/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua index 6d17fdfe49..6dfcd931e4 100644 --- a/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua +++ b/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- +-- Description: -- In case: -- 1) RC app is subscribed to a few RC modules -- 2) and then RC app is unsubscribed to one of the module diff --git a/test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua b/test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua index 0a4d0cce42..a2ef13d1d9 100644 --- a/test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua +++ b/test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- +-- Description: -- In case: -- 1) RC app is subscribed to a few RC modules -- 2) and then RC app is unsubscribed to one of the module diff --git a/test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua b/test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua index 9a812c494e..2d7e367a04 100644 --- a/test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua +++ b/test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification Requirement +-- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- +-- Description: -- In case: -- 1) RC app is subscribed to a RC module -- 2) and then SDL received OnInteriorVehicleData notification for this module with invalid data diff --git a/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua index 0057ec901f..61da35b3a6 100644 --- a/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- +-- Description: -- In case: -- 1) Application is registered with REMOTE_CONTROL appHMIType -- 2) and sends valid SetInteriorVehicleData RPC with valid parameters diff --git a/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index d924f1fbc1..2497af9aa4 100644 --- a/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- [SDL_RC] Policy support of basic RC functionality Requirement +-- +-- Description: -- In case: -- 1) "moduleType" in app's assigned policies has one or more valid values -- 2) and SDL received SetInteriorVehicleData request from App with moduleType not in list diff --git a/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index f358174e1d..cff85e39f7 100644 --- a/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- [SDL_RC] Policy support of basic RC functionality Requirement +-- +-- Description: -- In case: -- 1) "moduleType" in app's assigned policies has one or more valid values -- 2) and SDL received SetInteriorVehicleData request from App with moduleType not in list diff --git a/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index fb0fe6e003..8e42625b98 100644 --- a/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- +-- Description: -- In case: -- 1) Non remote-control application is registered on SDL -- 2) and SDL received SetInteriorVehicleData request from this App diff --git a/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua b/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua index cd006d8eb8..c7943f89a6 100644 --- a/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua +++ b/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description #1 +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- +-- Description: -- In case: -- 1) Application registered with REMOTE_CONTROL AppHMIType and sends SetInteriorVehicleData RPC -- 2) (with "climateControlData" and RADIO moduleType) OR (with "radioControlData" and CLIMATE moduleType) diff --git a/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua index b591f95cb7..e2d9216308 100644 --- a/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- +-- Description: -- In case: -- 1) RC app sends SetInteriorVehicleData request with invalid parameters -- - invalid parameter name diff --git a/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index f80b47cb22..81cbb50bf9 100644 --- a/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- [SDL_RC] Policy support of basic RC functionality Requirement +-- +-- Description: -- In case: -- 1) "moduleType" in app's assigned policies has an empty array -- 2) and RC app sends SetInteriorVehicleData request with valid parameters diff --git a/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 1438703581..599ce2fd87 100644 --- a/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -1,5 +1,9 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- [SDL_RC] Policy support of basic RC functionality Requirement +-- +-- Description: -- In case: -- 1) "moduleType" does not exist in app's assigned policies -- 2) and RC app sends SetInteriorVehicleData request with valid parameters diff --git a/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua b/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua index 44985083a2..e9c193484e 100644 --- a/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua +++ b/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- +-- Description: -- In case: -- 1) Mobile app send SetInteriorVehicleData with moduleType that matches with controlData structure -- 2) and control data structure has fake parameters (in this case related to another module or unknown) diff --git a/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua b/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua index 78a5bd066d..74275c0a62 100644 --- a/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +++ b/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- +-- Description: -- In case: -- 1) application sends valid SetInteriorVehicleData with just read-only parameters in "climateControlData" struct for muduleType: CLIMATE, -- OR diff --git a/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua b/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua index cfed345c85..b144b64809 100644 --- a/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua +++ b/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- +-- Description: -- In case: -- 1) Application sends valid SetInteriorVehicleData with read-only parameters -- 2) and one or more settable parameters in "radioControlData" struct, for moduleType: RADIO, diff --git a/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua b/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua index b049754cd6..90269e6aad 100644 --- a/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua +++ b/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua @@ -1,5 +1,8 @@ --------------------------------------------------------------------------------------------------- --- Description +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- +-- Description: -- In case: -- 1) SDL has sent SetInteriorVehicleData with one or more settable parameters in "moduleData" struct -- 2) and HMI responds with "resultCode: READ_ONLY" From b4de2eea015d9b09c83d3d3b9e3acf6c6e6648b3 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 26 Jul 2017 18:26:00 +0300 Subject: [PATCH 074/681] GetInteriorVehicleData: remove check on 'info' parameter --- ...08_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index c08fa73e77..3505c87088 100644 --- a/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -37,7 +37,7 @@ local function invalidParamType(pModuleType, self) }) end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Invalid message received from vehicle"}) + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) end local function missingMandatoryParam(pModuleType, self) @@ -60,7 +60,7 @@ local function missingMandatoryParam(pModuleType, self) }) end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Invalid message received from vehicle"}) + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) end --[[ Scenario ]] From 9c7c09a926f3c192e5dd7b3399df245c1d308c9a Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Thu, 27 Jul 2017 10:02:03 +0300 Subject: [PATCH 075/681] GetInteriorVehicleData: Add additional script for 2nd subscription/unsubscription --- ...ase_of_2nd_Subscription_UnSubscription.lua | 93 +++++++++++++++++++ test_sets/rc_GetInteriorVehicleData.txt | 1 + 2 files changed, 94 insertions(+) create mode 100644 test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua diff --git a/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua b/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua new file mode 100644 index 0000000000..3f721ab2b9 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua @@ -0,0 +1,93 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- +-- Description #1: +-- In case: +-- 1) RC app is subscribed to "" +-- 2) and sends valid and allowed-by-policies GetInteriorVehicleData request +-- 3) with "subscribe:true" parameter for the same "" +-- SDL must: +-- 1) Forward request to HMI without "subscribe:true" parameter +-- 2) not change the subscription status of the app +-- 3) transfer HMI's response with added "isSubscribed: true" to the app +-- +-- Description #2: +-- In case: +-- 1) RC app is not subscribed to "" +-- 2) and sends valid and allowed-by-policies GetInteriorVehicleData request +-- 3) with "subscribe:false" parameter for the same "" +-- SDL must: +-- 1) Forward request to HMI without "subscribe:false" parameter +-- 2) not change the subscription status of the app +-- 3) transfer HMI's response with added "isSubscribed: false" to the app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function subscriptionToModule(pModuleType, pSubscribe, self) + local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = pSubscribe + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleType = pModuleType + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = pSubscribe + }) + end) + :ValidIf(function(_, data) + if data.params.subscribe == nil then + return true + end + return false, 'Parameter "subscribe" is transfered to HMI with value: ' .. tostring(data.params.subscribe) + end) + + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = pSubscribe + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +runner.Title("Test") + +for _, mod in pairs(modules) do + -- app has not subscribed yet + runner.Step("Unsubscribe app to " .. mod, subscriptionToModule, { mod, false }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", commonRC.isUnsubscribed, { mod }) + + -- subscribe to module 1st time + runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", commonRC.isSubscribed, { mod }) + + -- subscribe to module 2nd time + runner.Step("Subscribe 2nd time app to " .. mod, subscriptionToModule, { mod, true }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", commonRC.isSubscribed, { mod }) + + -- unsubscribe to module 1st time + runner.Step("Unsubscribe app to " .. mod, commonRC.unSubscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", commonRC.isUnsubscribed, { mod }) + + -- unsubscribe to module 2nd time + runner.Step("Unsubscribe 2nd time app to " .. mod, subscriptionToModule, { mod, false }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", commonRC.isUnsubscribed, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_GetInteriorVehicleData.txt b/test_sets/rc_GetInteriorVehicleData.txt index d8c41b442b..ac3f7b97b7 100644 --- a/test_sets/rc_GetInteriorVehicleData.txt +++ b/test_sets/rc_GetInteriorVehicleData.txt @@ -11,3 +11,4 @@ ./test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua ./test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua From efc8db307cfa50ab9c179133b517b0fc81a90a01 Mon Sep 17 00:00:00 2001 From: Masato Ogawa Date: Thu, 27 Jul 2017 17:50:10 +0900 Subject: [PATCH 076/681] Add TouchType CANCEL --- test_scripts/API/ATF_OnTouchEvent.lua | 104 +++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 2 deletions(-) diff --git a/test_scripts/API/ATF_OnTouchEvent.lua b/test_scripts/API/ATF_OnTouchEvent.lua index 066000a3e5..68fe5071f3 100644 --- a/test_scripts/API/ATF_OnTouchEvent.lua +++ b/test_scripts/API/ATF_OnTouchEvent.lua @@ -282,7 +282,7 @@ end commonFunctions:newTestCasesGroup("Test suite: Check type parameter") --1. IsInBoundValues - local types = {"BEGIN", "MOVE", "END"} + local types = {"BEGIN", "MOVE", "END", "CANCEL"} for i = 1, #types do Test["OnTouchEvent_type_" .. types[i]] = function(self) @@ -1199,6 +1199,39 @@ end end + --1.1. Click and cancel on navigation + function Test:OnTouchEvent_type_BEGIN() + print() + print("Step 1.1. Click and cancel on navigation area" + + local parameter = { + type = "BEGIN", + event = { {c = {{x = 1, y = 1}}, id = 0, ts = {900} } } + } + + --hmi side: send OnTouchEvent + self.hmiConnection:SendNotification("UI.OnTouchEvent", parameter) + + --mobile side: expected OnTouchEvent notification + EXPECT_NOTIFICATION("OnTouchEvent", parameter) + + end + + function Test:OnTouchEvent_type_CANCEL() + + local parameter = { + type = "CANCEL", + event = { {c = {{x = 1, y = 1}}, id = 0, ts = {1000} } } + } + + --hmi side: send OnTouchEvent + self.hmiConnection:SendNotification("UI.OnTouchEvent", parameter) + + --mobile side: expected OnTouchEvent notification + EXPECT_NOTIFICATION("OnTouchEvent", parameter) + + end + --2. Click on navigation area with 2 fingers at the same time function Test:OnTouchEvent_type_BEGIN_2Fingers() @@ -1249,6 +1282,54 @@ end end + --2.1. Click and cancel on navigation area with 2 fingers at the same time + function Test:OnTouchEvent_type_BEGIN_2Fingers() + print() + print("Step 2.1. Click and cancel on navigation area with 2 fingers at the same time") + + local parameter1 = { + type = "BEGIN", + event = { {c = {{x = 1, y = 1}}, id = 0, ts = {900} } } + } + + local parameter2 = { + type = "BEGIN", + event = { {c = {{x = 2, y = 1}}, id = 1, ts = {900} } } + } + + --hmi side: send OnTouchEvent + self.hmiConnection:SendNotification("UI.OnTouchEvent", parameter1) + self.hmiConnection:SendNotification("UI.OnTouchEvent", parameter2) + + + --mobile side: expected OnTouchEvent notification + EXPECT_NOTIFICATION("OnTouchEvent", parameter1, parameter2) + :Times(2) + + end + + function Test:OnTouchEvent_type_CANCEL_2Fingers() + + local parameter1 = { + type = "CANCEL", + event = { {c = {{x = 1, y = 1}}, id = 0, ts = {900} } } + } + + local parameter2 = { + type = "CANCEL", + event = { {c = {{x = 2, y = 1}}, id = 1, ts = {900} } } + } + + --hmi side: send OnTouchEvent + self.hmiConnection:SendNotification("UI.OnTouchEvent", parameter1) + self.hmiConnection:SendNotification("UI.OnTouchEvent", parameter2) + + + --mobile side: expected OnTouchEvent notification + EXPECT_NOTIFICATION("OnTouchEvent", parameter1, parameter2) + :Times(2) + + end --3. Move on navigation area with 1 finger function Test:OnTouchEvent_type_BEGIN() @@ -1524,6 +1605,25 @@ end end + function Test:OnTouchEvent_Non_Navi_CANCEL() + DelayedExp(2000) + local parameter = { + type = "CANCEL", + event = { {c = {{x = 2, y = 2}}, id = 0, ts = {903} } } + } + + --hmi side: send OnTouchEvent + self.hmiConnection:SendNotification("UI.OnTouchEvent", parameter) + + --mobile side: expected OnTouchEvent notification + EXPECT_NOTIFICATION("OnTouchEvent", parameter) + + --mobile side: app2 expects notification + self.mobileSession2:ExpectNotification("OnTouchEvent", parameter) + :Times(0) + + end + --Postcondition: function Test:Unregister_App2() @@ -1694,4 +1794,4 @@ end return Test - \ No newline at end of file + From 8b3c1ba3f058d5f8bc0ad3afdb89fa5791b06f5b Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Thu, 27 Jul 2017 16:03:59 +0300 Subject: [PATCH 077/681] Minor fix of the description --- .../RC/ButtonPress/001_success_flow_for_climate_and_radio.lua | 2 +- .../ButtonPress/002_disallow_flow_by_policy_for_climate.lua | 4 ++-- .../RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua | 4 ++-- .../004_check_processing_button_press_for_nonRC_App.lua | 2 +- ...tached_buttonName_and_moduleType_for_radio_and_climate.lua | 2 +- .../ButtonPress/006_check_rpc_parameters_for_button_press.lua | 2 +- .../007_button_press_allowed_if_moduleType_is_empty.lua | 4 ++-- .../008_button_press_disallowed_if_moduleType_is_absent.lua | 4 ++-- ...ess_disallowed_if_moduleType_is_disallowed_by_policies.lua | 4 ++-- .../ButtonPress/010_generic_error_if_no_response_from_hmi.lua | 2 +- .../011_generic_error_if_read_only_response_come_from_hmi.lua | 2 +- test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua | 2 +- .../002_Disallow_flow_by_policy_CLIMATE.lua | 4 ++-- .../003_Disallow_flow_by_policy_RADIO.lua | 4 ++-- ...Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua | 2 +- .../005_Transfering_of_HMI_resultCode_to_mobile.lua | 2 +- .../RC/GetInteriorVehicleData/006_RPC_parameters_values.lua | 2 +- .../007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua | 2 +- ...08_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua | 2 +- ...ccess_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua | 4 ++-- .../010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua | 4 ++-- .../011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua | 2 +- ...e_parameter_but_response_from_HMI_without_isSubscribed.lua | 2 +- ...ribe_parameter_but_response_from_HMI_with_isSubscribed.lua | 2 +- ...est_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua | 2 +- test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua | 4 ++-- .../002_Disallow_flow_by_policy_CLIMATE.lua | 4 ++-- .../003_Disallow_flow_by_policy_RADIO.lua | 4 ++-- ...uccessfull_subscribing_with_isSubscribe_false_from_HMI.lua | 2 +- ...f_successfull_subscribing_without_isSubscribe_from_HMI.lua | 2 +- ...ce_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua | 2 +- ...OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua | 2 +- ..._in_case_of_subscribing_with_invalid_response_from_HMI.lua | 2 +- ...ccessfull_unsubscribing_with_isSubscribe_true_from_HMI.lua | 2 +- ...successfull_unsubscribing_without_isSubscribe_from_HMI.lua | 2 +- ...cessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua | 2 +- ...successfull_unsubscribing_without_isSubscribe_from_HMI.lua | 2 +- ...on_for_module_Climate_and_without_one_for_module_Radio.lua | 4 ++-- ...on_for_module_Radio_and_without_one_for_module_Climate.lua | 4 ++-- ...module_Climate_and_after_unsubscribe_from_module_Radio.lua | 2 +- ...module_Radio_and_after_unsubscribe_from_module_Climate.lua | 2 +- .../RC/OnInteriorVehicleData/017_RPC_parameters_values.lua | 4 ++-- test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua | 2 +- .../002_Disallow_flow_by_policy_CLIMATE.lua | 4 ++-- .../003_Disallow_flow_by_policy_RADIO.lua | 4 ++-- ...Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua | 2 +- ..._DATA_in_case_params_does_not_correspond_to_moduleType.lua | 2 +- .../RC/SetInteriorVehicleData/006_RPC_parameters_values.lua | 2 +- ...ccess_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua | 4 ++-- .../008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua | 4 ++-- .../009_Cut-off_of_fake_parameters_from_App.lua | 2 +- ...et_interior_vehicle_data_if_read_only_params_requested.lua | 2 +- ...se_request_with_read-only_and_not_read-only_parameters.lua | 2 +- ...and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua | 2 +- 54 files changed, 73 insertions(+), 73 deletions(-) diff --git a/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua b/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua index 5281397b70..d44b19a0d3 100644 --- a/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua +++ b/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Button press event emulation Requirement +-- [SDL_RC] Button press event emulation -- -- Description: -- In case: diff --git a/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua b/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua index 98dea7b8d0..fe14aecc0c 100644 --- a/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua +++ b/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Button press event emulation Requirement --- [SDL_RC] Policy support of basic RC functionality Requirement +-- [SDL_RC] Button press event emulation +-- [SDL_RC] Policy support of basic RC functionality -- -- Description: -- In case: diff --git a/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua b/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua index 56897caf86..5ddef5caea 100644 --- a/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua +++ b/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Button press event emulation Requirement --- [SDL_RC] Policy support of basic RC functionality Requirement +-- [SDL_RC] Button press event emulation +-- [SDL_RC] Policy support of basic RC functionality -- -- Description: -- In case: diff --git a/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua b/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua index 3ec4ef5501..a93a07e8d2 100644 --- a/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua +++ b/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Button press event emulation Requirement +-- [SDL_RC] Button press event emulation -- -- Description: -- In case: diff --git a/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua b/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua index 82dfc5a1e2..d3c4fbfd2c 100644 --- a/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua +++ b/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Button press event emulation Requirement +-- [SDL_RC] Button press event emulation -- -- Description: -- In case: diff --git a/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua b/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua index 1742b3e05d..0e10ced685 100644 --- a/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua +++ b/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Button press event emulation Requirement +-- [SDL_RC] Button press event emulation -- -- Description: -- In case: diff --git a/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua b/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua index 97bf56270d..66ba6dc033 100644 --- a/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua +++ b/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Button press event emulation Requirement --- [SDL_RC] Policy support of basic RC functionality Requirement +-- [SDL_RC] Button press event emulation +-- [SDL_RC] Policy support of basic RC functionality -- -- Description: -- In case: diff --git a/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua b/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua index 0abf6de02c..b2bd640311 100644 --- a/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua +++ b/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Button press event emulation Requirement --- [SDL_RC] Policy support of basic RC functionality Requirement +-- [SDL_RC] Button press event emulation +-- [SDL_RC] Policy support of basic RC functionality -- -- Description: -- In case: diff --git a/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua b/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua index 2eac2cc0c5..e45a7b3ad8 100644 --- a/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua +++ b/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Button press event emulation Requirement --- [SDL_RC] Policy support of basic RC functionality Requirement +-- [SDL_RC] Button press event emulation +-- [SDL_RC] Policy support of basic RC functionality -- -- Description: -- In case: diff --git a/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua b/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua index 62a32c7708..7bb95e092c 100644 --- a/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua +++ b/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Button press event emulation Requirement +-- [SDL_RC] Button press event emulation -- -- Description: -- In case: diff --git a/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua b/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua index 9109ef6a5e..bc38139ec1 100644 --- a/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua +++ b/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Button press event emulation Requirement +-- [SDL_RC] Button press event emulation -- -- Description: -- In case: diff --git a/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua index e0a8bc4a89..ecf8dcb463 100644 --- a/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- [SDL_RC] Current module status data GetInteriorVehicleData -- -- Description: -- In case: diff --git a/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 8a8f97ed75..a71b17e25d 100644 --- a/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Current module status data GetInteriorVehicleData Requirement --- [SDL_RC] Policy support of basic RC functionality Requirement +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality -- -- Description: -- In case: diff --git a/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index 6a7306076a..10dff7359a 100644 --- a/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Current module status data GetInteriorVehicleData Requirement --- [SDL_RC] Policy support of basic RC functionality Requirement +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality -- -- Description: -- In case: diff --git a/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index d271a9bd4a..dcbd58749b 100644 --- a/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- [SDL_RC] Current module status data GetInteriorVehicleData -- -- Description: -- In case: diff --git a/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua index ddd0828cbe..8c050dc043 100644 --- a/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- [SDL_RC] Current module status data GetInteriorVehicleData -- -- Description: -- In case: diff --git a/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua index 5231394783..d4a9d7740c 100644 --- a/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- [SDL_RC] Current module status data GetInteriorVehicleData -- -- Description: -- In case: diff --git a/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index 233a185d78..f046e6942e 100644 --- a/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- [SDL_RC] Current module status data GetInteriorVehicleData -- -- Description: -- In case: diff --git a/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index 3505c87088..aa8f4eb94c 100644 --- a/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- [SDL_RC] Current module status data GetInteriorVehicleData -- -- Description: -- In case: diff --git a/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 6934e83469..7c49c61968 100644 --- a/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Current module status data GetInteriorVehicleData Requirement --- [SDL_RC] Policy support of basic RC functionality Requirement +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality -- -- Description: -- In case: diff --git a/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index dba0026eb0..21ccfe0edc 100644 --- a/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Current module status data GetInteriorVehicleData Requirement --- [SDL_RC] Policy support of basic RC functionality Requirement +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality -- -- Description: -- In case: diff --git a/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua index f12a9c985d..96c77d61ec 100644 --- a/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +++ b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- [SDL_RC] Current module status data GetInteriorVehicleData -- -- Description: -- In case: diff --git a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua index 423469f8fe..dc01ad9797 100644 --- a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- [SDL_RC] Current module status data GetInteriorVehicleData -- -- Description: -- In case: diff --git a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index c793da2f2a..59c0d68440 100644 --- a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- [SDL_RC] Current module status data GetInteriorVehicleData -- -- Description: -- In case: diff --git a/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua b/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua index 3f721ab2b9..5fb2d09444 100644 --- a/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +++ b/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Current module status data GetInteriorVehicleData Requirement +-- [SDL_RC] Current module status data GetInteriorVehicleData -- -- Description #1: -- In case: diff --git a/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua index dc74d9b280..271718d42a 100644 --- a/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Subscribe on RC module change notification Requirement +-- [SDL_RC] Subscribe on RC module change notification -- Description: -- In case: -- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter @@ -11,7 +11,7 @@ -- 2) Transfer GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS", "success:true" to the related app -- 3) Re-send OnInteriorVehicleData notification to the related app -- --- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- [SDL_RC] Unsubscribe from RC module change notifications -- Description: -- In case: -- 1) RC app is subscribed to "" diff --git a/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index dbb32b0c45..5c09d9bd8c 100644 --- a/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Subscribe on RC module change notification Requirement --- [SDL_RC] Policy support of basic RC functionality Requirement +-- [SDL_RC] Subscribe on RC module change notification +-- [SDL_RC] Policy support of basic RC functionality -- -- Description: -- In case: diff --git a/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index 60484273c6..23e518687e 100644 --- a/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Subscribe on RC module change notification Requirement --- [SDL_RC] Policy support of basic RC functionality Requirement +-- [SDL_RC] Subscribe on RC module change notification +-- [SDL_RC] Policy support of basic RC functionality -- -- Description: -- In case: diff --git a/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua index e88f91c0b1..8ce4816627 100644 --- a/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Subscribe on RC module change notification Requirement +-- [SDL_RC] Subscribe on RC module change notification -- -- Description: -- In case: diff --git a/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua index 0f00adcdd0..1619e73491 100644 --- a/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Subscribe on RC module change notification Requirement +-- [SDL_RC] Subscribe on RC module change notification -- -- Description: -- In case: diff --git a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua index e561e44bc5..19576bc5a4 100644 --- a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Subscribe on RC module change notification Requirement +-- [SDL_RC] Subscribe on RC module change notification -- -- Description: -- In case: diff --git a/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua index cec61a423a..a26cb06952 100644 --- a/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Subscribe on RC module change notification Requirement +-- [SDL_RC] Subscribe on RC module change notification -- -- Description: -- In case: diff --git a/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua index f6b0c98a54..bd5ef719b4 100644 --- a/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Subscribe on RC module change notification Requirement +-- [SDL_RC] Subscribe on RC module change notification -- -- Description: -- In case: diff --git a/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua index 5669fa91dc..f7286bc108 100644 --- a/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- [SDL_RC] Unsubscribe from RC module change notifications -- -- Description: -- In case: diff --git a/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua index bef8c74de2..a5d2079d7b 100644 --- a/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- [SDL_RC] Unsubscribe from RC module change notifications -- -- Description: -- In case: diff --git a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua index a677adf515..c03b14ec04 100644 --- a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- [SDL_RC] Unsubscribe from RC module change notifications -- -- Description: -- In case: diff --git a/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua index df2bc1835f..6cdd3104a7 100644 --- a/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- [SDL_RC] Unsubscribe from RC module change notifications -- -- Description: -- In case: diff --git a/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua b/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua index 0af0f342ca..a73ba2a70c 100644 --- a/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua +++ b/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Subscribe on RC module change notification Requirement --- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- [SDL_RC] Subscribe on RC module change notification +-- [SDL_RC] Unsubscribe from RC module change notifications -- -- Description: -- In case: diff --git a/test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua b/test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua index d6833bfb3e..99d6b362ac 100644 --- a/test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua +++ b/test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Subscribe on RC module change notification Requirement --- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- [SDL_RC] Subscribe on RC module change notification +-- [SDL_RC] Unsubscribe from RC module change notifications -- -- Description: -- In case: diff --git a/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua b/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua index 6dfcd931e4..1bf2ae4061 100644 --- a/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua +++ b/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- [SDL_RC] Unsubscribe from RC module change notifications -- -- Description: -- In case: diff --git a/test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua b/test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua index a2ef13d1d9..ee70399404 100644 --- a/test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua +++ b/test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- [SDL_RC] Unsubscribe from RC module change notifications -- -- Description: -- In case: diff --git a/test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua b/test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua index 2d7e367a04..b37d005e58 100644 --- a/test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua +++ b/test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Subscribe on RC module change notification Requirement --- [SDL_RC] Unsubscribe from RC module change notifications Requirement +-- [SDL_RC] Subscribe on RC module change notification +-- [SDL_RC] Unsubscribe from RC module change notifications -- -- Description: -- In case: diff --git a/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua index 61da35b3a6..efde9990f4 100644 --- a/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- [SDL_RC] Set available control module settings SetInteriorVehicleData -- -- Description: -- In case: diff --git a/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 2497af9aa4..784342e616 100644 --- a/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement --- [SDL_RC] Policy support of basic RC functionality Requirement +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality -- -- Description: -- In case: diff --git a/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index cff85e39f7..73f21169b3 100644 --- a/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement --- [SDL_RC] Policy support of basic RC functionality Requirement +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality -- -- Description: -- In case: diff --git a/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 8e42625b98..b5fc906a71 100644 --- a/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- [SDL_RC] Set available control module settings SetInteriorVehicleData -- -- Description: -- In case: diff --git a/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua b/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua index c7943f89a6..3c740caf4a 100644 --- a/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua +++ b/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- [SDL_RC] Set available control module settings SetInteriorVehicleData -- -- Description: -- In case: diff --git a/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua index e2d9216308..51c529fcfa 100644 --- a/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- [SDL_RC] Set available control module settings SetInteriorVehicleData -- -- Description: -- In case: diff --git a/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 81cbb50bf9..9ae24ad6a0 100644 --- a/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement --- [SDL_RC] Policy support of basic RC functionality Requirement +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality -- -- Description: -- In case: diff --git a/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 599ce2fd87..153881422c 100644 --- a/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement --- [SDL_RC] Policy support of basic RC functionality Requirement +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality -- -- Description: -- In case: diff --git a/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua b/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua index e9c193484e..697e9a67ce 100644 --- a/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua +++ b/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- [SDL_RC] Set available control module settings SetInteriorVehicleData -- -- Description: -- In case: diff --git a/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua b/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua index 74275c0a62..a10bf58761 100644 --- a/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +++ b/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- [SDL_RC] Set available control module settings SetInteriorVehicleData -- -- Description: -- In case: diff --git a/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua b/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua index b144b64809..ae2d6e508e 100644 --- a/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua +++ b/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- [SDL_RC] Set available control module settings SetInteriorVehicleData -- -- Description: -- In case: diff --git a/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua b/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua index 90269e6aad..dbb0dcecf4 100644 --- a/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua +++ b/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua @@ -1,6 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: --- [SDL_RC] Set available control module settings SetInteriorVehicleData Requirement +-- [SDL_RC] Set available control module settings SetInteriorVehicleData -- -- Description: -- In case: From dad568bea5ac767a8d7c2e0ee5df032d10651be1 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Thu, 27 Jul 2017 18:24:30 +0300 Subject: [PATCH 078/681] Fix according to new req-t regarding 2nd subscribe/unsubscribe --- ...parameter_but_response_from_HMI_without_isSubscribed.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua index dc01ad9797..35590c7484 100644 --- a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -24,10 +24,14 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, s subscribe = pSubscribe }) + local pSubscribeHMI = pSubscribe + if (isSubscriptionActive and pSubscribe) or (not isSubscriptionActive and not pSubscribe) then + pSubscribeHMI = nil + end EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], moduleType = pModuleType, - subscribe = pSubscribe + subscribe = pSubscribeHMI }) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { From cb7d2ddac63f53bb709f4b19e60a17d935f7a6a0 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 28 Jul 2017 02:53:46 +0300 Subject: [PATCH 079/681] Update descriptions: add links to TRS --- .../001_Success_flow.lua | 8 +-- ...response_from_HMI_without_isSubscribed.lua | 11 +-- ...ut_response_from_HMI_with_isSubscribed.lua | 11 +-- ...ase_of_2nd_Subscription_UnSubscription.lua | 4 +- .../001_Success_flow.lua | 6 +- ...ribing_with_isSubscribe_false_from_HMI.lua | 2 +- ...bscribing_without_isSubscribe_from_HMI.lua | 2 +- ...ase_of_subscribing_with_error_from_HMI.lua | 5 +- ...cribing_with_isSubscribe_true_from_HMI.lua | 2 +- ...bscribing_without_isSubscribe_from_HMI.lua | 2 +- ...ribing_with_isSubscribe_false_from_HMI.lua | 70 ------------------- ...scribing_without_isSubscribe_from_HMI.lua} | 6 +- ...mate_and_without_one_for_module_Radio.lua} | 0 ...io_and_without_one_for_module_Climate.lua} | 0 ...d_after_unsubscribe_from_module_Radio.lua} | 0 ...after_unsubscribe_from_module_Climate.lua} | 0 ...lues.lua => 016_RPC_parameters_values.lua} | 0 test_sets/rc_OnInteriorVehicleData.txt | 13 ++-- 18 files changed, 38 insertions(+), 104 deletions(-) delete mode 100644 test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua rename test_scripts/RC/OnInteriorVehicleData/{012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua => 011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua} (94%) rename test_scripts/RC/OnInteriorVehicleData/{013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua => 012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua} (100%) rename test_scripts/RC/OnInteriorVehicleData/{014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua => 013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua} (100%) rename test_scripts/RC/OnInteriorVehicleData/{015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua => 014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua} (100%) rename test_scripts/RC/OnInteriorVehicleData/{016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua => 015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua} (100%) rename test_scripts/RC/OnInteriorVehicleData/{017_RPC_parameters_values.lua => 016_RPC_parameters_values.lua} (100%) diff --git a/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua index ecf8dcb463..e22910a07f 100644 --- a/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua @@ -2,12 +2,12 @@ -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- --- Description: +-- Description: TRS: GetInteriorVehicleData, #3 -- In case: --- 1) RC app sends valid and allowed by policies GetInteriorVehicleData request --- 2) and SDL received response with successful result code and current module data from HMI +-- 1) RC app sends valid and allowed by policies GetInteriorvehicleData_request +-- 2) and SDL received GetInteriorVehicledata_response with successful result code and current module data from HMI -- SDL must: --- 1) Transfer GetInteriorVehicleData response with provided from HMI current module data for allowed module and control items +-- 1) transfer GetInteriorVehicleData_response with provided from HMI current module data for allowed module and control items --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua index 35590c7484..ae9dde7977 100644 --- a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -2,13 +2,14 @@ -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- --- Description: +-- Description: TRS: GetInteriorVehicleData, #1 -- In case: --- 1) RC app sends valid and allowed by policies GetInteriorVehicleData request with "subscribe" parameter --- 2) and SDL received GetInteriorVehicledata response with "resultCode:" and without "isSubscribed" parameter from HMI +-- 1) RC app sends valid and allowed by policies GetInteriorvehicleData_request with "subscribe" parameter +-- 2) and SDL received GetInteriorVehicledata_response with resultCode: <"any_not_erroneous_result"> +-- 3) and without "isSubscribed" parameter from HMI -- SDL must: --- 1) Transfer GetInteriorVehicleData response with provided from HMI current module data --- and with added "isSubscribed: " to the related app +-- 1) transfer GetInteriorVehicleData_response with resultCode:<"any_not_erroneous_result"> +-- and with added isSubscribed: <"current_subscription_status"> to the related app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index 59c0d68440..421ba52199 100644 --- a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -2,13 +2,14 @@ -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- --- Description: +-- Description: TRS: GetInteriorVehicleData, #2 -- In case: --- 1) RC app sends valid and allowed by policies GetInteriorvehicleData request without "subscribe" parameter --- 2) and SDL received GetInteriorVehicledata response with "resultCode:" and with "isSubscribed" parameter from HMI +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData_request without "subscribe" parameter +-- 2) and SDL gets GetInteriorVehicleData_response with resultCode: <"any-result"> +-- 3) and with "isSubscribed" parameter from HMI -- SDL must: --- 1) Transfer GetInteriorVehicleData response with provided from HMI current module data --- and without "isSubscribed" parameter to the related app +-- 1) transfer GetInteriorVehicleData_response with resultCode: <"any-result"> +-- and without "isSubscribed" param to the related app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua b/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua index 5fb2d09444..2cf852df9c 100644 --- a/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +++ b/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua @@ -2,7 +2,7 @@ -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- --- Description #1: +-- Description: TRS: GetInteriorVehicleData, #12 -- In case: -- 1) RC app is subscribed to "" -- 2) and sends valid and allowed-by-policies GetInteriorVehicleData request @@ -12,7 +12,7 @@ -- 2) not change the subscription status of the app -- 3) transfer HMI's response with added "isSubscribed: true" to the app -- --- Description #2: +-- Description: TRS: GetInteriorVehicleData, #13 -- In case: -- 1) RC app is not subscribed to "" -- 2) and sends valid and allowed-by-policies GetInteriorVehicleData request diff --git a/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua index 271718d42a..f78a0af0bb 100644 --- a/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua @@ -1,7 +1,8 @@ --------------------------------------------------------------------------------------------------- -- Requirement summary: -- [SDL_RC] Subscribe on RC module change notification --- Description: +-- +-- Description: TRS: GetInteriorVehicleData, #4 -- In case: -- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter -- 2) and SDL received GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS" from HMI @@ -12,7 +13,8 @@ -- 3) Re-send OnInteriorVehicleData notification to the related app -- -- [SDL_RC] Unsubscribe from RC module change notifications --- Description: +-- +-- Description: TRS: GetInteriorVehicleData, #8 -- In case: -- 1) RC app is subscribed to "" -- 2) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter diff --git a/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua index 8ce4816627..10ec88f9b0 100644 --- a/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -2,7 +2,7 @@ -- Requirement summary: -- [SDL_RC] Subscribe on RC module change notification -- --- Description: +-- Description: TRS: GetInteriorVehicleData, #5 -- In case: -- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter -- 2) and SDL received GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS" from HMI diff --git a/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua index 1619e73491..5b9567b2f5 100644 --- a/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua @@ -2,7 +2,7 @@ -- Requirement summary: -- [SDL_RC] Subscribe on RC module change notification -- --- Description: +-- Description: TRS: GetInteriorVehicleData, #6 -- In case: -- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter -- 2) and SDL received GetInteriorVehicleData response without "isSubscribed" parameter, "resultCode: SUCCESS" from HMI diff --git a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua index 19576bc5a4..65e23e449c 100644 --- a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua @@ -2,13 +2,14 @@ -- Requirement summary: -- [SDL_RC] Subscribe on RC module change notification -- --- Description: +-- Description: TRS: GetInteriorVehicleData, #7 -- In case: -- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter -- 2) and SDL received GetInteriorVehicleData response with "resultCode: " from HMI -- 3) and then SDL received OnInteriorVehicleData notification -- SDL must: --- 1) Transfer GetInteriorVehicleData response with "resultCode: " and without "isSubscribed" param to the related app +-- 1) Transfer GetInteriorVehicleData response with "resultCode: " +-- and without "isSubscribed" param to the related app -- 2) Does not re-send OnInteriorVehicleData notification to the app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] diff --git a/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua index f7286bc108..53014b07aa 100644 --- a/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua @@ -2,7 +2,7 @@ -- Requirement summary: -- [SDL_RC] Unsubscribe from RC module change notifications -- --- Description: +-- Description: TRS: GetInteriorVehicleData, #9 -- In case: -- 1) RC app is subscribed to "" -- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter diff --git a/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua index a5d2079d7b..bd4a3dbd31 100644 --- a/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -2,7 +2,7 @@ -- Requirement summary: -- [SDL_RC] Unsubscribe from RC module change notifications -- --- Description: +-- Description: TRS: GetInteriorVehicleData, #10 -- In case: -- 1) RC app is subscribed to "" -- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter diff --git a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua deleted file mode 100644 index c03b14ec04..0000000000 --- a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua +++ /dev/null @@ -1,70 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- Requirement summary: --- [SDL_RC] Unsubscribe from RC module change notifications --- --- Description: --- In case: --- 1) RC app is subscribed to "" --- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter --- 3) and SDL received GetInteriorVehicleData response with "resultCode: " from HMI --- and with "isSubscribed" parameter --- 4) and then SDL received OnInteriorVehicleData notification --- SDL must: --- 1) Transfer GetInteriorVehicleData response with "resultCode: " and without "isSubscribed" param to the related app --- 2) Re-send OnInteriorVehicleData notification to the app ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/commonRC') - ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } -local error_codes = { - { name = "GENERIC_ERROR", id = 22 }, - { name = "INVALID_DATA", id = 11 }, - { name = "OUT_OF_MEMORY", id = 17 }, - { name = "REJECTED", id = 4 } -} - ---[[ Local Functions ]] -local function unSubscriptionToModule(pModuleType, pResultCodeName, pResultCodeId, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType, - subscribe = false - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleType = pModuleType, - subscribe = false - }) - :Do(function(_, data) - self.hmiConnection:Send('{"error":{"data":{"method":"' .. data.method .. '"},"params":{"isSubscribed":false},' - .. '"message":"error message","code":' .. pResultCodeId .. '},"jsonrpc":"2.0","id":' .. data.id .. '}') - end) - - EXPECT_RESPONSE(cid, { success = false, resultCode = pResultCodeName }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) - -for _, mod in pairs(modules) do - runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) - runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App subscribed", commonRC.isSubscribed, { mod }) -end - -runner.Title("Test") - -for _, mod in pairs(modules) do - for _, err in pairs(error_codes) do - runner.Step("Unsubscribe app to " .. mod .. " (" .. err.name .. " from HMI)", unSubscriptionToModule, { mod, err.name, err.id }) - runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App still subscribed", commonRC.isSubscribed, { mod }) - end -end - -runner.Title("Postconditions") -runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua similarity index 94% rename from test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua rename to test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua index 6cdd3104a7..2508695572 100644 --- a/test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -2,15 +2,15 @@ -- Requirement summary: -- [SDL_RC] Unsubscribe from RC module change notifications -- --- Description: +-- Description: TRS: GetInteriorVehicleData, #11 -- In case: -- 1) RC app is subscribed to "" -- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter -- 3) and SDL received GetInteriorVehicleData response with "resultCode: " from HMI --- and without "isSubscribed" parameter -- 4) and then SDL received OnInteriorVehicleData notification -- SDL must: --- 1) Transfer GetInteriorVehicleData response with "resultCode: " and without "isSubscribed" param to the related app +-- 1) Transfer GetInteriorVehicleData response with "resultCode: " +-- and without "isSubscribed" param to the related app -- 2) Re-send OnInteriorVehicleData notification to the app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] diff --git a/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua b/test_scripts/RC/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua rename to test_scripts/RC/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua b/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua rename to test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua b/test_scripts/RC/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua rename to test_scripts/RC/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua b/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua rename to test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua b/test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua rename to test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua diff --git a/test_sets/rc_OnInteriorVehicleData.txt b/test_sets/rc_OnInteriorVehicleData.txt index 9fccba9097..d3794dee8a 100644 --- a/test_sets/rc_OnInteriorVehicleData.txt +++ b/test_sets/rc_OnInteriorVehicleData.txt @@ -8,10 +8,9 @@ ./test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua ./test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua ./test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua -./test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_with_isSubscribe_false_from_HMI.lua -./test_scripts/RC/OnInteriorVehicleData/012_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua -./test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua -./test_scripts/RC/OnInteriorVehicleData/014_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua -./test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua -./test_scripts/RC/OnInteriorVehicleData/016_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua -./test_scripts/RC/OnInteriorVehicleData/017_RPC_parameters_values.lua +./test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua +./test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua +./test_scripts/RC/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua +./test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua +./test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua From 9eef4f3d225f5e08c1af731bf5e0abcf9109cee6 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 28 Jul 2017 03:15:14 +0300 Subject: [PATCH 080/681] GetInteriorVehicleData: corrections regarding new req-t on 2nd subscription/unsubscription --- ...005_Transfering_of_HMI_resultCode_to_mobile.lua | 8 +++++++- ..._but_response_from_HMI_without_isSubscribed.lua | 12 +++++++++--- ...ter_but_response_from_HMI_with_isSubscribed.lua | 14 ++++++++++++-- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua index 8c050dc043..377be284cd 100644 --- a/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua @@ -38,9 +38,15 @@ local function stepSuccessfull(pModuleType, pResultCode, self) end) EXPECT_RESPONSE(cid, { success = true, resultCode = pResultCode, - -- isSubscribed = true, + isSubscribed = false, moduleData = commonRC.getModuleControlData(pModuleType) }) + -- :ValidIf(function(_, data) -- no isSubscribed parameter + -- if data.payload.isSubscribed == nil then + -- return true + -- end + -- return false, 'Parameter "isSubscribed" is transfered to App with value: ' .. tostring(data.payload.isSubscribed) + -- end) end local function stepUnsuccessfull(pModuleType, pResultCode, self) diff --git a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua index ae9dde7977..c7d967c8b8 100644 --- a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -26,13 +26,13 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, s }) local pSubscribeHMI = pSubscribe - if (isSubscriptionActive and pSubscribe) or (not isSubscriptionActive and not pSubscribe) then + if isSubscriptionActive == pSubscribe then pSubscribeHMI = nil end + EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], - moduleType = pModuleType, - subscribe = pSubscribeHMI + moduleType = pModuleType }) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { @@ -40,6 +40,12 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, s -- no isSubscribed parameter }) end) + :ValidIf(function(_, data) + if data.params.subscribe == pSubscribeHMI then + return true + end + return false, 'Parameter "subscribe" is transfered to HMI with value: ' .. tostring(data.params.subscribe) + end) EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", isSubscribed = isSubscriptionActive, -- return current value of subscription diff --git a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index 421ba52199..3ad649179c 100644 --- a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -28,7 +28,6 @@ local function getDataForModule(pModuleType, isSubscriptionActive, self) EXPECT_HMICALL("RC.GetInteriorVehicleData", { appID = self.applications["Test Application"], moduleType = pModuleType - -- no subscribe parameter }) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { @@ -36,11 +35,22 @@ local function getDataForModule(pModuleType, isSubscriptionActive, self) isSubscribed = isSubscriptionActive -- return current value of subscription }) end) + :ValidIf(function(_, data) -- no subscribe parameter + if data.params.subscribe == nil then + return true + end + return false, 'Parameter "subscribe" is transfered with to HMI value: ' .. tostring(data.params.subscribe) + end) EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", moduleData = commonRC.getModuleControlData(pModuleType) - -- no isSubscribed parameter }) + :ValidIf(function(_, data) -- no isSubscribed parameter + if data.payload.isSubscribed == nil then + return true + end + return false, 'Parameter "isSubscribed" is transfered to App with value: ' .. tostring(data.payload.isSubscribed) + end) end --[[ Scenario ]] From 3df70e678b94b7a240d49d63ed1959f6019d2dd0 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 28 Jul 2017 03:30:40 +0300 Subject: [PATCH 081/681] OnInteriorVehicleData: corrections regarding new req-t on 2nd subscription/unsubscription --- ..._of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua | 6 ++++++ ...ccessfull_unsubscribing_without_isSubscribe_from_HMI.lua | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua index 65e23e449c..5143d33957 100644 --- a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua @@ -37,6 +37,12 @@ local function subscriptionToModule(pModuleType, pResultCode, self) end) EXPECT_RESPONSE(cid, { success = false, resultCode = pResultCode }) + :ValidIf(function(_, data) -- no isSubscribed parameter + if data.payload.isSubscribed == nil then + return true + end + return false, 'Parameter "isSubscribed" is transfered to App with value: ' .. tostring(data.payload.isSubscribed) + end) end --[[ Scenario ]] diff --git a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua index 2508695572..6efb448672 100644 --- a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -39,6 +39,12 @@ local function unSubscriptionToModule(pModuleType, pResultCode, self) end) EXPECT_RESPONSE(cid, { success = false, resultCode = pResultCode }) + :ValidIf(function(_, data) -- no isSubscribed parameter + if data.payload.isSubscribed == nil then + return true + end + return false, 'Parameter "isSubscribed" is transfered to App with value: ' .. tostring(data.payload.isSubscribed) + end) end --[[ Scenario ]] From 608cf35d2558bbc35abc139a14ab7ffdf207d124 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 28 Jul 2017 12:09:22 +0300 Subject: [PATCH 082/681] RC Common module: minor fixes --- test_scripts/RC/commonRC.lua | 71 +++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index fbe1de83bb..72ada5acb4 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -6,7 +6,7 @@ config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd40 config.defaultProtocolVersion = 2 config.ValidateSchema = false config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } -config.application2.registerAppInterfaceParams.appHMIType = nil +config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") @@ -82,34 +82,18 @@ end local function updatePTU(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = { - keep_context = false, - steal_focus = false, - priority = "NONE", - default_hmi = "NONE", - moduleType = { "RADIO", "CLIMATE" }, - groups = { "Base-4" }, - groups_primaryRC = { "Base-4", "RemoteControl" }, - AppHMIType = { "REMOTE_CONTROL" } - } - tbl.policy_table.functional_groupings["RemoteControl"] = { - rpcs = { - GetInteriorVehicleDataCapabilities = { - hmi_levels = { "BACKGROUND", "FULL", "LIMITED", "NONE" } - }, - GetInteriorVehicleData = { - hmi_levels = { "BACKGROUND", "FULL", "LIMITED", "NONE" } - }, - SetInteriorVehicleData = { - hmi_levels = { "BACKGROUND", "FULL", "LIMITED", "NONE" } - }, - ButtonPress = { - hmi_levels = { "BACKGROUND", "FULL", "LIMITED", "NONE" } - }, - OnInteriorVehicleData = { - hmi_levels = { "BACKGROUND", "FULL", "LIMITED", "NONE" } - }, - } - } + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + moduleType = { "RADIO", "CLIMATE" }, + groups = { "Base-4" }, + groups_primaryRC = { "Base-4", "RemoteControl" }, + AppHMIType = { "REMOTE_CONTROL" } + } + tbl.policy_table.functional_groupings["RemoteControl"].rpcs.OnInteriorVehicleData = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED", "NONE" } + } end local function jsonFileToTable(file_name) @@ -239,6 +223,35 @@ function commonRC.rai_n(id, self) end) end +function commonRC.activate_app(pAppId, self) + self, pAppId = commonRC.getSelfAndParams(pAppId, self) + + local pHMIAppId = self.applications["Test Application"] + local mobSession = self["mobileSession"] + if pAppId and pAppId > 1 then + mobSession = self["mobileSession" .. pAppId] + pHMIAppId = self.applications[config["application" .. pAppId].registerAppInterfaceParams.appID] + end + local requestId1 = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + EXPECT_HMIRESPONSE(requestId1) + :Do(function(_, data1) + if data1.result.isSDLAllowed ~= true then + local requestId2 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", + { language = "EN-US", messageCodes = { "DataConsent" } }) + EXPECT_HMIRESPONSE(requestId2) + :Do(function() + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", + { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + EXPECT_HMICALL("BasicCommunication.ActivateApp") + :Do(function(_, data2) + self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", { }) + end) + end) + end + end) + mobSession:ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) +end + function commonRC.postconditions() StopSDL() end From 2f39eda3a417ddb732068a6bc92550bbcb94ee97 Mon Sep 17 00:00:00 2001 From: Masato Ogawa Date: Fri, 28 Jul 2017 20:39:23 +0900 Subject: [PATCH 083/681] fix test break --- test_scripts/API/ATF_OnTouchEvent.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/API/ATF_OnTouchEvent.lua b/test_scripts/API/ATF_OnTouchEvent.lua index 68fe5071f3..4a5a436355 100644 --- a/test_scripts/API/ATF_OnTouchEvent.lua +++ b/test_scripts/API/ATF_OnTouchEvent.lua @@ -1202,7 +1202,7 @@ end --1.1. Click and cancel on navigation function Test:OnTouchEvent_type_BEGIN() print() - print("Step 1.1. Click and cancel on navigation area" + print("Step 1.1. Click and cancel on navigation area") local parameter = { type = "BEGIN", From 85f4bef003faca1ac12a4053b6f03a7fd86a5340 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 28 Jul 2017 14:58:02 +0300 Subject: [PATCH 084/681] RC Common module: Remove read-only parameter --- test_scripts/RC/commonRC.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 72ada5acb4..d53f067c56 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -447,7 +447,6 @@ function commonRC.getReadOnlyParamsByModule(pModuleType) availableHDs = 2, signalStrength = 4, signalChangeThreshold = 22, - radioEnable = true, state = "MULTICAST" } end From ae9e5515e25a1a9b546782a3c873217862c67025 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Tue, 1 Aug 2017 13:23:21 +0300 Subject: [PATCH 085/681] ButtonPress: Correct script --- .../006_check_rpc_parameters_for_button_press.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua b/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua index 0e10ced685..2964cd6a0d 100644 --- a/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua +++ b/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua @@ -77,12 +77,12 @@ local function SendButtonPressNegative(button_press_params, self) end --[[ Positive Scenario - check all positive climate names params]] -local climate_params = reset_climate_params() runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) for _, button_name_value in pairs( climate_button_names ) do + local climate_params = reset_climate_params() climate_params.buttonPressMode = "SHORT" climate_params.buttonName = button_name_value runner.Title("Test - ButtonPress with buttonName " .. button_name_value) @@ -92,8 +92,8 @@ for _, button_name_value in pairs( climate_button_names ) do end --[[ Positive Scenario - check all positive radio names params]] -local radio_params = reset_radio_params() for _, button_name_value in pairs( radio_button_names ) do + local radio_params = reset_radio_params() radio_params.buttonPressMode = "SHORT" radio_params.buttonName = button_name_value runner.Title("Test - ButtonPress with buttonName " .. button_name_value) @@ -103,8 +103,8 @@ for _, button_name_value in pairs( radio_button_names ) do end --[[ Negative Scenario - invalid value of buttonName in mobile request]] -climate_params = reset_climate_params() -radio_params = reset_radio_params() +local climate_params = reset_climate_params() +local radio_params = reset_radio_params() climate_params.buttonName = "invalid_name" radio_params.buttonName = "invalid_name" runner.Title("Test - negative, invalid value of buttonName in mobile request") From 140fb1d94e9d2638eee93dfe299ecad3ca9f3474 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Wed, 2 Aug 2017 08:54:07 +0300 Subject: [PATCH 086/681] Added tests for enable or disable RC functionality from HMI --- .../008_Allowed_false.lua | 85 +++++++++++++ ...009_Allowed_true_accessMode_AUTO_ALLOW.lua | 54 +++++++++ .../010_Allowed_true_accessMode_AUTO_DENY.lua | 54 +++++++++ ...011_Allowed_true_accessMode_ASK_DRIVER.lua | 54 +++++++++ .../012_Default_accessMode.lua | 46 +++++++ .../013_sequence_switches_of_accessMode.lua | 114 ++++++++++++++++++ 6 files changed, 407 insertions(+) create mode 100644 test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua create mode 100644 test_scripts/RC/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua create mode 100644 test_scripts/RC/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua create mode 100644 test_scripts/RC/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua create mode 100644 test_scripts/RC/OnRemoteControlSettings/012_Default_accessMode.lua create mode 100644 test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua b/test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua new file mode 100644 index 0000000000..7694ddaafb --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua @@ -0,0 +1,85 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- SDL received OnRemoteControlSettings (allowed:false) from HMI +-- +-- SDL must: +-- 1) store RC state allowed:false internally +-- 2) assign HMILevel none to all registered applications with appHMIType REMOTE_CONTROL and send OnHMIStatus (NONE) to such apps +-- 3) keep all applications with appHMIType REMOTE_CONTROL registered +-- 4) unsubscribe all REMOTE_CONTROL applications from OnInteriorVehicleData notifications for all HMI modules internally +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +local rcRpcs = {"GetInteriorVehicleData", "SetInteriorVehicleData", "ButtonPress"} + +--[[ Local Functions ]] + +local function ptu_update_func(tbl) + local notRcAppConfig = { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + groups = { "Base-4" }, + groups_primaryRC = { "Base-4"}, + AppHMIType = { "NAVIGATION" } + } + + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application3.registerAppInterfaceParams.appID] = notRcAppConfig +end + +local function disableRcFromHmi(self) + local mobileSession1 = commonRC.getMobileSession(self, 1) + local mobileSession2 = commonRC.getMobileSession(self, 2) + local mobileSession3 = commonRC.getMobileSession(self, 3) + + commonRC.defineRAMode(false, nil, self) + + mobileSession1:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE"}) -- REMOTE_CONTROL app + mobileSession2:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE"}) -- REMOTE_CONTROL app + mobileSession3:ExpectNotification("OnHMIStatus"):Times(0) -- NAVIGATION app + + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("Subscribe App2 on CLIMATE module", commonRC.subscribeToModule, { "CLIMATE", 2 }) +runner.Step("Subscribe App1 on RADIO module", commonRC.subscribeToModule, { "RADIO", 1 }) +runner.Step("RAI3", commonRC.rai_n, { 3 }) +runner.Step("Activate App3", commonRC.activate_app, { 3 }) + +runner.Title("Test") +runner.Step("Disable RC from HMI", disableRcFromHmi) + +for _, mod in pairs(modules) do + -- Apps are not subscribed from RC modules + runner.Step("Check App1 is not subscribed on " .. mod, commonRC.isUnsubscribed, { mod, 1 }) + runner.Step("Check App2 is not subscribed on " .. mod, commonRC.isUnsubscribed, { mod, 2 }) + -- All RC RPCs denied + for _, rpc in pairs(rcRpcs) do + runner.Step("Check module " .. mod .." App1 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 1, rpc, "DISALLOWED" }) + runner.Step("Check module " .. mod .." App2 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 2, rpc, "DISALLOWED" }) + end + +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua b/test_scripts/RC/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua new file mode 100644 index 0000000000..ce517365c7 --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua @@ -0,0 +1,54 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- RC_functionality is disabled on HMI and HMI sends notification OnRemoteControlSettings (allowed:true, ) +-- +-- SDL must: +-- 1) store RC state allowed:true and received from HMI internally +-- 2) allow RC functionality for applications with REMOTE_CONTROL appHMIType +-- +-- Case: accessMode = "AUTO_ALLOW" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +local rcRpcs = { "SetInteriorVehicleData", "ButtonPress" } + +--[[ Local Functions ]] + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +local function disableRcFromHmi(self) + commonRC.defineRAMode(false, nil, self) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Disable RC from HMI", disableRcFromHmi) + +runner.Title("Test") +runner.Step("Enable RC from HMI with AUTO_ALLOW access mode", commonRC.defineRAMode, { true, "AUTO_ALLOW"}) +for _, mod in pairs(modules) do + for _, rpc in pairs(rcRpcs) do + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Check module " .. mod .." App1 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 1, rpc }) + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Check module " .. mod .." App2 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 2, rpc }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua b/test_scripts/RC/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua new file mode 100644 index 0000000000..3b9e808f31 --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua @@ -0,0 +1,54 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- RC_functionality is disabled on HMI and HMI sends notification OnRemoteControlSettings (allowed:true, ) +-- +-- SDL must: +-- 1) store RC state allowed:true and received from HMI internally +-- 2) allow RC functionality for applications with REMOTE_CONTROL appHMIType +-- +-- Case: accessMode = "AUTO_DENY" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +local rcRpcs = {"SetInteriorVehicleData", "ButtonPress"} + +--[[ Local Functions ]] + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +local function disableRcFromHmi(self) + commonRC.defineRAMode(false, nil, self) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Disable RC from HMI", disableRcFromHmi) + +runner.Title("Test") +runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) +for _, mod in pairs(modules) do + for _, rpc in pairs(rcRpcs) do + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Check module " .. mod .." App1 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 1, rpc }) + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Check module " .. mod .." App2 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 2, rpc, "IN_USE" }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua b/test_scripts/RC/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua new file mode 100644 index 0000000000..747626d24e --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua @@ -0,0 +1,54 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- RC_functionality is disabled on HMI and HMI sends notification OnRemoteControlSettings (allowed:true, ) +-- +-- SDL must: +-- 1) store RC state allowed:true and received from HMI internally +-- 2) allow RC functionality for applications with REMOTE_CONTROL appHMIType +-- +-- Case: accessMode = "ASK_DRIVER" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +local function disableRcFromHmi(self) + commonRC.defineRAMode(false, nil, self) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Disable RC from HMI", disableRcFromHmi) + +runner.Title("Test") +runner.Step("Enable RC from HMI with ASK_DRIVER access mode", commonRC.defineRAMode, { true, "ASK_DRIVER"}) +for _, mod in pairs(modules) do + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Check module " .. mod .." App1 SetInteriorVehicleData allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 1, "SetInteriorVehicleData" }) + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Check module " .. mod .." App1 ButtonPress allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 2, "ButtonPress" }) + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Check module " .. mod .." App1 ButtonPress allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 1, "ButtonPress" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/012_Default_accessMode.lua b/test_scripts/RC/OnRemoteControlSettings/012_Default_accessMode.lua new file mode 100644 index 0000000000..a9a561a042 --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/012_Default_accessMode.lua @@ -0,0 +1,46 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- HMI didn't send OnRemoteControlSettings notifications on systems start +-- +-- SDL must: +-- use default value allowed:true and accessMode = "AUTO_ALLOW" for all registered REMOTE_CONTROL applications +-- until OnRemoteControlSettings notification with other settings is received +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +local rcRpcs = { "SetInteriorVehicleData", "ButtonPress" } + +--[[ Local Functions ]] + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("RAI2", commonRC.rai_n, { 2 }) + +runner.Title("Test") +for _, mod in pairs(modules) do + for _, rpc in pairs(rcRpcs) do + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Check module " .. mod .." App2 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 2, rpc }) + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Check module " .. mod .." App1 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 1, rpc }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua b/test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua new file mode 100644 index 0000000000..102c8dee4b --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua @@ -0,0 +1,114 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- RC_functionality is disabled on HMI and HMI sends notification OnRemoteControlSettings (allowed:true, ) +-- +-- SDL must: +-- 1) store RC state allowed:true and received from HMI internally +-- 2) allow RC functionality for applications with REMOTE_CONTROL appHMIType +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +local rcRpcs = { "SetInteriorVehicleData", "ButtonPress" } + +--[[ Local Functions ]] + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("RAI2", commonRC.rai_n, { 2 }) + +runner.Title("Test") +runner.Title("Default -> ASK_DRIVER") +runner.Step("Enable RC from HMI with ASK_DRIVER access mode", commonRC.defineRAMode, { true, "ASK_DRIVER"}) +for _, mod in pairs(modules) do + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Check module " .. mod .." App1 SetInteriorVehicleData allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 1, "SetInteriorVehicleData" }) + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Check module " .. mod .." App1 ButtonPress allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 2, "ButtonPress" }) + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Check module " .. mod .." App1 ButtonPress allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 1, "ButtonPress" }) +end +runner.Title("ASK_DRIVER -> AUTO_ALLOW") +runner.Step("Enable RC from HMI with AUTO_ALLOW access mode", commonRC.defineRAMode, { true, "AUTO_ALLOW"}) +for _, mod in pairs(modules) do + for _, rpc in pairs(rcRpcs) do + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Check module " .. mod .." App2 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 2, rpc }) + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Check module " .. mod .." App1 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 1, rpc }) + end +end +runner.Title("AUTO_ALLOW -> AUTO_DENY") +runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) +for _, mod in pairs(modules) do + for _, rpc in pairs(rcRpcs) do + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Check module " .. mod .." App2 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 2, rpc, "IN_USE" }) + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Check module " .. mod .." App1 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 1, rpc }) + end +end +runner.Title("AUTO_DENY -> ASK_DRIVER") +runner.Step("Enable RC from HMI with ASK_DRIVER access mode", commonRC.defineRAMode, { true, "ASK_DRIVER"}) +for _, mod in pairs(modules) do + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Check module " .. mod .." App1 SetInteriorVehicleData allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 1, "SetInteriorVehicleData" }) + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Check module " .. mod .." App1 ButtonPress allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 2, "ButtonPress" }) + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Check module " .. mod .." App1 ButtonPress allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 1, "ButtonPress" }) +end +runner.Title("ASK_DRIVER -> AUTO_DENY") +runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) +for _, mod in pairs(modules) do + for _, rpc in pairs(rcRpcs) do + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Check module " .. mod .." App2 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 2, rpc, "IN_USE" }) + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Check module " .. mod .." App1 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 1, rpc }) + end +end +runner.Title("AUTO_DENY -> AUTO_ALLOW") +runner.Step("Enable RC from HMI with AUTO_ALLOW access mode", commonRC.defineRAMode, { true, "AUTO_ALLOW"}) +for _, mod in pairs(modules) do + for _, rpc in pairs(rcRpcs) do + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Check module " .. mod .." App2 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 2, rpc }) + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Check module " .. mod .." App1 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 1, rpc }) + end +end +runner.Title("AUTO_ALLOW -> ASK_DRIVER") +runner.Step("Enable RC from HMI with ASK_DRIVER access mode", commonRC.defineRAMode, { true, "ASK_DRIVER"}) +for _, mod in pairs(modules) do + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Check module " .. mod .." App1 SetInteriorVehicleData allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 1, "SetInteriorVehicleData" }) + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Check module " .. mod .." App1 ButtonPress allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 2, "ButtonPress" }) + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Check module " .. mod .." App1 ButtonPress allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 1, "ButtonPress" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) From d7a2ebc94707e45da5d670062f17f9e728fa28cf Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Wed, 2 Aug 2017 16:11:46 +0300 Subject: [PATCH 087/681] Added test suite for OnRemoteControlSettings --- test_sets/rc_OnRemoteControlSettings.txt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 test_sets/rc_OnRemoteControlSettings.txt diff --git a/test_sets/rc_OnRemoteControlSettings.txt b/test_sets/rc_OnRemoteControlSettings.txt new file mode 100644 index 0000000000..a37b71813e --- /dev/null +++ b/test_sets/rc_OnRemoteControlSettings.txt @@ -0,0 +1,6 @@ +./test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua +./test_scripts/RC/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua +./test_scripts/RC/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua +./test_scripts/RC/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua +./test_scripts/RC/OnRemoteControlSettings/012_Default_accessMode.lua +./test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua From b1a778e67399f55d9f8850c27cc959055ecf80db Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Thu, 3 Aug 2017 01:13:50 +0300 Subject: [PATCH 088/681] Resource Allocation: Common module --- test_scripts/RC/commonRC.lua | 334 +++++++++++++++++++++++++++-------- 1 file changed, 256 insertions(+), 78 deletions(-) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index d53f067c56..2a56baa6f3 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -17,8 +17,12 @@ local json = require("modules/json") --[[ Local Variables ]] local ptu_table = {} +local hmiAppIds = {} + +local commonRC = {} + +commonRC.timeout = 2000 ---[[ Local Functions ]] local function initHMI(self) local exp_waiter = commonFunctions:createMultipleExpectationsWaiter(self, "HMI initialization") local function registerComponent(name, subscriptions) @@ -80,8 +84,8 @@ local function getPTUFromPTS(tbl) tbl.policy_table.module_config.preloaded_date = nil end -local function updatePTU(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = { +function commonRC.getRCAppConfig() + return { keep_context = false, steal_focus = false, priority = "NONE", @@ -91,6 +95,10 @@ local function updatePTU(tbl) groups_primaryRC = { "Base-4", "RemoteControl" }, AppHMIType = { "REMOTE_CONTROL" } } +end + +local function updatePTU(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() tbl.policy_table.functional_groupings["RemoteControl"].rpcs.OnInteriorVehicleData = { hmi_levels = { "BACKGROUND", "FULL", "LIMITED", "NONE" } } @@ -145,12 +153,6 @@ local function ptu(self, ptu_update_func) os.remove(ptu_file_name) end ---[[ Module Functions ]] - -local commonRC = {} - -commonRC.timeout = 2000 - function commonRC.preconditions() commonFunctions:SDLForceStop() commonSteps:DeletePolicyTable() @@ -187,7 +189,7 @@ function commonRC.rai_ptu(ptu_update_func, self) local corId = self.mobileSession:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config.application1.registerAppInterfaceParams.appName } }) :Do(function(_, d1) - self.applications[config.application1.registerAppInterfaceParams.appID] = d1.params.application.appID + hmiAppIds[config.application1.registerAppInterfaceParams.appID] = d1.params.application.appID EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) :Times(3) EXPECT_HMICALL("BasicCommunication.PolicyUpdate") @@ -212,7 +214,7 @@ function commonRC.rai_n(id, self) local corId = self["mobileSession" .. id]:SendRPC("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) :Do(function(_, d1) - self.applications[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID end) self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() @@ -226,11 +228,11 @@ end function commonRC.activate_app(pAppId, self) self, pAppId = commonRC.getSelfAndParams(pAppId, self) - local pHMIAppId = self.applications["Test Application"] + local pHMIAppId = hmiAppIds[config.application1.registerAppInterfaceParams.appID] local mobSession = self["mobileSession"] if pAppId and pAppId > 1 then mobSession = self["mobileSession" .. pAppId] - pHMIAppId = self.applications[config["application" .. pAppId].registerAppInterfaceParams.appID] + pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] end local requestId1 = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) EXPECT_HMIRESPONSE(requestId1) @@ -256,6 +258,13 @@ function commonRC.postconditions() StopSDL() end +function commonRC.getSelfAndParams(param, self) + if not self then + return param, nil + end + return self, param +end + function commonRC.getModuleControlData(module_type) local out = { moduleType = module_type } if module_type == "CLIMATE" then @@ -350,71 +359,6 @@ function commonRC.getAnotherModuleControlData(module_type) return out end -function commonRC.getSelfAndParams(param, self) - if not self then - return param, nil - end - return self, param -end - -function commonRC.getMobileSession(self, id) - if id == 2 then - return self.mobileSession2 - end - return self.mobileSession -end - -local function subscriptionToModule(pModuleType, pSubscribe, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType, - subscribe = pSubscribe - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleType = pModuleType, - subscribe = pSubscribe - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlData(pModuleType), - isSubscribed = pSubscribe - }) - end) - - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", - moduleData = commonRC.getModuleControlData(pModuleType), - isSubscribed = pSubscribe - }) -end - -function commonRC.subscribeToModule(pModuleType, self) - subscriptionToModule(pModuleType, true, self) -end - -function commonRC.unSubscribeToModule(pModuleType, self) - subscriptionToModule(pModuleType, false, self) -end - -function commonRC.isSubscribed(pModuleType, self) - self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { - moduleData = commonRC.getAnotherModuleControlData(pModuleType) - }) - - EXPECT_NOTIFICATION("OnInteriorVehicleData", { - moduleData = commonRC.getAnotherModuleControlData(pModuleType) - }) -end - -function commonRC.isUnsubscribed(pModuleType, self) - self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { - moduleData = commonRC.getAnotherModuleControlData(pModuleType) - }) - - EXPECT_NOTIFICATION("OnInteriorVehicleData", {}):Times(0) - commonTestCases:DelayedExp(commonRC.timeout) -end - function commonRC.getButtonNameByModule(pModuleType) if pModuleType == "CLIMATE" then return "FAN_UP" @@ -476,4 +420,238 @@ function commonRC.getSettableModuleControlData(pModuleType) return out end +-- RC RPCs structure +local rcRPCs = { + GetInteriorVehicleData = { + appEventName = "GetInteriorVehicleData", + hmiEventName = "RC.GetInteriorVehicleData", + requestParams = function(pModuleType, pSubscribe) + return { + moduleType = pModuleType, + subscribe = pSubscribe + } + end, + hmiRequestParams = function(pModuleType, pAppId, pSubscribe, self) + return { + appID = commonRC.getHMIAppId(self, pAppId), + moduleType = pModuleType, + subscribe = pSubscribe + } + end, + hmiResponseParams = function(pModuleType, pSubscribe) + return { + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = pSubscribe + } + end, + responseParams = function(success, resultCode, pModuleType, pSubscribe) + return { + success = success, + resultCode = resultCode, + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = pSubscribe + } + end + }, + SetInteriorVehicleData = { + appEventName = "SetInteriorVehicleData", + hmiEventName = "RC.SetInteriorVehicleData", + requestParams = function(pModuleType) + return { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + } + end, + hmiRequestParams = function(pModuleType, pAppId, self) + return { + appID = commonRC.getHMIAppId(self, pAppId), + moduleData = commonRC.getSettableModuleControlData(pModuleType) + } + end, + hmiResponseParams = function(pModuleType) + return { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + } + end + }, + ButtonPress = { + appEventName = "ButtonPress", + hmiEventName = "Buttons.ButtonPress", + requestParams = function(pModuleType) + return { + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + } + end, + hmiRequestParams = function(pModuleType, pAppId, self) + return { + appID = commonRC.getHMIAppId(self, pAppId), + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + } + end, + hmiResponseParams = function() + return {} + end + }, + GetInteriorVehicleDataConsent = { + hmiEventName = "RC.GetInteriorVehicleDataConsent", + hmiRequestParams = function(pModuleType, pAppId, self) + return { + appID = commonRC.getHMIAppId(self, pAppId), + moduleType = pModuleType + } + end, + hmiResponseParams = function(pAllowed) + return { + allowed = pAllowed + } + end, + }, + OnInteriorVehicleData = { + appEventName = "OnInteriorVehicleData", + hmiEventName = "RC.OnInteriorVehicleData", + hmiResponseParams = function(pModuleType) + return { + moduleData = commonRC.getAnotherModuleControlData(pModuleType) + } + end, + responseParams = function(pModuleType) + return { + moduleData = commonRC.getAnotherModuleControlData(pModuleType) + } + end + }, + OnRemoteControlSettings = { + hmiEventName = "RC.OnRemoteControlSettings", + hmiResponseParams = function(pAllowed, pAccessMode) + return { + allowed = pAllowed, + accessMode = pAccessMode + } + end + } +} + +function commonRC.getAppEventName(pRPC) + return rcRPCs[pRPC].appEventName +end + +function commonRC.getHMIEventName(pRPC) + return rcRPCs[pRPC].hmiEventName +end + +function commonRC.getAppRequestParams(pRPC, ...) + return rcRPCs[pRPC].requestParams(...) +end + +function commonRC.getAppResponseParams(pRPC, ...) + return rcRPCs[pRPC].responseParams(...) +end + +function commonRC.getHMIRequestParams(pRPC, ...) + return rcRPCs[pRPC].hmiRequestParams(...) +end + +function commonRC.getHMIResponseParams(pRPC, ...) + return rcRPCs[pRPC].hmiResponseParams(...) +end + +function commonRC.subscribeToModule(pModuleType, pAppId, self) + self, pAppId = commonRC.getSelfAndParams(pAppId, self) + local rpc = "GetInteriorVehicleData" + local subscribe = true + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(rpc), commonRC.getAppRequestParams(rpc, pModuleType, subscribe)) + EXPECT_HMICALL(commonRC.getHMIEventName(rpc), commonRC.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe, self)) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(rpc, pModuleType, subscribe)) + end) + mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) +end + +function commonRC.unSubscribeToModule(pModuleType, pAppId, self) + self, pAppId = commonRC.getSelfAndParams(pAppId, self) + local rpc = "GetInteriorVehicleData" + local subscribe = false + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(rpc), commonRC.getAppRequestParams(rpc, pModuleType, subscribe)) + EXPECT_HMICALL(commonRC.getHMIEventName(rpc), commonRC.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe, self)) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(rpc, pModuleType, subscribe)) + end) + mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) +end + +function commonRC.isSubscribed(pModuleType, pAppId, self) + self, pAppId = commonRC.getSelfAndParams(pAppId, self) + local mobSession = commonRC.getMobileSession(self, pAppId) + local rpc = "OnInteriorVehicleData" + self.hmiConnection:SendNotification(commonRC.getHMIEventName(rpc), commonRC.getHMIResponseParams(rpc, pModuleType)) + mobSession:ExpectNotification(commonRC.getAppEventName(rpc), commonRC.getAppResponseParams(rpc, pModuleType)) +end + +function commonRC.isUnsubscribed(pModuleType, pAppId, self) + self, pAppId = commonRC.getSelfAndParams(pAppId, self) + local mobSession = commonRC.getMobileSession(self, pAppId) + local rpc = "OnInteriorVehicleData" + self.hmiConnection:SendNotification(commonRC.getHMIEventName(rpc), commonRC.getHMIResponseParams(rpc, pModuleType)) + mobSession:ExpectNotification(commonRC.getAppEventName(rpc), {}):Times(0) + commonTestCases:DelayedExp(commonRC.timeout) +end + +function commonRC.getHMIAppId(self, pAppId) + if not pAppId then + pAppId = 1 + end + return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] +end + +function commonRC.getMobileSession(self, pAppId) + if pAppId and pAppId > 1 then + return self["mobileSession" .. pAppId] + end + return self["mobileSession"] +end + +function commonRC.defineRAMode(pAllowed, pAccessMode, self) + self, pAccessMode = commonRC.getSelfAndParams(pAccessMode, self) + local rpc = "OnRemoteControlSettings" + self.hmiConnection:SendNotification(commonRC.getHMIEventName(rpc), commonRC.getHMIResponseParams(rpc, pAllowed, pAccessMode)) +end + +function commonRC.rpcDenied(pModuleType, pAppId, pRPC, pResultCode, self) + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = pResultCode }) + commonTestCases:DelayedExp(commonRC.timeout) +end + +function commonRC.rpcAllowed(pModuleType, pAppId, pRPC, self) + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId, self)) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +function commonRC.rpcAllowedWithConsent(pModuleType, pAppId, pRPC, self) + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + local consentRPC = "GetInteriorVehicleDataConsent" + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(consentRPC, true)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId, self)) + :Do(function(_, data2) + self.hmiConnection:SendResponse(data2.id, data2.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) + end) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + return commonRC From cbf057ca9c7ec26a900b3219b389a60f5f9b13c1 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Thu, 3 Aug 2017 01:24:12 +0300 Subject: [PATCH 089/681] GetInteriorVehicleDataConsent: Initial version of the scripts --- .../001_Consent_true_SIVD.lua | 45 ++++++++++++ .../002_Consent_true_BP.lua | 45 ++++++++++++ .../003_Consent_false_SIVD.lua | 70 +++++++++++++++++++ .../004_Consent_false_BP.lua | 70 +++++++++++++++++++ .../005_TIMED_OUT_from_HMI_SIVD.lua | 60 ++++++++++++++++ .../006_TIMED_OUT_from_HMI_BP.lua | 60 ++++++++++++++++ .../007_HMI_no_response_SIVD.lua | 59 ++++++++++++++++ .../008_HMI_no_response_BP.lua | 59 ++++++++++++++++ .../009_HMI_invalid_response_SIVD.lua | 61 ++++++++++++++++ .../010_HMI_invalid_response_BP.lua | 61 ++++++++++++++++ .../rc_GetInteriorVehicleDataConsent.txt | 10 +++ 11 files changed, 600 insertions(+) create mode 100644 test_scripts/RC/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua create mode 100644 test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua create mode 100644 test_sets/rc_GetInteriorVehicleDataConsent.txt diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua new file mode 100644 index 0000000000..939d5e53e8 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #1 +-- In case: +-- +-- SDL must: +-- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: allowed:true + runner.Step("App2 ButtonPress 1st SUCCESS", commonRC.rpcAllowedWithConsent, { mod, 2, "ButtonPress" }) + runner.Step("App2 ButtonPress 2nd SUCCESS", commonRC.rpcAllowed, { mod, 2, "ButtonPress" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua new file mode 100644 index 0000000000..cfab0e286d --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #1 +-- In case: +-- +-- SDL must: +-- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 ButtonPress", commonRC.rpcAllowed, { mod, 1, "ButtonPress" }) + -- set control for App2 --> Ask driver --> HMI: allowed:true + runner.Step("App2 SetInteriorVehicleData 1st SUCCESS", commonRC.rpcAllowedWithConsent, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 SetInteriorVehicleData 2nd SUCCESS", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua new file mode 100644 index 0000000000..8be7ac473f --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #4 +-- In case: +-- +-- SDL must: +-- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +local function rpcConsentFalse(pModuleType, pAppId, pRPC, self) + local info = "The resource is in use and the driver disallows this remote control RPC" + local consentRPC = "GetInteriorVehicleDataConsent" + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(consentRPC, false)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED", info = info }) + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function rpcConsentAbsent(pModuleType, pAppId, pRPC, self) + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName("GetInteriorVehicleDataConsent")):Times(0) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: allowed:false + runner.Step("App2 SetInteriorVehicleData 1st REJECTED", rpcConsentFalse, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 SetInteriorVehicleData 2nd REJECTED", rpcConsentAbsent, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 ButtonPress 2nd REJECTED", rpcConsentAbsent, { mod, 2, "ButtonPress" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua new file mode 100644 index 0000000000..5cc84b2e71 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #4 +-- In case: +-- +-- SDL must: +-- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +local function rpcConsentFalse(pModuleType, pAppId, pRPC, self) + local info = "The resource is in use and the driver disallows this remote control RPC" + local consentRPC = "GetInteriorVehicleDataConsent" + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(consentRPC, false)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED", info = info }) + commonTestCases:DelayedExp(commonRC.timeout) +end + +local function rpcConsentAbsent(pModuleType, pAppId, pRPC, self) + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName("GetInteriorVehicleDataConsent")):Times(0) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: allowed:false + runner.Step("App2 ButtonPress 1st REJECTED", rpcConsentFalse, { mod, 2, "ButtonPress" }) + runner.Step("App2 ButtonPress 2nd REJECTED", rpcConsentAbsent, { mod, 2, "ButtonPress" }) + runner.Step("App2 SetInteriorVehicleData 2nd REJECTED", rpcConsentAbsent, { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua new file mode 100644 index 0000000000..2724e5d308 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua @@ -0,0 +1,60 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #2 +-- In case: +-- +-- SDL must: +-- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +local function rpcTimedOutHMIResponse(pModuleType, pAppId, pRPC, self) + local info = "The resource is in use and the driver did not respond in time" + local consentRPC = "GetInteriorVehicleDataConsent" + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + :Do(function(_, data) + self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", info) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "TIMED_OUT", info = info }) + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: TIMED_OUT + runner.Step("App2 SetInteriorVehicleData 1st TIMED_OUT", rpcTimedOutHMIResponse, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 SetInteriorVehicleData 2nd SUCCESS", commonRC.rpcAllowedWithConsent, { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua new file mode 100644 index 0000000000..e0cc942b97 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua @@ -0,0 +1,60 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #2 +-- In case: +-- +-- SDL must: +-- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +local function rpcTimedOutHMIResponse(pModuleType, pAppId, pRPC, self) + local info = "The resource is in use and the driver did not respond in time" + local consentRPC = "GetInteriorVehicleDataConsent" + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + :Do(function(_, data) + self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", info) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "TIMED_OUT", info = info }) + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: TIMED_OUT + runner.Step("App2 ButtonPress 1st TIMED_OUT", rpcTimedOutHMIResponse, { mod, 2, "ButtonPress" }) + runner.Step("App2 ButtonPress 2nd SUCCESS", commonRC.rpcAllowedWithConsent, { mod, 2, "ButtonPress" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua new file mode 100644 index 0000000000..f0a73df3c0 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua @@ -0,0 +1,59 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #3 +-- In case: +-- +-- SDL must: +-- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +local function rpcNoHMIResponse(pModuleType, pAppId, pRPC, self) + local consentRPC = "GetInteriorVehicleDataConsent" + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + :Do(function(_, _) + -- HMI does not respond + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) + commonTestCases:DelayedExp(11000) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: doesn't respond + runner.Step("App2 SetInteriorVehicleData 1st GENERIC_ERROR", rpcNoHMIResponse, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 SetInteriorVehicleData 2nd SUCCESS", commonRC.rpcAllowedWithConsent, { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua new file mode 100644 index 0000000000..3463a57b4a --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua @@ -0,0 +1,59 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #3 +-- In case: +-- +-- SDL must: +-- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +local function rpcNoHMIResponse(pModuleType, pAppId, pRPC, self) + local consentRPC = "GetInteriorVehicleDataConsent" + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + :Do(function(_, _) + -- HMI does not respond + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) + commonTestCases:DelayedExp(11000) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: doesn't respond + runner.Step("App2 ButtonPress 1st GENERIC_ERROR", rpcNoHMIResponse, { mod, 2, "ButtonPress" }) + runner.Step("App2 ButtonPress 2nd SUCCESS", commonRC.rpcAllowedWithConsent, { mod, 2, "ButtonPress" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua new file mode 100644 index 0000000000..1168b793fa --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #3 +-- In case: +-- +-- SDL must: +-- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +local function rpcInvalidHMIResponse(pModuleType, pAppId, pRPC, self) + local consentRPC = "GetInteriorVehicleDataConsent" + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + allowed = "aaa" -- invalid type of parameter + }) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: response with invalid data + runner.Step("App2 SetInteriorVehicleData 1st GENERIC_ERROR", rpcInvalidHMIResponse, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 SetInteriorVehicleData 2nd SUCCESS", commonRC.rpcAllowedWithConsent, { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua new file mode 100644 index 0000000000..c8dd1fb677 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #3 +-- In case: +-- +-- SDL must: +-- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +local function rpcInvalidHMIResponse(pModuleType, pAppId, pRPC, self) + local consentRPC = "GetInteriorVehicleDataConsent" + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + allowed = "aaa" -- invalid type of parameter + }) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: response with invalid data + runner.Step("App2 ButtonPress 1st GENERIC_ERROR", rpcInvalidHMIResponse, { mod, 2, "ButtonPress" }) + runner.Step("App2 ButtonPress 2nd SUCCESS", commonRC.rpcAllowedWithConsent, { mod, 2, "ButtonPress" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_GetInteriorVehicleDataConsent.txt b/test_sets/rc_GetInteriorVehicleDataConsent.txt new file mode 100644 index 0000000000..a38f11c217 --- /dev/null +++ b/test_sets/rc_GetInteriorVehicleDataConsent.txt @@ -0,0 +1,10 @@ +./test_scripts/RC/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua +./test_scripts/RC/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua +./test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua +./test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua +./test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua +./test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua +./test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua +./test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua +./test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua +./test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua From c284d0d10b10f2e930162fda3a0ff159d27d1cd2 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Wed, 2 Aug 2017 15:21:04 +0300 Subject: [PATCH 090/681] Added tests for cases incorrect or absent response from HMI --- ...ric_error_if_invalid_response_from_hmi.lua | 53 +++++++++++++ ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 52 +++++++++++++ ..._in_case_HMI_respond_with_invalid_data.lua | 75 +++++++++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua create mode 100644 test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua create mode 100644 test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua diff --git a/test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua b/test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua new file mode 100644 index 0000000000..a1750f6f4b --- /dev/null +++ b/test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua @@ -0,0 +1,53 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Button press event emulation +-- +-- Description: +-- In case: +-- 1) RC app sends ButtonPress request with valid parameters +-- 2) and HMI response is invalid +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, self) + local cid = self.mobileSession:SendRPC("ButtonPress", { + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + + EXPECT_HMICALL("Buttons.ButtonPress", { + appID = self.applications["Test Application"], + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + :Do(function(_, _) + self.hmiConnection:Send('{"jsonrpc";"2.0","result":{"cod":0,"method":"Buttons.ButtonPress"},"id":32}') + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("ButtonPress " .. mod, getDataForModule, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua new file mode 100644 index 0000000000..c8cb021b4f --- /dev/null +++ b/test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -0,0 +1,52 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) RC app sends SetInteriorVehicleData request with valid parameters +-- 2) and HMI didn't respond within default timeout +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function setVehicleData(pModuleType, self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, _) + -- HMI does not respond + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + + commonTestCases:DelayedExp(11000) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod .. " HMI does not respond", setVehicleData, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua new file mode 100644 index 0000000000..c0dc604ac3 --- /dev/null +++ b/test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -0,0 +1,75 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) RC app sends SetInteriorVehicleData request with valid parameters +-- 2) and HMI response is invalid +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function invalidParamType(pModuleType, self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, data) + local modData = commonRC.getSettableModuleControlData(pModuleType) + modData.moduleType = "MODULE" -- invalid value of parameter + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = modData, + isSubscribed = "yes" -- fake parameter + }) + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +local function missingMandatoryParam(pModuleType, self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, data) + local moduleData = commonRC.getModuleControlData(pModuleType) + moduleData.moduleType = nil -- missing mandatory parameter + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = moduleData + }) + end) + + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod .. " Invalid response from HMI-Invalid type of parameter", invalidParamType, { mod }) + runner.Step("SetInteriorVehicleData " .. mod .. " Invalid response from HMI-Missing mandatory parameter", missingMandatoryParam, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) From d9b11429e11a1c74c14299f624223d0d4c997c15 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Thu, 3 Aug 2017 06:47:44 +0300 Subject: [PATCH 091/681] Added tests to testsets --- test_sets/rc_ButtonPress.txt | 1 + test_sets/rc_SetInteriorVehicleData.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/test_sets/rc_ButtonPress.txt b/test_sets/rc_ButtonPress.txt index 0095372caa..8648056b55 100644 --- a/test_sets/rc_ButtonPress.txt +++ b/test_sets/rc_ButtonPress.txt @@ -9,3 +9,4 @@ ./test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua ./test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua ./test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua +./test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua diff --git a/test_sets/rc_SetInteriorVehicleData.txt b/test_sets/rc_SetInteriorVehicleData.txt index 62d271ccb6..31bc143cd2 100644 --- a/test_sets/rc_SetInteriorVehicleData.txt +++ b/test_sets/rc_SetInteriorVehicleData.txt @@ -10,3 +10,5 @@ ./test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua ./test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua ./test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua +./test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua From 235aa72cc98eaca6f0b12942955b2255225c5f86 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Thu, 3 Aug 2017 10:11:24 +0300 Subject: [PATCH 092/681] Comment unclarified requirements checks --- .../RC/OnRemoteControlSettings/008_Allowed_false.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua b/test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua index 7694ddaafb..22341361d1 100644 --- a/test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua +++ b/test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua @@ -73,11 +73,11 @@ for _, mod in pairs(modules) do -- Apps are not subscribed from RC modules runner.Step("Check App1 is not subscribed on " .. mod, commonRC.isUnsubscribed, { mod, 1 }) runner.Step("Check App2 is not subscribed on " .. mod, commonRC.isUnsubscribed, { mod, 2 }) - -- All RC RPCs denied - for _, rpc in pairs(rcRpcs) do - runner.Step("Check module " .. mod .." App1 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 1, rpc, "DISALLOWED" }) - runner.Step("Check module " .. mod .." App2 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 2, rpc, "DISALLOWED" }) - end + -- -- All RC RPCs denied - need clarification + -- for _, rpc in pairs(rcRpcs) do + -- runner.Step("Check module " .. mod .." App1 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 1, rpc, "DISALLOWED" }) + -- runner.Step("Check module " .. mod .." App2 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 2, rpc, "DISALLOWED" }) + -- end end From e0c05c8b66ae394b2ccdaeca434bf8e6f1b6b7c1 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Thu, 3 Aug 2017 11:27:33 +0300 Subject: [PATCH 093/681] Updated description for 009 test --- .../013_sequence_switches_of_accessMode.lua | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua b/test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua index 102c8dee4b..91a8a0aac9 100644 --- a/test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua +++ b/test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua @@ -9,6 +9,15 @@ -- SDL must: -- 1) store RC state allowed:true and received from HMI internally -- 2) allow RC functionality for applications with REMOTE_CONTROL appHMIType +-- +-- Additional checks: +-- - Switch RA access mode Default -> ASK_DRIVER +-- - Switch RA access mode ASK_DRIVER -> AUTO_ALLOW +-- - Switch RA access mode AUTO_ALLOW -> AUTO_DENY +-- - Switch RA access mode AUTO_DENY -> ASK_DRIVER +-- - Switch RA access mode DASK_DRIVER -> AUTO_DENY +-- - Switch RA access mode AUTO_DENY -> AUTO_ALLOW +-- - Switch RA access mode AUTO_ALLOW -> ASK_DRIVER --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') From d384490a14010f4337acd8280b4081ccb0ac381e Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Thu, 3 Aug 2017 14:44:38 +0300 Subject: [PATCH 094/681] OnRemoteControlSettings: Initial version of the scripts --- .../001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua | 52 ++++++++ .../002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua | 52 ++++++++ .../003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua | 52 ++++++++ .../004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua | 52 ++++++++ ...005_REJECTED_in_case_nonFULL_HMI_level.lua | 55 +++++++++ .../006_IN_USE_in_case_2_requests.lua | 112 ++++++++++++++++++ .../007_IN_USE_in_case_AUTO_DENY.lua | 48 ++++++++ .../014_Invalid_data_from_HMI.lua | 72 +++++++++++ test_sets/rc_OnRemoteControlSettings.txt | 8 ++ 9 files changed, 503 insertions(+) create mode 100644 test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua create mode 100644 test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua create mode 100644 test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua create mode 100644 test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua create mode 100644 test_scripts/RC/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua create mode 100644 test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua create mode 100644 test_scripts/RC/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua create mode 100644 test_scripts/RC/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua b/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua new file mode 100644 index 0000000000..a78e68bde8 --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua @@ -0,0 +1,52 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #1 +-- In case: +-- +-- SDL must: +-- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local access_modes = { nil, "AUTO_ALLOW" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) + +-- App's HMI levels: 1 - BACKGROUND, 2 - FULL + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + for i = 1, #access_modes do + runner.Title("Access mode: " .. tostring(access_modes[i])) + -- set RA mode + runner.Step("Set RA mode", commonRC.defineRAMode, { true, access_modes[i] }) + -- set control for App2 --> Allowed + runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 ButtonPress", commonRC.rpcAllowed, { mod, 2, "ButtonPress" }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua b/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua new file mode 100644 index 0000000000..013586376b --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua @@ -0,0 +1,52 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #1 +-- In case: +-- +-- SDL must: +-- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local access_modes = { nil, "AUTO_ALLOW" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) + +-- App's HMI levels: 1 - BACKGROUND, 2 - FULL + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + for i = 1, #access_modes do + runner.Title("Access mode: " .. tostring(access_modes[i])) + -- set RA mode + runner.Step("Set RA mode", commonRC.defineRAMode, { true, access_modes[i] }) + -- set control for App2 --> Allowed + runner.Step("App2 ButtonPress", commonRC.rpcAllowed, { mod, 2, "ButtonPress" }) + runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua b/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua new file mode 100644 index 0000000000..2c0814456b --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua @@ -0,0 +1,52 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #1 +-- In case: +-- +-- SDL must: +-- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local access_modes = { nil, "AUTO_ALLOW" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) + +-- App's HMI levels: 1 - BACKGROUND, 2 - FULL + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 ButtonPress", commonRC.rpcAllowed, { mod, 1, "ButtonPress" }) + for i = 1, #access_modes do + runner.Title("Access mode: " .. tostring(access_modes[i])) + -- set RA mode + runner.Step("Set RA mode", commonRC.defineRAMode, { true, access_modes[i] }) + -- set control for App2 --> Allowed + runner.Step("App2 ButtonPress", commonRC.rpcAllowed, { mod, 2, "ButtonPress" }) + runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua b/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua new file mode 100644 index 0000000000..63d0a9ab14 --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua @@ -0,0 +1,52 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #1 +-- In case: +-- +-- SDL must: +-- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local access_modes = { nil, "AUTO_ALLOW" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) + +-- App's HMI levels: 1 - BACKGROUND, 2 - FULL + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 ButtonPress", commonRC.rpcAllowed, { mod, 1, "ButtonPress" }) + for i = 1, #access_modes do + runner.Title("Access mode: " .. tostring(access_modes[i])) + -- set RA mode + runner.Step("Set RA mode", commonRC.defineRAMode, { true, access_modes[i] }) + -- set control for App2 --> Allowed + runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 ButtonPress", commonRC.rpcAllowed, { mod, 2, "ButtonPress" }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua b/test_scripts/RC/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua new file mode 100644 index 0000000000..7a092c53ab --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #2 +-- In case: +-- +-- SDL must: +-- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local access_modes = { nil, "AUTO_ALLOW", "AUTO_DENY", "ASK_DRIVER" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) + +-- App's HMI levels: 1 - BACKGROUND, 2 - FULL + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App2 + runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + for i = 1, #access_modes do + runner.Title("Access mode: " .. tostring(access_modes[i])) + -- set RA mode + runner.Step("Set RA mode", commonRC.defineRAMode, { true, access_modes[i] }) + -- try to set control for App1 --> Denied + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcDenied, { mod, 1, "SetInteriorVehicleData", "REJECTED" }) + runner.Step("App1 ButtonPress", commonRC.rpcDenied, { mod, 1, "ButtonPress", "REJECTED" }) + -- try to set control for App2 --> Allowed + runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 ButtonPress", commonRC.rpcAllowed, { mod, 2, "ButtonPress" }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua b/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua new file mode 100644 index 0000000000..25eb4dd857 --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua @@ -0,0 +1,112 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #3 +-- In case: +-- +-- SDL must: +-- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local access_modes = { nil, "AUTO_ALLOW" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +local function step(pModuleType, pRPC1, pRPC2, self) + local cid1 + if pRPC1 == "SetInteriorVehicleData" then + cid1 = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, data) + local function hmiRespond() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + end + RUN_AFTER(hmiRespond, 2000) + end) + elseif pRPC1 == "ButtonPress" then + cid1 = self.mobileSession:SendRPC("ButtonPress", { + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + EXPECT_HMICALL("Buttons.ButtonPress", { + appID = commonRC.getHMIAppId(self, 1), + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + :Do(function(_, data) + local function hmiRespond() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + RUN_AFTER(hmiRespond, 2000) + end) + end + self.mobileSession:ExpectResponse(cid1, { success = true, resultCode = "SUCCESS" }) + + local req2_func = function() + local cid2 + if pRPC2 == "SetInteriorVehicleData" then + cid2 = self.mobileSession2:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + elseif pRPC2 == "ButtonPress" then + cid2 = self.mobileSession2:SendRPC("ButtonPress", { + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + end + self.mobileSession2:ExpectResponse(cid2, { success = false, resultCode = "IN_USE" }) + end + + RUN_AFTER(req2_func, 1000) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + for i = 1, #access_modes do + runner.Title("Access mode: " .. tostring(access_modes[i])) + -- set RA mode + runner.Step("Set RA mode", commonRC.defineRAMode, { true, access_modes[i] }) + -- try to set control for App2 while request for App1 is executing + local rpcs = { "SetInteriorVehicleData", "ButtonPress" } + for _, rpc1 in pairs(rpcs) do + for _, rpc2 in pairs(rpcs) do + runner.Step("App1 " .. rpc1 .. " App2 " .. rpc2, step, { mod, rpc1, rpc2 }) + end + end + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua b/test_scripts/RC/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua new file mode 100644 index 0000000000..ba4d150c30 --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #4 +-- In case: +-- +-- SDL must: +-- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: AUTO_DENY", commonRC.defineRAMode, { true, "AUTO_DENY" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Denied + runner.Step("App2 SetInteriorVehicleData", commonRC.rpcDenied, { mod, 2, "SetInteriorVehicleData", "IN_USE" }) + runner.Step("App2 ButtonPress", commonRC.rpcDenied, { mod, 2, "ButtonPress", "IN_USE" }) + -- set control for App1 --> Allowed + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + runner.Step("App1 ButtonPress", commonRC.rpcAllowed, { mod, 1, "ButtonPress" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua b/test_scripts/RC/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua new file mode 100644 index 0000000000..c1847058f7 --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua @@ -0,0 +1,72 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- 1) HMI sends OnRemoteControlSettings notification with invalid parameters +-- SDL must: +-- 1) Do not take into account this request +-- 2) Leave previously defined access mode +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +local function setRAMode(self) + local rpc = "OnRemoteControlSettings" + local params = { + allowed = "aaa" -- invalid type of parameter + } + self.hmiConnection:SendNotification(commonRC.getHMIEventName(rpc), params) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + + runner.Title("RA mode Default AUTO_ALLOW") + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Send OnRemoteControlSettings with invalid data", setRAMode) + runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + + runner.Title("RA mode AUTO_DENY") + runner.Step("Set RA mode", commonRC.defineRAMode, { true, "AUTO_DENY" }) + runner.Step("Activate App1", commonRC.activate_app, { 1 }) + runner.Step("Send OnRemoteControlSettings with invalid data", setRAMode) + runner.Step("App2 SetInteriorVehicleData", commonRC.rpcDenied, { mod, 1, "SetInteriorVehicleData", "IN_USE" }) + + runner.Title("RA mode ASK_DRIVER") + runner.Step("Set RA mode", commonRC.defineRAMode, { true, "ASK_DRIVER" }) + runner.Step("Send OnRemoteControlSettings with invalid data", setRAMode) + runner.Step("App2 ButtonPress 1st SUCCESS", commonRC.rpcAllowedWithConsent, { mod, 1, "SetInteriorVehicleData" }) + runner.Step("App2 ButtonPress 2nd SUCCESS", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + + runner.Title("RA mode AUTO_ALLOW") + runner.Step("Set RA mode", commonRC.defineRAMode, { true, "AUTO_ALLOW" }) + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Send OnRemoteControlSettings with invalid data", setRAMode) + runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("Activate App1", commonRC.activate_app, { 1 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_OnRemoteControlSettings.txt b/test_sets/rc_OnRemoteControlSettings.txt index a37b71813e..f1931e0caa 100644 --- a/test_sets/rc_OnRemoteControlSettings.txt +++ b/test_sets/rc_OnRemoteControlSettings.txt @@ -1,6 +1,14 @@ +./test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua +./test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua +./test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua +./test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua +./test_scripts/RC/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua +./test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua +./test_scripts/RC/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua ./test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua ./test_scripts/RC/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua ./test_scripts/RC/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua ./test_scripts/RC/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua ./test_scripts/RC/OnRemoteControlSettings/012_Default_accessMode.lua ./test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua +./test_scripts/RC/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua From 7ae5210b761f77ca12e35e974649ccc1226b7c34 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Thu, 3 Aug 2017 16:11:07 +0300 Subject: [PATCH 095/681] OnRemoteControlSettings: Update descriptions --- .../001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua | 8 ++++++-- .../002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua | 8 ++++++-- .../003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua | 8 ++++++-- .../004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua | 8 ++++++-- .../005_REJECTED_in_case_nonFULL_HMI_level.lua | 10 ++++++++-- .../006_IN_USE_in_case_2_requests.lua | 10 ++++++++-- .../007_IN_USE_in_case_AUTO_DENY.lua | 8 ++++++-- 7 files changed, 46 insertions(+), 14 deletions(-) diff --git a/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua b/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua index a78e68bde8..14c7264b33 100644 --- a/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua +++ b/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua @@ -4,9 +4,13 @@ -- -- Description: TRS: OnRemoteControlSettings, #1 -- In case: --- +-- 1) SDL received OnRemoteControlSettings notification from HMI with allowed:true +-- 2) and "accessMode" = "AUTO_ALLOW" or without "accessMode" parameter at all +-- 3) and RC_module on HMI is alreay in control by RC-application -- SDL must: --- +-- 1) provide access to RC_module for the second RC_application in HMILevel FULL after it sends control RPC +-- (either SetInteriorVehicleData or ButtonPress) for the same RC_module without asking a driver +-- 2) process the request from the second RC_application --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua b/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua index 013586376b..53f44b8816 100644 --- a/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua +++ b/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua @@ -4,9 +4,13 @@ -- -- Description: TRS: OnRemoteControlSettings, #1 -- In case: --- +-- 1) SDL received OnRemoteControlSettings notification from HMI with allowed:true +-- 2) and "accessMode" = "AUTO_ALLOW" or without "accessMode" parameter at all +-- 3) and RC_module on HMI is alreay in control by RC-application -- SDL must: --- +-- 1) provide access to RC_module for the second RC_application in HMILevel FULL after it sends control RPC +-- (either SetInteriorVehicleData or ButtonPress) for the same RC_module without asking a driver +-- 2) process the request from the second RC_application --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua b/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua index 2c0814456b..c68daa310a 100644 --- a/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua +++ b/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua @@ -4,9 +4,13 @@ -- -- Description: TRS: OnRemoteControlSettings, #1 -- In case: --- +-- 1) SDL received OnRemoteControlSettings notification from HMI with allowed:true +-- 2) and "accessMode" = "AUTO_ALLOW" or without "accessMode" parameter at all +-- 3) and RC_module on HMI is alreay in control by RC-application -- SDL must: --- +-- 1) provide access to RC_module for the second RC_application in HMILevel FULL after it sends control RPC +-- (either SetInteriorVehicleData or ButtonPress) for the same RC_module without asking a driver +-- 2) process the request from the second RC_application --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua b/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua index 63d0a9ab14..daa4bb224c 100644 --- a/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua +++ b/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua @@ -4,9 +4,13 @@ -- -- Description: TRS: OnRemoteControlSettings, #1 -- In case: --- +-- 1) SDL received OnRemoteControlSettings notification from HMI with allowed:true +-- 2) and "accessMode" = "AUTO_ALLOW" or without "accessMode" parameter at all +-- 3) and RC_module on HMI is alreay in control by RC-application -- SDL must: --- +-- 1) provide access to RC_module for the second RC_application in HMILevel FULL after it sends control RPC +-- (either SetInteriorVehicleData or ButtonPress) for the same RC_module without asking a driver +-- 2) process the request from the second RC_application --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua b/test_scripts/RC/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua index 7a092c53ab..f8e95e0256 100644 --- a/test_scripts/RC/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua +++ b/test_scripts/RC/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua @@ -4,9 +4,15 @@ -- -- Description: TRS: OnRemoteControlSettings, #2 -- In case: --- +-- 1) SDL received OnRemoteControlSettings notification from HMI with allowed:true +-- 2) and with any "accessMode" or without "accessMode" parameter at all +-- 3) and RC_module on HMI is alreay in control by RC-application_1 +-- 4) and another RC_application_2 is in HMILevel other than FULL (either LIMITED or BACKGROUND) -- SDL must: --- +-- 1) deny access to RC_module for another RC_application_2 after it sends control RPC +-- (either SetInteriorVehicleData or ButtonPress) for the same RC_module without asking a driver +-- 2) not process the request from RC_application_2 and respond with result code REJECTED, success:false +-- 3) leave RC_application_1 in control of the RC_module --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua b/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua index 25eb4dd857..fbc399435b 100644 --- a/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua +++ b/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua @@ -4,9 +4,15 @@ -- -- Description: TRS: OnRemoteControlSettings, #3 -- In case: --- +-- 1) SDL received OnRemoteControlSettings notification from HMI with allowed:true +-- 2) and "accessMode" = "AUTO_ALLOW" or without "accessMode" parameter at all +-- 3) and RC_module on HMI is alreay in control by RC-application_1 +-- 4) and RC_module is currently executing request by RC_application_1 +-- 5) and another RC_application_2 in HMILevel FULL sends control RPC (either SetInteriorVehicleData or ButtonPress) -- SDL must: --- +-- 1) deny access to RC_module for RC_application_2 without asking a driver +-- 2) not process the request from RC_application_2 and respond with result code IN_USE, success:false +-- 3) leave RC_application_1 in control of the RC_module --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua b/test_scripts/RC/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua index ba4d150c30..1f1fb09c66 100644 --- a/test_scripts/RC/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua +++ b/test_scripts/RC/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua @@ -4,9 +4,13 @@ -- -- Description: TRS: OnRemoteControlSettings, #4 -- In case: --- +-- 1) SDL received OnRemoteControlSettings notification from HMI with allowed:true +-- 2) and parameter "accessMode" = "AUTO_DENY" +-- 3) and RC_module on HMI is alreay in control by RC-application -- SDL must: --- +-- 1) deny access to RC_module for another RC_application in HMILevel FULL after it sends control RPC +-- (either SetInteriorVehicleData or ButtonPress) for the same RC_module without asking a driver +-- 2) respond with result code IN_USE, success:false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') From 49e0975074bea53d789f7739890cb0105d98f1f6 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Thu, 3 Aug 2017 16:27:52 +0300 Subject: [PATCH 096/681] GetInteriorVehicleDataConsent: Update descriptions --- .../001_Consent_true_SIVD.lua | 9 +++++++-- .../002_Consent_true_BP.lua | 9 +++++++-- .../003_Consent_false_SIVD.lua | 13 +++++++++++-- .../004_Consent_false_BP.lua | 13 +++++++++++-- .../005_TIMED_OUT_from_HMI_SIVD.lua | 13 +++++++++++-- .../006_TIMED_OUT_from_HMI_BP.lua | 13 +++++++++++-- .../007_HMI_no_response_SIVD.lua | 11 +++++++++-- .../008_HMI_no_response_BP.lua | 11 +++++++++-- .../009_HMI_invalid_response_SIVD.lua | 11 +++++++++-- .../010_HMI_invalid_response_BP.lua | 11 +++++++++-- 10 files changed, 94 insertions(+), 20 deletions(-) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua index 939d5e53e8..6d0e84a5f2 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua @@ -4,9 +4,14 @@ -- -- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #1 -- In case: --- +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and user allowed access to RC module for requested application -- SDL must: --- +-- 1) allocate access to RC module to requested application +-- 2) process control request from this application --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua index cfab0e286d..393dd76752 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua @@ -4,9 +4,14 @@ -- -- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #1 -- In case: --- +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and user allowed access to RC module for requested application -- SDL must: --- +-- 1) allocate access to RC module to requested application +-- 2) process control request from this application --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua index 8be7ac473f..f5677c0049 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua @@ -4,9 +4,18 @@ -- -- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #4 -- In case: --- +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and user disallowed access to RC module for the requested application -- SDL must: --- +-- 1) respond on control request to RC application with result code REJECTED, success:false, +-- info: "The resource is in use and the driver disallows this remote control RPC" +-- 2) not allocate access for remote control module to the requested application +-- (meaning SDL must leave control of remote control module without changes) +-- Note: All further requests from this application to the same module in case +-- if it is still under control of another application must be rejected by SDL without initiating consent prompts --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua index 5cc84b2e71..7a9b86ee94 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua @@ -4,9 +4,18 @@ -- -- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #4 -- In case: --- +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and user disallowed access to RC module for the requested application -- SDL must: --- +-- 1) respond on control request to RC application with result code REJECTED, success:false, +-- info: "The resource is in use and the driver disallows this remote control RPC" +-- 2) not allocate access for remote control module to the requested application +-- (meaning SDL must leave control of remote control module without changes) +-- Note: All further requests from this application to the same module in case +-- if it is still under control of another application must be rejected by SDL without initiating consent prompts --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua index 2724e5d308..00bdfbf63b 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua @@ -4,9 +4,18 @@ -- -- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #2 -- In case: --- +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and user did not provide the answer during default timeout +-- 5) and SDL received in response from HMI GetInteriorVehicleDataConsent (TIMED_OUT) -- SDL must: --- +-- 1) respond on control request to RC application with result code TIMED_OUT, success:false, +-- info: "The resource is in use and the driver did not respond in time" +-- 2) not allocate access for remote control module to the requested application +-- (meaning SDL must leave control of remote control module without changes) +-- Note: SDL must initiate user prompt in case of consequent control request for the same module from this application --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua index e0cc942b97..3d17c7a84f 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua @@ -4,9 +4,18 @@ -- -- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #2 -- In case: --- +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and user did not provide the answer during default timeout +-- 5) and SDL received in response from HMI GetInteriorVehicleDataConsent (TIMED_OUT) -- SDL must: --- +-- 1) respond on control request to RC application with result code TIMED_OUT, success:false, +-- info: "The resource is in use and the driver did not respond in time" +-- 2) not allocate access for remote control module to the requested application +-- (meaning SDL must leave control of remote control module without changes) +-- Note: SDL must initiate user prompt in case of consequent control request for the same module from this application --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua index f0a73df3c0..f5394d225b 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua @@ -4,9 +4,16 @@ -- -- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #3 -- In case: --- +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and HMI did not respond during default timeout or response is invalid or erroneous -- SDL must: --- +-- 1) respond on control request to RC application with result code GENERIC_ERROR, success:false +-- 2) not allocate access for remote control module to the requested application +-- (meaning SDL must leave control of remote control module without changes) +-- Note: SDL must initiate user prompt in case of consequent control request for the same module from this application --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua index 3463a57b4a..ce011ad4de 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua @@ -4,9 +4,16 @@ -- -- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #3 -- In case: --- +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and HMI did not respond during default timeout or response is invalid or erroneous -- SDL must: --- +-- 1) respond on control request to RC application with result code GENERIC_ERROR, success:false +-- 2) not allocate access for remote control module to the requested application +-- (meaning SDL must leave control of remote control module without changes) +-- Note: SDL must initiate user prompt in case of consequent control request for the same module from this application --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua index 1168b793fa..6dd63b8047 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua @@ -4,9 +4,16 @@ -- -- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #3 -- In case: --- +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and HMI did not respond during default timeout or response is invalid or erroneous -- SDL must: --- +-- 1) respond on control request to RC application with result code GENERIC_ERROR, success:false +-- 2) not allocate access for remote control module to the requested application +-- (meaning SDL must leave control of remote control module without changes) +-- Note: SDL must initiate user prompt in case of consequent control request for the same module from this application --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua index c8dd1fb677..f76ca7a02c 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua @@ -4,9 +4,16 @@ -- -- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #3 -- In case: --- +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and HMI did not respond during default timeout or response is invalid or erroneous -- SDL must: --- +-- 1) respond on control request to RC application with result code GENERIC_ERROR, success:false +-- 2) not allocate access for remote control module to the requested application +-- (meaning SDL must leave control of remote control module without changes) +-- Note: SDL must initiate user prompt in case of consequent control request for the same module from this application --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') From 4aaeac1936a61c446d231ac4d6625566add8d32a Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Thu, 3 Aug 2017 18:27:28 +0300 Subject: [PATCH 097/681] Added mock according known issue --- test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua b/test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua index 22341361d1..573e103df1 100644 --- a/test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua +++ b/test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua @@ -46,8 +46,8 @@ local function disableRcFromHmi(self) commonRC.defineRAMode(false, nil, self) - mobileSession1:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE"}) -- REMOTE_CONTROL app - mobileSession2:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE"}) -- REMOTE_CONTROL app + mobileSession1:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE"}):Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + mobileSession2:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE"}):Times(AtLeast(1)) -- issue with SDL --> notification is sent twice mobileSession3:ExpectNotification("OnHMIStatus"):Times(0) -- NAVIGATION app commonTestCases:DelayedExp(commonRC.timeout) From 2bd50a4fb0f135415ba12746d62f097d3a2b5b4f Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 4 Aug 2017 11:25:51 +0300 Subject: [PATCH 098/681] OnRemoteControlSettings: Corrections according to comments in review --- .../001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua | 8 ++++---- .../002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua | 8 ++++---- .../003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua | 8 ++++---- .../004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua b/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua index 14c7264b33..f41b8ef4cc 100644 --- a/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua +++ b/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua @@ -30,9 +30,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) -- App's HMI levels: 1 - BACKGROUND, 2 - FULL @@ -40,13 +38,15 @@ runner.Title("Test") for _, mod in pairs(modules) do runner.Title("Module: " .. mod) - -- set control for App1 - runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) for i = 1, #access_modes do runner.Title("Access mode: " .. tostring(access_modes[i])) + -- set control for App1 + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) -- set RA mode runner.Step("Set RA mode", commonRC.defineRAMode, { true, access_modes[i] }) -- set control for App2 --> Allowed + runner.Step("Activate App2", commonRC.activate_app, { 2 }) runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) runner.Step("App2 ButtonPress", commonRC.rpcAllowed, { mod, 2, "ButtonPress" }) end diff --git a/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua b/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua index 53f44b8816..4938914699 100644 --- a/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua +++ b/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua @@ -30,9 +30,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) -- App's HMI levels: 1 - BACKGROUND, 2 - FULL @@ -40,13 +38,15 @@ runner.Title("Test") for _, mod in pairs(modules) do runner.Title("Module: " .. mod) - -- set control for App1 - runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) for i = 1, #access_modes do runner.Title("Access mode: " .. tostring(access_modes[i])) + -- set control for App1 + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) -- set RA mode runner.Step("Set RA mode", commonRC.defineRAMode, { true, access_modes[i] }) -- set control for App2 --> Allowed + runner.Step("Activate App2", commonRC.activate_app, { 2 }) runner.Step("App2 ButtonPress", commonRC.rpcAllowed, { mod, 2, "ButtonPress" }) runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) end diff --git a/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua b/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua index c68daa310a..3e5eae2353 100644 --- a/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua +++ b/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua @@ -30,9 +30,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) -- App's HMI levels: 1 - BACKGROUND, 2 - FULL @@ -40,13 +38,15 @@ runner.Title("Test") for _, mod in pairs(modules) do runner.Title("Module: " .. mod) - -- set control for App1 - runner.Step("App1 ButtonPress", commonRC.rpcAllowed, { mod, 1, "ButtonPress" }) for i = 1, #access_modes do runner.Title("Access mode: " .. tostring(access_modes[i])) + -- set control for App1 + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("App1 ButtonPress", commonRC.rpcAllowed, { mod, 1, "ButtonPress" }) -- set RA mode runner.Step("Set RA mode", commonRC.defineRAMode, { true, access_modes[i] }) -- set control for App2 --> Allowed + runner.Step("Activate App2", commonRC.activate_app, { 2 }) runner.Step("App2 ButtonPress", commonRC.rpcAllowed, { mod, 2, "ButtonPress" }) runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) end diff --git a/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua b/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua index daa4bb224c..dfc2a93bbb 100644 --- a/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua +++ b/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua @@ -30,9 +30,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) -- App's HMI levels: 1 - BACKGROUND, 2 - FULL @@ -40,13 +38,15 @@ runner.Title("Test") for _, mod in pairs(modules) do runner.Title("Module: " .. mod) - -- set control for App1 - runner.Step("App1 ButtonPress", commonRC.rpcAllowed, { mod, 1, "ButtonPress" }) for i = 1, #access_modes do runner.Title("Access mode: " .. tostring(access_modes[i])) + -- set control for App1 + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("App1 ButtonPress", commonRC.rpcAllowed, { mod, 1, "ButtonPress" }) -- set RA mode runner.Step("Set RA mode", commonRC.defineRAMode, { true, access_modes[i] }) -- set control for App2 --> Allowed + runner.Step("Activate App2", commonRC.activate_app, { 2 }) runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) runner.Step("App2 ButtonPress", commonRC.rpcAllowed, { mod, 2, "ButtonPress" }) end From 1a7cb89906bff4620de90d81b89c7acc627858e0 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 4 Aug 2017 11:26:12 +0300 Subject: [PATCH 099/681] OnRemoteControlSettings: Additional script --- .../015_Empty_data_from_HMI.lua | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 test_scripts/RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua b/test_scripts/RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua new file mode 100644 index 0000000000..3f37cf8866 --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- 1) HMI sends OnRemoteControlSettings notification with no parameters +-- SDL must: +-- 1) Do not take into account this request +-- 2) Leave previously defined access mode +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +local function setRAMode(self) + local rpc = "OnRemoteControlSettings" + local params = { } -- no parameters + self.hmiConnection:SendNotification(commonRC.getHMIEventName(rpc), params) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", commonRC.rai_n, { 2 }) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + + runner.Title("RA mode Default AUTO_ALLOW") + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Send OnRemoteControlSettings with invalid data", setRAMode) + runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + + runner.Title("RA mode AUTO_DENY") + runner.Step("Set RA mode", commonRC.defineRAMode, { true, "AUTO_DENY" }) + runner.Step("Activate App1", commonRC.activate_app, { 1 }) + runner.Step("Send OnRemoteControlSettings with invalid data", setRAMode) + runner.Step("App2 SetInteriorVehicleData", commonRC.rpcDenied, { mod, 1, "SetInteriorVehicleData", "IN_USE" }) + + runner.Title("RA mode ASK_DRIVER") + runner.Step("Set RA mode", commonRC.defineRAMode, { true, "ASK_DRIVER" }) + runner.Step("Send OnRemoteControlSettings with invalid data", setRAMode) + runner.Step("App2 ButtonPress 1st SUCCESS", commonRC.rpcAllowedWithConsent, { mod, 1, "SetInteriorVehicleData" }) + runner.Step("App2 ButtonPress 2nd SUCCESS", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + + runner.Title("RA mode AUTO_ALLOW") + runner.Step("Set RA mode", commonRC.defineRAMode, { true, "AUTO_ALLOW" }) + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Send OnRemoteControlSettings with invalid data", setRAMode) + runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("Activate App1", commonRC.activate_app, { 1 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) From b63c74b2b546876a22bdd9003696980e7d4dc939 Mon Sep 17 00:00:00 2001 From: Masato Ogawa Date: Fri, 4 Aug 2017 17:33:55 +0900 Subject: [PATCH 100/681] Implement SendHapticData RPC This is for discussion on proposal SDL-0075. --- test_scripts/API/ATF_HapticRequest.lua | 366 +++++++++++++++++++++++++ 1 file changed, 366 insertions(+) create mode 100644 test_scripts/API/ATF_HapticRequest.lua diff --git a/test_scripts/API/ATF_HapticRequest.lua b/test_scripts/API/ATF_HapticRequest.lua new file mode 100644 index 0000000000..cf9945113e --- /dev/null +++ b/test_scripts/API/ATF_HapticRequest.lua @@ -0,0 +1,366 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2017 Xevo Inc. +-- All rights reserved. +-------------------------------------------------------------------------------- + +Test = require('connecttest') +local commonFunctions = + require('user_modules/shared_testcases/commonFunctions') + +-------------------------------------------------------------------------------- +-- TEST BLOCK I : Check normal cases +-------------------------------------------------------------------------------- +commonFunctions:newTestCasesGroup("Test suite: Check normal cases") + +function Test:SingleSpatialData() + -- mobiel side + local cid = self.mobileSession:SendRPC( + "SendHapticData", + { + HapticSpatialData = + { { id = 1, x = 2.0, y = 3.0, width = 4.0, height = 5.0 } } + } + ) + -- hmi side + EXPECT_HMICALL( + "UI.SendHapticData", + { + HapticSpatialData = + { { id = 1, x = 2.0, y = 3.0, width = 4.0, height = 5.0, } } + } + ) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + -- mobiel side + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) + :ValidIf (function(_,data) + return true + end) +end + +function Test:MultiSpatialData() + -- mobiel side + local cid = self.mobileSession:SendRPC( + "SendHapticData", + { + HapticSpatialData = + { { id = 1, x = 2.0, y = 3.0, width = 4.0, height = 5.0 }, + { id = 2, x = 12.0, y = 13.0, width = 14.0, height = 15.0 } } + } + ) + -- hmi side + EXPECT_HMICALL( + "UI.SendHapticData", + { + HapticSpatialData = + { { id = 1, x = 2.0, y = 3.0, width = 4.0, height = 5.0 }, + { id = 2, x = 12.0, y = 13.0, width = 14.0, height = 15.0 } } + } + ) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + -- mobiel side + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) + :ValidIf (function(_,data) + return true + end) +end + +function Test:MaxSpatialData() + + local spatial_data = {} + for i= 1, 1000 do + table.insert(spatial_data, + {id = i, x = i+2, y=i+3, width=i+4, height=i+5}) + end + + -- mobiel side + local cid = self.mobileSession:SendRPC( + "SendHapticData", { HapticSpatialData = spatial_data } + ) + -- hmi side + EXPECT_HMICALL( + "UI.SendHapticData", + { + HapticSpatialData = spatial_data + } + ) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + -- mobiel side + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) + :ValidIf (function(_,data) + return true + end) +end + +function Test:NoSpatialData() + -- mobiel side + local cid = self.mobileSession:SendRPC( + "SendHapticData", {} + ) + -- hmi side + EXPECT_HMICALL( + "UI.SendHapticData", + { + } + ) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + -- mobiel side + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) + :ValidIf (function(_,data) + return true + end) +end + +-------------------------------------------------------------------------------- +-- TEST BLOCK II : Check error cases +-------------------------------------------------------------------------------- +commonFunctions:newTestCasesGroup("Test suite: Check error cases") + +function Test:GenericError() + -- mobiel side + local cid = self.mobileSession:SendRPC( + "SendHapticData", + { + HapticSpatialData = + { { id = 1, x = 2.0, y = 3.0, width = 4.0, height = 5.0 } } + } + ) + -- hmi side + EXPECT_HMICALL( + "UI.SendHapticData", + { + HapticSpatialData = + { { id = 1, x = 2.0, y = 3.0, width = 4.0, height = 5.0, } } + } + ) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "GENERIC_ERROR", {}) + end) + -- mobiel side + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) + :ValidIf (function(_,data) + return true + end) +end + +function Test:InvalidDataNonExistId() + -- mobiel side + local cid = self.mobileSession:SendRPC( + "SendHapticData", + { + HapticSpatialData = + { { x = 2.0, y = 3.0, width = 4.0, height = 5.0, } } + } + ) + -- mobiel side + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) + :ValidIf (function(_,data) + return true + end) +end + +function Test:InvalidDataNonExistX() + -- mobiel side + local cid = self.mobileSession:SendRPC( + "SendHapticData", + { + HapticSpatialData = + { { id = 1, y = 3.0, width = 4.0, height = 5.0, } } + } + ) + -- mobiel side + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) + :ValidIf (function(_,data) + return true + end) +end + +function Test:InvalidDataNonExistY() + -- mobiel side + local cid = self.mobileSession:SendRPC( + "SendHapticData", + { + HapticSpatialData = + { { id = 1, x = 2.0, width = 4.0, height = 5.0, } } + } + ) + -- mobiel side + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) + :ValidIf (function(_,data) + return true + end) +end + +function Test:InvalidDataNonExistWidth() + -- mobiel side + local cid = self.mobileSession:SendRPC( + "SendHapticData", + { + HapticSpatialData = + { { id = 1, x = 2.0, y = 3.0, height = 5.0, } } + } + ) + -- mobiel side + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) + :ValidIf (function(_,data) + return true + end) +end + +function Test:InvalidDataNonExistHeight() + -- mobiel side + local cid = self.mobileSession:SendRPC( + "SendHapticData", + { + HapticSpatialData = + { { id = 1, x = 2.0, y = 3.0, width = 4.0, } } + } + ) + -- mobiel side + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) + :ValidIf (function(_,data) + return true + end) +end + +function Test:InvalidDataWithUnknowItem() + -- mobiel side + local cid = self.mobileSession:SendRPC( + "SendHapticData", + { + HapticSpatialData = + { { id = 1, a = 2.0, y = 3.0, width = 4.0, height = 5.0} } + } + ) + -- mobiel side + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) + :ValidIf (function(_,data) + return true + end) +end + +function Test:InvalidDataOverMaxSpatialData() + + local spatial_data = {} + for i= 1, 1001 do + table.insert(spatial_data, {id = i, x = i+2, y=i+3, width=i+4, height=i+5}) + end + + -- mobiel side + local cid = self.mobileSession:SendRPC( + "SendHapticData", { HapticSpatialData = spatial_data } + ) + -- mobiel side + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) + :ValidIf (function(_,data) + return true + end) +end + +function Test:SingleSpatialDataWithMaxID() + -- mobiel side + local cid = self.mobileSession:SendRPC( + "SendHapticData", + { + HapticSpatialData = + { { id = 2000000000, x = 2.0, y = 3.0, width = 4.0, height = 5.0 } } + } + ) + -- hmi side + EXPECT_HMICALL( + "UI.SendHapticData", + { + HapticSpatialData = + { { id = 2000000000, x = 2.0, y = 3.0, width = 4.0, height = 5.0, } } + } + ) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + -- mobiel side + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) + :ValidIf (function(_,data) + return true + end) +end + +function Test:InvalidDataOverMaxID() + -- mobiel side + local cid = self.mobileSession:SendRPC( + "SendHapticData", + { + HapticSpatialData = + { { id = 2000000001, x = 2.0, y = 3.0, width = 5.0, height = 5.0, } } + } + ) + -- mobiel side + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) + :ValidIf (function(_,data) + return true + end) +end + +function Test:SingleSpatialDataWithLargeNumber() + -- mobiel side + local cid = self.mobileSession:SendRPC( + "SendHapticData", + { + HapticSpatialData = + { { id = 2000000000, x = 2000000001, y = 2000000002, + width = 2000000003, height = 2000000004 } } + } + ) + -- hmi side + EXPECT_HMICALL( + "UI.SendHapticData", + { + HapticSpatialData = + { { id = 2000000000, x = 2000000001, y = 2000000002, + width = 2000000003, height = 2000000004, } } + } + ) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + -- mobiel side + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) + :ValidIf (function(_,data) + return true + end) +end + +function Test:SingleSpatialDataWithFloatNumber() + -- mobiel side + local cid = self.mobileSession:SendRPC( + "SendHapticData", + { + HapticSpatialData = + { { id = 1, x = 2.1, y = 3.3, width = 4.7, height = 5.9 } } + } + ) + -- hmi side + EXPECT_HMICALL( + "UI.SendHapticData", + { + HapticSpatialData = + { { id = 1, x = 2.1, y = 3.3, width = 4.7, height = 5.9, } } + } + ) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + -- mobiel side + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) + :ValidIf (function(_,data) + return true + end) +end + +return Test From e652c55c4b3d58f44a089455539af31569848c8a Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 4 Aug 2017 12:33:22 +0300 Subject: [PATCH 101/681] OnRemoteControlSettings: Corrections according to comments in review 2 --- .../001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua | 2 -- .../002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua | 2 -- .../003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua | 2 -- .../004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua | 2 -- .../RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua | 6 +++--- test_sets/rc_OnRemoteControlSettings.txt | 1 + 6 files changed, 4 insertions(+), 11 deletions(-) diff --git a/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua b/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua index f41b8ef4cc..c405584846 100644 --- a/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua +++ b/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua @@ -32,8 +32,6 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) runner.Step("RAI2", commonRC.rai_n, { 2 }) --- App's HMI levels: 1 - BACKGROUND, 2 - FULL - runner.Title("Test") for _, mod in pairs(modules) do diff --git a/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua b/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua index 4938914699..9f6611aedf 100644 --- a/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua +++ b/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua @@ -32,8 +32,6 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) runner.Step("RAI2", commonRC.rai_n, { 2 }) --- App's HMI levels: 1 - BACKGROUND, 2 - FULL - runner.Title("Test") for _, mod in pairs(modules) do diff --git a/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua b/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua index 3e5eae2353..5bcdc9284e 100644 --- a/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua +++ b/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua @@ -32,8 +32,6 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) runner.Step("RAI2", commonRC.rai_n, { 2 }) --- App's HMI levels: 1 - BACKGROUND, 2 - FULL - runner.Title("Test") for _, mod in pairs(modules) do diff --git a/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua b/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua index dfc2a93bbb..df9076238f 100644 --- a/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua +++ b/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua @@ -32,8 +32,6 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) runner.Step("RAI2", commonRC.rai_n, { 2 }) --- App's HMI levels: 1 - BACKGROUND, 2 - FULL - runner.Title("Test") for _, mod in pairs(modules) do diff --git a/test_scripts/RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua b/test_scripts/RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua index 3f37cf8866..97e7b93e32 100644 --- a/test_scripts/RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua +++ b/test_scripts/RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua @@ -50,13 +50,13 @@ for _, mod in pairs(modules) do runner.Step("Set RA mode", commonRC.defineRAMode, { true, "AUTO_DENY" }) runner.Step("Activate App1", commonRC.activate_app, { 1 }) runner.Step("Send OnRemoteControlSettings with invalid data", setRAMode) - runner.Step("App2 SetInteriorVehicleData", commonRC.rpcDenied, { mod, 1, "SetInteriorVehicleData", "IN_USE" }) + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcDenied, { mod, 1, "SetInteriorVehicleData", "IN_USE" }) runner.Title("RA mode ASK_DRIVER") runner.Step("Set RA mode", commonRC.defineRAMode, { true, "ASK_DRIVER" }) runner.Step("Send OnRemoteControlSettings with invalid data", setRAMode) - runner.Step("App2 ButtonPress 1st SUCCESS", commonRC.rpcAllowedWithConsent, { mod, 1, "SetInteriorVehicleData" }) - runner.Step("App2 ButtonPress 2nd SUCCESS", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + runner.Step("App1 ButtonPress 1st SUCCESS", commonRC.rpcAllowedWithConsent, { mod, 1, "SetInteriorVehicleData" }) + runner.Step("App1 ButtonPress 2nd SUCCESS", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) runner.Title("RA mode AUTO_ALLOW") runner.Step("Set RA mode", commonRC.defineRAMode, { true, "AUTO_ALLOW" }) diff --git a/test_sets/rc_OnRemoteControlSettings.txt b/test_sets/rc_OnRemoteControlSettings.txt index f1931e0caa..c1198d68da 100644 --- a/test_sets/rc_OnRemoteControlSettings.txt +++ b/test_sets/rc_OnRemoteControlSettings.txt @@ -12,3 +12,4 @@ ./test_scripts/RC/OnRemoteControlSettings/012_Default_accessMode.lua ./test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua ./test_scripts/RC/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua +./test_scripts/RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua From 20ea98145925b715c8986a0ab81cabe2a8f2577c Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Mon, 7 Aug 2017 12:10:53 +0300 Subject: [PATCH 102/681] ButtonPress: Additional script on transferring HMI result codes --- ...ransfering_of_HMI_resultCode_to_mobile.lua | 88 +++++++++++++++++++ test_sets/rc_ButtonPress.txt | 1 + 2 files changed, 89 insertions(+) create mode 100644 test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua diff --git a/test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua new file mode 100644 index 0000000000..3b0c6ce839 --- /dev/null +++ b/test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua @@ -0,0 +1,88 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Button press event emulation +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) and sends valid ButtonPress RPC with valid parameters +-- SDL must: +-- 1) Transfer this request to HMI +-- 2) Respond with received from HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local success_codes = { "WARNINGS" } +local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } + +--[[ Local Functions ]] +local function stepSuccessfull(pModuleType, pResultCode, self) + local cid = self.mobileSession:SendRPC("ButtonPress", { + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + + EXPECT_HMICALL("Buttons.ButtonPress", { + appID = self.applications["Test Application"], + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, pResultCode, { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + end) + + self.mobileSession:ExpectResponse(cid, { success = true, resultCode = pResultCode }) +end + +local function stepUnsuccessfull(pModuleType, pResultCode, self) + local cid = self.mobileSession:SendRPC("ButtonPress", { + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + + EXPECT_HMICALL("Buttons.ButtonPress", { + appID = self.applications["Test Application"], + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + :Do(function(_, data) + self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") + end) + + self.mobileSession:ExpectResponse(cid, { success = false, resultCode = pResultCode }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + for _, code in pairs(success_codes) do + runner.Step("ButtonPress with " .. code .. " resultCode", stepSuccessfull, { mod, code }) + end +end + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + for _, code in pairs(error_codes) do + runner.Step("ButtonPress with " .. code .. " resultCode", stepUnsuccessfull, { mod, code }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_ButtonPress.txt b/test_sets/rc_ButtonPress.txt index 8648056b55..2e1a807a83 100644 --- a/test_sets/rc_ButtonPress.txt +++ b/test_sets/rc_ButtonPress.txt @@ -10,3 +10,4 @@ ./test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua ./test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua ./test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua +./test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua From e6afac52aa4e6be5f7f668bef55fa5b9e5c44388 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Mon, 7 Aug 2017 12:16:23 +0300 Subject: [PATCH 103/681] SetInteriorVehicleData: Additional script on transferring HMI result codes --- ...ransfering_of_HMI_resultCode_to_mobile.lua | 81 +++++++++++++++++++ test_sets/rc_SetInteriorVehicleData.txt | 1 + 2 files changed, 82 insertions(+) create mode 100644 test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua new file mode 100644 index 0000000000..7ffeea391d --- /dev/null +++ b/test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua @@ -0,0 +1,81 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) RC app sends valid and allowed by policies SetInteriorvehicleData request +-- 2) and SDL received SetInteriorVehicleData response with successful result code and current module data from HMI +-- SDL must: +-- 1) Transfer SetInteriorVehicleData response with provided from HMI current module data +-- for allowed module and control items +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local success_codes = { "WARNINGS" } +local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } + +--[[ Local Functions ]] +local function stepSuccessfull(pModuleType, pResultCode, self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, pResultCode, { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + end) + + self.mobileSession:ExpectResponse(cid, + { success = true, resultCode = pResultCode, moduleData = commonRC.getSettableModuleControlData(pModuleType) }) +end + +local function stepUnsuccessfull(pModuleType, pResultCode, self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, data) + self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") + end) + + self.mobileSession:ExpectResponse(cid, { success = false, resultCode = pResultCode }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + for _, code in pairs(success_codes) do + runner.Step("SetInteriorVehicleData with " .. code .. " resultCode", stepSuccessfull, { mod, code }) + end +end + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + for _, code in pairs(error_codes) do + runner.Step("SetInteriorVehicleData with " .. code .. " resultCode", stepUnsuccessfull, { mod, code }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_SetInteriorVehicleData.txt b/test_sets/rc_SetInteriorVehicleData.txt index 31bc143cd2..18dc430d95 100644 --- a/test_sets/rc_SetInteriorVehicleData.txt +++ b/test_sets/rc_SetInteriorVehicleData.txt @@ -12,3 +12,4 @@ ./test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua ./test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua ./test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua From 00db39ee7705311b431ecda2fdbd54d9f106c113 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Mon, 7 Aug 2017 17:08:35 +0300 Subject: [PATCH 104/681] GetInteriorVehicleDataConsent: Additional script on TIMED_OUT --- .../011_TIMED_OUT_after_default_timeout.lua | 63 +++++++++++++++++++ .../rc_GetInteriorVehicleDataConsent.txt | 1 + 2 files changed, 64 insertions(+) create mode 100644 test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua new file mode 100644 index 0000000000..d8ccad4cc1 --- /dev/null +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua @@ -0,0 +1,63 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Sequence: +-- 1) 2 REMOTE_CONTROL Apps are registered (App_1, App_2) +-- 2) Access mode: ASK_DRIVER +-- 3) App_1 takes control for +-- 4) App_2 is activated (FULL) +-- 5) App_2->SDL: for +-- 6) SDL->HMI: GetInteriorVehicleDataConsent (App_2) +-- 7) HMI doesn't respond for GetInteriorVehicleDataConsent (App_2) during default period (10s) +-- 8) HMI->SDL: TIMED_OUT: GetInteriorVehicleDataConsent (App_2) after default period (10s) +-- 9) SDL->App_2: GENERIC_ERROR: SetInteriorVehicleData (success:false) +-- 10) SDL doesn't transfer request for to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") + +--[[ Local Variables ]] +local pModuleType = "CLIMATE" +local pRPC1 = "SetInteriorVehicleData" + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +local function rpcHMIRespondAfterDefaultTimeout(self) + local cid1 = self.mobileSession2:SendRPC(commonRC.getAppEventName(pRPC1), commonRC.getAppRequestParams(pRPC1, pModuleType)) + local consentRPC = "GetInteriorVehicleDataConsent" + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, 2, self)) + :Do(function(_, data) + local function hmiRespond() + self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", "info") + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC1)):Times(0) + end + RUN_AFTER(hmiRespond, 11000) + end) + + self.mobileSession2:ExpectResponse(cid1, { success = false, resultCode = "GENERIC_ERROR" }) + commonTestCases:DelayedExp(12000) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("RAI2", commonRC.rai_n, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) + +runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { pModuleType, 1, "SetInteriorVehicleData" }) + +runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("App2 SetInteriorVehicleData, HMI respond after default timeout", rpcHMIRespondAfterDefaultTimeout) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_GetInteriorVehicleDataConsent.txt b/test_sets/rc_GetInteriorVehicleDataConsent.txt index a38f11c217..1f51852e04 100644 --- a/test_sets/rc_GetInteriorVehicleDataConsent.txt +++ b/test_sets/rc_GetInteriorVehicleDataConsent.txt @@ -8,3 +8,4 @@ ./test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua ./test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua ./test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua +./test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua From 226d39150e6d9b9ddf6879534a368984944c16ef Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Wed, 9 Aug 2017 11:03:59 +0300 Subject: [PATCH 105/681] Update commonRC with functions related to unregister app and driver consent answer --- test_scripts/RC/commonRC.lua | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 2a56baa6f3..2a00d9433b 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -225,6 +225,12 @@ function commonRC.rai_n(id, self) end) end +function commonRC.unregisterApp(pAppId, self) + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC("UnregisterAppInterface",{}) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + function commonRC.activate_app(pAppId, self) self, pAppId = commonRC.getSelfAndParams(pAppId, self) @@ -654,4 +660,27 @@ function commonRC.rpcAllowedWithConsent(pModuleType, pAppId, pRPC, self) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end +function commonRC.rpcRejectWithConsent(pModuleType, pAppId, pRPC, self) + local info = "The resource is in use and the driver disallows this remote control RPC" + local consentRPC = "GetInteriorVehicleDataConsent" + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(consentRPC, false)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED", info = info }) + commonTestCases:DelayedExp(commonRC.timeout) +end + +function commonRC.rpcRejectWithoutConsent(pModuleType, pAppId, pRPC, self) + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName("GetInteriorVehicleDataConsent")):Times(0) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) + commonTestCases:DelayedExp(commonRC.timeout) +end + return commonRC From 05c4593b15d39dc58a9cba6f93e8389655f30386 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Wed, 9 Aug 2017 11:05:57 +0300 Subject: [PATCH 106/681] Update GetInteriorVehicleDataConsent tests with new common functions --- .../003_Consent_false_SIVD.lua | 30 ++----------------- .../004_Consent_false_BP.lua | 30 ++----------------- 2 files changed, 6 insertions(+), 54 deletions(-) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua index f5677c0049..b737dbdbcc 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua @@ -20,7 +20,6 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') -local commonTestCases = require("user_modules/shared_testcases/commonTestCases") --[[ Local Variables ]] local modules = { "CLIMATE", "RADIO" } @@ -30,29 +29,6 @@ local function ptu_update_func(tbl) tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() end -local function rpcConsentFalse(pModuleType, pAppId, pRPC, self) - local info = "The resource is in use and the driver disallows this remote control RPC" - local consentRPC = "GetInteriorVehicleDataConsent" - local mobSession = commonRC.getMobileSession(self, pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(consentRPC, false)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) - end) - mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED", info = info }) - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function rpcConsentAbsent(pModuleType, pAppId, pRPC, self) - local mobSession = commonRC.getMobileSession(self, pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName("GetInteriorVehicleDataConsent")):Times(0) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) - mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) - commonTestCases:DelayedExp(commonRC.timeout) -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) @@ -70,9 +46,9 @@ for _, mod in pairs(modules) do -- set control for App1 runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) -- set control for App2 --> Ask driver --> HMI: allowed:false - runner.Step("App2 SetInteriorVehicleData 1st REJECTED", rpcConsentFalse, { mod, 2, "SetInteriorVehicleData" }) - runner.Step("App2 SetInteriorVehicleData 2nd REJECTED", rpcConsentAbsent, { mod, 2, "SetInteriorVehicleData" }) - runner.Step("App2 ButtonPress 2nd REJECTED", rpcConsentAbsent, { mod, 2, "ButtonPress" }) + runner.Step("App2 SetInteriorVehicleData 1st REJECTED", commonRC.rpcRejectWithConsent, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 SetInteriorVehicleData 2nd REJECTED", commonRC.rpcRejectWithoutConsent, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 ButtonPress 2nd REJECTED", commonRC.rpcRejectWithoutConsent, { mod, 2, "ButtonPress" }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua index 7a9b86ee94..428df8dbaa 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua @@ -20,7 +20,6 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') -local commonTestCases = require("user_modules/shared_testcases/commonTestCases") --[[ Local Variables ]] local modules = { "CLIMATE", "RADIO" } @@ -30,29 +29,6 @@ local function ptu_update_func(tbl) tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() end -local function rpcConsentFalse(pModuleType, pAppId, pRPC, self) - local info = "The resource is in use and the driver disallows this remote control RPC" - local consentRPC = "GetInteriorVehicleDataConsent" - local mobSession = commonRC.getMobileSession(self, pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(consentRPC, false)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) - end) - mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED", info = info }) - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function rpcConsentAbsent(pModuleType, pAppId, pRPC, self) - local mobSession = commonRC.getMobileSession(self, pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName("GetInteriorVehicleDataConsent")):Times(0) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) - mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) - commonTestCases:DelayedExp(commonRC.timeout) -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) @@ -70,9 +46,9 @@ for _, mod in pairs(modules) do -- set control for App1 runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) -- set control for App2 --> Ask driver --> HMI: allowed:false - runner.Step("App2 ButtonPress 1st REJECTED", rpcConsentFalse, { mod, 2, "ButtonPress" }) - runner.Step("App2 ButtonPress 2nd REJECTED", rpcConsentAbsent, { mod, 2, "ButtonPress" }) - runner.Step("App2 SetInteriorVehicleData 2nd REJECTED", rpcConsentAbsent, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 ButtonPress 1st REJECTED", commonRC.rpcRejectWithConsent, { mod, 2, "ButtonPress" }) + runner.Step("App2 ButtonPress 2nd REJECTED", commonRC.rpcRejectWithoutConsent, { mod, 2, "ButtonPress" }) + runner.Step("App2 SetInteriorVehicleData 2nd REJECTED", commonRC.rpcRejectWithoutConsent, { mod, 2, "SetInteriorVehicleData" }) end runner.Title("Postconditions") From c2133ddd9c817cf52fff22a1be6755a09dbf848e Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Wed, 9 Aug 2017 11:07:09 +0300 Subject: [PATCH 107/681] Add new tests for OnRemoteControlSettings --- ...DENY_for_app_with_reject_in_ASK_DRIVER.lua | 57 +++++++++++++++++++ ...017_Release_resource_on_unregister_app.lua | 56 ++++++++++++++++++ ...low_for_rejected_app_on_unregister_app.lua | 54 ++++++++++++++++++ 3 files changed, 167 insertions(+) create mode 100644 test_scripts/RC/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua create mode 100644 test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua create mode 100644 test_scripts/RC/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua b/test_scripts/RC/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua new file mode 100644 index 0000000000..6edc5ccd1a --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- RC_functionality is disabled on HMI and HMI sends notification OnRemoteControlSettings (allowed:true, ) +-- +-- SDL must: +-- 1) store RC state allowed:true and received from HMI internally +-- 2) allow RC functionality for applications with REMOTE_CONTROL appHMIType +-- +-- Additional checks: +-- - Result code IN_USE in AUTO_DENY access mode for previously rejected apps in ASK_DRIVER access mode +-- - Result code SUCCESS in AUTO_ALLOW access mode for previously rejected apps in ASK_DRIVER access mode +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Title("Default -> ASK_DRIVER") +runner.Step("Enable RC from HMI with ASK_DRIVER access mode", commonRC.defineRAMode, { true, "ASK_DRIVER"}) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("Module CLIMATE App2 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "CLIMATE", 2, "SetInteriorVehicleData" }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("Module RADIO App1 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "RADIO", 1, "SetInteriorVehicleData" }) +runner.Step("Check module CLIMATE App1 SetInteriorVehicleData rejected with driver consent", commonRC.rpcRejectWithConsent, { "CLIMATE", 1, "SetInteriorVehicleData" }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("Check module RADIO App2 SetInteriorVehicleData rejected with driver consent", commonRC.rpcRejectWithConsent, { "RADIO", 2, "SetInteriorVehicleData" }) + +runner.Title("Test") +runner.Title("ASK_DRIVER -> AUTO_DENY") +runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) +runner.Step("Check module RADIO App2 SetInteriorVehicleData denied", commonRC.rpcDenied, { "RADIO", 2, "SetInteriorVehicleData", "IN_USE" }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("Check module CLIMATE App1 SetInteriorVehicleData denied", commonRC.rpcDenied, { "CLIMATE", 1, "SetInteriorVehicleData", "IN_USE" }) + +runner.Title("AUTO_DENY -> AUTO_ALLOW") +runner.Step("Enable RC from HMI with AUTO_ALLOW access mode", commonRC.defineRAMode, { true, "AUTO_ALLOW"}) +runner.Step("Check module CLIMATE App1 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "CLIMATE", 1, "SetInteriorVehicleData" }) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("Check module RADIO App2 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "RADIO", 2, "SetInteriorVehicleData" }) + + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua b/test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua new file mode 100644 index 0000000000..e5e9421bc1 --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- RC_functionality is disabled on HMI and HMI sends notification OnRemoteControlSettings (allowed:true, ) +-- +-- SDL must: +-- 1) store RC state allowed:true and received from HMI internally +-- 2) allow RC functionality for applications with REMOTE_CONTROL appHMIType +-- +-- Additional checks: +-- - Result code SUCCESS in AUTO_DENY access mode after unregister app which allocated resource on +-- - Result code SUCCESS in ASK_DRIVER access mode after unregister app which allocated resource on +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +config.application3.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application3.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("RAI3", commonRC.rai_n, { 3 }) + +runner.Title("Test") +runner.Title("Default -> ASK_DRIVER") +runner.Step("Enable RC from HMI with ASK_DRIVER access mode", commonRC.defineRAMode, { true, "ASK_DRIVER"}) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("Module CLIMATE App2 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "CLIMATE", 2, "SetInteriorVehicleData" }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("Module RADIO App1 ButtonPress allowed", commonRC.rpcAllowed, { "RADIO", 1, "ButtonPress" }) +runner.Step("Unregister App2", commonRC.unregisterApp, { 2 }) +runner.Step("Module CLIMATE App1 ButtonPress allowed", commonRC.rpcAllowed, { "CLIMATE", 1, "ButtonPress" }) +runner.Step("Activate App3", commonRC.activate_app, { 3 }) +runner.Step("Activate App1", commonRC.activate_app, { 1 }) +runner.Title("ASK_DRIVER -> AUTO_DENY") +runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) +runner.Step("Unregister App1", commonRC.unregisterApp, { 1 }) +runner.Step("Module CLIMATE App3 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "CLIMATE", 3, "SetInteriorVehicleData" }) +runner.Step("Activate App3", commonRC.activate_app, { 3 }) +runner.Step("Module RADIO App13 ButtonPress allowed", commonRC.rpcAllowed, { "RADIO", 3, "ButtonPress" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua b/test_scripts/RC/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua new file mode 100644 index 0000000000..1f6c020336 --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua @@ -0,0 +1,54 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- RC_functionality is disabled on HMI and HMI sends notification OnRemoteControlSettings (allowed:true, ) +-- +-- SDL must: +-- 1) store RC state allowed:true and received from HMI internally +-- 2) allow RC functionality for applications with REMOTE_CONTROL appHMIType +-- +-- Additional checks: +-- - Result code SUCCESS in ASK_DRIVER access mode for previously rejected apps in ASK_DRIVER access mode after unregister app which allocated resource on +-- - Result code IN_USE in AUTO_DENY access mode for previously rejected apps in ASK_DRIVER access mode after unregister app which allocated resource on +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +config.application3.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application3.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("RAI3", commonRC.rai_n, { 3 }) + +runner.Title("Test") +runner.Title("Default -> ASK_DRIVER") +runner.Step("Enable RC from HMI with ASK_DRIVER access mode", commonRC.defineRAMode, { true, "ASK_DRIVER"}) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("Module CLIMATE App2 ButtonPress allowed", commonRC.rpcAllowed, { "CLIMATE", 2, "ButtonPress" }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("Module CLIMATE App1 SetInteriorVehicleData rejected with driver consent", commonRC.rpcRejectWithConsent, { "CLIMATE", 1, "SetInteriorVehicleData" }) +runner.Step("Activate App3", commonRC.activate_app, { 3 }) +runner.Step("Module CLIMATE App3 ButtonPress rejected with driver consent", commonRC.rpcRejectWithConsent, { "CLIMATE", 3, "ButtonPress" }) +runner.Step("Unregister App2", commonRC.unregisterApp, { 2 }) +runner.Step("Module CLIMATE App3 ButtonPress allowed", commonRC.rpcAllowed, { "CLIMATE", 3, "ButtonPress" }) +runner.Title("ASK_DRIVER -> AUTO_DENY") +runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("Check module CLIMATE App1 SetInteriorVehicleData denied", commonRC.rpcDenied, { "CLIMATE", 1, "SetInteriorVehicleData", "IN_USE" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) From 53de055cc66137498dbdaf67fb0b44f99c646c7c Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Wed, 9 Aug 2017 15:33:59 +0300 Subject: [PATCH 108/681] Added new tests into test set --- ...W_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua | 1 - .../017_Release_resource_on_unregister_app.lua | 5 +++-- test_scripts/RC/commonRC.lua | 2 ++ test_sets/rc_OnRemoteControlSettings.txt | 3 +++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/test_scripts/RC/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua b/test_scripts/RC/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua index 6edc5ccd1a..b6a92566f7 100644 --- a/test_scripts/RC/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua +++ b/test_scripts/RC/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua @@ -52,6 +52,5 @@ runner.Step("Check module CLIMATE App1 SetInteriorVehicleData allowed", commonRC runner.Step("Activate App2", commonRC.activate_app, { 2 }) runner.Step("Check module RADIO App2 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "RADIO", 2, "SetInteriorVehicleData" }) - runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua b/test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua index e5e9421bc1..6ac944d578 100644 --- a/test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua +++ b/test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua @@ -49,8 +49,9 @@ runner.Title("ASK_DRIVER -> AUTO_DENY") runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) runner.Step("Unregister App1", commonRC.unregisterApp, { 1 }) runner.Step("Module CLIMATE App3 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "CLIMATE", 3, "SetInteriorVehicleData" }) -runner.Step("Activate App3", commonRC.activate_app, { 3 }) -runner.Step("Module RADIO App13 ButtonPress allowed", commonRC.rpcAllowed, { "RADIO", 3, "ButtonPress" }) +runner.Title("AUTO_DENY -> AUTO_ALLOW") +runner.Step("Enable RC from HMI with AUTO_ALLOW access mode", commonRC.defineRAMode, { true, "AUTO_ALLOW"}) +runner.Step("Module RADIO App3 ButtonPress allowed", commonRC.rpcAllowed, { "RADIO", 3, "ButtonPress" }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 2a00d9433b..9dee190684 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -227,7 +227,9 @@ end function commonRC.unregisterApp(pAppId, self) local mobSession = commonRC.getMobileSession(self, pAppId) + local hmiAppId = commonRC.getHMIAppId(self, pAppId) local cid = mobSession:SendRPC("UnregisterAppInterface",{}) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = hmiAppId, unexpectedDisconnect = false }) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) end diff --git a/test_sets/rc_OnRemoteControlSettings.txt b/test_sets/rc_OnRemoteControlSettings.txt index c1198d68da..5ac04bd6d0 100644 --- a/test_sets/rc_OnRemoteControlSettings.txt +++ b/test_sets/rc_OnRemoteControlSettings.txt @@ -13,3 +13,6 @@ ./test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua ./test_scripts/RC/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua ./test_scripts/RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua +./test_scripts/RC/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua +./test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua +./test_scripts/RC/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua From 2d244f5aa7a343d97c01c1edff61423ccaa00cfc Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Thu, 10 Aug 2017 08:40:18 +0300 Subject: [PATCH 109/681] Added test for OnRemoteControlSettings to check release of resources --- .../019_Release_resource_on_RC_disable.lua | 63 +++++++++++++++++++ test_sets/rc_OnRemoteControlSettings.txt | 1 + 2 files changed, 64 insertions(+) create mode 100644 test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua b/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua new file mode 100644 index 0000000000..be4768a034 --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua @@ -0,0 +1,63 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- RC_functionality is disabled on HMI and HMI sends notification OnRemoteControlSettings (allowed:true, ) +-- +-- SDL must: +-- 1) store RC state allowed:true received from HMI internally +-- 2) allow RC functionality for applications with REMOTE_CONTROL appHMIType +-- +-- Additional checks: +-- - Release resource on RC functionality disable +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local rcRpcs = { "SetInteriorVehicleData", "ButtonPress" } +local accessModes = { "AUTO_ALLOW", "AUTO_DENY", "ASK_DRIVER" } +local HMILevels = { "FULL", "NOT_FULL" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("RAI2", commonRC.rai_n, { 2 }) + +runner.Title("Test") + +for _,initialAccessMode in pairs(accessModes) do + for _,targetAccessMode in pairs(accessModes) do + for _,appLevel in pairs(HMILevels) do + runner.Title(initialAccessMode .. " -> Disable RC -> " .. targetAccessMode .. " (" .. appLevel .. ")") + for _, mod in pairs(modules) do + runner.Step("Enable RC from HMI with " .. initialAccessMode .." access mode", commonRC.defineRAMode, { true, initialAccessMode }) + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Check module " .. mod .." App1 " .. rcRpcs[1] .. " allowed", commonRC.rpcAllowed, { mod, 1, rcRpcs[1] }) + runner.Step("Disable RC from HMI", commonRC.defineRAMode, { false, initialAccessMode }) + runner.Step("Enable RC from HMI with " .. targetAccessMode .. " access mode", commonRC.defineRAMode, { true, targetAccessMode }) + if appLevel == "FULL" then + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Check module " .. mod .." App2 " .. rcRpcs[2] .. " allowed", commonRC.rpcAllowed, { mod, 2, rcRpcs[2] }) + else + runner.Step("Check module " .. mod .." App2 " .. rcRpcs[2] .. " allowed", commonRC.rpcAllowed, { mod, 2, rcRpcs[2] }) + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + end + end + end + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_OnRemoteControlSettings.txt b/test_sets/rc_OnRemoteControlSettings.txt index 5ac04bd6d0..1296318a16 100644 --- a/test_sets/rc_OnRemoteControlSettings.txt +++ b/test_sets/rc_OnRemoteControlSettings.txt @@ -16,3 +16,4 @@ ./test_scripts/RC/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua ./test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua ./test_scripts/RC/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua +./test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua From de6bf301d6ca371b563b6ee04855ec91106fa9df Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 11 Aug 2017 12:13:01 +0300 Subject: [PATCH 110/681] SystemCapabilities: Common modules --- test_scripts/RC/commonRC.lua | 58 +--- user_modules/dummy_connecttest.lua | 318 ++++----------------- user_modules/hmi_values.lua | 425 +++++++++++++++++++++++++++++ 3 files changed, 476 insertions(+), 325 deletions(-) create mode 100644 user_modules/hmi_values.lua diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 9dee190684..85a3f37506 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -23,57 +23,6 @@ local commonRC = {} commonRC.timeout = 2000 -local function initHMI(self) - local exp_waiter = commonFunctions:createMultipleExpectationsWaiter(self, "HMI initialization") - local function registerComponent(name, subscriptions) - local rid = self.hmiConnection:SendRequest("MB.registerComponent", { componentName = name }) - local exp = EXPECT_HMIRESPONSE(rid) - exp_waiter:AddExpectation(exp) - if subscriptions then - for _, s in ipairs(subscriptions) do - exp:Do(function() - rid = self.hmiConnection:SendRequest("MB.subscribeTo", { propertyName = s }) - exp = EXPECT_HMIRESPONSE(rid) - exp_waiter:AddExpectation(exp) - end) - end - end - end - - local web_socket_connected_event = EXPECT_HMIEVENT(events.connectedEvent, "Connected websocket") - :Do(function() - registerComponent("Buttons", {"Buttons.OnButtonSubscription"}) - registerComponent("TTS") - registerComponent("VR") - registerComponent("BasicCommunication", { - "BasicCommunication.OnPutFile", - "SDL.OnStatusUpdate", - "SDL.OnAppPermissionChanged", - "BasicCommunication.OnSDLPersistenceComplete", - "BasicCommunication.OnFileRemoved", - "BasicCommunication.OnAppRegistered", - "BasicCommunication.OnAppUnregistered", - "BasicCommunication.PlayTone", - "BasicCommunication.OnSDLClose", - "SDL.OnSDLConsentNeeded", - "BasicCommunication.OnResumeAudioSource" - }) - registerComponent("UI", { - "UI.OnRecordStart" - }) - registerComponent("VehicleInfo") - registerComponent("RC") - registerComponent("Navigation", { - "Navigation.OnAudioDataStreaming", - "Navigation.OnVideoDataStreaming" - }) - end) - exp_waiter:AddExpectation(web_socket_connected_event) - - self.hmiConnection:Connect() - return exp_waiter.expectation -end - local function getPTUFromPTS(tbl) tbl.policy_table.consumer_friendly_messages.messages = nil tbl.policy_table.device_data = nil @@ -159,14 +108,15 @@ function commonRC.preconditions() commonSteps:DeleteLogsFiles() end -function commonRC.start(self) +function commonRC.start(pHMIParams, self) + self, pHMIParams = commonRC.getSelfAndParams(pHMIParams, self) self:runSDL() commonFunctions:waitForSDLStart(self) :Do(function() - initHMI(self) + self:initHMI(self) :Do(function() commonFunctions:userPrint(35, "HMI initialized") - self:initHMI_onReady() + self:initHMI_onReady(pHMIParams) :Do(function() commonFunctions:userPrint(35, "HMI is ready") self:connectMobile() diff --git a/user_modules/dummy_connecttest.lua b/user_modules/dummy_connecttest.lua index 2b186a2637..73639a3af5 100644 --- a/user_modules/dummy_connecttest.lua +++ b/user_modules/dummy_connecttest.lua @@ -13,6 +13,7 @@ local SDL = require('SDL') local exit_codes = require('exit_codes') local load_schema = require('load_schema') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local hmi_values = require("user_modules/hmi_values") local mob_schema = load_schema.mob_schema local hmi_schema = load_schema.hmi_schema @@ -350,6 +351,7 @@ function module:initHMI() "UI.OnRecordStart" }) registerComponent("VehicleInfo") + registerComponent("RC") registerComponent("Navigation", { "Navigation.OnAudioDataStreaming", @@ -362,275 +364,73 @@ function module:initHMI() return exp_waiter.expectation end -function module:initHMI_onReady() +--[[ @initHMI_onReady: the function is HMI's onReady response +--! @parameters: +--! @hmi_table - hmi_table of hmi specification values, default one is specified in "user_modules/hmi_values" +--! @example: self:initHMI_onReady(local_hmi_table) ]] +function module:initHMI_onReady(hmi_table) local exp_waiter = commonFunctions:createMultipleExpectationsWaiter(module, "HMI on ready") - local function ExpectRequest(name, mandatory, params) + + local function ExpectRequest(name, hmi_table_element) local event = events.Event() event.level = 2 event.matches = function(self, data) return data.method == name end local exp = EXPECT_HMIEVENT(event, name) - :Times(mandatory and 1 or AnyNumber()) + :Times(hmi_table_element.mandatory and 1 or AnyNumber()) :Do(function(_, data) - xmlReporter.AddMessage("hmi_connection","SendResponse", - { - ["methodName"] = tostring(name), - ["mandatory"] = mandatory , - ["params"]= params - }) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", params) - end) - if (mandatory) then - exp_waiter:AddExpectation(exp) + xmlReporter.AddMessage("hmi_connection","SendResponse", + { + ["methodName"] = tostring(name), + ["mandatory"] = hmi_table_element.mandatory, + ["params"] = hmi_table_element.params + }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", hmi_table_element.params) + end) + if hmi_table_element.mandatory then + exp_waiter:AddExpectation(exp) + end + if hmi_table_element.pinned then + exp:Pin() end return exp end - local function ExpectNotification(name, mandatory) - xmlReporter.AddMessage(debug.getinfo(1, "n").name, tostring(name)) - local event = events.Event() - event.level = 2 - event.matches = function(self, data) return data.method == name end - local exp = EXPECT_HMIEVENT(event, name) - :Times(mandatory and 1 or AnyNumber()) - exp_waiter:AddExpectation(exp) - return exp + local hmi_table_internal + if type(hmi_table) == "table" then + hmi_table_internal = commonFunctions:cloneTable(hmi_table) + else + hmi_table_internal = hmi_values.getDefaultHMITable() end - ExpectRequest("BasicCommunication.MixingAudioSupported", - true, - { attenuatedSupported = true }) - ExpectRequest("BasicCommunication.GetSystemInfo", false, - { - ccpu_version = "ccpu_version", - language = "EN-US", - wersCountryCode = "wersCountryCode" - }) - ExpectRequest("UI.GetLanguage", true, { language = "EN-US" }) - ExpectRequest("VR.GetLanguage", true, { language = "EN-US" }) - ExpectRequest("TTS.GetLanguage", true, { language = "EN-US" }) - ExpectRequest("UI.ChangeRegistration", false, { }):Pin() - ExpectRequest("TTS.SetGlobalProperties", false, { }):Pin() - ExpectRequest("BasicCommunication.UpdateDeviceList", false, { }):Pin() - ExpectRequest("VR.ChangeRegistration", false, { }):Pin() - ExpectRequest("TTS.ChangeRegistration", false, { }):Pin() - ExpectRequest("VR.GetSupportedLanguages", true, { - languages = { - "EN-US","ES-MX","FR-CA","DE-DE","ES-ES","EN-GB","RU-RU", - "TR-TR","PL-PL","FR-FR","IT-IT","SV-SE","PT-PT","NL-NL", - "ZH-TW","JA-JP","AR-SA","KO-KR","PT-BR","CS-CZ","DA-DK", - "NO-NO","NL-BE","EL-GR","HU-HU","FI-FI","SK-SK" } - }) - ExpectRequest("TTS.GetSupportedLanguages", true, { - languages = { - "EN-US","ES-MX","FR-CA","DE-DE","ES-ES","EN-GB","RU-RU", - "TR-TR","PL-PL","FR-FR","IT-IT","SV-SE","PT-PT","NL-NL", - "ZH-TW","JA-JP","AR-SA","KO-KR","PT-BR","CS-CZ","DA-DK", - "NO-NO","NL-BE","EL-GR","HU-HU","FI-FI","SK-SK" } - }) - ExpectRequest("UI.GetSupportedLanguages", true, { - languages = { - "EN-US","ES-MX","FR-CA","DE-DE","ES-ES","EN-GB","RU-RU", - "TR-TR","PL-PL","FR-FR","IT-IT","SV-SE","PT-PT","NL-NL", - "ZH-TW","JA-JP","AR-SA","KO-KR","PT-BR","CS-CZ","DA-DK", - "NO-NO","NL-BE","EL-GR","HU-HU","FI-FI","SK-SK" } - }) - ExpectRequest("VehicleInfo.GetVehicleType", true, { - vehicleType = - { - make = "Ford", - model = "Fiesta", - modelYear = "2013", - trim = "SE" - } - }) - ExpectRequest("VehicleInfo.GetVehicleData", true, { vin = "52-452-52-752" }) - - local function button_capability(name, shortPressAvailable, longPressAvailable, upDownAvailable) - return - { - name = name, - shortPressAvailable = shortPressAvailable == nil and true or shortPressAvailable, - longPressAvailable = longPressAvailable == nil and true or longPressAvailable, - upDownAvailable = upDownAvailable == nil and true or upDownAvailable - } + local bc_update_app_list + if hmi_table_internal.BasicCommunication then + bc_update_app_list = hmi_table_internal.BasicCommunication.UpdateAppList + hmi_table_internal.BasicCommunication.UpdateAppList = nil end - local buttons_capabilities = - { - capabilities = - { - button_capability("PRESET_0"), - button_capability("PRESET_1"), - button_capability("PRESET_2"), - button_capability("PRESET_3"), - button_capability("PRESET_4"), - button_capability("PRESET_5"), - button_capability("PRESET_6"), - button_capability("PRESET_7"), - button_capability("PRESET_8"), - button_capability("PRESET_9"), - button_capability("OK", true, false, true), - button_capability("SEEKLEFT"), - button_capability("SEEKRIGHT"), - button_capability("TUNEUP"), - button_capability("TUNEDOWN") - }, - presetBankCapabilities = { onScreenPresetsAvailable = true } - } - ExpectRequest("Buttons.GetCapabilities", true, buttons_capabilities) - ExpectRequest("VR.GetCapabilities", true, { vrCapabilities = { "TEXT" } }) - ExpectRequest("TTS.GetCapabilities", true, { - speechCapabilities = { "TEXT", "PRE_RECORDED" }, - prerecordedSpeechCapabilities = - { - "HELP_JINGLE", - "INITIAL_JINGLE", - "LISTEN_JINGLE", - "POSITIVE_JINGLE", - "NEGATIVE_JINGLE" - } - }) - - local function text_field(name, characterSet, width, rows) - return - { - name = name, - characterSet = characterSet or "TYPE2SET", - width = width or 500, - rows = rows or 1 - } - end - local function image_field(name, width, height) - return - { - name = name, - imageTypeSupported = - { - "GRAPHIC_BMP", - "GRAPHIC_JPEG", - "GRAPHIC_PNG" - }, - imageResolution = - { - resolutionWidth = width or 64, - resolutionHeight = height or 64 - } - } - + for k_module, v_module in pairs(hmi_table_internal) do + if type(v_module) ~= "table" then + break + end + for k_request, v_request in pairs(v_module) do + local request_name = k_module .. "." .. k_request + ExpectRequest(request_name, v_request) + end end - ExpectRequest("UI.GetCapabilities", true, { - displayCapabilities = - { - displayType = "GEN2_8_DMA", - textFields = - { - text_field("mainField1"), - text_field("mainField2"), - text_field("mainField3"), - text_field("mainField4"), - text_field("statusBar"), - text_field("mediaClock"), - text_field("mediaTrack"), - text_field("alertText1"), - text_field("alertText2"), - text_field("alertText3"), - text_field("scrollableMessageBody"), - text_field("initialInteractionText"), - text_field("navigationText1"), - text_field("navigationText2"), - text_field("ETA"), - text_field("totalDistance"), - text_field("navigationText"), - text_field("audioPassThruDisplayText1"), - text_field("audioPassThruDisplayText2"), - text_field("sliderHeader"), - text_field("sliderFooter"), - text_field("notificationText"), - text_field("menuName"), - text_field("secondaryText"), - text_field("tertiaryText"), - text_field("timeToDestination"), - text_field("turnText"), - text_field("menuTitle"), - text_field("locationName"), - text_field("locationDescription"), - text_field("addressLines"), - text_field("phoneNumber") - }, - imageFields = - { - image_field("softButtonImage"), - image_field("choiceImage"), - image_field("choiceSecondaryImage"), - image_field("vrHelpItem"), - image_field("turnIcon"), - image_field("menuIcon"), - image_field("cmdIcon"), - image_field("showConstantTBTIcon"), - image_field("locationImage") - }, - mediaClockFormats = - { - "CLOCK1", - "CLOCK2", - "CLOCK3", - "CLOCKTEXT1", - "CLOCKTEXT2", - "CLOCKTEXT3", - "CLOCKTEXT4" - }, - graphicSupported = true, - imageCapabilities = { "DYNAMIC", "STATIC" }, - templatesAvailable = { "TEMPLATE" }, - screenParams = - { - resolution = { resolutionWidth = 800, resolutionHeight = 480 }, - touchEventAvailable = - { - pressAvailable = true, - multiTouchAvailable = true, - doublePressAvailable = false - } - }, - numCustomPresetsAvailable = 10 - }, - audioPassThruCapabilities = - { - samplingRate = "44KHZ", - bitsPerSample = "8_BIT", - audioType = "PCM" - }, - hmiZoneCapabilities = "FRONT", - softButtonCapabilities = - { - { - shortPressAvailable = true, - longPressAvailable = true, - upDownAvailable = true, - imageSupported = true - } - } - }) - - ExpectRequest("VR.IsReady", true, { available = true }) - ExpectRequest("TTS.IsReady", true, { available = true }) - ExpectRequest("UI.IsReady", true, { available = true }) - ExpectRequest("Navigation.IsReady", true, { available = true }) - ExpectRequest("VehicleInfo.IsReady", true, { available = true }) - - self.applications = { } - ExpectRequest("BasicCommunication.UpdateAppList", false, { }) - :Pin() - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) - self.applications = { } + if type(bc_update_app_list) == "table" then + ExpectRequest("BasicCommunication.UpdateAppList", bc_update_app_list) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + self.applications = {} for _, app in pairs(data.params.applications) do self.applications[app.appName] = app.appID end end) + end + self.hmiConnection:SendNotification("BasicCommunication.OnReady") return exp_waiter.expectation end @@ -664,28 +464,4 @@ function module:startSession() return mobile_connected end -function enableFullATFLogs() - function enableFullLoggintTestCase() - if (config.storeFullATFLogs) then - module:FailTestCase("full ATF logs already enabled") - else - config.storeFullATFLogs = true - end - end - module["EnableFullATFLogs"] = nil - module["EnableFullATFLogs"] = enableFullLoggintTestCase -end - -function disableFullATFLogs() - function disableFullLoggintTestCase() - if (not config.storeFullATFLogs) then - module:FailTestCase("full ATF logs already disabled") - else - config.storeFullATFLogs = false - end - end - module["DisableFullATFLogs"] = nil - module["DisableFullATFLogs"] = disableFullLoggintTestCase -end - return module diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua new file mode 100644 index 0000000000..1988ec0caa --- /dev/null +++ b/user_modules/hmi_values.lua @@ -0,0 +1,425 @@ +local module = { } + +--[[ Functions for Values' Creation ]] +--[[ @createButtonCapability: the function creates a value for Buttons.GetCapabilities +--! @parameters: +--! for shortPressAvailable, longPressAvailable and upDownAvailable params "true" is +-- default value, so if they are not specified or equal to different values +-- than "false" they are set to "true" ]] +function module.createButtonCapability(name, shortPressAvailable, longPressAvailable, upDownAvailable) + return { + name = name, + shortPressAvailable = shortPressAvailable ~= false or false, + longPressAvailable = longPressAvailable ~= false or false, + upDownAvailable = upDownAvailable ~= false or false + } +end + +--[[ @createTextField: the function creates a value for UI.GetCapabilities.displayCapabilities.textFields ]] +function module.createTextField(name, characterSet, width, rows) + return { + name = name, + characterSet = characterSet or "TYPE2SET", + width = width or 500, + rows = rows or 1 + } +end + +--[[ @createImageField: the function creates a value for UI.GetCapabilities.displayCapabilities.imageFields ]] +function module.createImageField(name, width, height) + return { + name = name, + imageTypeSupported = { + "GRAPHIC_BMP", + "GRAPHIC_JPEG", + "GRAPHIC_PNG" + }, + imageResolution = { + resolutionWidth = width or 64, + resolutionHeight = height or 64 + } + } +end + +--[[ @getDefaultHMITable: the function returns the default value for HMI Table containing all default values +-- used in dummy_connecttest->initHMI_onReady() ]] +function module.getDefaultHMITable() + local default_language = "EN-US" + local default_languages = { + "EN-US","ES-MX","FR-CA","DE-DE","ES-ES","EN-GB","RU-RU", + "TR-TR","PL-PL","FR-FR","IT-IT","SV-SE","PT-PT","NL-NL", + "ZH-TW","JA-JP","AR-SA","KO-KR","PT-BR","CS-CZ","DA-DK", + "NO-NO","NL-BE","EL-GR","HU-HU","FI-FI","SK-SK" + } + local hmi_table = { + BasicCommunication = { }, + UI = { }, + VR = { }, + TTS = { }, + VehicleInfo = { }, + Buttons = { }, + Navigation = { }, + RC = { } + } + -- "params" subtables contain values to be passed for creating expectations in + -- initHMI_onReady() function of "connecttest"/"dummy_connecttest" file. + + -- "mandatory" and "pinned" fields defined here to control execution flow + -- in initHMI_onReady() function + + -- "mandatory" field with a "true" value means that this expectation must happen one time + -- "true" value is default for "mandatory" field + + -- "pinned" field with a "false" value means that this expectation will be pinned, so that + -- it will be expected even after initHMI_onReady() finishes it's execution + -- "false" value is default for "pinned" field + + hmi_table.BasicCommunication.MixingAudioSupported = { + params = { + attenuatedSupported = true + }, + mandatory = true, + pinned = false + } + + hmi_table.BasicCommunication.GetSystemInfo = { + params = { + ccpu_version = "ccpu_version", + language = "EN-US", + wersCountryCode = "wersCountryCode" + }, + mandatory = false, + pinned = false + } + + hmi_table.UI.GetLanguage = { + params = { + language = default_language + }, + mandatory = true, + pinned = false + } + + hmi_table.VR.GetLanguage = { + params = { + language = default_language + }, + mandatory = true, + pinned = false + } + + hmi_table.TTS.GetLanguage = { + params = { + language = default_language + }, + mandatory = true, + pinned = false + } + + hmi_table.BasicCommunication.UpdateDeviceList = { + params = { }, + mandatory = false, + pinned = true + } + + hmi_table.UI.ChangeRegistration = { + params = { }, + mandatory = false, + pinned = true + } + + hmi_table.VR.ChangeRegistration = { + params = { }, + mandatory = false, + pinned = true + } + + hmi_table.TTS.ChangeRegistration = { + params = { }, + mandatory = false, + pinned = true + } + + hmi_table.TTS.SetGlobalProperties = { + params = { }, + mandatory = false, + pinned = true + } + + hmi_table.UI.GetSupportedLanguages = { + params = { + languages = default_languages + }, + mandatory = true, + pinned = false + } + + hmi_table.VR.GetSupportedLanguages = { + params = { + languages = default_languages + }, + mandatory = true, + pinned = false + } + + hmi_table.TTS.GetSupportedLanguages = { + params = { + languages = default_languages + }, + mandatory = true, + pinned = false + } + + hmi_table.VehicleInfo.GetVehicleType = { + params = { + vehicleType = { + make = "Ford", + model = "Fiesta", + modelYear = "2013", + trim = "SE" + } + }, + mandatory = true, + pinned = false + } + + hmi_table.VehicleInfo.GetVehicleData = { + params = { + vin = "52-452-52-752" + }, + mandatory = true, + pinned = false + } + + hmi_table.UI.GetCapabilities = { + params = { + displayCapabilities = { + displayType = "GEN2_8_DMA", + textFields = (function() + local fields = { + "mainField1", "mainField2", "mainField3", "mainField4", "statusBar", "mediaClock", "mediaTrack", + "alertText1", "alertText2", "alertText3", "scrollableMessageBody", "initialInteractionText", + "navigationText1", "navigationText2", "ETA", "totalDistance", "navigationText", "audioPassThruDisplayText1", + "audioPassThruDisplayText2", "sliderHeader", "sliderFooter", "notificationText", "menuName", + "secondaryText", "tertiaryText", "timeToDestination", "turnText", "menuTitle", "locationName", + "locationDescription", "addressLines", "phoneNumber" + } + local out = { } + for _, field in pairs(fields) do + table.insert(out, module.createTextField(field)) + end + return out + end)(), + imageFields = (function() + local fields = { + "softButtonImage", "choiceImage", "choiceSecondaryImage", "vrHelpItem", "turnIcon", "menuIcon", "cmdIcon", + "showConstantTBTIcon", "locationImage" + } + local out = { } + for _, field in pairs(fields) do + table.insert(out, module.createImageField(field)) + end + return out + end)(), + mediaClockFormats = { "CLOCK1", "CLOCK2", "CLOCK3", "CLOCKTEXT1", "CLOCKTEXT2", "CLOCKTEXT3", "CLOCKTEXT4" }, + graphicSupported = true, + imageCapabilities = { "DYNAMIC", "STATIC" }, + templatesAvailable = { "TEMPLATE" }, + screenParams = { + resolution = { resolutionWidth = 800, resolutionHeight = 480 }, + touchEventAvailable = { + pressAvailable = true, + multiTouchAvailable = true, + doublePressAvailable = false + } + }, + numCustomPresetsAvailable = 10 + }, + audioPassThruCapabilities = { + samplingRate = "44KHZ", + bitsPerSample = "8_BIT", + audioType = "PCM" + }, + hmiZoneCapabilities = "FRONT", + softButtonCapabilities = { + { + shortPressAvailable = true, + longPressAvailable = true, + upDownAvailable = true, + imageSupported = true + } + }, + hmiCapabilities = { navigation = true, phoneCall = true }, + systemCapabilities = { + navigationCapability = { + sendLocationEnabled = true, + getWayPointsEnabled = true + }, + phoneCapability = { + dialNumberEnabled = true + } + } + }, + mandatory = true, + pinned = false + } + + hmi_table.VR.GetCapabilities = { + params = { + vrCapabilities = { "TEXT" } + }, + mandatory = true, + pinned = false + } + + hmi_table.TTS.GetCapabilities = { + params = { + speechCapabilities = { "TEXT", "PRE_RECORDED" }, + prerecordedSpeechCapabilities = { + "HELP_JINGLE", "INITIAL_JINGLE", "LISTEN_JINGLE", "POSITIVE_JINGLE","NEGATIVE_JINGLE" + } + }, + mandatory = true, + pinned = false + } + + hmi_table.Buttons.GetCapabilities = { + params = { + capabilities = { + module.createButtonCapability("PRESET_0"), + module.createButtonCapability("PRESET_1"), + module.createButtonCapability("PRESET_2"), + module.createButtonCapability("PRESET_3"), + module.createButtonCapability("PRESET_4"), + module.createButtonCapability("PRESET_5"), + module.createButtonCapability("PRESET_6"), + module.createButtonCapability("PRESET_7"), + module.createButtonCapability("PRESET_8"), + module.createButtonCapability("PRESET_9"), + module.createButtonCapability("OK", true, false, true), + module.createButtonCapability("SEEKLEFT"), + module.createButtonCapability("SEEKRIGHT"), + module.createButtonCapability("TUNEUP"), + module.createButtonCapability("TUNEDOWN") + }, + presetBankCapabilities = { onScreenPresetsAvailable = true }, + }, + mandatory = true, + pinned = false + } + + hmi_table.RC.GetCapabilities = { + params = { + remoteControlCapability = { + climateControlCapabilities = { + { + moduleName = "Climate", + fanSpeedAvailable = true, + desiredTemperatureAvailable = true, + acEnableAvailable = true, + acMaxEnableAvailable = true, + circulateAirEnableAvailable = true, + autoModeEnableAvailable = true, + dualModeEnableAvailable = true, + defrostZoneAvailable = true, + defrostZone = { + "FRONT", "REAR", "ALL", "NONE" + }, + ventilationModeAvailable = true, + ventilationMode = { + "UPPER", "LOWER", "BOTH", "NONE" + } + } + }, + radioControlCapabilities = { + { + moduleName = "Radio", + radioEnableAvailable = true, + radioBandAvailable = true, + radioFrequencyAvailable = true, + hdChannelAvailable = true, + rdsDataAvailable = true, + availableHDsAvailable = true, + stateAvailable = true, + signalStrengthAvailable = true, + signalChangeThresholdAvailable = true + } + }, + buttonCapabilities = (function() + local buttons = { + -- climate + "AC_MAX", "AC", "RECIRCULATE", "FAN_UP", "FAN_DOWN", "TEMP_UP", "TEMP_DOWN", "DEFROST_MAX", "DEFROST", + "DEFROST_REAR", "UPPER_VENT", "LOWER_VENT", + -- radio + "VOLUME_UP", "VOLUME_DOWN", "EJECT", "SOURCE", "SHUFFLE", "REPEAT" + } + local out = { } + for _, button in pairs(buttons) do + table.insert(out, module.createButtonCapability(button, true, true, true)) + end + return out + end)() + } + }, + mandatory = true, + pinned = false + } + + hmi_table.UI.IsReady = { + params = { + available = true + }, + mandatory = true, + pinned = false + } + + hmi_table.VR.IsReady = { + params = { + available = true + }, + mandatory = true, + pinned = false + } + + hmi_table.TTS.IsReady = { + params = { + available = true + }, + mandatory = true, + pinned = false + } + + hmi_table.VehicleInfo.IsReady = { + params = { + available = true + }, + mandatory = true, + pinned = false + } + + hmi_table.Navigation.IsReady = { + params = { + available = true + }, + mandatory = true, + pinned = false + } + + hmi_table.RC.IsReady = { + params = { + available = true + }, + mandatory = true, + pinned = false + } + + hmi_table.BasicCommunication.UpdateAppList = { + params = { }, + mandatory = false, + pinned = true + } + + return hmi_table +end + +return module From f0fe00124c4bc441bc8405dff527827aef234063 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Fri, 11 Aug 2017 14:45:45 +0300 Subject: [PATCH 111/681] Updated RC common and dummy_connecttest --- test_scripts/RC/commonRC.lua | 39 ++++++++++++++++++++++++++++++ user_modules/dummy_connecttest.lua | 16 ++++++++---- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 85a3f37506..fa04f41e0b 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -14,6 +14,7 @@ local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") local mobile_session = require("mobile_session") local json = require("modules/json") +local hmi_values = require("user_modules/hmi_values") --[[ Local Variables ]] local ptu_table = {} @@ -22,6 +23,7 @@ local hmiAppIds = {} local commonRC = {} commonRC.timeout = 2000 +commonRC.DEFAULT = "Default" local function getPTUFromPTS(tbl) tbl.policy_table.consumer_friendly_messages.messages = nil @@ -635,4 +637,41 @@ function commonRC.rpcRejectWithoutConsent(pModuleType, pAppId, pRPC, self) commonTestCases:DelayedExp(commonRC.timeout) end +function commonRC.buildButtonCapability(name, shortPressAvailable, longPressAvailable, upDownAvailable) + return hmi_values.createButtonCapability(name, shortPressAvailable, longPressAvailable, upDownAvailable) +end + +function commonRC.buildHmiRcCapabilities(pClimateCapabilities, pRadioCapabilities, pButtonCapabilities) + local hmiParams = hmi_values.getDefaultHMITable() + local capParams = hmiParams.RC.GetCapabilities.params.remoteControlCapability + + hmiParams.RC.IsReady.params.available = true + + if pClimateCapabilities then + if pClimateCapabilities ~= commonRC.DEFAULT then + capParams.climateControlCapabilities = pClimateCapabilities + end + else + capParams.climateControlCapabilities = nil + end + + if pRadioCapabilities then + if pClimateCapabilities ~= commonRC.DEFAULT then + capParams.radioControlCapabilities = pRadioCapabilities + end + else + capParams.radioControlCapabilities = nil + end + + if pButtonCapabilities then + if pButtonCapabilities ~= commonRC.DEFAULT then + capParams.buttonCapabilities = pButtonCapabilities + end + else + capParams.buttonCapabilities = nil + end + + return hmiParams +end + return commonRC diff --git a/user_modules/dummy_connecttest.lua b/user_modules/dummy_connecttest.lua index 73639a3af5..acca2c1737 100644 --- a/user_modules/dummy_connecttest.lua +++ b/user_modules/dummy_connecttest.lua @@ -13,6 +13,7 @@ local SDL = require('SDL') local exit_codes = require('exit_codes') local load_schema = require('load_schema') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local hmi_values = require("user_modules/hmi_values") local mob_schema = load_schema.mob_schema local hmi_schema = load_schema.hmi_schema @@ -378,20 +379,25 @@ function module:initHMI_onReady(hmi_table) return data.method == name end local exp = EXPECT_HMIEVENT(event, name) - :Times(hmi_table_element.mandatory and 1 or AnyNumber()) + :Times(hmi_table_element.occurrence or hmi_table_element.mandatory and 1 or AnyNumber()) :Do(function(_, data) - xmlReporter.AddMessage("hmi_connection","SendResponse", + if hmi_table_element.occurrence ~= 0 then + xmlReporter.AddMessage("hmi_connection","SendResponse", { ["methodName"] = tostring(name), ["mandatory"] = hmi_table_element.mandatory, ["params"] = hmi_table_element.params }) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", hmi_table_element.params) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", hmi_table_element.params) + end end) - if hmi_table_element.mandatory then + if hmi_table_element.occurrence == 0 then + commonTestCases:DelayedExp(3000) + end + if hmi_table_element.mandatory or hmi_table_element.occurrence then exp_waiter:AddExpectation(exp) end - if hmi_table_element.pinned then + if hmi_table_element.pinned and hmi_table_element.occurrence ~= 0 then exp:Pin() end return exp From d8383f1608d395790cc7ee4e451a8661a1391ecb Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Fri, 11 Aug 2017 14:51:10 +0300 Subject: [PATCH 112/681] Added test set for RC.GetCapabilities --- test_sets/rc_Capabilities.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 test_sets/rc_Capabilities.txt diff --git a/test_sets/rc_Capabilities.txt b/test_sets/rc_Capabilities.txt new file mode 100644 index 0000000000..36ea3ca5b6 --- /dev/null +++ b/test_sets/rc_Capabilities.txt @@ -0,0 +1 @@ +./test_scripts/RC/Capabilities/001_All_modules_all_params.lua From eb5f7e916b42438ac3b77105959e36a0b9231990 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Fri, 11 Aug 2017 17:07:29 +0300 Subject: [PATCH 113/681] Add tests for RC.GetCapabilities to check allowed rc modules --- .../001_All_modules_all_params.lua | 34 +++++++++++++++++++ .../010_Only_CLIMATE_all_params.lua | 34 +++++++++++++++++++ .../011_Only_RADIO_all_params.lua | 34 +++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 test_scripts/RC/Capabilities/001_All_modules_all_params.lua create mode 100644 test_scripts/RC/Capabilities/010_Only_CLIMATE_all_params.lua create mode 100644 test_scripts/RC/Capabilities/011_Only_RADIO_all_params.lua diff --git a/test_scripts/RC/Capabilities/001_All_modules_all_params.lua b/test_scripts/RC/Capabilities/001_All_modules_all_params.lua new file mode 100644 index 0000000000..3d1f1405a7 --- /dev/null +++ b/test_scripts/RC/Capabilities/001_All_modules_all_params.lua @@ -0,0 +1,34 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- 1) SDL gets all RC capabilities for RADIO and CLIMATE modules through RC.GetCapabilities +-- SDL must: +-- 1) Send RPC request to HMI and resend HMI answer to Mobile app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI (HMI has all posible RC capabilities), connect Mobile, start Session", commonRC.start, + {commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, commonRC.DEFAULT, commonRC.DEFAULT)}) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App1", commonRC.activate_app) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod, commonRC.subscribeToModule, { mod, 1 }) + runner.Step("SetInteriorVehicleData " .. mod, commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + runner.Step("ButtonPress " .. mod, commonRC.rpcAllowed, { mod, 1, "ButtonPress" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/Capabilities/010_Only_CLIMATE_all_params.lua b/test_scripts/RC/Capabilities/010_Only_CLIMATE_all_params.lua new file mode 100644 index 0000000000..374bb0c44c --- /dev/null +++ b/test_scripts/RC/Capabilities/010_Only_CLIMATE_all_params.lua @@ -0,0 +1,34 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- 1) SDL does not get RC capabilities for RADIO module through RC.GetCapabilities +-- SDL must: +-- 1) Response with success = false and resultCode = UNSUPPORTED_RESOURCE on all valid RPC with module RADIO +-- 2) Does not send RPC request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI (HMI has all CLIMATE RC capabilities), connect Mobile, start Session", commonRC.start, + {commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, nil, commonRC.DEFAULT)}) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App1", commonRC.activate_app) + +runner.Title("Test") + +-- CLIMATE RPC is allowed +runner.Step("GetInteriorVehicleData CLIMATE", commonRC.subscribeToModule, { "CLIMATE", 1 }) +runner.Step("SetInteriorVehicleData CLIMATE", commonRC.rpcAllowed, { "CLIMATE", 1, "SetInteriorVehicleData" }) +-- RADIO PRC is unsupported +runner.Step("GetInteriorVehicleData RADIO", commonRC.rpcDenied, { "RADIO", 1, "GetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) +runner.Step("SetInteriorVehicleData RADIO", commonRC.rpcDenied, { "RADIO", 1, "SetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/Capabilities/011_Only_RADIO_all_params.lua b/test_scripts/RC/Capabilities/011_Only_RADIO_all_params.lua new file mode 100644 index 0000000000..243bdd45cf --- /dev/null +++ b/test_scripts/RC/Capabilities/011_Only_RADIO_all_params.lua @@ -0,0 +1,34 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- 1) SDL does not get RC capabilities for CLIMATE module through RC.GetCapabilities +-- SDL must: +-- 1) Response with success = false and resultCode = UNSUPPORTED_RESOURCE on all valid RPC with module CLIMATE +-- 2) Does not send RPC request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI (HMI has all CLIMATE RC capabilities), connect Mobile, start Session", commonRC.start, + {commonRC.buildHmiRcCapabilities(nil, commonRC.DEFAULT, commonRC.DEFAULT)}) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App1", commonRC.activate_app) + +runner.Title("Test") + +-- RADIO RPC is allowed +runner.Step("GetInteriorVehicleData RADIO", commonRC.subscribeToModule, { "RADIO", 1 }) +runner.Step("SetInteriorVehicleData RADIO", commonRC.rpcAllowed, { "RADIO", 1, "SetInteriorVehicleData" }) +-- CLIMATE PRC is unsupported +runner.Step("GetInteriorVehicleData CLIMATE", commonRC.rpcDenied, { "CLIMATE", 1, "GetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) +runner.Step("SetInteriorVehicleData CLIMATE", commonRC.rpcDenied, { "CLIMATE", 1, "SetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) From 50a024cda393c613a51b91ed6d38c3b5acf0070e Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Fri, 11 Aug 2017 17:19:03 +0300 Subject: [PATCH 114/681] Add tests into test set rc_Capabilities --- test_sets/rc_Capabilities.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test_sets/rc_Capabilities.txt b/test_sets/rc_Capabilities.txt index 36ea3ca5b6..2741abe69c 100644 --- a/test_sets/rc_Capabilities.txt +++ b/test_sets/rc_Capabilities.txt @@ -1 +1,3 @@ ./test_scripts/RC/Capabilities/001_All_modules_all_params.lua +./test_scripts/RC/Capabilities/010_Only_CLIMATE_all_params.lua +./test_scripts/RC/Capabilities/011_Only_RADIO_all_params.lua From f7e391bfbbaca92d571c6514017292403dd8e083 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 11 Aug 2017 17:25:00 +0300 Subject: [PATCH 115/681] SystemCapabilities: Fix for zero occurences --- user_modules/dummy_connecttest.lua | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/user_modules/dummy_connecttest.lua b/user_modules/dummy_connecttest.lua index acca2c1737..0c678f4c1e 100644 --- a/user_modules/dummy_connecttest.lua +++ b/user_modules/dummy_connecttest.lua @@ -373,15 +373,21 @@ function module:initHMI_onReady(hmi_table) local exp_waiter = commonFunctions:createMultipleExpectationsWaiter(module, "HMI on ready") local function ExpectRequest(name, hmi_table_element) + if hmi_table_element.occurrence == 0 then + commonFunctions:printTable(hmi_table_element) + EXPECT_HMICALL(name, hmi_table_element.params) + :Times(0) + commonTestCases:DelayedExp(3000) + return + end local event = events.Event() event.level = 2 event.matches = function(self, data) return data.method == name end local exp = EXPECT_HMIEVENT(event, name) - :Times(hmi_table_element.occurrence or hmi_table_element.mandatory and 1 or AnyNumber()) + :Times(hmi_table_element.mandatory and 1 or AnyNumber()) :Do(function(_, data) - if hmi_table_element.occurrence ~= 0 then xmlReporter.AddMessage("hmi_connection","SendResponse", { ["methodName"] = tostring(name), @@ -389,15 +395,11 @@ function module:initHMI_onReady(hmi_table) ["params"] = hmi_table_element.params }) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", hmi_table_element.params) - end - end) - if hmi_table_element.occurrence == 0 then - commonTestCases:DelayedExp(3000) - end - if hmi_table_element.mandatory or hmi_table_element.occurrence then + end) + if hmi_table_element.mandatory then exp_waiter:AddExpectation(exp) end - if hmi_table_element.pinned and hmi_table_element.occurrence ~= 0 then + if hmi_table_element.pinned then exp:Pin() end return exp From d4aab1543bfc407d4c8a88ad1f32d683532fd6de Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 11 Aug 2017 17:51:36 +0300 Subject: [PATCH 116/681] SystemCapabilities: Fix for zero occurences, remove printing --- user_modules/dummy_connecttest.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/user_modules/dummy_connecttest.lua b/user_modules/dummy_connecttest.lua index 0c678f4c1e..f0f815a1cc 100644 --- a/user_modules/dummy_connecttest.lua +++ b/user_modules/dummy_connecttest.lua @@ -374,7 +374,6 @@ function module:initHMI_onReady(hmi_table) local function ExpectRequest(name, hmi_table_element) if hmi_table_element.occurrence == 0 then - commonFunctions:printTable(hmi_table_element) EXPECT_HMICALL(name, hmi_table_element.params) :Times(0) commonTestCases:DelayedExp(3000) From b57e9317a4a6af1d77f16e6c4cda2d1dc04a75c2 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Sat, 12 Aug 2017 16:51:41 +0300 Subject: [PATCH 117/681] Fix: App activation is added due to impossibility to send RPCs in NONE HMI level --- .../001_success_flow_for_climate_and_radio.lua | 3 +++ .../002_disallow_flow_by_policy_for_climate.lua | 3 +++ .../003_disallow_flow_by_policy_for_radio.lua | 3 +++ ...4_check_processing_button_press_for_nonRC_App.lua | 12 +++++++++++- ...ttonName_and_moduleType_for_radio_and_climate.lua | 3 +++ .../006_check_rpc_parameters_for_button_press.lua | 2 ++ ...7_button_press_allowed_if_moduleType_is_empty.lua | 1 + ...tton_press_disallowed_if_moduleType_is_absent.lua | 1 + ...lowed_if_moduleType_is_disallowed_by_policies.lua | 1 + .../010_generic_error_if_no_response_from_hmi.lua | 1 + ...ric_error_if_read_only_response_come_from_hmi.lua | 1 + ...12_generic_error_if_invalid_response_from_hmi.lua | 1 + .../013_Transfering_of_HMI_resultCode_to_mobile.lua | 1 + .../RC/GetInteriorVehicleData/001_Success_flow.lua | 1 + .../002_Disallow_flow_by_policy_CLIMATE.lua | 1 + .../003_Disallow_flow_by_policy_RADIO.lua | 1 + ...flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua | 10 +++++++++- .../005_Transfering_of_HMI_resultCode_to_mobile.lua | 7 +------ .../006_RPC_parameters_values.lua | 1 + ...007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua | 1 + ...C_ERROR_in_case_HMI_respond_with_invalid_data.lua | 1 + ...w_in_case_moduleType_is_an_empty_array_in_LPT.lua | 1 + ...llow_flow_in_case_moduleType_is_absent_in_LPT.lua | 1 + ...ERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua | 1 + ...er_but_response_from_HMI_without_isSubscribed.lua | 1 + ...meter_but_response_from_HMI_with_isSubscribed.lua | 1 + ...MI_in_case_of_2nd_Subscription_UnSubscription.lua | 1 + .../RC/OnInteriorVehicleData/001_Success_flow.lua | 1 + .../002_Disallow_flow_by_policy_CLIMATE.lua | 1 + .../003_Disallow_flow_by_policy_RADIO.lua | 1 + ...l_subscribing_with_isSubscribe_false_from_HMI.lua | 1 + ...full_subscribing_without_isSubscribe_from_HMI.lua | 1 + ...VD_in_case_of_subscribing_with_error_from_HMI.lua | 1 + ...case_of_subscribing_with_no_response_from_HMI.lua | 1 + ...of_subscribing_with_invalid_response_from_HMI.lua | 1 + ..._unsubscribing_with_isSubscribe_true_from_HMI.lua | 1 + ...ll_unsubscribing_without_isSubscribe_from_HMI.lua | 1 + ...ll_unsubscribing_without_isSubscribe_from_HMI.lua | 1 + ...dule_Climate_and_without_one_for_module_Radio.lua | 1 + ...dule_Radio_and_without_one_for_module_Climate.lua | 1 + ...imate_and_after_unsubscribe_from_module_Radio.lua | 1 + ...dio_and_after_unsubscribe_from_module_Climate.lua | 1 + .../016_RPC_parameters_values.lua | 1 + .../019_Release_resource_on_RC_disable.lua | 10 +++++++--- .../RC/SetInteriorVehicleData/001_Success_flow.lua | 1 + .../002_Disallow_flow_by_policy_CLIMATE.lua | 1 + .../003_Disallow_flow_by_policy_RADIO.lua | 1 + ...flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua | 10 +++++++++- ...case_params_does_not_correspond_to_moduleType.lua | 1 + .../006_RPC_parameters_values.lua | 1 + ...w_in_case_moduleType_is_an_empty_array_in_LPT.lua | 1 + ...llow_flow_in_case_moduleType_is_absent_in_LPT.lua | 1 + .../009_Cut-off_of_fake_parameters_from_App.lua | 1 + ...or_vehicle_data_if_read_only_params_requested.lua | 2 ++ ...t_with_read-only_and_not_read-only_parameters.lua | 1 + ...ead-only_parameters_and_HMI_returns_READ_ONLY.lua | 1 + ...013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua | 1 + ...C_ERROR_in_case_HMI_respond_with_invalid_data.lua | 1 + .../015_Transfering_of_HMI_resultCode_to_mobile.lua | 1 + test_scripts/RC/commonRC.lua | 4 +--- 60 files changed, 102 insertions(+), 15 deletions(-) diff --git a/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua b/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua index d44b19a0d3..69f4b62622 100644 --- a/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua +++ b/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua @@ -60,8 +60,11 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + runner.Title("Test") runner.Step("ButtonPress_CLIMATE", step1) runner.Step("ButtonPress_RADIO", step2) + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua b/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua index fe14aecc0c..43bebb95f6 100644 --- a/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua +++ b/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua @@ -40,7 +40,10 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) + runner.Title("Test") runner.Step("ButtonPress_CLIMATE", step1) + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua b/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua index 5ddef5caea..9a7cbdadbd 100644 --- a/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua +++ b/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua @@ -40,7 +40,10 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) + runner.Title("Test") runner.Step("ButtonPress_RADIO", step1) + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua b/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua index a93a07e8d2..aecf9f95fd 100644 --- a/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua +++ b/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua @@ -48,13 +48,23 @@ local function step2(self) commonTestCases:DelayedExp(commonRC.timeout) end +local function ptu_update_func(tbl) + local appId = config.application1.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId].moduleType = nil + tbl.policy_table.app_policies[appId].groups_primaryRC = nil + tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } +end + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) + runner.Title("Test") runner.Step("ButtonPress_CLIMATE", step1) runner.Step("ButtonPress_RADIO", step2) + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua b/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua index d3c4fbfd2c..1cd58891b4 100644 --- a/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua +++ b/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua @@ -51,8 +51,11 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + runner.Title("Test") runner.Step("ButtonPress_CLIMATE", step1) runner.Step("ButtonPress_RADIO", step2) + runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua b/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua index 2964cd6a0d..443c066660 100644 --- a/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua +++ b/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua @@ -81,6 +81,8 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + for _, button_name_value in pairs( climate_button_names ) do local climate_params = reset_climate_params() climate_params.buttonPressMode = "SHORT" diff --git a/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua b/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua index 66ba6dc033..81e30926b4 100644 --- a/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua +++ b/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua @@ -48,6 +48,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua b/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua index b2bd640311..a984fd67c0 100644 --- a/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua +++ b/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua @@ -43,6 +43,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua b/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua index e45a7b3ad8..758d22d7c3 100644 --- a/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua +++ b/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua @@ -43,6 +43,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua b/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua index 7bb95e092c..fa79885692 100644 --- a/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua +++ b/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua @@ -45,6 +45,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua b/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua index bc38139ec1..3c3f8799a2 100644 --- a/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua +++ b/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua @@ -42,6 +42,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua b/test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua index a1750f6f4b..e7dc526429 100644 --- a/test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua +++ b/test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua @@ -42,6 +42,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua index 3b0c6ce839..2a2e4890de 100644 --- a/test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua @@ -67,6 +67,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua index e22910a07f..3aa2a50868 100644 --- a/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua @@ -21,6 +21,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index a71b17e25d..50193c6789 100644 --- a/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -41,6 +41,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) diff --git a/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index 10dff7359a..c390e17419 100644 --- a/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -41,6 +41,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) diff --git a/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index dcbd58749b..eb7309b37e 100644 --- a/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -34,11 +34,19 @@ local function getDataForModule(pModuleType, self) commonTestCases:DelayedExp(commonRC.timeout) end +local function ptu_update_func(tbl) + local appId = config.application1.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId].moduleType = nil + tbl.policy_table.app_policies[appId].groups_primaryRC = nil + tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } +end + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua index 377be284cd..675ceb7e51 100644 --- a/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua @@ -41,12 +41,6 @@ local function stepSuccessfull(pModuleType, pResultCode, self) isSubscribed = false, moduleData = commonRC.getModuleControlData(pModuleType) }) - -- :ValidIf(function(_, data) -- no isSubscribed parameter - -- if data.payload.isSubscribed == nil then - -- return true - -- end - -- return false, 'Parameter "isSubscribed" is transfered to App with value: ' .. tostring(data.payload.isSubscribed) - -- end) end local function stepUnsuccessfull(pModuleType, pResultCode, self) @@ -72,6 +66,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua index d4a9d7740c..16bff682a6 100644 --- a/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua @@ -93,6 +93,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index f046e6942e..c7e41627ab 100644 --- a/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -43,6 +43,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index aa8f4eb94c..ef2ceab027 100644 --- a/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -68,6 +68,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 7c49c61968..c497913a6c 100644 --- a/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -52,6 +52,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 21ccfe0edc..2ea6ade00d 100644 --- a/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -42,6 +42,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua index 96c77d61ec..7fa9b553f7 100644 --- a/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +++ b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -40,6 +40,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua index c7d967c8b8..38599e564f 100644 --- a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -58,6 +58,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index 3ad649179c..4a4e78c85b 100644 --- a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -58,6 +58,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua b/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua index 2cf852df9c..d93fbefd8d 100644 --- a/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +++ b/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua @@ -64,6 +64,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua index f78a0af0bb..0c24a7bb75 100644 --- a/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua @@ -37,6 +37,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 5c09d9bd8c..33ae435d99 100644 --- a/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -27,6 +27,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") runner.Step("GetInteriorVehicleData " .. mod, commonRC.subscribeToModule, { mod }) diff --git a/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index 23e518687e..8904115be9 100644 --- a/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -27,6 +27,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") runner.Step("GetInteriorVehicleData " .. mod, commonRC.subscribeToModule, { mod }) diff --git a/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua index 10ec88f9b0..52779155fd 100644 --- a/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -48,6 +48,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua index 5b9567b2f5..caebc8277c 100644 --- a/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua @@ -48,6 +48,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua index 5143d33957..2bec5fb8c9 100644 --- a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua @@ -50,6 +50,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua index a26cb06952..d73d98a59b 100644 --- a/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua @@ -45,6 +45,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua index bd5ef719b4..af4fbf88bc 100644 --- a/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua @@ -45,6 +45,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua index 53014b07aa..394c815624 100644 --- a/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua @@ -49,6 +49,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) for _, mod in pairs(modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) diff --git a/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua index bd4a3dbd31..f1ef3f82c0 100644 --- a/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -49,6 +49,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) for _, mod in pairs(modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) diff --git a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua index 6efb448672..aaec99ddc1 100644 --- a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -52,6 +52,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) for _, mod in pairs(modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) diff --git a/test_scripts/RC/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua b/test_scripts/RC/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua index a73ba2a70c..3b4fc78055 100644 --- a/test_scripts/RC/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua +++ b/test_scripts/RC/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua @@ -23,6 +23,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua b/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua index 99d6b362ac..0fdbdd5a57 100644 --- a/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua +++ b/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua @@ -23,6 +23,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua b/test_scripts/RC/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua index 1bf2ae4061..c8f18ca3cf 100644 --- a/test_scripts/RC/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua +++ b/test_scripts/RC/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua @@ -25,6 +25,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) for _, mod in pairs(modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) diff --git a/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua b/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua index ee70399404..8b4bbe4e26 100644 --- a/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua +++ b/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua @@ -25,6 +25,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) for _, mod in pairs(modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) diff --git a/test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua b/test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua index b37d005e58..2f32e09f6e 100644 --- a/test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua +++ b/test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua @@ -66,6 +66,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) for _, mod in pairs(modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) diff --git a/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua b/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua index be4768a034..bda82155a1 100644 --- a/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua +++ b/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua @@ -42,18 +42,22 @@ for _,initialAccessMode in pairs(accessModes) do for _,appLevel in pairs(HMILevels) do runner.Title(initialAccessMode .. " -> Disable RC -> " .. targetAccessMode .. " (" .. appLevel .. ")") for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) runner.Step("Enable RC from HMI with " .. initialAccessMode .." access mode", commonRC.defineRAMode, { true, initialAccessMode }) runner.Step("Activate App1", commonRC.activate_app) - runner.Step("Check module " .. mod .." App1 " .. rcRpcs[1] .. " allowed", commonRC.rpcAllowed, { mod, 1, rcRpcs[1] }) + runner.Step("Check App1 " .. rcRpcs[1] .. " allowed", commonRC.rpcAllowed, { mod, 1, rcRpcs[1] }) runner.Step("Disable RC from HMI", commonRC.defineRAMode, { false, initialAccessMode }) runner.Step("Enable RC from HMI with " .. targetAccessMode .. " access mode", commonRC.defineRAMode, { true, targetAccessMode }) if appLevel == "FULL" then runner.Step("Activate App2", commonRC.activate_app, { 2 }) - runner.Step("Check module " .. mod .." App2 " .. rcRpcs[2] .. " allowed", commonRC.rpcAllowed, { mod, 2, rcRpcs[2] }) + runner.Step("Check App2 " .. rcRpcs[2] .. " allowed", commonRC.rpcAllowed, { mod, 2, rcRpcs[2] }) else - runner.Step("Check module " .. mod .." App2 " .. rcRpcs[2] .. " allowed", commonRC.rpcAllowed, { mod, 2, rcRpcs[2] }) + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App1", commonRC.activate_app, { 1 }) + runner.Step("Check App2 " .. rcRpcs[2] .. " allowed", commonRC.rpcAllowed, { mod, 2, rcRpcs[2] }) runner.Step("Activate App2", commonRC.activate_app, { 2 }) end + runner.Step("Disable RC from HMI", commonRC.defineRAMode, { false, targetAccessMode }) end end end diff --git a/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua index efde9990f4..9af1af9ef0 100644 --- a/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua @@ -41,6 +41,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 784342e616..19417cdb74 100644 --- a/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -41,6 +41,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) diff --git a/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index 73f21169b3..72aa6b7b1f 100644 --- a/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -41,6 +41,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) diff --git a/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index b5fc906a71..cb56f0e1af 100644 --- a/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -34,11 +34,19 @@ local function setVehicleData(pModuleType, self) commonTestCases:DelayedExp(commonRC.timeout) end +local function ptu_update_func(tbl) + local appId = config.application1.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId].moduleType = nil + tbl.policy_table.app_policies[appId].groups_primaryRC = nil + tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } +end + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua b/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua index 3c740caf4a..3ca2372395 100644 --- a/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua +++ b/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua @@ -46,6 +46,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua index 51c529fcfa..f565e81cf3 100644 --- a/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua @@ -90,6 +90,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 9ae24ad6a0..77ce47065d 100644 --- a/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -46,6 +46,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 153881422c..4cd9641e6f 100644 --- a/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -41,6 +41,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua b/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua index 697e9a67ce..48918f3215 100644 --- a/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua +++ b/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua @@ -41,6 +41,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua b/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua index a10bf58761..7d33717506 100644 --- a/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +++ b/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua @@ -34,6 +34,8 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + runner.Title("Test: SDL respond with READ_ONLY if SetInteriorVehicleData is sent with read_only params") for parameter_name, parameter_value in pairs(module_data_climate.climateControlData) do diff --git a/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua b/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua index ae2d6e508e..0d2f3f0b04 100644 --- a/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua +++ b/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua @@ -73,6 +73,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua b/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua index dbb0dcecf4..05115d44d2 100644 --- a/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua +++ b/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua @@ -38,6 +38,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index c8cb021b4f..d88a639882 100644 --- a/test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -41,6 +41,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index c0dc604ac3..c2a046f589 100644 --- a/test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -63,6 +63,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua index 7ffeea391d..080f6e7e4f 100644 --- a/test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua @@ -60,6 +60,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 9dee190684..0c9d8a742f 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -99,9 +99,6 @@ end local function updatePTU(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() - tbl.policy_table.functional_groupings["RemoteControl"].rpcs.OnInteriorVehicleData = { - hmi_levels = { "BACKGROUND", "FULL", "LIMITED", "NONE" } - } end local function jsonFileToTable(file_name) @@ -627,6 +624,7 @@ function commonRC.defineRAMode(pAllowed, pAccessMode, self) self, pAccessMode = commonRC.getSelfAndParams(pAccessMode, self) local rpc = "OnRemoteControlSettings" self.hmiConnection:SendNotification(commonRC.getHMIEventName(rpc), commonRC.getHMIResponseParams(rpc, pAllowed, pAccessMode)) + commonTestCases:DelayedExp(500) -- workaround due to issue with SDL -> redundant OnHMIStatus notification is sent end function commonRC.rpcDenied(pModuleType, pAppId, pRPC, pResultCode, self) From 64d4efced3fdd8781651ca9e6da870c994055d46 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 11 Aug 2017 12:13:01 +0300 Subject: [PATCH 118/681] SystemCapabilities: Common modules --- test_scripts/RC/commonRC.lua | 58 +--- user_modules/dummy_connecttest.lua | 318 ++++----------------- user_modules/hmi_values.lua | 425 +++++++++++++++++++++++++++++ 3 files changed, 476 insertions(+), 325 deletions(-) create mode 100644 user_modules/hmi_values.lua diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 0c9d8a742f..c2b5384d17 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -23,57 +23,6 @@ local commonRC = {} commonRC.timeout = 2000 -local function initHMI(self) - local exp_waiter = commonFunctions:createMultipleExpectationsWaiter(self, "HMI initialization") - local function registerComponent(name, subscriptions) - local rid = self.hmiConnection:SendRequest("MB.registerComponent", { componentName = name }) - local exp = EXPECT_HMIRESPONSE(rid) - exp_waiter:AddExpectation(exp) - if subscriptions then - for _, s in ipairs(subscriptions) do - exp:Do(function() - rid = self.hmiConnection:SendRequest("MB.subscribeTo", { propertyName = s }) - exp = EXPECT_HMIRESPONSE(rid) - exp_waiter:AddExpectation(exp) - end) - end - end - end - - local web_socket_connected_event = EXPECT_HMIEVENT(events.connectedEvent, "Connected websocket") - :Do(function() - registerComponent("Buttons", {"Buttons.OnButtonSubscription"}) - registerComponent("TTS") - registerComponent("VR") - registerComponent("BasicCommunication", { - "BasicCommunication.OnPutFile", - "SDL.OnStatusUpdate", - "SDL.OnAppPermissionChanged", - "BasicCommunication.OnSDLPersistenceComplete", - "BasicCommunication.OnFileRemoved", - "BasicCommunication.OnAppRegistered", - "BasicCommunication.OnAppUnregistered", - "BasicCommunication.PlayTone", - "BasicCommunication.OnSDLClose", - "SDL.OnSDLConsentNeeded", - "BasicCommunication.OnResumeAudioSource" - }) - registerComponent("UI", { - "UI.OnRecordStart" - }) - registerComponent("VehicleInfo") - registerComponent("RC") - registerComponent("Navigation", { - "Navigation.OnAudioDataStreaming", - "Navigation.OnVideoDataStreaming" - }) - end) - exp_waiter:AddExpectation(web_socket_connected_event) - - self.hmiConnection:Connect() - return exp_waiter.expectation -end - local function getPTUFromPTS(tbl) tbl.policy_table.consumer_friendly_messages.messages = nil tbl.policy_table.device_data = nil @@ -156,14 +105,15 @@ function commonRC.preconditions() commonSteps:DeleteLogsFiles() end -function commonRC.start(self) +function commonRC.start(pHMIParams, self) + self, pHMIParams = commonRC.getSelfAndParams(pHMIParams, self) self:runSDL() commonFunctions:waitForSDLStart(self) :Do(function() - initHMI(self) + self:initHMI(self) :Do(function() commonFunctions:userPrint(35, "HMI initialized") - self:initHMI_onReady() + self:initHMI_onReady(pHMIParams) :Do(function() commonFunctions:userPrint(35, "HMI is ready") self:connectMobile() diff --git a/user_modules/dummy_connecttest.lua b/user_modules/dummy_connecttest.lua index 2b186a2637..73639a3af5 100644 --- a/user_modules/dummy_connecttest.lua +++ b/user_modules/dummy_connecttest.lua @@ -13,6 +13,7 @@ local SDL = require('SDL') local exit_codes = require('exit_codes') local load_schema = require('load_schema') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local hmi_values = require("user_modules/hmi_values") local mob_schema = load_schema.mob_schema local hmi_schema = load_schema.hmi_schema @@ -350,6 +351,7 @@ function module:initHMI() "UI.OnRecordStart" }) registerComponent("VehicleInfo") + registerComponent("RC") registerComponent("Navigation", { "Navigation.OnAudioDataStreaming", @@ -362,275 +364,73 @@ function module:initHMI() return exp_waiter.expectation end -function module:initHMI_onReady() +--[[ @initHMI_onReady: the function is HMI's onReady response +--! @parameters: +--! @hmi_table - hmi_table of hmi specification values, default one is specified in "user_modules/hmi_values" +--! @example: self:initHMI_onReady(local_hmi_table) ]] +function module:initHMI_onReady(hmi_table) local exp_waiter = commonFunctions:createMultipleExpectationsWaiter(module, "HMI on ready") - local function ExpectRequest(name, mandatory, params) + + local function ExpectRequest(name, hmi_table_element) local event = events.Event() event.level = 2 event.matches = function(self, data) return data.method == name end local exp = EXPECT_HMIEVENT(event, name) - :Times(mandatory and 1 or AnyNumber()) + :Times(hmi_table_element.mandatory and 1 or AnyNumber()) :Do(function(_, data) - xmlReporter.AddMessage("hmi_connection","SendResponse", - { - ["methodName"] = tostring(name), - ["mandatory"] = mandatory , - ["params"]= params - }) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", params) - end) - if (mandatory) then - exp_waiter:AddExpectation(exp) + xmlReporter.AddMessage("hmi_connection","SendResponse", + { + ["methodName"] = tostring(name), + ["mandatory"] = hmi_table_element.mandatory, + ["params"] = hmi_table_element.params + }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", hmi_table_element.params) + end) + if hmi_table_element.mandatory then + exp_waiter:AddExpectation(exp) + end + if hmi_table_element.pinned then + exp:Pin() end return exp end - local function ExpectNotification(name, mandatory) - xmlReporter.AddMessage(debug.getinfo(1, "n").name, tostring(name)) - local event = events.Event() - event.level = 2 - event.matches = function(self, data) return data.method == name end - local exp = EXPECT_HMIEVENT(event, name) - :Times(mandatory and 1 or AnyNumber()) - exp_waiter:AddExpectation(exp) - return exp + local hmi_table_internal + if type(hmi_table) == "table" then + hmi_table_internal = commonFunctions:cloneTable(hmi_table) + else + hmi_table_internal = hmi_values.getDefaultHMITable() end - ExpectRequest("BasicCommunication.MixingAudioSupported", - true, - { attenuatedSupported = true }) - ExpectRequest("BasicCommunication.GetSystemInfo", false, - { - ccpu_version = "ccpu_version", - language = "EN-US", - wersCountryCode = "wersCountryCode" - }) - ExpectRequest("UI.GetLanguage", true, { language = "EN-US" }) - ExpectRequest("VR.GetLanguage", true, { language = "EN-US" }) - ExpectRequest("TTS.GetLanguage", true, { language = "EN-US" }) - ExpectRequest("UI.ChangeRegistration", false, { }):Pin() - ExpectRequest("TTS.SetGlobalProperties", false, { }):Pin() - ExpectRequest("BasicCommunication.UpdateDeviceList", false, { }):Pin() - ExpectRequest("VR.ChangeRegistration", false, { }):Pin() - ExpectRequest("TTS.ChangeRegistration", false, { }):Pin() - ExpectRequest("VR.GetSupportedLanguages", true, { - languages = { - "EN-US","ES-MX","FR-CA","DE-DE","ES-ES","EN-GB","RU-RU", - "TR-TR","PL-PL","FR-FR","IT-IT","SV-SE","PT-PT","NL-NL", - "ZH-TW","JA-JP","AR-SA","KO-KR","PT-BR","CS-CZ","DA-DK", - "NO-NO","NL-BE","EL-GR","HU-HU","FI-FI","SK-SK" } - }) - ExpectRequest("TTS.GetSupportedLanguages", true, { - languages = { - "EN-US","ES-MX","FR-CA","DE-DE","ES-ES","EN-GB","RU-RU", - "TR-TR","PL-PL","FR-FR","IT-IT","SV-SE","PT-PT","NL-NL", - "ZH-TW","JA-JP","AR-SA","KO-KR","PT-BR","CS-CZ","DA-DK", - "NO-NO","NL-BE","EL-GR","HU-HU","FI-FI","SK-SK" } - }) - ExpectRequest("UI.GetSupportedLanguages", true, { - languages = { - "EN-US","ES-MX","FR-CA","DE-DE","ES-ES","EN-GB","RU-RU", - "TR-TR","PL-PL","FR-FR","IT-IT","SV-SE","PT-PT","NL-NL", - "ZH-TW","JA-JP","AR-SA","KO-KR","PT-BR","CS-CZ","DA-DK", - "NO-NO","NL-BE","EL-GR","HU-HU","FI-FI","SK-SK" } - }) - ExpectRequest("VehicleInfo.GetVehicleType", true, { - vehicleType = - { - make = "Ford", - model = "Fiesta", - modelYear = "2013", - trim = "SE" - } - }) - ExpectRequest("VehicleInfo.GetVehicleData", true, { vin = "52-452-52-752" }) - - local function button_capability(name, shortPressAvailable, longPressAvailable, upDownAvailable) - return - { - name = name, - shortPressAvailable = shortPressAvailable == nil and true or shortPressAvailable, - longPressAvailable = longPressAvailable == nil and true or longPressAvailable, - upDownAvailable = upDownAvailable == nil and true or upDownAvailable - } + local bc_update_app_list + if hmi_table_internal.BasicCommunication then + bc_update_app_list = hmi_table_internal.BasicCommunication.UpdateAppList + hmi_table_internal.BasicCommunication.UpdateAppList = nil end - local buttons_capabilities = - { - capabilities = - { - button_capability("PRESET_0"), - button_capability("PRESET_1"), - button_capability("PRESET_2"), - button_capability("PRESET_3"), - button_capability("PRESET_4"), - button_capability("PRESET_5"), - button_capability("PRESET_6"), - button_capability("PRESET_7"), - button_capability("PRESET_8"), - button_capability("PRESET_9"), - button_capability("OK", true, false, true), - button_capability("SEEKLEFT"), - button_capability("SEEKRIGHT"), - button_capability("TUNEUP"), - button_capability("TUNEDOWN") - }, - presetBankCapabilities = { onScreenPresetsAvailable = true } - } - ExpectRequest("Buttons.GetCapabilities", true, buttons_capabilities) - ExpectRequest("VR.GetCapabilities", true, { vrCapabilities = { "TEXT" } }) - ExpectRequest("TTS.GetCapabilities", true, { - speechCapabilities = { "TEXT", "PRE_RECORDED" }, - prerecordedSpeechCapabilities = - { - "HELP_JINGLE", - "INITIAL_JINGLE", - "LISTEN_JINGLE", - "POSITIVE_JINGLE", - "NEGATIVE_JINGLE" - } - }) - - local function text_field(name, characterSet, width, rows) - return - { - name = name, - characterSet = characterSet or "TYPE2SET", - width = width or 500, - rows = rows or 1 - } - end - local function image_field(name, width, height) - return - { - name = name, - imageTypeSupported = - { - "GRAPHIC_BMP", - "GRAPHIC_JPEG", - "GRAPHIC_PNG" - }, - imageResolution = - { - resolutionWidth = width or 64, - resolutionHeight = height or 64 - } - } - + for k_module, v_module in pairs(hmi_table_internal) do + if type(v_module) ~= "table" then + break + end + for k_request, v_request in pairs(v_module) do + local request_name = k_module .. "." .. k_request + ExpectRequest(request_name, v_request) + end end - ExpectRequest("UI.GetCapabilities", true, { - displayCapabilities = - { - displayType = "GEN2_8_DMA", - textFields = - { - text_field("mainField1"), - text_field("mainField2"), - text_field("mainField3"), - text_field("mainField4"), - text_field("statusBar"), - text_field("mediaClock"), - text_field("mediaTrack"), - text_field("alertText1"), - text_field("alertText2"), - text_field("alertText3"), - text_field("scrollableMessageBody"), - text_field("initialInteractionText"), - text_field("navigationText1"), - text_field("navigationText2"), - text_field("ETA"), - text_field("totalDistance"), - text_field("navigationText"), - text_field("audioPassThruDisplayText1"), - text_field("audioPassThruDisplayText2"), - text_field("sliderHeader"), - text_field("sliderFooter"), - text_field("notificationText"), - text_field("menuName"), - text_field("secondaryText"), - text_field("tertiaryText"), - text_field("timeToDestination"), - text_field("turnText"), - text_field("menuTitle"), - text_field("locationName"), - text_field("locationDescription"), - text_field("addressLines"), - text_field("phoneNumber") - }, - imageFields = - { - image_field("softButtonImage"), - image_field("choiceImage"), - image_field("choiceSecondaryImage"), - image_field("vrHelpItem"), - image_field("turnIcon"), - image_field("menuIcon"), - image_field("cmdIcon"), - image_field("showConstantTBTIcon"), - image_field("locationImage") - }, - mediaClockFormats = - { - "CLOCK1", - "CLOCK2", - "CLOCK3", - "CLOCKTEXT1", - "CLOCKTEXT2", - "CLOCKTEXT3", - "CLOCKTEXT4" - }, - graphicSupported = true, - imageCapabilities = { "DYNAMIC", "STATIC" }, - templatesAvailable = { "TEMPLATE" }, - screenParams = - { - resolution = { resolutionWidth = 800, resolutionHeight = 480 }, - touchEventAvailable = - { - pressAvailable = true, - multiTouchAvailable = true, - doublePressAvailable = false - } - }, - numCustomPresetsAvailable = 10 - }, - audioPassThruCapabilities = - { - samplingRate = "44KHZ", - bitsPerSample = "8_BIT", - audioType = "PCM" - }, - hmiZoneCapabilities = "FRONT", - softButtonCapabilities = - { - { - shortPressAvailable = true, - longPressAvailable = true, - upDownAvailable = true, - imageSupported = true - } - } - }) - - ExpectRequest("VR.IsReady", true, { available = true }) - ExpectRequest("TTS.IsReady", true, { available = true }) - ExpectRequest("UI.IsReady", true, { available = true }) - ExpectRequest("Navigation.IsReady", true, { available = true }) - ExpectRequest("VehicleInfo.IsReady", true, { available = true }) - - self.applications = { } - ExpectRequest("BasicCommunication.UpdateAppList", false, { }) - :Pin() - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) - self.applications = { } + if type(bc_update_app_list) == "table" then + ExpectRequest("BasicCommunication.UpdateAppList", bc_update_app_list) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + self.applications = {} for _, app in pairs(data.params.applications) do self.applications[app.appName] = app.appID end end) + end + self.hmiConnection:SendNotification("BasicCommunication.OnReady") return exp_waiter.expectation end @@ -664,28 +464,4 @@ function module:startSession() return mobile_connected end -function enableFullATFLogs() - function enableFullLoggintTestCase() - if (config.storeFullATFLogs) then - module:FailTestCase("full ATF logs already enabled") - else - config.storeFullATFLogs = true - end - end - module["EnableFullATFLogs"] = nil - module["EnableFullATFLogs"] = enableFullLoggintTestCase -end - -function disableFullATFLogs() - function disableFullLoggintTestCase() - if (not config.storeFullATFLogs) then - module:FailTestCase("full ATF logs already disabled") - else - config.storeFullATFLogs = false - end - end - module["DisableFullATFLogs"] = nil - module["DisableFullATFLogs"] = disableFullLoggintTestCase -end - return module diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua new file mode 100644 index 0000000000..1988ec0caa --- /dev/null +++ b/user_modules/hmi_values.lua @@ -0,0 +1,425 @@ +local module = { } + +--[[ Functions for Values' Creation ]] +--[[ @createButtonCapability: the function creates a value for Buttons.GetCapabilities +--! @parameters: +--! for shortPressAvailable, longPressAvailable and upDownAvailable params "true" is +-- default value, so if they are not specified or equal to different values +-- than "false" they are set to "true" ]] +function module.createButtonCapability(name, shortPressAvailable, longPressAvailable, upDownAvailable) + return { + name = name, + shortPressAvailable = shortPressAvailable ~= false or false, + longPressAvailable = longPressAvailable ~= false or false, + upDownAvailable = upDownAvailable ~= false or false + } +end + +--[[ @createTextField: the function creates a value for UI.GetCapabilities.displayCapabilities.textFields ]] +function module.createTextField(name, characterSet, width, rows) + return { + name = name, + characterSet = characterSet or "TYPE2SET", + width = width or 500, + rows = rows or 1 + } +end + +--[[ @createImageField: the function creates a value for UI.GetCapabilities.displayCapabilities.imageFields ]] +function module.createImageField(name, width, height) + return { + name = name, + imageTypeSupported = { + "GRAPHIC_BMP", + "GRAPHIC_JPEG", + "GRAPHIC_PNG" + }, + imageResolution = { + resolutionWidth = width or 64, + resolutionHeight = height or 64 + } + } +end + +--[[ @getDefaultHMITable: the function returns the default value for HMI Table containing all default values +-- used in dummy_connecttest->initHMI_onReady() ]] +function module.getDefaultHMITable() + local default_language = "EN-US" + local default_languages = { + "EN-US","ES-MX","FR-CA","DE-DE","ES-ES","EN-GB","RU-RU", + "TR-TR","PL-PL","FR-FR","IT-IT","SV-SE","PT-PT","NL-NL", + "ZH-TW","JA-JP","AR-SA","KO-KR","PT-BR","CS-CZ","DA-DK", + "NO-NO","NL-BE","EL-GR","HU-HU","FI-FI","SK-SK" + } + local hmi_table = { + BasicCommunication = { }, + UI = { }, + VR = { }, + TTS = { }, + VehicleInfo = { }, + Buttons = { }, + Navigation = { }, + RC = { } + } + -- "params" subtables contain values to be passed for creating expectations in + -- initHMI_onReady() function of "connecttest"/"dummy_connecttest" file. + + -- "mandatory" and "pinned" fields defined here to control execution flow + -- in initHMI_onReady() function + + -- "mandatory" field with a "true" value means that this expectation must happen one time + -- "true" value is default for "mandatory" field + + -- "pinned" field with a "false" value means that this expectation will be pinned, so that + -- it will be expected even after initHMI_onReady() finishes it's execution + -- "false" value is default for "pinned" field + + hmi_table.BasicCommunication.MixingAudioSupported = { + params = { + attenuatedSupported = true + }, + mandatory = true, + pinned = false + } + + hmi_table.BasicCommunication.GetSystemInfo = { + params = { + ccpu_version = "ccpu_version", + language = "EN-US", + wersCountryCode = "wersCountryCode" + }, + mandatory = false, + pinned = false + } + + hmi_table.UI.GetLanguage = { + params = { + language = default_language + }, + mandatory = true, + pinned = false + } + + hmi_table.VR.GetLanguage = { + params = { + language = default_language + }, + mandatory = true, + pinned = false + } + + hmi_table.TTS.GetLanguage = { + params = { + language = default_language + }, + mandatory = true, + pinned = false + } + + hmi_table.BasicCommunication.UpdateDeviceList = { + params = { }, + mandatory = false, + pinned = true + } + + hmi_table.UI.ChangeRegistration = { + params = { }, + mandatory = false, + pinned = true + } + + hmi_table.VR.ChangeRegistration = { + params = { }, + mandatory = false, + pinned = true + } + + hmi_table.TTS.ChangeRegistration = { + params = { }, + mandatory = false, + pinned = true + } + + hmi_table.TTS.SetGlobalProperties = { + params = { }, + mandatory = false, + pinned = true + } + + hmi_table.UI.GetSupportedLanguages = { + params = { + languages = default_languages + }, + mandatory = true, + pinned = false + } + + hmi_table.VR.GetSupportedLanguages = { + params = { + languages = default_languages + }, + mandatory = true, + pinned = false + } + + hmi_table.TTS.GetSupportedLanguages = { + params = { + languages = default_languages + }, + mandatory = true, + pinned = false + } + + hmi_table.VehicleInfo.GetVehicleType = { + params = { + vehicleType = { + make = "Ford", + model = "Fiesta", + modelYear = "2013", + trim = "SE" + } + }, + mandatory = true, + pinned = false + } + + hmi_table.VehicleInfo.GetVehicleData = { + params = { + vin = "52-452-52-752" + }, + mandatory = true, + pinned = false + } + + hmi_table.UI.GetCapabilities = { + params = { + displayCapabilities = { + displayType = "GEN2_8_DMA", + textFields = (function() + local fields = { + "mainField1", "mainField2", "mainField3", "mainField4", "statusBar", "mediaClock", "mediaTrack", + "alertText1", "alertText2", "alertText3", "scrollableMessageBody", "initialInteractionText", + "navigationText1", "navigationText2", "ETA", "totalDistance", "navigationText", "audioPassThruDisplayText1", + "audioPassThruDisplayText2", "sliderHeader", "sliderFooter", "notificationText", "menuName", + "secondaryText", "tertiaryText", "timeToDestination", "turnText", "menuTitle", "locationName", + "locationDescription", "addressLines", "phoneNumber" + } + local out = { } + for _, field in pairs(fields) do + table.insert(out, module.createTextField(field)) + end + return out + end)(), + imageFields = (function() + local fields = { + "softButtonImage", "choiceImage", "choiceSecondaryImage", "vrHelpItem", "turnIcon", "menuIcon", "cmdIcon", + "showConstantTBTIcon", "locationImage" + } + local out = { } + for _, field in pairs(fields) do + table.insert(out, module.createImageField(field)) + end + return out + end)(), + mediaClockFormats = { "CLOCK1", "CLOCK2", "CLOCK3", "CLOCKTEXT1", "CLOCKTEXT2", "CLOCKTEXT3", "CLOCKTEXT4" }, + graphicSupported = true, + imageCapabilities = { "DYNAMIC", "STATIC" }, + templatesAvailable = { "TEMPLATE" }, + screenParams = { + resolution = { resolutionWidth = 800, resolutionHeight = 480 }, + touchEventAvailable = { + pressAvailable = true, + multiTouchAvailable = true, + doublePressAvailable = false + } + }, + numCustomPresetsAvailable = 10 + }, + audioPassThruCapabilities = { + samplingRate = "44KHZ", + bitsPerSample = "8_BIT", + audioType = "PCM" + }, + hmiZoneCapabilities = "FRONT", + softButtonCapabilities = { + { + shortPressAvailable = true, + longPressAvailable = true, + upDownAvailable = true, + imageSupported = true + } + }, + hmiCapabilities = { navigation = true, phoneCall = true }, + systemCapabilities = { + navigationCapability = { + sendLocationEnabled = true, + getWayPointsEnabled = true + }, + phoneCapability = { + dialNumberEnabled = true + } + } + }, + mandatory = true, + pinned = false + } + + hmi_table.VR.GetCapabilities = { + params = { + vrCapabilities = { "TEXT" } + }, + mandatory = true, + pinned = false + } + + hmi_table.TTS.GetCapabilities = { + params = { + speechCapabilities = { "TEXT", "PRE_RECORDED" }, + prerecordedSpeechCapabilities = { + "HELP_JINGLE", "INITIAL_JINGLE", "LISTEN_JINGLE", "POSITIVE_JINGLE","NEGATIVE_JINGLE" + } + }, + mandatory = true, + pinned = false + } + + hmi_table.Buttons.GetCapabilities = { + params = { + capabilities = { + module.createButtonCapability("PRESET_0"), + module.createButtonCapability("PRESET_1"), + module.createButtonCapability("PRESET_2"), + module.createButtonCapability("PRESET_3"), + module.createButtonCapability("PRESET_4"), + module.createButtonCapability("PRESET_5"), + module.createButtonCapability("PRESET_6"), + module.createButtonCapability("PRESET_7"), + module.createButtonCapability("PRESET_8"), + module.createButtonCapability("PRESET_9"), + module.createButtonCapability("OK", true, false, true), + module.createButtonCapability("SEEKLEFT"), + module.createButtonCapability("SEEKRIGHT"), + module.createButtonCapability("TUNEUP"), + module.createButtonCapability("TUNEDOWN") + }, + presetBankCapabilities = { onScreenPresetsAvailable = true }, + }, + mandatory = true, + pinned = false + } + + hmi_table.RC.GetCapabilities = { + params = { + remoteControlCapability = { + climateControlCapabilities = { + { + moduleName = "Climate", + fanSpeedAvailable = true, + desiredTemperatureAvailable = true, + acEnableAvailable = true, + acMaxEnableAvailable = true, + circulateAirEnableAvailable = true, + autoModeEnableAvailable = true, + dualModeEnableAvailable = true, + defrostZoneAvailable = true, + defrostZone = { + "FRONT", "REAR", "ALL", "NONE" + }, + ventilationModeAvailable = true, + ventilationMode = { + "UPPER", "LOWER", "BOTH", "NONE" + } + } + }, + radioControlCapabilities = { + { + moduleName = "Radio", + radioEnableAvailable = true, + radioBandAvailable = true, + radioFrequencyAvailable = true, + hdChannelAvailable = true, + rdsDataAvailable = true, + availableHDsAvailable = true, + stateAvailable = true, + signalStrengthAvailable = true, + signalChangeThresholdAvailable = true + } + }, + buttonCapabilities = (function() + local buttons = { + -- climate + "AC_MAX", "AC", "RECIRCULATE", "FAN_UP", "FAN_DOWN", "TEMP_UP", "TEMP_DOWN", "DEFROST_MAX", "DEFROST", + "DEFROST_REAR", "UPPER_VENT", "LOWER_VENT", + -- radio + "VOLUME_UP", "VOLUME_DOWN", "EJECT", "SOURCE", "SHUFFLE", "REPEAT" + } + local out = { } + for _, button in pairs(buttons) do + table.insert(out, module.createButtonCapability(button, true, true, true)) + end + return out + end)() + } + }, + mandatory = true, + pinned = false + } + + hmi_table.UI.IsReady = { + params = { + available = true + }, + mandatory = true, + pinned = false + } + + hmi_table.VR.IsReady = { + params = { + available = true + }, + mandatory = true, + pinned = false + } + + hmi_table.TTS.IsReady = { + params = { + available = true + }, + mandatory = true, + pinned = false + } + + hmi_table.VehicleInfo.IsReady = { + params = { + available = true + }, + mandatory = true, + pinned = false + } + + hmi_table.Navigation.IsReady = { + params = { + available = true + }, + mandatory = true, + pinned = false + } + + hmi_table.RC.IsReady = { + params = { + available = true + }, + mandatory = true, + pinned = false + } + + hmi_table.BasicCommunication.UpdateAppList = { + params = { }, + mandatory = false, + pinned = true + } + + return hmi_table +end + +return module From 0076b980e92a3de7afe26a31fab8138046d460e8 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Fri, 11 Aug 2017 14:45:45 +0300 Subject: [PATCH 119/681] Updated RC common and dummy_connecttest --- test_scripts/RC/commonRC.lua | 39 ++++++++++++++++++++++++++++++ user_modules/dummy_connecttest.lua | 16 ++++++++---- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index c2b5384d17..a7a3204df3 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -14,6 +14,7 @@ local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") local mobile_session = require("mobile_session") local json = require("modules/json") +local hmi_values = require("user_modules/hmi_values") --[[ Local Variables ]] local ptu_table = {} @@ -22,6 +23,7 @@ local hmiAppIds = {} local commonRC = {} commonRC.timeout = 2000 +commonRC.DEFAULT = "Default" local function getPTUFromPTS(tbl) tbl.policy_table.consumer_friendly_messages.messages = nil @@ -633,4 +635,41 @@ function commonRC.rpcRejectWithoutConsent(pModuleType, pAppId, pRPC, self) commonTestCases:DelayedExp(commonRC.timeout) end +function commonRC.buildButtonCapability(name, shortPressAvailable, longPressAvailable, upDownAvailable) + return hmi_values.createButtonCapability(name, shortPressAvailable, longPressAvailable, upDownAvailable) +end + +function commonRC.buildHmiRcCapabilities(pClimateCapabilities, pRadioCapabilities, pButtonCapabilities) + local hmiParams = hmi_values.getDefaultHMITable() + local capParams = hmiParams.RC.GetCapabilities.params.remoteControlCapability + + hmiParams.RC.IsReady.params.available = true + + if pClimateCapabilities then + if pClimateCapabilities ~= commonRC.DEFAULT then + capParams.climateControlCapabilities = pClimateCapabilities + end + else + capParams.climateControlCapabilities = nil + end + + if pRadioCapabilities then + if pClimateCapabilities ~= commonRC.DEFAULT then + capParams.radioControlCapabilities = pRadioCapabilities + end + else + capParams.radioControlCapabilities = nil + end + + if pButtonCapabilities then + if pButtonCapabilities ~= commonRC.DEFAULT then + capParams.buttonCapabilities = pButtonCapabilities + end + else + capParams.buttonCapabilities = nil + end + + return hmiParams +end + return commonRC diff --git a/user_modules/dummy_connecttest.lua b/user_modules/dummy_connecttest.lua index 73639a3af5..acca2c1737 100644 --- a/user_modules/dummy_connecttest.lua +++ b/user_modules/dummy_connecttest.lua @@ -13,6 +13,7 @@ local SDL = require('SDL') local exit_codes = require('exit_codes') local load_schema = require('load_schema') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local hmi_values = require("user_modules/hmi_values") local mob_schema = load_schema.mob_schema local hmi_schema = load_schema.hmi_schema @@ -378,20 +379,25 @@ function module:initHMI_onReady(hmi_table) return data.method == name end local exp = EXPECT_HMIEVENT(event, name) - :Times(hmi_table_element.mandatory and 1 or AnyNumber()) + :Times(hmi_table_element.occurrence or hmi_table_element.mandatory and 1 or AnyNumber()) :Do(function(_, data) - xmlReporter.AddMessage("hmi_connection","SendResponse", + if hmi_table_element.occurrence ~= 0 then + xmlReporter.AddMessage("hmi_connection","SendResponse", { ["methodName"] = tostring(name), ["mandatory"] = hmi_table_element.mandatory, ["params"] = hmi_table_element.params }) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", hmi_table_element.params) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", hmi_table_element.params) + end end) - if hmi_table_element.mandatory then + if hmi_table_element.occurrence == 0 then + commonTestCases:DelayedExp(3000) + end + if hmi_table_element.mandatory or hmi_table_element.occurrence then exp_waiter:AddExpectation(exp) end - if hmi_table_element.pinned then + if hmi_table_element.pinned and hmi_table_element.occurrence ~= 0 then exp:Pin() end return exp From c19f623658bd3b0364f2267dba3c90cd13563d4c Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Fri, 11 Aug 2017 14:51:10 +0300 Subject: [PATCH 120/681] Added test set for RC.GetCapabilities --- test_sets/rc_Capabilities.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 test_sets/rc_Capabilities.txt diff --git a/test_sets/rc_Capabilities.txt b/test_sets/rc_Capabilities.txt new file mode 100644 index 0000000000..36ea3ca5b6 --- /dev/null +++ b/test_sets/rc_Capabilities.txt @@ -0,0 +1 @@ +./test_scripts/RC/Capabilities/001_All_modules_all_params.lua From e23ea08d5a45ef62f4b6d0a28418ce1639d0e18d Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 11 Aug 2017 17:25:00 +0300 Subject: [PATCH 121/681] SystemCapabilities: Fix for zero occurences --- user_modules/dummy_connecttest.lua | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/user_modules/dummy_connecttest.lua b/user_modules/dummy_connecttest.lua index acca2c1737..0c678f4c1e 100644 --- a/user_modules/dummy_connecttest.lua +++ b/user_modules/dummy_connecttest.lua @@ -373,15 +373,21 @@ function module:initHMI_onReady(hmi_table) local exp_waiter = commonFunctions:createMultipleExpectationsWaiter(module, "HMI on ready") local function ExpectRequest(name, hmi_table_element) + if hmi_table_element.occurrence == 0 then + commonFunctions:printTable(hmi_table_element) + EXPECT_HMICALL(name, hmi_table_element.params) + :Times(0) + commonTestCases:DelayedExp(3000) + return + end local event = events.Event() event.level = 2 event.matches = function(self, data) return data.method == name end local exp = EXPECT_HMIEVENT(event, name) - :Times(hmi_table_element.occurrence or hmi_table_element.mandatory and 1 or AnyNumber()) + :Times(hmi_table_element.mandatory and 1 or AnyNumber()) :Do(function(_, data) - if hmi_table_element.occurrence ~= 0 then xmlReporter.AddMessage("hmi_connection","SendResponse", { ["methodName"] = tostring(name), @@ -389,15 +395,11 @@ function module:initHMI_onReady(hmi_table) ["params"] = hmi_table_element.params }) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", hmi_table_element.params) - end - end) - if hmi_table_element.occurrence == 0 then - commonTestCases:DelayedExp(3000) - end - if hmi_table_element.mandatory or hmi_table_element.occurrence then + end) + if hmi_table_element.mandatory then exp_waiter:AddExpectation(exp) end - if hmi_table_element.pinned and hmi_table_element.occurrence ~= 0 then + if hmi_table_element.pinned then exp:Pin() end return exp From 09d09c749e4616f4290ef2f0e18236b3653d4d5b Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 11 Aug 2017 17:51:36 +0300 Subject: [PATCH 122/681] SystemCapabilities: Fix for zero occurences, remove printing --- user_modules/dummy_connecttest.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/user_modules/dummy_connecttest.lua b/user_modules/dummy_connecttest.lua index 0c678f4c1e..f0f815a1cc 100644 --- a/user_modules/dummy_connecttest.lua +++ b/user_modules/dummy_connecttest.lua @@ -374,7 +374,6 @@ function module:initHMI_onReady(hmi_table) local function ExpectRequest(name, hmi_table_element) if hmi_table_element.occurrence == 0 then - commonFunctions:printTable(hmi_table_element) EXPECT_HMICALL(name, hmi_table_element.params) :Times(0) commonTestCases:DelayedExp(3000) From e416c34a143e7dacef9e5dffd9afc63062374dcf Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Sat, 12 Aug 2017 20:21:49 +0300 Subject: [PATCH 123/681] RC: Remove redundant self parameter --- .../005_TIMED_OUT_from_HMI_SIVD.lua | 2 +- .../006_TIMED_OUT_from_HMI_BP.lua | 2 +- .../007_HMI_no_response_SIVD.lua | 2 +- .../008_HMI_no_response_BP.lua | 2 +- .../009_HMI_invalid_response_SIVD.lua | 2 +- .../010_HMI_invalid_response_BP.lua | 2 +- .../011_TIMED_OUT_after_default_timeout.lua | 2 +- .../006_IN_USE_in_case_2_requests.lua | 2 +- test_scripts/RC/commonRC.lua | 32 +++++++++---------- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua index 00bdfbf63b..694a95086d 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua @@ -35,7 +35,7 @@ local function rpcTimedOutHMIResponse(pModuleType, pAppId, pRPC, self) local consentRPC = "GetInteriorVehicleDataConsent" local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", info) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua index 3d17c7a84f..9d4947ef75 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua @@ -35,7 +35,7 @@ local function rpcTimedOutHMIResponse(pModuleType, pAppId, pRPC, self) local consentRPC = "GetInteriorVehicleDataConsent" local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", info) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua index f5394d225b..725c335e7b 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua @@ -32,7 +32,7 @@ local function rpcNoHMIResponse(pModuleType, pAppId, pRPC, self) local consentRPC = "GetInteriorVehicleDataConsent" local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, _) -- HMI does not respond EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua index ce011ad4de..c86594588b 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua @@ -32,7 +32,7 @@ local function rpcNoHMIResponse(pModuleType, pAppId, pRPC, self) local consentRPC = "GetInteriorVehicleDataConsent" local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, _) -- HMI does not respond EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua index 6dd63b8047..26dbfa5bc7 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua @@ -32,7 +32,7 @@ local function rpcInvalidHMIResponse(pModuleType, pAppId, pRPC, self) local consentRPC = "GetInteriorVehicleDataConsent" local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { allowed = "aaa" -- invalid type of parameter diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua index f76ca7a02c..d9e287fd0f 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua @@ -32,7 +32,7 @@ local function rpcInvalidHMIResponse(pModuleType, pAppId, pRPC, self) local consentRPC = "GetInteriorVehicleDataConsent" local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { allowed = "aaa" -- invalid type of parameter diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua index d8ccad4cc1..1b5afe0318 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua @@ -31,7 +31,7 @@ end local function rpcHMIRespondAfterDefaultTimeout(self) local cid1 = self.mobileSession2:SendRPC(commonRC.getAppEventName(pRPC1), commonRC.getAppRequestParams(pRPC1, pModuleType)) local consentRPC = "GetInteriorVehicleDataConsent" - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, 2, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, 2)) :Do(function(_, data) local function hmiRespond() self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", "info") diff --git a/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua b/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua index fbc399435b..3561b19f28 100644 --- a/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua +++ b/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua @@ -52,7 +52,7 @@ local function step(pModuleType, pRPC1, pRPC2, self) buttonPressMode = "SHORT" }) EXPECT_HMICALL("Buttons.ButtonPress", { - appID = commonRC.getHMIAppId(self, 1), + appID = commonRC.getHMIAppId(1), moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 0c9d8a742f..e87c503ca5 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -224,7 +224,7 @@ end function commonRC.unregisterApp(pAppId, self) local mobSession = commonRC.getMobileSession(self, pAppId) - local hmiAppId = commonRC.getHMIAppId(self, pAppId) + local hmiAppId = commonRC.getHMIAppId(pAppId) local cid = mobSession:SendRPC("UnregisterAppInterface",{}) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = hmiAppId, unexpectedDisconnect = false }) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) @@ -436,9 +436,9 @@ local rcRPCs = { subscribe = pSubscribe } end, - hmiRequestParams = function(pModuleType, pAppId, pSubscribe, self) + hmiRequestParams = function(pModuleType, pAppId, pSubscribe) return { - appID = commonRC.getHMIAppId(self, pAppId), + appID = commonRC.getHMIAppId(pAppId), moduleType = pModuleType, subscribe = pSubscribe } @@ -466,9 +466,9 @@ local rcRPCs = { moduleData = commonRC.getSettableModuleControlData(pModuleType) } end, - hmiRequestParams = function(pModuleType, pAppId, self) + hmiRequestParams = function(pModuleType, pAppId) return { - appID = commonRC.getHMIAppId(self, pAppId), + appID = commonRC.getHMIAppId(pAppId), moduleData = commonRC.getSettableModuleControlData(pModuleType) } end, @@ -488,9 +488,9 @@ local rcRPCs = { buttonPressMode = "SHORT" } end, - hmiRequestParams = function(pModuleType, pAppId, self) + hmiRequestParams = function(pModuleType, pAppId) return { - appID = commonRC.getHMIAppId(self, pAppId), + appID = commonRC.getHMIAppId(pAppId), moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" @@ -502,9 +502,9 @@ local rcRPCs = { }, GetInteriorVehicleDataConsent = { hmiEventName = "RC.GetInteriorVehicleDataConsent", - hmiRequestParams = function(pModuleType, pAppId, self) + hmiRequestParams = function(pModuleType, pAppId) return { - appID = commonRC.getHMIAppId(self, pAppId), + appID = commonRC.getHMIAppId(pAppId), moduleType = pModuleType } end, @@ -569,7 +569,7 @@ function commonRC.subscribeToModule(pModuleType, pAppId, self) local subscribe = true local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(rpc), commonRC.getAppRequestParams(rpc, pModuleType, subscribe)) - EXPECT_HMICALL(commonRC.getHMIEventName(rpc), commonRC.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(rpc), commonRC.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe)) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(rpc, pModuleType, subscribe)) end) @@ -582,7 +582,7 @@ function commonRC.unSubscribeToModule(pModuleType, pAppId, self) local subscribe = false local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(rpc), commonRC.getAppRequestParams(rpc, pModuleType, subscribe)) - EXPECT_HMICALL(commonRC.getHMIEventName(rpc), commonRC.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(rpc), commonRC.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe)) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(rpc, pModuleType, subscribe)) end) @@ -606,7 +606,7 @@ function commonRC.isUnsubscribed(pModuleType, pAppId, self) commonTestCases:DelayedExp(commonRC.timeout) end -function commonRC.getHMIAppId(self, pAppId) +function commonRC.getHMIAppId(pAppId) if not pAppId then pAppId = 1 end @@ -638,7 +638,7 @@ end function commonRC.rpcAllowed(pModuleType, pAppId, pRPC, self) local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) end) @@ -649,10 +649,10 @@ function commonRC.rpcAllowedWithConsent(pModuleType, pAppId, pRPC, self) local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) local consentRPC = "GetInteriorVehicleDataConsent" - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(consentRPC, true)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) :Do(function(_, data2) self.hmiConnection:SendResponse(data2.id, data2.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) end) @@ -665,7 +665,7 @@ function commonRC.rpcRejectWithConsent(pModuleType, pAppId, pRPC, self) local consentRPC = "GetInteriorVehicleDataConsent" local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(consentRPC, false)) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) From d12ac1db9f05735d99572043e35f261ee4df48a9 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Sat, 12 Aug 2017 20:21:49 +0300 Subject: [PATCH 124/681] RC: Remove redundant self parameter --- .../005_TIMED_OUT_from_HMI_SIVD.lua | 2 +- .../006_TIMED_OUT_from_HMI_BP.lua | 2 +- .../007_HMI_no_response_SIVD.lua | 2 +- .../008_HMI_no_response_BP.lua | 2 +- .../009_HMI_invalid_response_SIVD.lua | 2 +- .../010_HMI_invalid_response_BP.lua | 2 +- .../011_TIMED_OUT_after_default_timeout.lua | 2 +- .../006_IN_USE_in_case_2_requests.lua | 2 +- test_scripts/RC/commonRC.lua | 32 +++++++++---------- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua index 00bdfbf63b..694a95086d 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua @@ -35,7 +35,7 @@ local function rpcTimedOutHMIResponse(pModuleType, pAppId, pRPC, self) local consentRPC = "GetInteriorVehicleDataConsent" local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", info) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua index 3d17c7a84f..9d4947ef75 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua @@ -35,7 +35,7 @@ local function rpcTimedOutHMIResponse(pModuleType, pAppId, pRPC, self) local consentRPC = "GetInteriorVehicleDataConsent" local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", info) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua index f5394d225b..725c335e7b 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua @@ -32,7 +32,7 @@ local function rpcNoHMIResponse(pModuleType, pAppId, pRPC, self) local consentRPC = "GetInteriorVehicleDataConsent" local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, _) -- HMI does not respond EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua index ce011ad4de..c86594588b 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua @@ -32,7 +32,7 @@ local function rpcNoHMIResponse(pModuleType, pAppId, pRPC, self) local consentRPC = "GetInteriorVehicleDataConsent" local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, _) -- HMI does not respond EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua index 6dd63b8047..26dbfa5bc7 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua @@ -32,7 +32,7 @@ local function rpcInvalidHMIResponse(pModuleType, pAppId, pRPC, self) local consentRPC = "GetInteriorVehicleDataConsent" local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { allowed = "aaa" -- invalid type of parameter diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua index f76ca7a02c..d9e287fd0f 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua @@ -32,7 +32,7 @@ local function rpcInvalidHMIResponse(pModuleType, pAppId, pRPC, self) local consentRPC = "GetInteriorVehicleDataConsent" local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { allowed = "aaa" -- invalid type of parameter diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua index d8ccad4cc1..1b5afe0318 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua @@ -31,7 +31,7 @@ end local function rpcHMIRespondAfterDefaultTimeout(self) local cid1 = self.mobileSession2:SendRPC(commonRC.getAppEventName(pRPC1), commonRC.getAppRequestParams(pRPC1, pModuleType)) local consentRPC = "GetInteriorVehicleDataConsent" - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, 2, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, 2)) :Do(function(_, data) local function hmiRespond() self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", "info") diff --git a/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua b/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua index fbc399435b..3561b19f28 100644 --- a/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua +++ b/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua @@ -52,7 +52,7 @@ local function step(pModuleType, pRPC1, pRPC2, self) buttonPressMode = "SHORT" }) EXPECT_HMICALL("Buttons.ButtonPress", { - appID = commonRC.getHMIAppId(self, 1), + appID = commonRC.getHMIAppId(1), moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index a7a3204df3..0182a6a0ed 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -176,7 +176,7 @@ end function commonRC.unregisterApp(pAppId, self) local mobSession = commonRC.getMobileSession(self, pAppId) - local hmiAppId = commonRC.getHMIAppId(self, pAppId) + local hmiAppId = commonRC.getHMIAppId(pAppId) local cid = mobSession:SendRPC("UnregisterAppInterface",{}) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = hmiAppId, unexpectedDisconnect = false }) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) @@ -388,9 +388,9 @@ local rcRPCs = { subscribe = pSubscribe } end, - hmiRequestParams = function(pModuleType, pAppId, pSubscribe, self) + hmiRequestParams = function(pModuleType, pAppId, pSubscribe) return { - appID = commonRC.getHMIAppId(self, pAppId), + appID = commonRC.getHMIAppId(pAppId), moduleType = pModuleType, subscribe = pSubscribe } @@ -418,9 +418,9 @@ local rcRPCs = { moduleData = commonRC.getSettableModuleControlData(pModuleType) } end, - hmiRequestParams = function(pModuleType, pAppId, self) + hmiRequestParams = function(pModuleType, pAppId) return { - appID = commonRC.getHMIAppId(self, pAppId), + appID = commonRC.getHMIAppId(pAppId), moduleData = commonRC.getSettableModuleControlData(pModuleType) } end, @@ -440,9 +440,9 @@ local rcRPCs = { buttonPressMode = "SHORT" } end, - hmiRequestParams = function(pModuleType, pAppId, self) + hmiRequestParams = function(pModuleType, pAppId) return { - appID = commonRC.getHMIAppId(self, pAppId), + appID = commonRC.getHMIAppId(pAppId), moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" @@ -454,9 +454,9 @@ local rcRPCs = { }, GetInteriorVehicleDataConsent = { hmiEventName = "RC.GetInteriorVehicleDataConsent", - hmiRequestParams = function(pModuleType, pAppId, self) + hmiRequestParams = function(pModuleType, pAppId) return { - appID = commonRC.getHMIAppId(self, pAppId), + appID = commonRC.getHMIAppId(pAppId), moduleType = pModuleType } end, @@ -521,7 +521,7 @@ function commonRC.subscribeToModule(pModuleType, pAppId, self) local subscribe = true local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(rpc), commonRC.getAppRequestParams(rpc, pModuleType, subscribe)) - EXPECT_HMICALL(commonRC.getHMIEventName(rpc), commonRC.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(rpc), commonRC.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe)) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(rpc, pModuleType, subscribe)) end) @@ -534,7 +534,7 @@ function commonRC.unSubscribeToModule(pModuleType, pAppId, self) local subscribe = false local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(rpc), commonRC.getAppRequestParams(rpc, pModuleType, subscribe)) - EXPECT_HMICALL(commonRC.getHMIEventName(rpc), commonRC.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(rpc), commonRC.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe)) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(rpc, pModuleType, subscribe)) end) @@ -558,7 +558,7 @@ function commonRC.isUnsubscribed(pModuleType, pAppId, self) commonTestCases:DelayedExp(commonRC.timeout) end -function commonRC.getHMIAppId(self, pAppId) +function commonRC.getHMIAppId(pAppId) if not pAppId then pAppId = 1 end @@ -590,7 +590,7 @@ end function commonRC.rpcAllowed(pModuleType, pAppId, pRPC, self) local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) end) @@ -601,10 +601,10 @@ function commonRC.rpcAllowedWithConsent(pModuleType, pAppId, pRPC, self) local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) local consentRPC = "GetInteriorVehicleDataConsent" - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(consentRPC, true)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) :Do(function(_, data2) self.hmiConnection:SendResponse(data2.id, data2.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) end) @@ -617,7 +617,7 @@ function commonRC.rpcRejectWithConsent(pModuleType, pAppId, pRPC, self) local consentRPC = "GetInteriorVehicleDataConsent" local mobSession = commonRC.getMobileSession(self, pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId, self)) + EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(consentRPC, false)) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) From cd45476e933af14a96bb09b030cdd9aa6de68443 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Sun, 13 Aug 2017 11:03:28 +0300 Subject: [PATCH 125/681] RC: remove redundant action --- .../019_Release_resource_on_RC_disable.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua b/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua index bda82155a1..0397d836bf 100644 --- a/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua +++ b/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua @@ -37,9 +37,9 @@ runner.Step("RAI2", commonRC.rai_n, { 2 }) runner.Title("Test") -for _,initialAccessMode in pairs(accessModes) do - for _,targetAccessMode in pairs(accessModes) do - for _,appLevel in pairs(HMILevels) do +for _, initialAccessMode in pairs(accessModes) do + for _, targetAccessMode in pairs(accessModes) do + for _, appLevel in pairs(HMILevels) do runner.Title(initialAccessMode .. " -> Disable RC -> " .. targetAccessMode .. " (" .. appLevel .. ")") for _, mod in pairs(modules) do runner.Title("Module: " .. mod) @@ -57,7 +57,6 @@ for _,initialAccessMode in pairs(accessModes) do runner.Step("Check App2 " .. rcRpcs[2] .. " allowed", commonRC.rpcAllowed, { mod, 2, rcRpcs[2] }) runner.Step("Activate App2", commonRC.activate_app, { 2 }) end - runner.Step("Disable RC from HMI", commonRC.defineRAMode, { false, targetAccessMode }) end end end From 8530a1584a096fdbde256eab242d76231c8ea693 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Sun, 13 Aug 2017 11:03:28 +0300 Subject: [PATCH 126/681] RC: remove redundant action --- .../019_Release_resource_on_RC_disable.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua b/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua index bda82155a1..0397d836bf 100644 --- a/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua +++ b/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua @@ -37,9 +37,9 @@ runner.Step("RAI2", commonRC.rai_n, { 2 }) runner.Title("Test") -for _,initialAccessMode in pairs(accessModes) do - for _,targetAccessMode in pairs(accessModes) do - for _,appLevel in pairs(HMILevels) do +for _, initialAccessMode in pairs(accessModes) do + for _, targetAccessMode in pairs(accessModes) do + for _, appLevel in pairs(HMILevels) do runner.Title(initialAccessMode .. " -> Disable RC -> " .. targetAccessMode .. " (" .. appLevel .. ")") for _, mod in pairs(modules) do runner.Title("Module: " .. mod) @@ -57,7 +57,6 @@ for _,initialAccessMode in pairs(accessModes) do runner.Step("Check App2 " .. rcRpcs[2] .. " allowed", commonRC.rpcAllowed, { mod, 2, rcRpcs[2] }) runner.Step("Activate App2", commonRC.activate_app, { 2 }) end - runner.Step("Disable RC from HMI", commonRC.defineRAMode, { false, targetAccessMode }) end end end From bbdc84ef9ccd35ef04a397d96bb08b5c62622478 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Sun, 13 Aug 2017 13:18:44 +0300 Subject: [PATCH 127/681] RC Capabilities: Scripts on IsReady --- ...f_HMI_respond_to_RC_IsReady_with_false.lua | 57 +++++++++++++ ...d_doesnt_respond_to_RC_GetCapabilities.lua | 71 ++++++++++++++++ ...d_doesnt_respond_to_RC_GetCapabilities.lua | 71 ++++++++++++++++ ...d_doesnt_respond_to_RC_GetCapabilities.lua | 71 ++++++++++++++++ ...d_doesnt_respond_to_RC_GetCapabilities.lua | 71 ++++++++++++++++ ...ady_and_responds_to_RC_GetCapabilities.lua | 80 +++++++++++++++++++ ...ady_and_responds_to_RC_GetCapabilities.lua | 80 +++++++++++++++++++ test_scripts/RC/commonRC.lua | 52 ++++++++++-- 8 files changed, 547 insertions(+), 6 deletions(-) create mode 100644 test_scripts/RC/Capabilities/002_Check_that_SDL_reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua create mode 100644 test_scripts/RC/Capabilities/003_1_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua create mode 100644 test_scripts/RC/Capabilities/003_2_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua create mode 100644 test_scripts/RC/Capabilities/004_1_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua create mode 100644 test_scripts/RC/Capabilities/004_2_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua create mode 100644 test_scripts/RC/Capabilities/005_1_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua create mode 100644 test_scripts/RC/Capabilities/005_2_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua diff --git a/test_scripts/RC/Capabilities/002_Check_that_SDL_reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua b/test_scripts/RC/Capabilities/002_Check_that_SDL_reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua new file mode 100644 index 0000000000..02045c7557 --- /dev/null +++ b/test_scripts/RC/Capabilities/002_Check_that_SDL_reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- HMI respond with available = false on RC.IsReady request from SDL +-- +-- SDL must: +-- Do not send RC.GetCapabilities request to HMI +-- Reject all RPCs from mobile application to such interface with result code UNSUPPORTED_RESOURCE, success:false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local hmi_values = require('user_modules/hmi_values') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } + +--[[ Local Functions ]] +local function getHMIParams() + local params = hmi_values.getDefaultHMITable() + params.RC.IsReady.params.available = false + params.RC.GetCapabilities.params = { } + params.RC.GetCapabilities.occurrence = 0 + return params +end + +local function rpcUnsupportedResource(pModuleType, pRPC, self) + local pAppId = 1 + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + runner.Step("GetInteriorVehicleData", rpcUnsupportedResource, { mod, "GetInteriorVehicleData" }) + runner.Step("SetInteriorVehicleData", rpcUnsupportedResource, { mod, "SetInteriorVehicleData" }) + runner.Step("ButtonPress", rpcUnsupportedResource, { mod, "ButtonPress" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) +runner.Step("Restore HMI capabilities file", commonRC.restoreHMICapabilities) diff --git a/test_scripts/RC/Capabilities/003_1_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/003_1_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua new file mode 100644 index 0000000000..bb82841aa1 --- /dev/null +++ b/test_scripts/RC/Capabilities/003_1_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua @@ -0,0 +1,71 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- HMI didn't respond on RC.IsReady request from SDL +-- and HMI didn't respond on capabilities request from SDL +-- +-- SDL must: +-- Use default capabiltites during ignition cycle stored in HMI_capabilities.json file +-- Process RC-related RPCs +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local hmi_values = require('user_modules/hmi_values') + +--[[ Local Variables ]] +local disabledModule = "CLIMATE" +local enabledModule = "RADIO" + +--[[ Local Functions ]] +local function getHMIParams() + local params = hmi_values.getDefaultHMITable() + params.RC.IsReady = nil + params.RC.GetCapabilities = nil + return params +end + +local function rpcUnsupportedResource(pModuleType, pRPC, self) + local pAppId = 1 + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) +end + +local function rpcSuccess(pModuleType, pRPC, self) + local pAppId = 1 + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) + end) + mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { disabledModule }) +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test - Module enabled: " .. enabledModule .. ", disabled: " .. disabledModule) + +runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "ButtonPress" }) + +runner.Step("GetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_SUCCESS", rpcSuccess, { enabledModule, "ButtonPress" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) +runner.Step("Restore HMI capabilities file", commonRC.restoreHMICapabilities) diff --git a/test_scripts/RC/Capabilities/003_2_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/003_2_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua new file mode 100644 index 0000000000..215f9b8f9a --- /dev/null +++ b/test_scripts/RC/Capabilities/003_2_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua @@ -0,0 +1,71 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- HMI didn't respond on RC.IsReady request from SDL +-- and HMI didn't respond on capabilities request from SDL +-- +-- SDL must: +-- Use default capabiltites during ignition cycle stored in HMI_capabilities.json file +-- Process RC-related RPCs +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local hmi_values = require('user_modules/hmi_values') + +--[[ Local Variables ]] +local disabledModule = "RADIO" +local enabledModule = "CLIMATE" + +--[[ Local Functions ]] +local function getHMIParams() + local params = hmi_values.getDefaultHMITable() + params.RC.IsReady = nil + params.RC.GetCapabilities = nil + return params +end + +local function rpcUnsupportedResource(pModuleType, pRPC, self) + local pAppId = 1 + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) +end + +local function rpcSuccess(pModuleType, pRPC, self) + local pAppId = 1 + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) + end) + mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { disabledModule }) +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test - Module enabled: " .. enabledModule .. ", disabled: " .. disabledModule) + +runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "ButtonPress" }) + +runner.Step("GetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_SUCCESS", rpcSuccess, { enabledModule, "ButtonPress" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) +runner.Step("Restore HMI capabilities file", commonRC.restoreHMICapabilities) diff --git a/test_scripts/RC/Capabilities/004_1_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/004_1_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua new file mode 100644 index 0000000000..31481e45a7 --- /dev/null +++ b/test_scripts/RC/Capabilities/004_1_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua @@ -0,0 +1,71 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- HMI respond with available = true on RC.IsReady request from SDL +-- and HMI didn't respond on capabilities request from SDL +-- +-- SDL must: +-- Use default capabiltites during ignition cycle stored in HMI_capabilities.json file +-- Process RC-related RPCs +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local hmi_values = require('user_modules/hmi_values') + +--[[ Local Variables ]] +local disabledModule = "CLIMATE" +local enabledModule = "RADIO" + +--[[ Local Functions ]] +local function getHMIParams() + local params = hmi_values.getDefaultHMITable() + params.RC.IsReady.params.available = true + params.RC.GetCapabilities = nil + return params +end + +local function rpcUnsupportedResource(pModuleType, pRPC, self) + local pAppId = 1 + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) +end + +local function rpcSuccess(pModuleType, pRPC, self) + local pAppId = 1 + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) + end) + mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { disabledModule }) +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test - Module enabled: " .. enabledModule .. ", disabled: " .. disabledModule) + +runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "ButtonPress" }) + +runner.Step("GetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_SUCCESS", rpcSuccess, { enabledModule, "ButtonPress" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) +runner.Step("Restore HMI capabilities file", commonRC.restoreHMICapabilities) diff --git a/test_scripts/RC/Capabilities/004_2_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/004_2_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua new file mode 100644 index 0000000000..e17b9c61b8 --- /dev/null +++ b/test_scripts/RC/Capabilities/004_2_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua @@ -0,0 +1,71 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- HMI respond with available = true on RC.IsReady request from SDL +-- and HMI didn't respond on capabilities request from SDL +-- +-- SDL must: +-- Use default capabiltites during ignition cycle stored in HMI_capabilities.json file +-- Process RC-related RPCs +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local hmi_values = require('user_modules/hmi_values') + +--[[ Local Variables ]] +local disabledModule = "RADIO" +local enabledModule = "CLIMATE" + +--[[ Local Functions ]] +local function getHMIParams() + local params = hmi_values.getDefaultHMITable() + params.RC.IsReady.params.available = true + params.RC.GetCapabilities = nil + return params +end + +local function rpcUnsupportedResource(pModuleType, pRPC, self) + local pAppId = 1 + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) +end + +local function rpcSuccess(pModuleType, pRPC, self) + local pAppId = 1 + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) + end) + mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { disabledModule }) +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test - Module enabled: " .. enabledModule .. ", disabled: " .. disabledModule) + +runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "ButtonPress" }) + +runner.Step("GetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_SUCCESS", rpcSuccess, { enabledModule, "ButtonPress" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) +runner.Step("Restore HMI capabilities file", commonRC.restoreHMICapabilities) diff --git a/test_scripts/RC/Capabilities/005_1_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/005_1_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua new file mode 100644 index 0000000000..03b8814674 --- /dev/null +++ b/test_scripts/RC/Capabilities/005_1_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua @@ -0,0 +1,80 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- HMI didn't respond on RC.IsReady request from SDL +-- and SDL send RC.GetCapabilities request to HMI +-- and HMI respond on this request with capabilities +-- +-- SDL must: +-- Use these capabiltites during ignition cycle +-- Process RC-related RPCs accordingly +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local disabledModule = "CLIMATE" +local enabledModule = "RADIO" + +--[[ Local Functions ]] +local function getHMIParams() + local function getHMICapsParams() + if enabledModule == "CLIMATE" then + return { commonRC.DEFAULT, nil, commonRC.DEFAULT } + elseif enabledModule == "RADIO" then + return { nil, commonRC.DEFAULT, commonRC.DEFAULT } + end + end + local hmiCaps = commonRC.buildHmiRcCapabilities(unpack(getHMICapsParams())) + hmiCaps.RC.IsReady = nil + local buttonCaps = hmiCaps.RC.GetCapabilities.params.remoteControlCapability.buttonCapabilities + local buttonId = commonRC.getButtonIdByName(buttonCaps, commonRC.getButtonNameByModule(disabledModule)) + table.remove(buttonCaps, buttonId) + return hmiCaps +end + +local function rpcUnsupportedResource(pModuleType, pRPC, self) + local pAppId = 1 + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) +end + +local function rpcSuccess(pModuleType, pRPC, self) + local pAppId = 1 + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) + end) + mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { enabledModule }) +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test - Module enabled: " .. enabledModule .. ", disabled: " .. disabledModule) + +runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "ButtonPress" }) + +runner.Step("GetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_SUCCESS", rpcSuccess, { enabledModule, "ButtonPress" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) +runner.Step("Restore HMI capabilities file", commonRC.restoreHMICapabilities) diff --git a/test_scripts/RC/Capabilities/005_2_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/005_2_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua new file mode 100644 index 0000000000..4f6292571e --- /dev/null +++ b/test_scripts/RC/Capabilities/005_2_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua @@ -0,0 +1,80 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- HMI didn't respond on RC.IsReady request from SDL +-- and SDL send RC.GetCapabilities request to HMI +-- and HMI respond on this request with capabilities +-- +-- SDL must: +-- Use these capabiltites during ignition cycle +-- Process RC-related RPCs accordingly +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local disabledModule = "RADIO" +local enabledModule = "CLIMATE" + +--[[ Local Functions ]] +local function getHMIParams() + local function getHMICapsParams() + if enabledModule == "CLIMATE" then + return { commonRC.DEFAULT, nil, commonRC.DEFAULT } + elseif enabledModule == "RADIO" then + return { nil, commonRC.DEFAULT, commonRC.DEFAULT } + end + end + local hmiCaps = commonRC.buildHmiRcCapabilities(unpack(getHMICapsParams())) + hmiCaps.RC.IsReady = nil + local buttonCaps = hmiCaps.RC.GetCapabilities.params.remoteControlCapability.buttonCapabilities + local buttonId = commonRC.getButtonIdByName(buttonCaps, commonRC.getButtonNameByModule(disabledModule)) + table.remove(buttonCaps, buttonId) + return hmiCaps +end + +local function rpcUnsupportedResource(pModuleType, pRPC, self) + local pAppId = 1 + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) +end + +local function rpcSuccess(pModuleType, pRPC, self) + local pAppId = 1 + local mobSession = commonRC.getMobileSession(self, pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) + end) + mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { enabledModule }) +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test - Module enabled: " .. enabledModule .. ", disabled: " .. disabledModule) + +runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "ButtonPress" }) + +runner.Step("GetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_SUCCESS", rpcSuccess, { enabledModule, "ButtonPress" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) +runner.Step("Restore HMI capabilities file", commonRC.restoreHMICapabilities) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 0182a6a0ed..8fb2c5e160 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -12,6 +12,7 @@ config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') local mobile_session = require("mobile_session") local json = require("modules/json") local hmi_values = require("user_modules/hmi_values") @@ -24,6 +25,7 @@ local commonRC = {} commonRC.timeout = 2000 commonRC.DEFAULT = "Default" +commonRC.buttons = { climate = "FAN_UP", radio = "VOLUME_UP" } local function getPTUFromPTS(tbl) tbl.policy_table.consumer_friendly_messages.messages = nil @@ -317,11 +319,7 @@ function commonRC.getAnotherModuleControlData(module_type) end function commonRC.getButtonNameByModule(pModuleType) - if pModuleType == "CLIMATE" then - return "FAN_UP" - elseif pModuleType == "RADIO" then - return "VOLUME_UP" - end + return commonRC.buttons[string.lower(pModuleType)] end function commonRC.getReadOnlyParamsByModule(pModuleType) @@ -428,6 +426,13 @@ local rcRPCs = { return { moduleData = commonRC.getSettableModuleControlData(pModuleType) } + end, + responseParams = function(success, resultCode, pModuleType) + return { + success = success, + resultCode = resultCode, + moduleData = commonRC.getSettableModuleControlData(pModuleType) + } end }, ButtonPress = { @@ -450,6 +455,12 @@ local rcRPCs = { end, hmiResponseParams = function() return {} + end, + responseParams = function(success, resultCode) + return { + success = success, + resultCode = resultCode + } end }, GetInteriorVehicleDataConsent = { @@ -654,7 +665,7 @@ function commonRC.buildHmiRcCapabilities(pClimateCapabilities, pRadioCapabilitie end if pRadioCapabilities then - if pClimateCapabilities ~= commonRC.DEFAULT then + if pRadioCapabilities ~= commonRC.DEFAULT then capParams.radioControlCapabilities = pRadioCapabilities end else @@ -672,4 +683,33 @@ function commonRC.buildHmiRcCapabilities(pClimateCapabilities, pRadioCapabilitie return hmiParams end +function commonRC.backupHMICapabilities() + local hmiCapabilitiesFile = commonFunctions:read_parameter_from_smart_device_link_ini("HMICapabilities") + commonPreconditions:BackupFile(hmiCapabilitiesFile) +end + +function commonRC.restoreHMICapabilities() + local hmiCapabilitiesFile = commonFunctions:read_parameter_from_smart_device_link_ini("HMICapabilities") + commonPreconditions:RestoreFile(hmiCapabilitiesFile) +end + +function commonRC.getButtonIdByName(pArray, pButtonName) + for id, buttonData in pairs(pArray) do + if buttonData.name == pButtonName then + return id + end + end +end + +function commonRC.updateDefaultCapabilities(pDisabledModuleType) + local hmiCapabilitiesFile = commonPreconditions:GetPathToSDL() + .. commonFunctions:read_parameter_from_smart_device_link_ini("HMICapabilities") + local hmiCapTbl = jsonFileToTable(hmiCapabilitiesFile) + local rcCapTbl = hmiCapTbl.UI.systemCapabilities.remoteControlCapability + local buttonId = commonRC.getButtonIdByName(rcCapTbl.buttonCapabilities, commonRC.getButtonNameByModule(pDisabledModuleType)) + table.remove(rcCapTbl.buttonCapabilities, buttonId) + rcCapTbl[string.lower(pDisabledModuleType) .. "ControlCapabilities"] = nil + tableToJsonFile(hmiCapTbl, hmiCapabilitiesFile) +end + return commonRC From c00ab0dee73cd1e313459d43244edf3287febb3c Mon Sep 17 00:00:00 2001 From: Igor Kovalenko Date: Sun, 13 Aug 2017 13:48:04 +0300 Subject: [PATCH 128/681] RC.GetCapabilities diff params tests --- ..._supported_parameter_and_reject_others.lua | 60 +++++++++++++++++ .../007_resend_only_supported_parameters.lua | 64 +++++++++++++++++++ ...supported_and_not_supported_parameters.lua | 57 +++++++++++++++++ ...arameter_was_absent_in_GetCapabilities.lua | 37 +++++++++++ 4 files changed, 218 insertions(+) create mode 100644 test_scripts/RC/Capabilities/006_resend_only_supported_parameter_and_reject_others.lua create mode 100644 test_scripts/RC/Capabilities/007_resend_only_supported_parameters.lua create mode 100644 test_scripts/RC/Capabilities/008_reject_request_with_both_supported_and_not_supported_parameters.lua create mode 100644 test_scripts/RC/Capabilities/009_reject_request_if_remoteControlCapabilities_parameter_was_absent_in_GetCapabilities.lua diff --git a/test_scripts/RC/Capabilities/006_resend_only_supported_parameter_and_reject_others.lua b/test_scripts/RC/Capabilities/006_resend_only_supported_parameter_and_reject_others.lua new file mode 100644 index 0000000000..40b7dc20fc --- /dev/null +++ b/test_scripts/RC/Capabilities/006_resend_only_supported_parameter_and_reject_others.lua @@ -0,0 +1,60 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) SDL receive only one parameter in GetCapabilites response for CLIMATE module +-- SDL must: +-- 1) Transfer to HMI remote control RPCs only with supported parameter and +-- 2) Reject any request for CLIMATE with unsupported parameters with UNSUPPORTED_RESOURCE result code, success: false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local common_functions = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Variables ]] +local climate_capabilities = {moduleName = "Climate", fanSpeedAvailable = true} +local rc_capabilities = commonRC.buildHmiRcCapabilities(climate_capabilities, commonRC.DEFAULT, commonRC.DEFAULT) +local available_params = {moduleType = "CLIMATE", climateControlData = {fanSpeed = 30}} +local absent_params = {moduleType = "CLIMATE", climateControlData = {acMaxEnable = true}} + +--[[ Local Functions ]] +local function setVehicleData(params, self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", {moduleData = params}) + + if params.climateControlData.fanSpeed then + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = commonRC.getHMIAppId(1), + moduleData = params}) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = params}) + end) + self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + else + EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) + self.mobileSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) + common_functions:DelayedExp(commonRC.timeout) + end +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, {rc_capabilities}) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate_App", commonRC.activate_app) + +runner.Title("Test") +for _, module_name in pairs({"CLIMATE", "RADIO"}) do + runner.Step("GetInteriorVehicleData for " .. module_name, commonRC.subscribeToModule, {module_name, 1}) + runner.Step("ButtonPress for " .. module_name, commonRC.rpcAllowed, {module_name, 1, "ButtonPress"}) +end +--SDL process only supported by HMI parameter +runner.Step("SetInteriorVehicleData processed with supported fanSpeed", setVehicleData, { available_params }) +runner.Step("SetInteriorVehicleData rejected with unsupported acMaxEnable", setVehicleData, { absent_params }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/Capabilities/007_resend_only_supported_parameters.lua b/test_scripts/RC/Capabilities/007_resend_only_supported_parameters.lua new file mode 100644 index 0000000000..540537388d --- /dev/null +++ b/test_scripts/RC/Capabilities/007_resend_only_supported_parameters.lua @@ -0,0 +1,64 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) SDL receive several supported Radio parameters in GetCapabilites response +-- SDL must: +-- 1) Transfer to HMI remote control RPCs only with supported parameters and +-- 2) Reject any request for RADIO with unsupported parameters with UNSUPPORTED_RESOURCE result code, success: false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local common_functions = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Variables ]] +local radio_capabilities = {moduleName = "Radio", radioFrequencyAvailable = true, radioBandAvailable = true} + +local rc_capabilities = commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, radio_capabilities, commonRC.DEFAULT) +local available_params = +{ + moduleType = "RADIO", + radioControlData = {frequencyInteger = 1, frequencyFraction = 2, band = "AM"} +} +local absent_params = {moduleType = "RADIO", radioControlData = {frequencyInteger = 1, frequencyFraction = 2}} + +--[[ Local Functions ]] +local function setVehicleData(params, self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", {moduleData = params}) + + if params.radioControlData.frequencyInteger then + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = commonRC.getHMIAppId(1), + moduleData = params}) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = params}) + end) + self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + else + EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) + self.mobileSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) + common_functions.DelayedExp(commonRC.timeout) + end +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, {rc_capabilities}) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate_App", commonRC.activate_app) + +runner.Title("Test") +for _, module_name in pairs({"CLIMATE", "RADIO"}) do + runner.Step("GetInteriorVehicleData for " .. module_name, commonRC.subscribeToModule, {module_name, 1}) + runner.Step("ButtonPress for " .. module_name, commonRC.rpcAllowed, {module_name, 1, "ButtonPress"}) +end +runner.Step("SetInteriorVehicleData processed for several supported params", setVehicleData, { available_params }) +runner.Step("SetInteriorVehicleData rejected with unsupported parameter", setVehicleData, { absent_params }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/Capabilities/008_reject_request_with_both_supported_and_not_supported_parameters.lua b/test_scripts/RC/Capabilities/008_reject_request_with_both_supported_and_not_supported_parameters.lua new file mode 100644 index 0000000000..304cf834a4 --- /dev/null +++ b/test_scripts/RC/Capabilities/008_reject_request_with_both_supported_and_not_supported_parameters.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) SDL receive several supported Radio parameters in GetCapabilites response and +-- 2) App sends RC RPC request with several supported by HMI parameters and some unssuported +-- SDL must: +-- 1) Reject such request with UNSUPPORTED_RESOURCE result code, success: false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local climate_capabilities = +{ + moduleName = "Climate", + fanSpeedAvailable = true, + acEnableAvailable = true, + acMaxEnableAvailable = true +} +local rc_capabilities = commonRC.buildHmiRcCapabilities(climate_capabilities, commonRC.DEFAULT, commonRC.DEFAULT) +local climate_params = +{ + moduleType = "CLIMATE", + climateControlData = + { + fanSpeed = 30, + acEnable = true, + acMaxEnable = true, + circulateAirEnableAvailable = true -- unsupported parameter + } +} + +--[[ Local Functions ]] +local function setVehicleData(params, self) + local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", {moduleData = params}) + + EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) + self.mobileSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, {rc_capabilities}) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate_App", commonRC.activate_app) + +runner.Title("Test") +for _, module_name in pairs({"CLIMATE", "RADIO"}) do + runner.Step("GetInteriorVehicleData for " .. module_name, commonRC.subscribeToModule, {module_name, 1}) + runner.Step("ButtonPress for " .. module_name, commonRC.rpcAllowed, {module_name, 1, "ButtonPress"}) +end +runner.Step("SetInteriorVehicleData rejected if at least one prameter unsuported", setVehicleData, { climate_params }) diff --git a/test_scripts/RC/Capabilities/009_reject_request_if_remoteControlCapabilities_parameter_was_absent_in_GetCapabilities.lua b/test_scripts/RC/Capabilities/009_reject_request_if_remoteControlCapabilities_parameter_was_absent_in_GetCapabilities.lua new file mode 100644 index 0000000000..ed8b10285b --- /dev/null +++ b/test_scripts/RC/Capabilities/009_reject_request_if_remoteControlCapabilities_parameter_was_absent_in_GetCapabilities.lua @@ -0,0 +1,37 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) SDL didn't receive in GetCapabilites response remoteControlCapability parameter +-- SDL must: +-- 1) Reject any RC related RPCs with UNSUPPORTED_RESOURCE result code, success: false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local rc_capabilities = commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, commonRC.DEFAULT, commonRC.DEFAULT) +rc_capabilities.RC.GetCapabilities.params.remoteControlCapability = nil + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, {rc_capabilities}) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate_App", commonRC.activate_app) +--Check that all RC RPCs are rejected by SDL +runner.Title("Test") +for _, module_name in pairs({"CLIMATE", "RADIO"}) do + runner.Step("GetInteriorVehicleData for " .. module_name, + commonRC.rpcDenied, + {module_name, 1, "GetInteriorVehicleData", "UNSUPPORTED_RESOURCE"}) + runner.Step("SetInteriorVehicleData for " .. module_name, + commonRC.rpcDenied, + {module_name, 1, "SetInteriorVehicleData", "UNSUPPORTED_RESOURCE"}) + runner.Step("ButtonPress for " .. module_name, + commonRC.rpcDenied, + {module_name, 1, "ButtonPress", "UNSUPPORTED_RESOURCE"}) +end From 9cf561570cbcbe2fe9be09bbd4511d2df830e9d8 Mon Sep 17 00:00:00 2001 From: Igor Kovalenko Date: Sun, 13 Aug 2017 13:52:04 +0300 Subject: [PATCH 129/681] added tests to test set --- test_sets/rc_Capabilities.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test_sets/rc_Capabilities.txt b/test_sets/rc_Capabilities.txt index 2741abe69c..3f20e4c3d4 100644 --- a/test_sets/rc_Capabilities.txt +++ b/test_sets/rc_Capabilities.txt @@ -1,3 +1,7 @@ ./test_scripts/RC/Capabilities/001_All_modules_all_params.lua +./test_scripts/RC/Capabilities/006_resend_only_supported_parameter_and_reject_others.lua +./test_scripts/RC/Capabilities/007_resend_only_supported_parameters.lua +./test_scripts/RC/Capabilities/008_reject_request_with_both_supported_and_not_supported_parameters.lua +./test_scripts/RC/Capabilities/009_reject_request_if_remoteControlCapabilities_parameter_was_absent_in_GetCapabilities.lua ./test_scripts/RC/Capabilities/010_Only_CLIMATE_all_params.lua ./test_scripts/RC/Capabilities/011_Only_RADIO_all_params.lua From 0320f79780509db66f48ed63326941bd8e7575cf Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Sun, 13 Aug 2017 14:44:21 +0300 Subject: [PATCH 130/681] RC: Add activation of application --- .../011_TIMED_OUT_after_default_timeout.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua index 1b5afe0318..77eee27ac0 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua @@ -50,6 +50,7 @@ runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App1", commonRC.activate_app) runner.Title("Test") runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) From bbbfce4ed9e6bd2c6b3e3b994ca2d35879457324 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Sun, 13 Aug 2017 14:44:21 +0300 Subject: [PATCH 131/681] RC: Add activation of application --- .../011_TIMED_OUT_after_default_timeout.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua index 1b5afe0318..77eee27ac0 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua @@ -50,6 +50,7 @@ runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("Activate App1", commonRC.activate_app) runner.Title("Test") runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) From 767da0b4547d1a64bc214333da04e7f89e1ccb4f Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Sun, 13 Aug 2017 14:58:18 +0300 Subject: [PATCH 132/681] RC: Remove default capabilities --- .../RC/Capabilities/001_All_modules_all_params.lua | 4 ++++ ...sReady_and_doesnt_respond_to_RC_GetCapabilities.lua | 2 +- ...sReady_and_doesnt_respond_to_RC_GetCapabilities.lua | 2 +- ...h_true_and_doesnt_respond_to_RC_GetCapabilities.lua | 2 +- ...h_true_and_doesnt_respond_to_RC_GetCapabilities.lua | 2 +- ...o_RC_IsReady_and_responds_to_RC_GetCapabilities.lua | 2 +- ...o_RC_IsReady_and_responds_to_RC_GetCapabilities.lua | 2 +- .../RC/Capabilities/010_Only_CLIMATE_all_params.lua | 3 +++ .../RC/Capabilities/011_Only_RADIO_all_params.lua | 3 +++ test_scripts/RC/commonRC.lua | 10 ++++++---- 10 files changed, 22 insertions(+), 10 deletions(-) diff --git a/test_scripts/RC/Capabilities/001_All_modules_all_params.lua b/test_scripts/RC/Capabilities/001_All_modules_all_params.lua index 3d1f1405a7..f2b6365b04 100644 --- a/test_scripts/RC/Capabilities/001_All_modules_all_params.lua +++ b/test_scripts/RC/Capabilities/001_All_modules_all_params.lua @@ -11,11 +11,14 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') + --[[ Local Variables ]] local modules = { "CLIMATE", "RADIO" } --[[ Scenario ]] runner.Title("Preconditions") +runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { "CLIMATE", "RADIO" } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI (HMI has all posible RC capabilities), connect Mobile, start Session", commonRC.start, {commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, commonRC.DEFAULT, commonRC.DEFAULT)}) @@ -32,3 +35,4 @@ end runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) +runner.Step("Restore HMI capabilities file", commonRC.restoreHMICapabilities) diff --git a/test_scripts/RC/Capabilities/003_1_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/003_1_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua index bb82841aa1..2ea7f69c19 100644 --- a/test_scripts/RC/Capabilities/003_1_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua +++ b/test_scripts/RC/Capabilities/003_1_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua @@ -50,7 +50,7 @@ end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) -runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { disabledModule }) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { disabledModule } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) runner.Step("RAI, PTU", commonRC.rai_ptu) diff --git a/test_scripts/RC/Capabilities/003_2_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/003_2_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua index 215f9b8f9a..aed50cc611 100644 --- a/test_scripts/RC/Capabilities/003_2_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua +++ b/test_scripts/RC/Capabilities/003_2_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua @@ -50,7 +50,7 @@ end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) -runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { disabledModule }) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { disabledModule } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) runner.Step("RAI, PTU", commonRC.rai_ptu) diff --git a/test_scripts/RC/Capabilities/004_1_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/004_1_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua index 31481e45a7..5bc5270d3d 100644 --- a/test_scripts/RC/Capabilities/004_1_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua +++ b/test_scripts/RC/Capabilities/004_1_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua @@ -50,7 +50,7 @@ end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) -runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { disabledModule }) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { disabledModule } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) runner.Step("RAI, PTU", commonRC.rai_ptu) diff --git a/test_scripts/RC/Capabilities/004_2_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/004_2_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua index e17b9c61b8..807de5edfa 100644 --- a/test_scripts/RC/Capabilities/004_2_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua +++ b/test_scripts/RC/Capabilities/004_2_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua @@ -50,7 +50,7 @@ end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) -runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { disabledModule }) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { disabledModule } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) runner.Step("RAI, PTU", commonRC.rai_ptu) diff --git a/test_scripts/RC/Capabilities/005_1_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/005_1_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua index 03b8814674..60487e5a02 100644 --- a/test_scripts/RC/Capabilities/005_1_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua +++ b/test_scripts/RC/Capabilities/005_1_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua @@ -59,7 +59,7 @@ end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) -runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { enabledModule }) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { enabledModule } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) runner.Step("RAI, PTU", commonRC.rai_ptu) diff --git a/test_scripts/RC/Capabilities/005_2_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/005_2_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua index 4f6292571e..c1b58d7cfe 100644 --- a/test_scripts/RC/Capabilities/005_2_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua +++ b/test_scripts/RC/Capabilities/005_2_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua @@ -59,7 +59,7 @@ end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) -runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { enabledModule }) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { enabledModule } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) runner.Step("RAI, PTU", commonRC.rai_ptu) diff --git a/test_scripts/RC/Capabilities/010_Only_CLIMATE_all_params.lua b/test_scripts/RC/Capabilities/010_Only_CLIMATE_all_params.lua index 374bb0c44c..aa46e553f6 100644 --- a/test_scripts/RC/Capabilities/010_Only_CLIMATE_all_params.lua +++ b/test_scripts/RC/Capabilities/010_Only_CLIMATE_all_params.lua @@ -15,6 +15,8 @@ local commonRC = require('test_scripts/RC/commonRC') --[[ Scenario ]] runner.Title("Preconditions") +runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { "CLIMATE", "RADIO" } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI (HMI has all CLIMATE RC capabilities), connect Mobile, start Session", commonRC.start, {commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, nil, commonRC.DEFAULT)}) @@ -32,3 +34,4 @@ runner.Step("SetInteriorVehicleData RADIO", commonRC.rpcDenied, { "RADIO", 1, "S runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) +runner.Step("Restore HMI capabilities file", commonRC.restoreHMICapabilities) diff --git a/test_scripts/RC/Capabilities/011_Only_RADIO_all_params.lua b/test_scripts/RC/Capabilities/011_Only_RADIO_all_params.lua index 243bdd45cf..63452dae52 100644 --- a/test_scripts/RC/Capabilities/011_Only_RADIO_all_params.lua +++ b/test_scripts/RC/Capabilities/011_Only_RADIO_all_params.lua @@ -15,6 +15,8 @@ local commonRC = require('test_scripts/RC/commonRC') --[[ Scenario ]] runner.Title("Preconditions") +runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { "CLIMATE", "RADIO" } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI (HMI has all CLIMATE RC capabilities), connect Mobile, start Session", commonRC.start, {commonRC.buildHmiRcCapabilities(nil, commonRC.DEFAULT, commonRC.DEFAULT)}) @@ -32,3 +34,4 @@ runner.Step("SetInteriorVehicleData CLIMATE", commonRC.rpcDenied, { "CLIMATE", 1 runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) +runner.Step("Restore HMI capabilities file", commonRC.restoreHMICapabilities) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 8fb2c5e160..8500788b06 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -701,14 +701,16 @@ function commonRC.getButtonIdByName(pArray, pButtonName) end end -function commonRC.updateDefaultCapabilities(pDisabledModuleType) +function commonRC.updateDefaultCapabilities(pDisabledModuleTypes) local hmiCapabilitiesFile = commonPreconditions:GetPathToSDL() .. commonFunctions:read_parameter_from_smart_device_link_ini("HMICapabilities") local hmiCapTbl = jsonFileToTable(hmiCapabilitiesFile) local rcCapTbl = hmiCapTbl.UI.systemCapabilities.remoteControlCapability - local buttonId = commonRC.getButtonIdByName(rcCapTbl.buttonCapabilities, commonRC.getButtonNameByModule(pDisabledModuleType)) - table.remove(rcCapTbl.buttonCapabilities, buttonId) - rcCapTbl[string.lower(pDisabledModuleType) .. "ControlCapabilities"] = nil + for _, pDisabledModuleType in pairs(pDisabledModuleTypes) do + local buttonId = commonRC.getButtonIdByName(rcCapTbl.buttonCapabilities, commonRC.getButtonNameByModule(pDisabledModuleType)) + table.remove(rcCapTbl.buttonCapabilities, buttonId) + rcCapTbl[string.lower(pDisabledModuleType) .. "ControlCapabilities"] = nil + end tableToJsonFile(hmiCapTbl, hmiCapabilitiesFile) end From cd2bf20e1107815d4ade2b1ccce8b64562646b53 Mon Sep 17 00:00:00 2001 From: Igor Kovalenko Date: Sun, 13 Aug 2017 15:38:02 +0300 Subject: [PATCH 133/681] deleted unclarified script, fixed climate_capabilities --- ..._supported_parameter_and_reject_others.lua | 2 +- .../007_resend_only_supported_parameters.lua | 2 +- ...supported_and_not_supported_parameters.lua | 5 +-- ...arameter_was_absent_in_GetCapabilities.lua | 37 ------------------- user_modules/hmi_values.lua | 1 + 5 files changed, 5 insertions(+), 42 deletions(-) delete mode 100644 test_scripts/RC/Capabilities/009_reject_request_if_remoteControlCapabilities_parameter_was_absent_in_GetCapabilities.lua diff --git a/test_scripts/RC/Capabilities/006_resend_only_supported_parameter_and_reject_others.lua b/test_scripts/RC/Capabilities/006_resend_only_supported_parameter_and_reject_others.lua index 40b7dc20fc..659551a2ea 100644 --- a/test_scripts/RC/Capabilities/006_resend_only_supported_parameter_and_reject_others.lua +++ b/test_scripts/RC/Capabilities/006_resend_only_supported_parameter_and_reject_others.lua @@ -15,7 +15,7 @@ local commonRC = require('test_scripts/RC/commonRC') local common_functions = require('user_modules/shared_testcases/commonTestCases') --[[ Local Variables ]] -local climate_capabilities = {moduleName = "Climate", fanSpeedAvailable = true} +local climate_capabilities = {{moduleName = "Climate", fanSpeedAvailable = true}} local rc_capabilities = commonRC.buildHmiRcCapabilities(climate_capabilities, commonRC.DEFAULT, commonRC.DEFAULT) local available_params = {moduleType = "CLIMATE", climateControlData = {fanSpeed = 30}} local absent_params = {moduleType = "CLIMATE", climateControlData = {acMaxEnable = true}} diff --git a/test_scripts/RC/Capabilities/007_resend_only_supported_parameters.lua b/test_scripts/RC/Capabilities/007_resend_only_supported_parameters.lua index 540537388d..72f5903081 100644 --- a/test_scripts/RC/Capabilities/007_resend_only_supported_parameters.lua +++ b/test_scripts/RC/Capabilities/007_resend_only_supported_parameters.lua @@ -15,7 +15,7 @@ local commonRC = require('test_scripts/RC/commonRC') local common_functions = require('user_modules/shared_testcases/commonTestCases') --[[ Local Variables ]] -local radio_capabilities = {moduleName = "Radio", radioFrequencyAvailable = true, radioBandAvailable = true} +local radio_capabilities = {{moduleName = "Radio", radioFrequencyAvailable = true, radioBandAvailable = true}} local rc_capabilities = commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, radio_capabilities, commonRC.DEFAULT) local available_params = diff --git a/test_scripts/RC/Capabilities/008_reject_request_with_both_supported_and_not_supported_parameters.lua b/test_scripts/RC/Capabilities/008_reject_request_with_both_supported_and_not_supported_parameters.lua index 304cf834a4..fd88b96bc3 100644 --- a/test_scripts/RC/Capabilities/008_reject_request_with_both_supported_and_not_supported_parameters.lua +++ b/test_scripts/RC/Capabilities/008_reject_request_with_both_supported_and_not_supported_parameters.lua @@ -14,13 +14,12 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') --[[ Local Variables ]] -local climate_capabilities = -{ +local climate_capabilities = {{ moduleName = "Climate", fanSpeedAvailable = true, acEnableAvailable = true, acMaxEnableAvailable = true -} +}} local rc_capabilities = commonRC.buildHmiRcCapabilities(climate_capabilities, commonRC.DEFAULT, commonRC.DEFAULT) local climate_params = { diff --git a/test_scripts/RC/Capabilities/009_reject_request_if_remoteControlCapabilities_parameter_was_absent_in_GetCapabilities.lua b/test_scripts/RC/Capabilities/009_reject_request_if_remoteControlCapabilities_parameter_was_absent_in_GetCapabilities.lua deleted file mode 100644 index ed8b10285b..0000000000 --- a/test_scripts/RC/Capabilities/009_reject_request_if_remoteControlCapabilities_parameter_was_absent_in_GetCapabilities.lua +++ /dev/null @@ -1,37 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- Requirement summary: --- [SDL_RC] Set available control module settings SetInteriorVehicleData --- --- Description: --- In case: --- 1) SDL didn't receive in GetCapabilites response remoteControlCapability parameter --- SDL must: --- 1) Reject any RC related RPCs with UNSUPPORTED_RESOURCE result code, success: false ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/commonRC') - ---[[ Local Variables ]] -local rc_capabilities = commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, commonRC.DEFAULT, commonRC.DEFAULT) -rc_capabilities.RC.GetCapabilities.params.remoteControlCapability = nil - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, {rc_capabilities}) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate_App", commonRC.activate_app) ---Check that all RC RPCs are rejected by SDL -runner.Title("Test") -for _, module_name in pairs({"CLIMATE", "RADIO"}) do - runner.Step("GetInteriorVehicleData for " .. module_name, - commonRC.rpcDenied, - {module_name, 1, "GetInteriorVehicleData", "UNSUPPORTED_RESOURCE"}) - runner.Step("SetInteriorVehicleData for " .. module_name, - commonRC.rpcDenied, - {module_name, 1, "SetInteriorVehicleData", "UNSUPPORTED_RESOURCE"}) - runner.Step("ButtonPress for " .. module_name, - commonRC.rpcDenied, - {module_name, 1, "ButtonPress", "UNSUPPORTED_RESOURCE"}) -end diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index 1988ec0caa..7b6b6e3b96 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -314,6 +314,7 @@ function module.getDefaultHMITable() climateControlCapabilities = { { moduleName = "Climate", + currentTemperatureAvailable = true, fanSpeedAvailable = true, desiredTemperatureAvailable = true, acEnableAvailable = true, From 45d1c3115f6865acb965e05b14d01033cf9597df Mon Sep 17 00:00:00 2001 From: Igor Kovalenko Date: Sun, 13 Aug 2017 15:43:29 +0300 Subject: [PATCH 134/681] deleted test from test set --- test_sets/rc_Capabilities.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/test_sets/rc_Capabilities.txt b/test_sets/rc_Capabilities.txt index 3f20e4c3d4..5bcc8422fe 100644 --- a/test_sets/rc_Capabilities.txt +++ b/test_sets/rc_Capabilities.txt @@ -2,6 +2,5 @@ ./test_scripts/RC/Capabilities/006_resend_only_supported_parameter_and_reject_others.lua ./test_scripts/RC/Capabilities/007_resend_only_supported_parameters.lua ./test_scripts/RC/Capabilities/008_reject_request_with_both_supported_and_not_supported_parameters.lua -./test_scripts/RC/Capabilities/009_reject_request_if_remoteControlCapabilities_parameter_was_absent_in_GetCapabilities.lua ./test_scripts/RC/Capabilities/010_Only_CLIMATE_all_params.lua ./test_scripts/RC/Capabilities/011_Only_RADIO_all_params.lua From 8a89d7ad48dfc5ff3731acc2695e24f0893e0cbc Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Sun, 13 Aug 2017 16:24:35 +0300 Subject: [PATCH 135/681] RC: Rename scripts --- ...rams.lua => 002_Only_CLIMATE_all_params.lua} | 0 ...params.lua => 003_Only_RADIO_all_params.lua} | 0 ...y_supported_parameter_and_reject_others.lua} | 0 ...=> 005_resend_only_supported_parameters.lua} | 0 ..._supported_and_not_supported_parameters.lua} | 0 ...if_HMI_respond_to_RC_IsReady_with_false.lua} | 0 ...nd_doesnt_respond_to_RC_GetCapabilities.lua} | 0 ...nd_doesnt_respond_to_RC_GetCapabilities.lua} | 0 ...nd_doesnt_respond_to_RC_GetCapabilities.lua} | 0 ...nd_doesnt_respond_to_RC_GetCapabilities.lua} | 0 ...eady_and_responds_to_RC_GetCapabilities.lua} | 0 ...eady_and_responds_to_RC_GetCapabilities.lua} | 0 test_sets/rc_Capabilities.txt | 17 ++++++++++++----- 13 files changed, 12 insertions(+), 5 deletions(-) rename test_scripts/RC/Capabilities/{010_Only_CLIMATE_all_params.lua => 002_Only_CLIMATE_all_params.lua} (100%) rename test_scripts/RC/Capabilities/{011_Only_RADIO_all_params.lua => 003_Only_RADIO_all_params.lua} (100%) rename test_scripts/RC/Capabilities/{006_resend_only_supported_parameter_and_reject_others.lua => 004_resend_only_supported_parameter_and_reject_others.lua} (100%) rename test_scripts/RC/Capabilities/{007_resend_only_supported_parameters.lua => 005_resend_only_supported_parameters.lua} (100%) rename test_scripts/RC/Capabilities/{008_reject_request_with_both_supported_and_not_supported_parameters.lua => 006_reject_request_with_both_supported_and_not_supported_parameters.lua} (100%) rename test_scripts/RC/Capabilities/{002_Check_that_SDL_reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua => 007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua} (100%) rename test_scripts/RC/Capabilities/{003_1_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua => 008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua} (100%) rename test_scripts/RC/Capabilities/{003_2_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua => 009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua} (100%) rename test_scripts/RC/Capabilities/{004_1_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua => 010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua} (100%) rename test_scripts/RC/Capabilities/{004_2_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua => 011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua} (100%) rename test_scripts/RC/Capabilities/{005_1_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua => 012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua} (100%) rename test_scripts/RC/Capabilities/{005_2_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua => 013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua} (100%) diff --git a/test_scripts/RC/Capabilities/010_Only_CLIMATE_all_params.lua b/test_scripts/RC/Capabilities/002_Only_CLIMATE_all_params.lua similarity index 100% rename from test_scripts/RC/Capabilities/010_Only_CLIMATE_all_params.lua rename to test_scripts/RC/Capabilities/002_Only_CLIMATE_all_params.lua diff --git a/test_scripts/RC/Capabilities/011_Only_RADIO_all_params.lua b/test_scripts/RC/Capabilities/003_Only_RADIO_all_params.lua similarity index 100% rename from test_scripts/RC/Capabilities/011_Only_RADIO_all_params.lua rename to test_scripts/RC/Capabilities/003_Only_RADIO_all_params.lua diff --git a/test_scripts/RC/Capabilities/006_resend_only_supported_parameter_and_reject_others.lua b/test_scripts/RC/Capabilities/004_resend_only_supported_parameter_and_reject_others.lua similarity index 100% rename from test_scripts/RC/Capabilities/006_resend_only_supported_parameter_and_reject_others.lua rename to test_scripts/RC/Capabilities/004_resend_only_supported_parameter_and_reject_others.lua diff --git a/test_scripts/RC/Capabilities/007_resend_only_supported_parameters.lua b/test_scripts/RC/Capabilities/005_resend_only_supported_parameters.lua similarity index 100% rename from test_scripts/RC/Capabilities/007_resend_only_supported_parameters.lua rename to test_scripts/RC/Capabilities/005_resend_only_supported_parameters.lua diff --git a/test_scripts/RC/Capabilities/008_reject_request_with_both_supported_and_not_supported_parameters.lua b/test_scripts/RC/Capabilities/006_reject_request_with_both_supported_and_not_supported_parameters.lua similarity index 100% rename from test_scripts/RC/Capabilities/008_reject_request_with_both_supported_and_not_supported_parameters.lua rename to test_scripts/RC/Capabilities/006_reject_request_with_both_supported_and_not_supported_parameters.lua diff --git a/test_scripts/RC/Capabilities/002_Check_that_SDL_reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua b/test_scripts/RC/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua similarity index 100% rename from test_scripts/RC/Capabilities/002_Check_that_SDL_reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua rename to test_scripts/RC/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua diff --git a/test_scripts/RC/Capabilities/003_1_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua similarity index 100% rename from test_scripts/RC/Capabilities/003_1_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua rename to test_scripts/RC/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua diff --git a/test_scripts/RC/Capabilities/003_2_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua similarity index 100% rename from test_scripts/RC/Capabilities/003_2_Check_that_SDL_apply_default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua rename to test_scripts/RC/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua diff --git a/test_scripts/RC/Capabilities/004_1_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua similarity index 100% rename from test_scripts/RC/Capabilities/004_1_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua rename to test_scripts/RC/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua diff --git a/test_scripts/RC/Capabilities/004_2_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua similarity index 100% rename from test_scripts/RC/Capabilities/004_2_Check_that_SDL_apply_default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua rename to test_scripts/RC/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua diff --git a/test_scripts/RC/Capabilities/005_1_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua similarity index 100% rename from test_scripts/RC/Capabilities/005_1_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua rename to test_scripts/RC/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua diff --git a/test_scripts/RC/Capabilities/005_2_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua similarity index 100% rename from test_scripts/RC/Capabilities/005_2_Check_that_SDL_apply_sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua rename to test_scripts/RC/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua diff --git a/test_sets/rc_Capabilities.txt b/test_sets/rc_Capabilities.txt index 5bcc8422fe..82f4a3f4d2 100644 --- a/test_sets/rc_Capabilities.txt +++ b/test_sets/rc_Capabilities.txt @@ -1,6 +1,13 @@ ./test_scripts/RC/Capabilities/001_All_modules_all_params.lua -./test_scripts/RC/Capabilities/006_resend_only_supported_parameter_and_reject_others.lua -./test_scripts/RC/Capabilities/007_resend_only_supported_parameters.lua -./test_scripts/RC/Capabilities/008_reject_request_with_both_supported_and_not_supported_parameters.lua -./test_scripts/RC/Capabilities/010_Only_CLIMATE_all_params.lua -./test_scripts/RC/Capabilities/011_Only_RADIO_all_params.lua +./test_scripts/RC/Capabilities/002_Only_CLIMATE_all_params.lua +./test_scripts/RC/Capabilities/003_Only_RADIO_all_params.lua +./test_scripts/RC/Capabilities/004_resend_only_supported_parameter_and_reject_others.lua +./test_scripts/RC/Capabilities/005_resend_only_supported_parameters.lua +./test_scripts/RC/Capabilities/006_reject_request_with_both_supported_and_not_supported_parameters.lua +./test_scripts/RC/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua +./test_scripts/RC/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua +./test_scripts/RC/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua +./test_scripts/RC/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua +./test_scripts/RC/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua +./test_scripts/RC/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua +./test_scripts/RC/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua From ec3417cb4ce41e19c9f53fa2d2326d7234165fa6 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Sun, 13 Aug 2017 17:22:04 +0300 Subject: [PATCH 136/681] RC: Rename scripts 2 --- ..._supported_parameter_and_reject_others.lua} | 0 ...> 005_Resend_only_supported_parameters.lua} | 0 ...supported_and_not_supported_parameters.lua} | 0 ...nt_respond_to_RC_GetCapabilities_RADIO.lua} | 0 ..._respond_to_RC_GetCapabilities_CLIMATE.lua} | 0 ...nt_respond_to_RC_GetCapabilities_RADIO.lua} | 0 ..._respond_to_RC_GetCapabilities_CLIMATE.lua} | 0 ...d_responds_to_RC_GetCapabilities_RADIO.lua} | 0 ...responds_to_RC_GetCapabilities_CLIMATE.lua} | 0 test_sets/rc_Capabilities.txt | 18 +++++++++--------- 10 files changed, 9 insertions(+), 9 deletions(-) rename test_scripts/RC/Capabilities/{004_resend_only_supported_parameter_and_reject_others.lua => 004_Resend_only_supported_parameter_and_reject_others.lua} (100%) rename test_scripts/RC/Capabilities/{005_resend_only_supported_parameters.lua => 005_Resend_only_supported_parameters.lua} (100%) rename test_scripts/RC/Capabilities/{006_reject_request_with_both_supported_and_not_supported_parameters.lua => 006_Reject_request_with_both_supported_and_not_supported_parameters.lua} (100%) rename test_scripts/RC/Capabilities/{008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua => 008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua} (100%) rename test_scripts/RC/Capabilities/{009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua => 009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua} (100%) rename test_scripts/RC/Capabilities/{010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua => 010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua} (100%) rename test_scripts/RC/Capabilities/{011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua => 011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua} (100%) rename test_scripts/RC/Capabilities/{012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua => 012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua} (100%) rename test_scripts/RC/Capabilities/{013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua => 013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua} (100%) diff --git a/test_scripts/RC/Capabilities/004_resend_only_supported_parameter_and_reject_others.lua b/test_scripts/RC/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua similarity index 100% rename from test_scripts/RC/Capabilities/004_resend_only_supported_parameter_and_reject_others.lua rename to test_scripts/RC/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua diff --git a/test_scripts/RC/Capabilities/005_resend_only_supported_parameters.lua b/test_scripts/RC/Capabilities/005_Resend_only_supported_parameters.lua similarity index 100% rename from test_scripts/RC/Capabilities/005_resend_only_supported_parameters.lua rename to test_scripts/RC/Capabilities/005_Resend_only_supported_parameters.lua diff --git a/test_scripts/RC/Capabilities/006_reject_request_with_both_supported_and_not_supported_parameters.lua b/test_scripts/RC/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua similarity index 100% rename from test_scripts/RC/Capabilities/006_reject_request_with_both_supported_and_not_supported_parameters.lua rename to test_scripts/RC/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua diff --git a/test_scripts/RC/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua similarity index 100% rename from test_scripts/RC/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua rename to test_scripts/RC/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua diff --git a/test_scripts/RC/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua similarity index 100% rename from test_scripts/RC/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua rename to test_scripts/RC/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua diff --git a/test_scripts/RC/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua similarity index 100% rename from test_scripts/RC/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua rename to test_scripts/RC/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua diff --git a/test_scripts/RC/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua similarity index 100% rename from test_scripts/RC/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua rename to test_scripts/RC/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua diff --git a/test_scripts/RC/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua similarity index 100% rename from test_scripts/RC/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua rename to test_scripts/RC/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua diff --git a/test_scripts/RC/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua b/test_scripts/RC/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua similarity index 100% rename from test_scripts/RC/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua rename to test_scripts/RC/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua diff --git a/test_sets/rc_Capabilities.txt b/test_sets/rc_Capabilities.txt index 82f4a3f4d2..d6739047fd 100644 --- a/test_sets/rc_Capabilities.txt +++ b/test_sets/rc_Capabilities.txt @@ -1,13 +1,13 @@ ./test_scripts/RC/Capabilities/001_All_modules_all_params.lua ./test_scripts/RC/Capabilities/002_Only_CLIMATE_all_params.lua ./test_scripts/RC/Capabilities/003_Only_RADIO_all_params.lua -./test_scripts/RC/Capabilities/004_resend_only_supported_parameter_and_reject_others.lua -./test_scripts/RC/Capabilities/005_resend_only_supported_parameters.lua -./test_scripts/RC/Capabilities/006_reject_request_with_both_supported_and_not_supported_parameters.lua +./test_scripts/RC/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua +./test_scripts/RC/Capabilities/005_Resend_only_supported_parameters.lua +./test_scripts/RC/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua ./test_scripts/RC/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua -./test_scripts/RC/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua -./test_scripts/RC/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities.lua -./test_scripts/RC/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua -./test_scripts/RC/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities.lua -./test_scripts/RC/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua -./test_scripts/RC/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities.lua +./test_scripts/RC/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua +./test_scripts/RC/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua +./test_scripts/RC/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua +./test_scripts/RC/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua +./test_scripts/RC/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua +./test_scripts/RC/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua From 936ddbeb083d354ff49b96d64a5ffe8a7aeab8af Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Wed, 16 Aug 2017 10:45:59 +0300 Subject: [PATCH 137/681] Added links to user stories and use cases --- .../001_success_flow_for_climate_and_radio.lua | 4 ++++ .../002_disallow_flow_by_policy_for_climate.lua | 8 ++++++++ .../003_disallow_flow_by_policy_for_radio.lua | 8 ++++++++ ...4_check_processing_button_press_for_nonRC_App.lua | 4 ++++ ...ttonName_and_moduleType_for_radio_and_climate.lua | 4 ++++ .../006_check_rpc_parameters_for_button_press.lua | 4 ++++ ...7_button_press_allowed_if_moduleType_is_empty.lua | 4 ++++ ...tton_press_disallowed_if_moduleType_is_absent.lua | 4 ++++ ...lowed_if_moduleType_is_disallowed_by_policies.lua | 4 ++++ .../010_generic_error_if_no_response_from_hmi.lua | 4 ++++ ...ric_error_if_read_only_response_come_from_hmi.lua | 4 ++++ ...12_generic_error_if_invalid_response_from_hmi.lua | 4 ++++ .../013_Transfering_of_HMI_resultCode_to_mobile.lua | 4 ++++ .../RC/Capabilities/001_All_modules_all_params.lua | 4 ++++ .../RC/Capabilities/002_Only_CLIMATE_all_params.lua | 8 ++++++++ .../RC/Capabilities/003_Only_RADIO_all_params.lua | 8 ++++++++ ...nd_only_supported_parameter_and_reject_others.lua | 4 ++++ .../005_Resend_only_supported_parameters.lua | 4 ++++ ...h_both_supported_and_not_supported_parameters.lua | 4 ++++ ...VD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua | 4 ++++ ...nd_doesnt_respond_to_RC_GetCapabilities_RADIO.lua | 4 ++++ ..._doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua | 4 ++++ ...nd_doesnt_respond_to_RC_GetCapabilities_RADIO.lua | 4 ++++ ..._doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua | 4 ++++ ...eady_and_responds_to_RC_GetCapabilities_RADIO.lua | 4 ++++ ...dy_and_responds_to_RC_GetCapabilities_CLIMATE.lua | 4 ++++ .../RC/GetInteriorVehicleData/001_Success_flow.lua | 4 ++++ .../002_Disallow_flow_by_policy_CLIMATE.lua | 4 ++++ .../003_Disallow_flow_by_policy_RADIO.lua | 4 ++++ ...flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua | 4 ++++ .../005_Transfering_of_HMI_resultCode_to_mobile.lua | 4 ++++ .../006_RPC_parameters_values.lua | 4 ++++ ...007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua | 4 ++++ ...C_ERROR_in_case_HMI_respond_with_invalid_data.lua | 4 ++++ ...w_in_case_moduleType_is_an_empty_array_in_LPT.lua | 4 ++++ ...llow_flow_in_case_moduleType_is_absent_in_LPT.lua | 4 ++++ ...ERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua | 4 ++++ ...er_but_response_from_HMI_without_isSubscribed.lua | 4 ++++ ...meter_but_response_from_HMI_with_isSubscribed.lua | 4 ++++ ...MI_in_case_of_2nd_Subscription_UnSubscription.lua | 4 ++++ .../001_Consent_true_SIVD.lua | 4 ++++ .../002_Consent_true_BP.lua | 4 ++++ .../003_Consent_false_SIVD.lua | 4 ++++ .../004_Consent_false_BP.lua | 4 ++++ .../005_TIMED_OUT_from_HMI_SIVD.lua | 4 ++++ .../006_TIMED_OUT_from_HMI_BP.lua | 4 ++++ .../007_HMI_no_response_SIVD.lua | 4 ++++ .../008_HMI_no_response_BP.lua | 4 ++++ .../009_HMI_invalid_response_SIVD.lua | 4 ++++ .../010_HMI_invalid_response_BP.lua | 4 ++++ .../011_TIMED_OUT_after_default_timeout.lua | 4 ++++ .../RC/OnInteriorVehicleData/001_Success_flow.lua | 8 ++++++++ .../002_Disallow_flow_by_policy_CLIMATE.lua | 4 ++++ .../003_Disallow_flow_by_policy_RADIO.lua | 4 ++++ ...l_subscribing_with_isSubscribe_false_from_HMI.lua | 4 ++++ ...full_subscribing_without_isSubscribe_from_HMI.lua | 4 ++++ ...VD_in_case_of_subscribing_with_error_from_HMI.lua | 4 ++++ ...case_of_subscribing_with_no_response_from_HMI.lua | 4 ++++ ...of_subscribing_with_invalid_response_from_HMI.lua | 4 ++++ ..._unsubscribing_with_isSubscribe_true_from_HMI.lua | 4 ++++ ...ll_unsubscribing_without_isSubscribe_from_HMI.lua | 4 ++++ ...ll_unsubscribing_without_isSubscribe_from_HMI.lua | 4 ++++ ...dule_Climate_and_without_one_for_module_Radio.lua | 4 ++++ ...dule_Radio_and_without_one_for_module_Climate.lua | 4 ++++ ...imate_and_after_unsubscribe_from_module_Radio.lua | 4 ++++ ...dio_and_after_unsubscribe_from_module_Climate.lua | 4 ++++ .../016_RPC_parameters_values.lua | 4 ++++ .../001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua | 4 ++++ .../002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua | 4 ++++ .../003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua | 4 ++++ .../004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua | 4 ++++ .../005_REJECTED_in_case_nonFULL_HMI_level.lua | 4 ++++ .../006_IN_USE_in_case_2_requests.lua | 12 ++++++++++++ .../007_IN_USE_in_case_AUTO_DENY.lua | 4 ++++ .../RC/OnRemoteControlSettings/008_Allowed_false.lua | 4 ++++ .../009_Allowed_true_accessMode_AUTO_ALLOW.lua | 4 ++++ .../010_Allowed_true_accessMode_AUTO_DENY.lua | 4 ++++ .../011_Allowed_true_accessMode_ASK_DRIVER.lua | 4 ++++ .../012_Default_accessMode.lua | 4 ++++ .../013_sequence_switches_of_accessMode.lua | 12 ++++++++++++ .../014_Invalid_data_from_HMI.lua | 4 ++++ .../015_Empty_data_from_HMI.lua | 4 ++++ ...n_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua | 4 ++++ .../017_Release_resource_on_unregister_app.lua | 8 ++++++++ ..._and_allow_for_rejected_app_on_unregister_app.lua | 8 ++++++++ .../019_Release_resource_on_RC_disable.lua | 4 ++++ .../RC/SetInteriorVehicleData/001_Success_flow.lua | 4 ++++ .../002_Disallow_flow_by_policy_CLIMATE.lua | 4 ++++ .../003_Disallow_flow_by_policy_RADIO.lua | 4 ++++ ...flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua | 4 ++++ ...case_params_does_not_correspond_to_moduleType.lua | 7 +++++++ .../006_RPC_parameters_values.lua | 4 ++++ ...w_in_case_moduleType_is_an_empty_array_in_LPT.lua | 4 ++++ ...llow_flow_in_case_moduleType_is_absent_in_LPT.lua | 4 ++++ .../009_Cut-off_of_fake_parameters_from_App.lua | 4 ++++ ...or_vehicle_data_if_read_only_params_requested.lua | 4 ++++ ...t_with_read-only_and_not_read-only_parameters.lua | 4 ++++ ...ead-only_parameters_and_HMI_returns_READ_ONLY.lua | 4 ++++ ...013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua | 4 ++++ ...C_ERROR_in_case_HMI_respond_with_invalid_data.lua | 4 ++++ .../015_Transfering_of_HMI_resultCode_to_mobile.lua | 4 ++++ 101 files changed, 451 insertions(+) diff --git a/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua b/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua index 69f4b62622..80fc237d8d 100644 --- a/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua +++ b/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/9 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/button_press_emulation.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Button press event emulation -- diff --git a/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua b/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua index 43bebb95f6..3a31b03697 100644 --- a/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua +++ b/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua @@ -1,4 +1,12 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/9 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/button_press_emulation.md +-- Item: Use Case 1: Exceptions: 1.3 +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Exceptions: 5.1 +-- -- Requirement summary: -- [SDL_RC] Button press event emulation -- [SDL_RC] Policy support of basic RC functionality diff --git a/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua b/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua index 9a7cbdadbd..fc1b720efb 100644 --- a/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua +++ b/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua @@ -1,4 +1,12 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/9 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/button_press_emulation.md +-- Item: Use Case 1: Exceptions: 1.3 +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Exceptions: 5.1 +-- -- Requirement summary: -- [SDL_RC] Button press event emulation -- [SDL_RC] Policy support of basic RC functionality diff --git a/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua b/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua index aecf9f95fd..02a0b1884c 100644 --- a/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua +++ b/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Alternative flow 1 +-- -- Requirement summary: -- [SDL_RC] Button press event emulation -- diff --git a/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua b/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua index 1cd58891b4..9d81ee4570 100644 --- a/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua +++ b/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/9 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/button_press_emulation.md +-- Item: Use Case 1: Alternative flow 1 +-- -- Requirement summary: -- [SDL_RC] Button press event emulation -- diff --git a/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua b/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua index 443c066660..cf95a000cb 100644 --- a/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua +++ b/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/9 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/button_press_emulation.md +-- Item: Use Case 1: Exceptions: 1.1 +-- -- Requirement summary: -- [SDL_RC] Button press event emulation -- diff --git a/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua b/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua index 81e30926b4..92cbf20024 100644 --- a/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua +++ b/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/9 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/button_press_emulation.md +-- Item: Use Case 1: Exceptions: 1.2 +-- -- Requirement summary: -- [SDL_RC] Button press event emulation -- [SDL_RC] Policy support of basic RC functionality diff --git a/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua b/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua index a984fd67c0..bcb2775abc 100644 --- a/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua +++ b/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/9 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/button_press_emulation.md +-- Item: Use Case 1: Exceptions: 1.2 +-- -- Requirement summary: -- [SDL_RC] Button press event emulation -- [SDL_RC] Policy support of basic RC functionality diff --git a/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua b/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua index 758d22d7c3..fba9f50492 100644 --- a/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua +++ b/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Button press event emulation -- [SDL_RC] Policy support of basic RC functionality diff --git a/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua b/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua index fa79885692..d8c67add71 100644 --- a/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua +++ b/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/9 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/button_press_emulation.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Button press event emulation -- diff --git a/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua b/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua index 3c3f8799a2..a8d9cdbda3 100644 --- a/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua +++ b/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/9 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/button_press_emulation.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Button press event emulation -- diff --git a/test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua b/test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua index e7dc526429..72a63b3468 100644 --- a/test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua +++ b/test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/9 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/button_press_emulation.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Button press event emulation -- diff --git a/test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua index 2a2e4890de..236c1a665d 100644 --- a/test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/9 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/button_press_emulation.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Button press event emulation -- diff --git a/test_scripts/RC/Capabilities/001_All_modules_all_params.lua b/test_scripts/RC/Capabilities/001_All_modules_all_params.lua index f2b6365b04..c42aa2fadb 100644 --- a/test_scripts/RC/Capabilities/001_All_modules_all_params.lua +++ b/test_scripts/RC/Capabilities/001_All_modules_all_params.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/detailed_info_GetSystemCapability.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Capabilities -- diff --git a/test_scripts/RC/Capabilities/002_Only_CLIMATE_all_params.lua b/test_scripts/RC/Capabilities/002_Only_CLIMATE_all_params.lua index aa46e553f6..6e280c8cfb 100644 --- a/test_scripts/RC/Capabilities/002_Only_CLIMATE_all_params.lua +++ b/test_scripts/RC/Capabilities/002_Only_CLIMATE_all_params.lua @@ -1,4 +1,12 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/detailed_info_GetSystemCapability.md +-- Item: Use Case 1:Exception 3.1 +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 5.1 +-- -- Requirement summary: -- [SDL_RC] Capabilities -- diff --git a/test_scripts/RC/Capabilities/003_Only_RADIO_all_params.lua b/test_scripts/RC/Capabilities/003_Only_RADIO_all_params.lua index 63452dae52..429005e250 100644 --- a/test_scripts/RC/Capabilities/003_Only_RADIO_all_params.lua +++ b/test_scripts/RC/Capabilities/003_Only_RADIO_all_params.lua @@ -1,4 +1,12 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/detailed_info_GetSystemCapability.md +-- Item: Use Case 1:Exception 3.1 +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 5.1 +-- -- Requirement summary: -- [SDL_RC] Capabilities -- diff --git a/test_scripts/RC/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua b/test_scripts/RC/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua index 659551a2ea..5c5171d259 100644 --- a/test_scripts/RC/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua +++ b/test_scripts/RC/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/detailed_info_GetSystemCapability.md +-- Item: Use Case 1:Exception 3.3 +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- diff --git a/test_scripts/RC/Capabilities/005_Resend_only_supported_parameters.lua b/test_scripts/RC/Capabilities/005_Resend_only_supported_parameters.lua index 72f5903081..fea57c4a9b 100644 --- a/test_scripts/RC/Capabilities/005_Resend_only_supported_parameters.lua +++ b/test_scripts/RC/Capabilities/005_Resend_only_supported_parameters.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/detailed_info_GetSystemCapability.md +-- Item: Use Case 1:Exception 3.3 +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- diff --git a/test_scripts/RC/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua b/test_scripts/RC/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua index fd88b96bc3..1c65c0ebe0 100644 --- a/test_scripts/RC/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua +++ b/test_scripts/RC/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/detailed_info_GetSystemCapability.md +-- Item: Use Case 1:Exception 3.3 +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- diff --git a/test_scripts/RC/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua b/test_scripts/RC/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua index 02045c7557..d36ae24bb8 100644 --- a/test_scripts/RC/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua +++ b/test_scripts/RC/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/detailed_info_GetSystemCapability.md +-- Item: Use Case 1: Alternative flow 1 +-- -- Requirement summary: -- [SDL_RC] Capabilities -- diff --git a/test_scripts/RC/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua b/test_scripts/RC/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua index 2ea7f69c19..3aa3e6bf39 100644 --- a/test_scripts/RC/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua +++ b/test_scripts/RC/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/detailed_info_GetSystemCapability.md +-- Item: Use Case 1: Exception 2.1 +-- -- Requirement summary: -- [SDL_RC] Capabilities -- diff --git a/test_scripts/RC/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua b/test_scripts/RC/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua index aed50cc611..c9d6c61615 100644 --- a/test_scripts/RC/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua +++ b/test_scripts/RC/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/detailed_info_GetSystemCapability.md +-- Item: Use Case 1: Exception 2.1 +-- -- Requirement summary: -- [SDL_RC] Capabilities -- diff --git a/test_scripts/RC/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua b/test_scripts/RC/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua index 5bc5270d3d..ba0782b4e9 100644 --- a/test_scripts/RC/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua +++ b/test_scripts/RC/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/detailed_info_GetSystemCapability.md +-- Item: Use Case 1: Exception 2 +-- -- Requirement summary: -- [SDL_RC] Capabilities -- diff --git a/test_scripts/RC/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua b/test_scripts/RC/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua index 807de5edfa..76d6a707e9 100644 --- a/test_scripts/RC/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua +++ b/test_scripts/RC/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/detailed_info_GetSystemCapability.md +-- Item: Use Case 1: Exception 2 +-- -- Requirement summary: -- [SDL_RC] Capabilities -- diff --git a/test_scripts/RC/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua b/test_scripts/RC/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua index 60487e5a02..94c66a0294 100644 --- a/test_scripts/RC/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua +++ b/test_scripts/RC/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/detailed_info_GetSystemCapability.md +-- Item: Use Case 1: Alternative flow 2 +-- -- Requirement summary: -- [SDL_RC] Capabilities -- diff --git a/test_scripts/RC/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua b/test_scripts/RC/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua index c1b58d7cfe..1b0b24e20a 100644 --- a/test_scripts/RC/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua +++ b/test_scripts/RC/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/detailed_info_GetSystemCapability.md +-- Item: Use Case 1: Alternative flow 2 +-- -- Requirement summary: -- [SDL_RC] Capabilities -- diff --git a/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua index 3aa2a50868..10e5caf581 100644 --- a/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- diff --git a/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 50193c6789..d62b9a7150 100644 --- a/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Exceptions: 3.1 +-- -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- [SDL_RC] Policy support of basic RC functionality diff --git a/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index c390e17419..9eaa2fcd57 100644 --- a/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Use Case 1: Exceptions: 3.1 +-- -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- [SDL_RC] Policy support of basic RC functionality diff --git a/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index eb7309b37e..846ec34890 100644 --- a/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Alternative flow 1 +-- -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- diff --git a/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua index 675ceb7e51..76f5c0f876 100644 --- a/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Exceptions: 5.2 +-- -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- diff --git a/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua index 16bff682a6..d02e60213b 100644 --- a/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Exceptions: 2.1 +-- -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- diff --git a/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index c7e41627ab..f6270a7ed4 100644 --- a/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Exceptions: 5.1 +-- -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- diff --git a/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index ef2ceab027..292397a71c 100644 --- a/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Exceptions: 5.1 +-- -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- diff --git a/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index c497913a6c..f1f20db70b 100644 --- a/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- [SDL_RC] Policy support of basic RC functionality diff --git a/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 2ea6ade00d..532a44037e 100644 --- a/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- [SDL_RC] Policy support of basic RC functionality diff --git a/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua index 7fa9b553f7..f5cdc82b84 100644 --- a/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +++ b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- diff --git a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua index 38599e564f..668b521690 100644 --- a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- diff --git a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index 4a4e78c85b..abd936ec07 100644 --- a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- diff --git a/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua b/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua index d93fbefd8d..ce964aa2b3 100644 --- a/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +++ b/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Current module status data GetInteriorVehicleData -- diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua index 6d0e84a5f2..753d815958 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Alternative flow 2 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua index 393dd76752..c1ff27508f 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Alternative flow 2 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua index b737dbdbcc..e73364055e 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Alternative flow 2.1 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua index 428df8dbaa..e73a05f598 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Alternative flow 2.1 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua index 694a95086d..ca4278b1d6 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Alternative flow 2.2 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua index 9d4947ef75..75c7edeb75 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Alternative flow 2.2 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua index 725c335e7b..ee43ec6d2d 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 2.1 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua index c86594588b..8edd8f8a51 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 2.1 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua index 26dbfa5bc7..d02876ba6f 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 2.1 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua index d9e287fd0f..913017bd6f 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 2.1 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua b/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua index 77eee27ac0..5309196f86 100644 --- a/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua +++ b/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Alternative flow 2.2 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua index 0c24a7bb75..e2c2c5de34 100644 --- a/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua @@ -1,4 +1,12 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/4 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/subscription_on_module_status_change_notification.md +-- Item: Use Case 1: Main Flow +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Subscribe on RC module change notification -- diff --git a/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 33ae435d99..9a4a6be45c 100644 --- a/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Exceptions: 5.1 +-- -- Requirement summary: -- [SDL_RC] Subscribe on RC module change notification -- [SDL_RC] Policy support of basic RC functionality diff --git a/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index 8904115be9..f1cb4cbeac 100644 --- a/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Exceptions: 5.1 +-- -- Requirement summary: -- [SDL_RC] Subscribe on RC module change notification -- [SDL_RC] Policy support of basic RC functionality diff --git a/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua index 52779155fd..87ead490bf 100644 --- a/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/4 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/subscription_on_module_status_change_notification.md +-- Use Case 1: Alternative flow 1 +-- -- Requirement summary: -- [SDL_RC] Subscribe on RC module change notification -- diff --git a/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua index caebc8277c..2d7c137bda 100644 --- a/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/4 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/subscription_on_module_status_change_notification.md +-- Use Case 1: Alternative flow 2 +-- -- Requirement summary: -- [SDL_RC] Subscribe on RC module change notification -- diff --git a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua index 2bec5fb8c9..7d78222d58 100644 --- a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/4 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/subscription_on_module_status_change_notification.md +-- Item: Use Case 1: Alternative flow 3 +-- -- Requirement summary: -- [SDL_RC] Subscribe on RC module change notification -- diff --git a/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua index d73d98a59b..becec9d8f4 100644 --- a/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/4 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/subscription_on_module_status_change_notification.md +-- Item: Use Case 1: Alternative flow 3 +-- -- Requirement summary: -- [SDL_RC] Subscribe on RC module change notification -- diff --git a/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua index af4fbf88bc..4d1e24d559 100644 --- a/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/4 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/subscription_on_module_status_change_notification.md +-- Item: Use Case 1: Alternative flow 3 +-- -- Requirement summary: -- [SDL_RC] Subscribe on RC module change notification -- diff --git a/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua index 394c815624..143e41f14b 100644 --- a/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Alternative flow 1 +-- -- Requirement summary: -- [SDL_RC] Unsubscribe from RC module change notifications -- diff --git a/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua index f1ef3f82c0..6a6edc4de1 100644 --- a/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Alternative flow 2 +-- -- Requirement summary: -- [SDL_RC] Unsubscribe from RC module change notifications -- diff --git a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua index aaec99ddc1..b59384ce69 100644 --- a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Alternative flow 3 +-- -- Requirement summary: -- [SDL_RC] Unsubscribe from RC module change notifications -- diff --git a/test_scripts/RC/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua b/test_scripts/RC/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua index 3b4fc78055..2f0340392f 100644 --- a/test_scripts/RC/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua +++ b/test_scripts/RC/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Alternative flow 3 +-- -- Requirement summary: -- [SDL_RC] Subscribe on RC module change notification -- [SDL_RC] Unsubscribe from RC module change notifications diff --git a/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua b/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua index 0fdbdd5a57..decaab1b0d 100644 --- a/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua +++ b/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Alternative flow 3 +-- -- Requirement summary: -- [SDL_RC] Subscribe on RC module change notification -- [SDL_RC] Unsubscribe from RC module change notifications diff --git a/test_scripts/RC/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua b/test_scripts/RC/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua index c8f18ca3cf..1b381d86a3 100644 --- a/test_scripts/RC/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua +++ b/test_scripts/RC/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Unsubscribe from RC module change notifications -- diff --git a/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua b/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua index 8b4bbe4e26..ca815b23c0 100644 --- a/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua +++ b/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Unsubscribe from RC module change notifications -- diff --git a/test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua b/test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua index 2f32e09f6e..ebd0d340e0 100644 --- a/test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua +++ b/test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Subscribe on RC module change notification -- [SDL_RC] Unsubscribe from RC module change notifications diff --git a/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua b/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua index c405584846..1e7307d267 100644 --- a/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua +++ b/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua b/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua index 9f6611aedf..681bf2178a 100644 --- a/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua +++ b/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua b/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua index 5bcdc9284e..449e83335d 100644 --- a/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua +++ b/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua b/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua index df9076238f..30ea672fd2 100644 --- a/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua +++ b/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua b/test_scripts/RC/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua index f8e95e0256..46fdc199bd 100644 --- a/test_scripts/RC/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua +++ b/test_scripts/RC/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 1 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua b/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua index 3561b19f28..49b849803a 100644 --- a/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua +++ b/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua @@ -1,4 +1,16 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 2 +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/9 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/button_press_emulation.md +-- Item: Use Case 1: Exception 1.5 +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exception 6.1 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua b/test_scripts/RC/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua index 1f1fb09c66..6c79b8d044 100644 --- a/test_scripts/RC/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua +++ b/test_scripts/RC/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Alternative flow 1 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua b/test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua index 573e103df1..f272226a97 100644 --- a/test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua +++ b/test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua b/test_scripts/RC/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua index ce517365c7..b34c1c7165 100644 --- a/test_scripts/RC/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua +++ b/test_scripts/RC/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md +-- Item: Use Case 2: Main Flow +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua b/test_scripts/RC/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua index 3b9e808f31..00f5e7cc21 100644 --- a/test_scripts/RC/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua +++ b/test_scripts/RC/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md +-- Item: Use Case 2: Main Flow +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua b/test_scripts/RC/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua index 747626d24e..6651c7569f 100644 --- a/test_scripts/RC/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua +++ b/test_scripts/RC/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md +-- Item: Use Case 2: Main Flow +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/012_Default_accessMode.lua b/test_scripts/RC/OnRemoteControlSettings/012_Default_accessMode.lua index a9a561a042..f10abc7c3a 100644 --- a/test_scripts/RC/OnRemoteControlSettings/012_Default_accessMode.lua +++ b/test_scripts/RC/OnRemoteControlSettings/012_Default_accessMode.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua b/test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua index 91a8a0aac9..c81bf9ed81 100644 --- a/test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua +++ b/test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua @@ -1,4 +1,16 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Main Flow +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Alternative flow 1 +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Alternative flow 2 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua b/test_scripts/RC/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua index c1847058f7..614c759273 100644 --- a/test_scripts/RC/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua +++ b/test_scripts/RC/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua b/test_scripts/RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua index 97e7b93e32..7df469d81c 100644 --- a/test_scripts/RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua +++ b/test_scripts/RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua b/test_scripts/RC/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua index b6a92566f7..fba44244cb 100644 --- a/test_scripts/RC/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua +++ b/test_scripts/RC/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Alternative flow 2.1 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua b/test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua index 6ac944d578..dfc5e03342 100644 --- a/test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua +++ b/test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua @@ -1,4 +1,12 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 1.1 +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 2.2 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua b/test_scripts/RC/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua index 1f6c020336..96b301a381 100644 --- a/test_scripts/RC/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua +++ b/test_scripts/RC/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua @@ -1,4 +1,12 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 1.1 +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 2.2 +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua b/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua index 0397d836bf..89c6da5d71 100644 --- a/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua +++ b/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md +-- Item: Use Case 2: Main Flow +-- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode -- diff --git a/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua index 9af1af9ef0..04c849ac8e 100644 --- a/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- diff --git a/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 19417cdb74..db68e3496c 100644 --- a/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 4.1 +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- [SDL_RC] Policy support of basic RC functionality diff --git a/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index 72aa6b7b1f..e4b62ed5ab 100644 --- a/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 4.1 +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- [SDL_RC] Policy support of basic RC functionality diff --git a/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index cb56f0e1af..18c8964459 100644 --- a/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Alternative flow 1 +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- diff --git a/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua b/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua index 3ca2372395..fea4a1ab33 100644 --- a/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua +++ b/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua @@ -1,4 +1,11 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 2.2 +-- +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Use Case 1: Exceptions: 7.3 +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- diff --git a/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua index f565e81cf3..6adcf4971d 100644 --- a/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 2.1 +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- diff --git a/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 77ce47065d..cfb3adabfa 100644 --- a/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- [SDL_RC] Policy support of basic RC functionality diff --git a/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 4cd9641e6f..a24e350823 100644 --- a/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- [SDL_RC] Policy support of basic RC functionality diff --git a/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua b/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua index 48918f3215..24396118a6 100644 --- a/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua +++ b/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 7.4.3 +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- diff --git a/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua b/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua index 7d33717506..d5b89f0eb8 100644 --- a/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +++ b/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 7.1 +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- diff --git a/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua b/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua index 0d2f3f0b04..3f9c3c6177 100644 --- a/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua +++ b/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 7.2 +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- diff --git a/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua b/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua index 05115d44d2..137a30883b 100644 --- a/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua +++ b/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 7.1 +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- diff --git a/test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index d88a639882..bcebb5f509 100644 --- a/test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- diff --git a/test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index c2a046f589..2da8ade57e 100644 --- a/test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- diff --git a/test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua index 080f6e7e4f..b437cffa2d 100644 --- a/test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua @@ -1,4 +1,8 @@ --------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Main Flow +-- -- Requirement summary: -- [SDL_RC] Set available control module settings SetInteriorVehicleData -- From 4388d793a9dad01f9ab8709e2d0f617fe916c334 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 18 Aug 2017 11:14:35 -0400 Subject: [PATCH 138/681] RC: Add additional delay for app activation --- test_scripts/RC/commonRC.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 8500788b06..9f8bdbbac8 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -24,6 +24,7 @@ local hmiAppIds = {} local commonRC = {} commonRC.timeout = 2000 +commonRC.minTimeout = 500 commonRC.DEFAULT = "Default" commonRC.buttons = { climate = "FAN_UP", radio = "VOLUME_UP" } @@ -211,6 +212,7 @@ function commonRC.activate_app(pAppId, self) end end) mobSession:ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + commonTestCases:DelayedExp(commonRC.minTimeout) end function commonRC.postconditions() @@ -587,7 +589,7 @@ function commonRC.defineRAMode(pAllowed, pAccessMode, self) self, pAccessMode = commonRC.getSelfAndParams(pAccessMode, self) local rpc = "OnRemoteControlSettings" self.hmiConnection:SendNotification(commonRC.getHMIEventName(rpc), commonRC.getHMIResponseParams(rpc, pAllowed, pAccessMode)) - commonTestCases:DelayedExp(500) -- workaround due to issue with SDL -> redundant OnHMIStatus notification is sent + commonTestCases:DelayedExp(commonRC.minTimeout) -- workaround due to issue with SDL -> redundant OnHMIStatus notification is sent end function commonRC.rpcDenied(pModuleType, pAppId, pRPC, pResultCode, self) From 940e871554e02df7b72133cdf214f5f3f0562d52 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 18 Aug 2017 13:55:06 -0400 Subject: [PATCH 139/681] RC: Remove Driver/Passenger dependency --- test_scripts/RC/commonRC.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 9f8bdbbac8..06327ac5c1 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -45,8 +45,7 @@ function commonRC.getRCAppConfig() priority = "NONE", default_hmi = "NONE", moduleType = { "RADIO", "CLIMATE" }, - groups = { "Base-4" }, - groups_primaryRC = { "Base-4", "RemoteControl" }, + groups = { "Base-4", "RemoteControl" }, AppHMIType = { "REMOTE_CONTROL" } } end From 553ed9d14e1cbfbb14e3ccdbc65448eb90c5f73f Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Mon, 21 Aug 2017 17:06:33 -0400 Subject: [PATCH 140/681] Fix force killing of SDL --- user_modules/shared_testcases/commonFunctions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_modules/shared_testcases/commonFunctions.lua b/user_modules/shared_testcases/commonFunctions.lua index 43755523d1..ad20efa7e9 100644 --- a/user_modules/shared_testcases/commonFunctions.lua +++ b/user_modules/shared_testcases/commonFunctions.lua @@ -854,7 +854,7 @@ end --14. Functions for SDL stop --------------------------------------------------------------------------------------------- function commonFunctions:SDLForceStop(self) - os.execute("ps aux | grep smart | awk \'{print $2}\' | xargs kill -9") + os.execute("ps aux | grep ./smartDeviceLinkCore | awk '{print $2}' | xargs kill -9") commonFunctions:sleep(1) end From 4ae2df3bc30675c7dd91f9ab43806eb8a96b550a Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Tue, 22 Aug 2017 10:36:21 -0400 Subject: [PATCH 141/681] Added shut down of created connections in Postconditions --- .../ATF_Register_5_connection.lua | 79 ++++++++----------- 1 file changed, 35 insertions(+), 44 deletions(-) diff --git a/test_scripts/Smoke/Registration/ATF_Register_5_connection.lua b/test_scripts/Smoke/Registration/ATF_Register_5_connection.lua index 0049b19900..c81c87e6ef 100644 --- a/test_scripts/Smoke/Registration/ATF_Register_5_connection.lua +++ b/test_scripts/Smoke/Registration/ATF_Register_5_connection.lua @@ -33,7 +33,7 @@ local commonSteps = require('user_modules/shared_testcases/commonSteps') local mobile_session = require('mobile_session') local mobile = require('mobile_connection') local tcp = require('tcp_connection') -local file_connection = require('file_connection') +local file_connection = require('file_connection') --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') @@ -41,29 +41,15 @@ require('cardinalities') require('user_modules/AppTypes') -- [[Local variables]] -local default_app_params1 = config.application1.registerAppInterfaceParams -local default_app_params2 = config.application2.registerAppInterfaceParams -local default_app_params3 = config.application3.registerAppInterfaceParams -local default_app_params4 = config.application4.registerAppInterfaceParams -local default_app_params5 = config.application5.registerAppInterfaceParams local devicePort = 12345 ---1. Device 1: -local device1 = "127.0.0.1" ---2. Device 2: -local device2 = "192.168.100.199" ---3. Device 3: -local device3 = "10.42.0.1" ---4. Device 4: -local device4 = "1.0.0.1" ---5. Device 5: -local device5 = "8.8.8.8" - --- Cretion dummy connections for script -os.execute("ifconfig lo:1 " .. device2) -os.execute("ifconfig lo:2 " .. device3) -os.execute("ifconfig lo:3 " .. device4) -os.execute("ifconfig lo:4 " .. device5) +local devices = { + "127.0.0.1", + "192.168.100.199", + "10.42.0.1", + "1.0.0.1", + "8.8.8.8" +} --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") @@ -82,13 +68,19 @@ local function createConnectionAndRegisterApp(self, device, filename, app) local correlationId = self.mobileSession:SendRPC("RegisterAppInterface", app) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", {application = { appName = app.appName}}) self.mobileSession:ExpectResponse(correlationId , { success = true, resultCode = "SUCCESS"}) - self.mobileSession:ExpectNotification("OnHMIStatus",{hmiLevel = "NONE", + self.mobileSession:ExpectNotification("OnHMIStatus",{hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}):Do(function() - commonFunctions:userPrint(35, "1st App is successfully registered") + commonFunctions:userPrint(35, "App is successfully registered") end) end) end +function Test.CreateDummyConections() + for i = 1, 4 do + os.execute("ifconfig lo:" .. i .." " .. devices[i + 1]) + end +end + function Test:Start_SDL() self:runSDL() commonFunctions:waitForSDLStart(self):Do(function() @@ -104,30 +96,29 @@ end --[[ Test ]] commonFunctions:newTestCasesGroup("Test") -function Test:FirstConnection() - createConnectionAndRegisterApp(self, device1, "mobile1.out", default_app_params1) -end - -function Test:SecondConnection() - createConnectionAndRegisterApp(self, device2, "mobile2.out", default_app_params2) -end - -function Test:ThirdConnection() - createConnectionAndRegisterApp(self, device3, "mobile3.out", default_app_params3) -end - -function Test:FourthConnection() - createConnectionAndRegisterApp(self, device4, "mobile4.out", default_app_params4) -end - -function Test:FifthConnection() - createConnectionAndRegisterApp(self, device5, "mobile5.out", default_app_params5) +for i = 1, 5 do + Test["CreateConnection_" .. i] = function(self) + local filename = "mobile" .. i .. ".out" + local app = config["application"..i].registerAppInterfaceParams + createConnectionAndRegisterApp(self, devices[i], filename, app) + end end - -- [[ Postconditions ]] commonFunctions:newTestCasesGroup("Postcondition") function Test.Stop_SDL() StopSDL() end -return Test \ No newline at end of file +function Test.ShutDownDummyConnections() + for i = 1, 4 do + os.execute("ifconfig lo:" .. i .." down") + end +end + +function Test.CleanTemporaryFiles() + for i = 1, 5 do + os.execute("rm -f " .. "mobile" .. i .. ".out") + end +end + +return Test From 3f968de006c0ffe841f66cc044dc437b6e5fadbc Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 23 Aug 2017 19:37:54 -0400 Subject: [PATCH 142/681] Fix issues concerning StopSDL --- ..._does_not_send_HB_and_does_not_respond.lua | 10 ++-- ...tBeat_App_does_not_send_HB_but_respond.lua | 8 +-- .../HeartBeat/ATF_HeartBeat_App_send_HB.lua | 4 +- ...ATF_HeartBeat_no_heartbeat_v2_protocol.lua | 4 +- .../ATF_Register_5_connection.lua | 3 ++ .../Registration/ATF_Register_5_session.lua | 11 ++-- .../Smoke/Registration/ATF_Register_App.lua | 5 +- .../Smoke/Registration/ATF_Reregister_App.lua | 5 +- .../ATF_Reregister_App_after_disconnect.lua | 10 ++-- ...egister_App_if_two_apps_are_registered.lua | 12 +++-- .../ATF_Resumption_3rd_ignition_cycle.lua | 47 +++++++++-------- .../ATF_Resumption_App_Unregister_itself.lua | 20 +++----- .../ATF_Resumption_BACKGROUND_level.lua | 15 +++--- .../ATF_Resumption_FULL_IGNITION_OFF.lua | 13 +++-- .../ATF_Resumption_LIMITED_IGNITION_OFF.lua | 17 +++---- .../ATF_Resumption_LIMITED_level.lua | 13 ++--- ...ed_in_more_than_30sec_after_BC.OnReady.lua | 18 +++---- .../ATF_Resumption_big_amount_of_data.lua | 29 +++++------ ...isconnect_more_than_30s_before_SUSPEND.lua | 17 +++---- .../ATF_Resumption_heartbeat_disconnect.lua | 9 ++-- .../ATF_Resumption_unexpected_disconnect.lua | 11 ++-- .../ShutDown/ATF_ShutDown_IGNITION_OFF.lua | 25 +++++----- .../ShutDown/ATF_ShutDown_MASTER_RESET.lua | 27 +++++----- .../commonStepsResumption.lua | 50 ++++++++++++------- 24 files changed, 201 insertions(+), 182 deletions(-) mode change 100755 => 100644 test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua diff --git a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua index d65514bddb..6ba37d729d 100644 --- a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua +++ b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua @@ -20,7 +20,7 @@ -- Expected behavior: -- 1. App has successfully registered. -- 2. App is disconnected by SDL due to heartbeat timeout occurs. - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] config.defaultProtocolVersion = 3 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -72,13 +72,13 @@ function Test:Start_Session_And_Register_App() self.mobileSession.ignoreSDLHeartBeatACK = false self.mobileSession:StartRPC():Do(function() local correlation_id = self.mobileSession:SendRPC("RegisterAppInterface", default_app_params) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = default_app_params.appName}}):Do(function(_,data) default_app_params.hmi_app_id = data.params.application.appID end) self.mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "SUCCESS"}) self.mobileSession:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) - self.mobileSession:ExpectNotification("OnPermissionsChange", {}) + self.mobileSession:ExpectNotification("OnPermissionsChange", {}) end) end @@ -92,12 +92,12 @@ function Test:Register_Second_App_With_HeartBeat() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = default_app_params2.appName}}) self.mobileSession1:ExpectResponse(correlation_id, {success = true, resultCode = "SUCCESS"}) self.mobileSession1:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) - self.mobileSession1:ExpectNotification("OnPermissionsChange", {}) + self.mobileSession1:ExpectNotification("OnPermissionsChange", {}) end) end function Test:Wait_15_seconds_And_Verify_OnAppUnregistered() - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {appID = default_app_params.hmi_app_id, unexpectedDisconnect = true}):Timeout(15000):Do(function() self.mobileSession:StopHeartbeat() end) diff --git a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_but_respond.lua b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_but_respond.lua index 956e3c525e..5223012591 100644 --- a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_but_respond.lua +++ b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_but_respond.lua @@ -2,7 +2,7 @@ -- [HeartBeat][Genivi]: SDL must track sending of HeartBeat_request from/to mobile app -- -- Description: --- Check that no heartbeat timeout occurs if App uses v3 protocol version and doesn't send HB to SDL, +-- Check that no heartbeat timeout occurs if App uses v3 protocol version and doesn't send HB to SDL, -- but response to SDL heartbeat requests in time or less than HB timeout. -- 1. Used precondition @@ -19,7 +19,7 @@ -- Expected behavior: -- 1. App has successfully registered. -- 2. App is still registered on HU, no unexpected disconnect occurs. - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] config.defaultProtocolVersion = 3 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -71,13 +71,13 @@ function Test:Start_Session_And_Register_App() self.mobileSession.ignoreSDLHeartBeatACK = false self.mobileSession:StartRPC():Do(function() local correlation_id = self.mobileSession:SendRPC("RegisterAppInterface", default_app_params) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = default_app_params.appName}}):Do(function(_,data) default_app_params.hmi_app_id = data.params.application.appID end) self.mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "SUCCESS"}) self.mobileSession:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) - self.mobileSession:ExpectNotification("OnPermissionsChange", {}) + self.mobileSession:ExpectNotification("OnPermissionsChange", {}) end) end diff --git a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_send_HB.lua b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_send_HB.lua index 398b38e5ba..9c4ba44187 100644 --- a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_send_HB.lua +++ b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_send_HB.lua @@ -19,7 +19,7 @@ -- Expected behavior: -- 1. App has successfully registered. -- 2. App is still registered, no unexpected disconnect occurs. - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] config.defaultProtocolVersion = 3 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -73,7 +73,7 @@ function Test:Start_Session_And_Register_App() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = default_app_params.appName}}) self.mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "SUCCESS"}) self.mobileSession:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) - self.mobileSession:ExpectNotification("OnPermissionsChange", {}) + self.mobileSession:ExpectNotification("OnPermissionsChange", {}) end) end diff --git a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_no_heartbeat_v2_protocol.lua b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_no_heartbeat_v2_protocol.lua index cc9b84843a..b2ae7af7b5 100644 --- a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_no_heartbeat_v2_protocol.lua +++ b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_no_heartbeat_v2_protocol.lua @@ -16,7 +16,7 @@ -- Expected behavior: -- 1. App has successfully registered. -- 2. App is still registered, no unexpected disconnect occurs. - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -72,7 +72,7 @@ function Test:Start_Session_And_Register_App() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = default_app_params.appName}}) self.mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "SUCCESS"}) self.mobileSession:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) - self.mobileSession:ExpectNotification("OnPermissionsChange", {}) + self.mobileSession:ExpectNotification("OnPermissionsChange", {}) end) end diff --git a/test_scripts/Smoke/Registration/ATF_Register_5_connection.lua b/test_scripts/Smoke/Registration/ATF_Register_5_connection.lua index 0049b19900..cbd1dfce15 100644 --- a/test_scripts/Smoke/Registration/ATF_Register_5_connection.lua +++ b/test_scripts/Smoke/Registration/ATF_Register_5_connection.lua @@ -26,6 +26,9 @@ -- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() -- 2. SDL assignes HMILevel after application registering: -- SDL->appID: OnHMIStatus(HMlLevel, audioStreamingState, systemContext) +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 -- [[ Required Shared Libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Smoke/Registration/ATF_Register_5_session.lua b/test_scripts/Smoke/Registration/ATF_Register_5_session.lua index a9e18fe02b..186ad7720a 100644 --- a/test_scripts/Smoke/Registration/ATF_Register_5_session.lua +++ b/test_scripts/Smoke/Registration/ATF_Register_5_session.lua @@ -9,7 +9,7 @@ -- 1. Used precondition -- SDL, HMI are running on system. -- Mobile device is connected to system. --- 1 session is added, 1 app is registered. +-- 1 session is added, 1 app is registered. -- -- 2. Performed steps -- Add 2 session @@ -22,11 +22,14 @@ -- appID_5->RegisterAppInterface(params) -- -- Expected behavior: --- 1. SDL successfully registers all four applications and notifies HMI and mobile +-- 1. SDL successfully registers all four applications and notifies HMI and mobile -- SDL->HMI: OnAppRegistered(params) --- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() +-- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() -- 2. SDL assignes HMILevel after application registering: -- SDL->appID: OnHMIStatus(HMlLevel, audioStreamingState, systemContext) +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 -- [[ Required Shared Libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') @@ -52,7 +55,7 @@ local function startSessionAndRegisterApp(self, app) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = app.appName}}) self.mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "SUCCESS"}) self.mobileSession:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) - self.mobileSession:ExpectNotification("OnPermissionsChange", {}) + self.mobileSession:ExpectNotification("OnPermissionsChange", {}) end) end diff --git a/test_scripts/Smoke/Registration/ATF_Register_App.lua b/test_scripts/Smoke/Registration/ATF_Register_App.lua index 91a8d9dac7..8f837a5a59 100644 --- a/test_scripts/Smoke/Registration/ATF_Register_App.lua +++ b/test_scripts/Smoke/Registration/ATF_Register_App.lua @@ -18,6 +18,9 @@ -- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() -- 2. SDL assignes HMILevel after application registering: -- SDL->appID: OnHMIStatus(HMlLevel, audioStreamingState, systemContext) +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 -- [[ Required Shared Libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') @@ -68,7 +71,7 @@ function Test:Register_App() EXPECT_NOTIFICATION("OnPermissionsChange") end) end - + -- [[ Postconditions ]] commonFunctions:newTestCasesGroup("Postcondition") function Test.Stop_SDL() diff --git a/test_scripts/Smoke/Registration/ATF_Reregister_App.lua b/test_scripts/Smoke/Registration/ATF_Reregister_App.lua index d2ee31ebaf..03215b042b 100644 --- a/test_scripts/Smoke/Registration/ATF_Reregister_App.lua +++ b/test_scripts/Smoke/Registration/ATF_Reregister_App.lua @@ -23,6 +23,9 @@ -- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() -- 3. SDL assignes HMILevel after application registering: -- SDL->appID: OnHMIStatus(HMlLevel, audioStreamingState, systemContext) +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 -- [[ Required Shared Libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') @@ -65,7 +68,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:Unregister_App() local cid = self.mobileSession:SendRPC("UnregisterAppInterface", default_app_params) EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = false, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = false, appID = self.applications[default_app_params.appName]}) end diff --git a/test_scripts/Smoke/Registration/ATF_Reregister_App_after_disconnect.lua b/test_scripts/Smoke/Registration/ATF_Reregister_App_after_disconnect.lua index f66540b2bb..3c85be08cc 100644 --- a/test_scripts/Smoke/Registration/ATF_Reregister_App_after_disconnect.lua +++ b/test_scripts/Smoke/Registration/ATF_Reregister_App_after_disconnect.lua @@ -22,15 +22,15 @@ -- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() -- 3. SDL assignes HMILevel after application registering: -- SDL->appID: OnHMIStatus(HMlLevel, audioStreamingState, systemContext) - +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 -- [[ Required Shared Libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local mobile_session = require('mobile_session') -config.defaultProtocolVersion = 2 - --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') require('cardinalities') @@ -66,7 +66,7 @@ end commonFunctions:newTestCasesGroup("Check that it is able to reregister App after disconnect") function Test:Close_Connection() - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = self.applications[default_app_params.appName]}) self.mobileSession:Stop() end @@ -75,7 +75,7 @@ function Test:Reregister_Application() local mobileSession = mobile_session.MobileSession(self, self.mobileConnection) local on_rpc_service_started = mobileSession:StartRPC() on_rpc_service_started:Do(function() - local cid = self.mobileSession:SendRPC("RegisterAppInterface", default_app_params) + local cid = self.mobileSession:SendRPC("RegisterAppInterface", default_app_params) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = {appName = default_app_params.appName} }) self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) diff --git a/test_scripts/Smoke/Registration/ATF_Reregister_App_if_two_apps_are_registered.lua b/test_scripts/Smoke/Registration/ATF_Reregister_App_if_two_apps_are_registered.lua index 37b53fe7ea..4803b63835 100644 --- a/test_scripts/Smoke/Registration/ATF_Reregister_App_if_two_apps_are_registered.lua +++ b/test_scripts/Smoke/Registration/ATF_Reregister_App_if_two_apps_are_registered.lua @@ -24,7 +24,9 @@ -- SDL->appID_1: SUCCESS, success:"true":RegisterAppInterface() -- 3. SDL assignes HMILevel after application registering: -- SDL->appID_1: OnHMIStatus(HMlLevel, audioStreamingState, systemContext) - +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 -- [[ Required Shared Libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') @@ -62,7 +64,7 @@ function Test:Start_SDL_With_One_Activated_App() end commonSteps:precondition_AddNewSession() -commonSteps:RegisterTheSecondMediaApp() +commonSteps:RegisterTheSecondMediaApp() --[[ Test ]] commonFunctions:newTestCasesGroup("Test") @@ -70,12 +72,12 @@ commonFunctions:newTestCasesGroup("Test") function Test:Unregister_App() local cid = self.mobileSession:SendRPC("UnregisterAppInterface", default_app_params1) EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = false, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = false, appID = self.applications[default_app_params1.appName]}) end function Test:Reregister_Application() - local cid = self.mobileSession:SendRPC("RegisterAppInterface", default_app_params1) + local cid = self.mobileSession:SendRPC("RegisterAppInterface", default_app_params1) self.mobileSession:ExpectResponse(cid, { success = true }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = {appName = default_app_params1.appName} }) @@ -84,7 +86,7 @@ function Test:Reregister_Application() self.hmiConnection:SendResponse(data.id, "BasicCommunication.UpdateAppList", "SUCCESS", {}) end) EXPECT_NOTIFICATION("OnHMIStatus", { systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE"}) - EXPECT_NOTIFICATION("OnPermissionsChange", {}) + EXPECT_NOTIFICATION("OnPermissionsChange", {}) end -- [[ Postconditions ]] diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua index a361eb8901..3ddf4ea934 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua @@ -3,7 +3,7 @@ -- [HMILevel Resumption]: Conditions to resume app to FULL in the next ignition cycle. -- Description: --- Check that: +-- Check that: -- 1. SDL performs App data resumption in case when media app tries to resume in 3rd ignition cycle. -- 2. SDL doesn't resumes App to FULL hmi level. -- @@ -19,10 +19,8 @@ -- -- Expected behavior: -- 1. In 3rd ignition cycle App is registered and get default HMI level, app data is resumed. - - +--------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] ---TODO(ilytvynenko): should be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -31,6 +29,7 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonStepsResumption = require('user_modules/shared_testcases/commonStepsResumption') local mobile_session = require('mobile_session') +local SDL = require('SDL') --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') @@ -42,20 +41,6 @@ local default_app_params = config.application1.registerAppInterfaceParams local default_app = nil -- will be initialized after application registration -- [[ Local Functions ]] -local function IGNITION_OFF() - Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", - { reason = "SUSPEND" }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() - Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", - { reason = "IGNITION_OFF" }) - EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) - end) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose"):Do(function() - StopSDL() - end) -end - local function Start_SDL_And_Add_Mobile_Connection() Test:runSDL() commonFunctions:waitForSDLStart(Test):Do(function() @@ -106,7 +91,16 @@ end commonFunctions:newTestCasesGroup("SDL should perform data resumption application is registered within 3 ign cycles") function Test.IGNITION_OFF() - IGNITION_OFF() + Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", + { reason = "SUSPEND" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() + Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", + { reason = "IGNITION_OFF" }) + EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + SDL:DeleteFile() + end) end function Test.Restart_SDL_And_Add_Mobile_Connection() @@ -114,7 +108,14 @@ function Test.Restart_SDL_And_Add_Mobile_Connection() end function Test.IGNITION_OFF() - IGNITION_OFF() + Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", + { reason = "SUSPEND" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() + Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", + { reason = "IGNITION_OFF" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + SDL:DeleteFile() + end) end function Test.Restart_SDL_And_Add_Mobile_Connection() @@ -126,10 +127,8 @@ function Test:Register_And_No_Resume_App() local on_rpc_service_started = mobile_session1:StartRPC() on_rpc_service_started:Do(function() default_app_params.hashID = self.currentHashID - commonStepsResumption:Expect_Resumption_Data(default_app_params) - commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectNoResumeApp, false):Do(function() - StopSDL() - end) + commonStepsResumption:Expect_Resumption_Data(default_app_params) + commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectResumeAppFULL, true) end) end diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_App_Unregister_itself.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_App_Unregister_itself.lua index 2087cedd0f..c1e8795ced 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_App_Unregister_itself.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_App_Unregister_itself.lua @@ -12,16 +12,18 @@ -- Start SPT again, Find Apps -- -- Expected behavior: --- 1. SPT sends UnregisterAppInterface and EndSession to SDL. +-- 1. SPT sends UnregisterAppInterface and EndSession to SDL. -- SPT register in usual way, no resumption occurs - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true -- [[ Required Shared Libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonStepsResumption = require('user_modules/shared_testcases/commonStepsResumption') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') @@ -85,20 +87,12 @@ commonFunctions:newTestCasesGroup("No resumption if App unregister itself") function Test:Unregister_App() local cid = self.mobileSession:SendRPC("UnregisterAppInterface", default_app_params) EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = false, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = false, appID = self.applications[default_app_params]}) end -function Test:Register_And_No_Resume_App_And_Data() - commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectNoResumeApp, false):Do(function() - local cid1 = self.mobileSession:SendRPC("ListFiles", {}) - EXPECT_RESPONSE(cid1, { success = true, resultCode = "SUCCESS" }):ValidIf (function(_,data) - return not data.payload.filenames - end) - EXPECT_HMICALL("VR.AddCommand"):Times(0) - end):Do(function() - StopSDL() - end) +function Test:Register_And_No_Resume_App() + commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectNoResumeApp, false) end -- [[ Postconditions ]] diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_BACKGROUND_level.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_BACKGROUND_level.lua index c4da2b64c7..4846ea7ac6 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_BACKGROUND_level.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_BACKGROUND_level.lua @@ -3,7 +3,7 @@ -- -- Description: -- Applications of BACKGROUND are not the case of HMILevel resumption in the next ignition cycle. --- Check that SDL performs app's data resumption and does not resume BACKGROUND HMI level +-- Check that SDL performs app's data resumption and does not resume BACKGROUND HMI level -- of media after transport unexpected disconnect on mobile side. -- 1. Used precondition @@ -18,8 +18,9 @@ -- Expected behavior: -- 1. App is unregistered from HMI. -- App is registered on HMI, SDL resumes all data and App gets default HMI level NONE. - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true config.application2.registerAppInterfaceParams.isMediaApplication = true @@ -79,17 +80,17 @@ end --[[ Test ]] commonFunctions:newTestCasesGroup("Transport unexpected disconnect. Media app not resume at BACKGROUND level") commonSteps:precondition_AddNewSession() -commonSteps:RegisterTheSecondMediaApp() +commonSteps:RegisterTheSecondMediaApp() commonSteps:ActivateTheSecondMediaApp() function Test:Close_Session2() - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = self.applications[default_app_params2.appName]}) self.mobileSession2:Stop() end function Test:Close_Session1() - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = self.applications[default_app_params1.appName]}) self.mobileSession:Stop() end @@ -100,9 +101,7 @@ function Test:Register_And_No_Resume_App_BACKGROUND_And_Resumes_Data() default_app_params1.hashID = self.currentHashID on_rpc_service_started:Do(function() commonStepsResumption:Expect_Resumption_Data(default_app_params1) - commonStepsResumption:RegisterApp(default_app_params1, commonStepsResumption.ExpectNoResumeApp, true):Do(function() - StopSDL() - end) + commonStepsResumption:RegisterApp(default_app_params1, commonStepsResumption.ExpectNoResumeApp, true) end) end diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua index 4fe3e28055..9b698c027e 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua @@ -16,11 +16,10 @@ -- -- Expected behavior: -- 1. SDL sends to HMI OnSDLClose --- 2. App is registered, SDL sends OnAppRegistered with the same HMI appID as in last ignition cycle, +-- 2. App is registered, SDL sends OnAppRegistered with the same HMI appID as in last ignition cycle, -- then sends BasicCommunication.ActivateApp to HMI and after success response from HMI, SDL sends to App OnHMIStatus(FULL) - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] ---TODO(ilytvynenko): should be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -29,6 +28,7 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonStepsResumption = require('user_modules/shared_testcases/commonStepsResumption') local mobile_session = require('mobile_session') +local SDL = require('SDL') --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') @@ -77,10 +77,9 @@ function Test:IGNITION_OFF() { reason = "IGNITION_OFF" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) end) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose"):Do(function() - StopSDL() - end) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + SDL:DeleteFile() end function Test:Restart_SDL_And_Add_Mobile_Connection() diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua index 71d2cc3fac..ca6efe9b35 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua @@ -3,8 +3,8 @@ -- [HMILevel Resumption]: Conditions to resume app to LIMITED in the next ignition cycle -- -- Description: --- Any application in LIMITED HMILevel during the time frame of 30 sec (inclusive) before --- BC.OnExitAllApplications(SUSPEND) from HMI +-- Any application in LIMITED HMILevel during the time frame of 30 sec (inclusive) before +-- BC.OnExitAllApplications(SUSPEND) from HMI -- SDL must resume LIMITED level, send OnResumeAudioSource to each application. -- -- 1. Used preconditions @@ -17,9 +17,8 @@ -- Expected result: -- 1. SDL sends to HMI OnSDLClose -- 2. App is registered, SDL sends OnAppRegistered with the same HMI appID as in last ignition cycle, then sets App to LIMITED HMI level - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] ---TODO(ilytvynenko):should be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -28,6 +27,7 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonStepsResumption = require('user_modules/shared_testcases/commonStepsResumption') local mobile_session = require('mobile_session') +local SDL = require('SDL') --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') @@ -52,7 +52,7 @@ function Test:Start_SDL_With_One_Activated_App() self:connectMobile():Do(function () commonFunctions:userPrint(35, "Mobile Connected") self:startSession():Do(function () - commonSteps:ActivateAppInSpecificLevel(self, + commonSteps:ActivateAppInSpecificLevel(self, self.applications[default_app_params.appName]) EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "FULL", systemContext = "MAIN"}) end) @@ -73,10 +73,9 @@ function Test:IGNITION_OFF() { reason = "IGNITION_OFF" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) end) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose"):Do(function () - StopSDL() - end) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + SDL:DeleteFile() end function Test:Restart_SDL_And_Add_Mobile_Connection() diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_level.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_level.lua index 2eee723c71..cbf30bb8a7 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_level.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_level.lua @@ -2,7 +2,7 @@ -- [HMILevel Resumption]: Conditions to resume app to LIMITED after "unexpected disconnect" event. -- -- Description: --- Check that SDL resumes LIMITED level of media App and it's data +-- Check that SDL resumes LIMITED level of media App and it's data -- after transport unexpected disconnect -- 1. Used precondition @@ -15,10 +15,11 @@ -- -- Expected behavior: -- 1. App is unregistered from HMI. --- 2. App is registered on HMI, SDL resumes all App's data and sends OnResumeAudioSource to HMI. +-- 2. App is registered on HMI, SDL resumes all App's data and sends OnResumeAudioSource to HMI. -- App gets LIMITED HMI Level - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true -- [[ Required Shared Libraries ]] @@ -78,7 +79,7 @@ commonFunctions:newTestCasesGroup("Transport unexpected disconnect. App resume a commonSteps:ChangeHMIToLimited("Change_app_to_Limited") function Test:Close_Session() - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = self.applications[default_app_params]}) self.mobileSession:Stop() end @@ -86,9 +87,9 @@ end function Test:Register_And_Resumes_App_And_Data() local mobileSession = mobile_session.MobileSession(self, self.mobileConnection) local on_rpc_service_started = mobileSession:StartRPC() - on_rpc_service_started:Do(function() + on_rpc_service_started:Do(function() default_app_params.hashID = self.currentHashID - commonStepsResumption:Expect_Resumption_Data(default_app_params) + commonStepsResumption:Expect_Resumption_Data(default_app_params) commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectResumeAppLIMITED, true) end) end diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua index 3cab7a812b..5d7f0e7f1c 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua @@ -2,7 +2,7 @@ -- [HMILevel Resumption]: Conditions to resume app to FULL in the next ignition cycle -- -- Description: --- Check that SDL does not perform App resumption in case when app is +-- Check that SDL does not perform App resumption in case when app is -- registered in more than 30 sec. after BC.OnReady from HMI in the very next ignition cycle -- -- 1. Used precondition @@ -16,9 +16,8 @@ -- Expected behavior: -- 1. SDL sends to HMI OnSDLClose. -- App is registered successfully and get default HMI level. - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] ---TODO(ilytvynenko): should be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -27,6 +26,7 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonStepsResumption = require('user_modules/shared_testcases/commonStepsResumption') local mobile_session = require('mobile_session') +local SDL = require('SDL') --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') @@ -73,11 +73,9 @@ function Test:IGNITION_OFF() { reason = "IGNITION_OFF" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) end) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose"):Do(function () - self.mobileSession:Stop() - StopSDL() - end) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + SDL:DeleteFile() end function Test:Restart_SDL_And_Add_Mobile_Connection() @@ -103,9 +101,7 @@ function Test:Register_And_No_Resume_App() local mobile_session1 = mobile_session.MobileSession(self, self.mobileConnection) local on_rpc_service_started = mobile_session1:StartRPC() on_rpc_service_started:Do(function() - commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectNoResumeApp, false):Do(function () - StopSDL() - end) + commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectNoResumeApp, false) end) end diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua index 9a33cb6f97..0ca0087c3e 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua @@ -15,10 +15,11 @@ -- -- Expected behavior: -- 1. App is unregistered successfully. --- App is registered successfully, SDL sends OnAppRegistered on HMI with "resumeVrGrammars"=true. +-- App is registered successfully, SDL sends OnAppRegistered on HMI with "resumeVrGrammars"=true. -- SDL resumes all app's data and sends BC.ActivateApp to HMI. App gets FULL HMI Level - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true -- [[ Required Shared Libraries ]] @@ -109,7 +110,7 @@ end commonFunctions:newTestCasesGroup("Transport unexpected disconnect. App resume at FULL level") function Test:Close_Session() - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = self.applications[default_app_params]}) self.mobileSession:Stop() end @@ -117,10 +118,10 @@ end function Test:Register_And_Resume_App_And_Data() local mobileSession = mobile_session.MobileSession(self, self.mobileConnection) local on_rpc_service_started = mobileSession:StartRPC() - on_rpc_service_started:Do(function() + on_rpc_service_started:Do(function() config.application1.registerAppInterfaceParams.hashID = self.currentHashID Test:expect_Resumption_Data() - commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectResumeAppFULL, true) + commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectResumeAppFULL, true) end) end @@ -133,12 +134,12 @@ function Test:expect_Resumption_Data() if data.params.menuParams.position == 500 then if data.params.appID == default_app_params.hmi_app_id then return true - else + else commonFunctions:userPrint(31, "App is registered with wrong appID " ) return false end end - end) + end) local is_command_received = 20 local is_choice_received = 20 local on_vr_commands_added = EXPECT_HMICALL("VR.AddCommand"):Times(40) @@ -147,10 +148,10 @@ function Test:expect_Resumption_Data() end) on_vr_commands_added:ValidIf(function(_,data) if (data.params.type == "Command" and is_command_received ~= 0) then - if (data.params.appID == default_app_params.hmi_app_id) then + if (data.params.appID == default_app_params.hmi_app_id) then is_command_received = is_command_received - 1 return true - else + else commonFunctions:userPrint(31, "Received the same notification or App is registered with wrong appID") return false end @@ -158,7 +159,7 @@ function Test:expect_Resumption_Data() if (data.params.appID == default_app_params.hmi_app_id) then is_choice_received = is_choice_received - 1 return true - else + else commonFunctions:userPrint(31, "Received the same notification or App is registered with wrong appID") return false end @@ -173,16 +174,16 @@ function Test:OnCommand() end function Test:PerformInteraction() - self.mobileSession:SendRPC("PerformInteraction",{ + self.mobileSession:SendRPC("PerformInteraction",{ initialText = "StartPerformInteraction", - initialPrompt = { + initialPrompt = { { text = "Makeyourchoice", type = "TEXT"}}, interactionMode = "BOTH", interactionChoiceSetIDList = { 20 }, timeout = 5000 }) - EXPECT_HMICALL("VR.PerformInteraction", {appID = default_app_params.hmi_app_id}):Do(function(_,data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {choiceID = 20}) + EXPECT_HMICALL("VR.PerformInteraction", {appID = default_app_params.hmi_app_id}):Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {choiceID = 20}) end) end diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua index f08eb1f816..61e9463b51 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua @@ -15,9 +15,8 @@ -- -- Expected behavior: -- 1. App is successfully registered and receive default HMI level - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] ---TODO(ilytvynenko): should be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -26,6 +25,7 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonStepsResumption = require('user_modules/shared_testcases/commonStepsResumption') local mobile_session = require('mobile_session') +local SDL = require('SDL') --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') @@ -67,7 +67,7 @@ end commonFunctions:newTestCasesGroup("App disconnect >30s before BC.OnExitAllApplications(SUSPEND). App not resume") function Test:Close_Session() - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = self.applications[default_app_params]}) self.mobileSession:Stop() end @@ -82,12 +82,9 @@ function Test:IGNITION_OFF() EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) - EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) - end) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose"):Do(function () - StopSDL() end) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + SDL:DeleteFile() end function Test:Restart_SDL_And_Add_Mobile_Connection() @@ -109,9 +106,7 @@ function Test:Register_And_No_Resume_App() local mobile_session1 = mobile_session.MobileSession(self, self.mobileConnection) local on_rpc_service_started = mobile_session1:StartRPC() on_rpc_service_started:Do(function() - commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectNoResumeApp, false):Do(function () - StopSDL() - end) + commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectNoResumeApp, false) end) end diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua index 7ffa632ad2..2c6a3b362e 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua @@ -17,8 +17,9 @@ -- Expected behavior: -- 1. SDL sends OnAppUnregistered to HMI. -- 2. App is registered and SDL resumes all App data, sends BC.ActivateApp to HMI, app gets FULL HMI level. - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 3 config.application1.registerAppInterfaceParams.isMediaApplication = true -- [[ Required Shared Libraries ]] @@ -76,7 +77,7 @@ end --[[ Test ]] commonFunctions:newTestCasesGroup("Check that SDL perform resumption after heartbeat disconnect") -function Test:Wait_20_sec() +function Test:Wait_20_sec() self.mobileSession:StopHeartbeat() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {appID = self.applications[default_app_params], unexpectedDisconnect = true }) :Timeout(20000) @@ -89,10 +90,10 @@ end function Test:Register_And_Resume_App_And_Data() local mobileSession = mobile_session.MobileSession(self, self.mobileConnection) local on_rpc_service_started = mobileSession:StartRPC() - on_rpc_service_started:Do(function() + on_rpc_service_started:Do(function() default_app_params.hashID = self.currentHashID commonStepsResumption:Expect_Resumption_Data(default_app_params) - commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectResumeAppFULL, true) + commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectResumeAppFULL, true) end) end diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_unexpected_disconnect.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_unexpected_disconnect.lua index ef84561be7..5d07396b5a 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_unexpected_disconnect.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_unexpected_disconnect.lua @@ -14,10 +14,11 @@ -- -- Expected behavior: -- 1. App is unregistered. --- 2. App is registered successfully, SDL resumes all App data and sends +-- 2. App is registered successfully, SDL resumes all App data and sends -- BC.ActivateApp to HMI. App gets FULL HMI Level. - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true -- [[ Required Shared Libraries ]] @@ -76,7 +77,7 @@ end commonFunctions:newTestCasesGroup("Transport unexpected disconnect. App resume at FULL level") function Test:Close_Session() - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = self.applications[default_app_params]}) self.mobileSession:Stop() end @@ -84,9 +85,9 @@ end function Test:Register_And_Resume_App_And_Data() local mobileSession = mobile_session.MobileSession(self, self.mobileConnection) local on_rpc_service_started = mobileSession:StartRPC() - on_rpc_service_started:Do(function() + on_rpc_service_started:Do(function() default_app_params.hashID = self.currentHashID - commonStepsResumption:Expect_Resumption_Data(default_app_params) + commonStepsResumption:Expect_Resumption_Data(default_app_params) commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectResumeAppFULL, true) end) end diff --git a/test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua b/test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua index 2bf85b8bcb..ecf80a0462 100644 --- a/test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua +++ b/test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua @@ -1,28 +1,31 @@ -- Requirement summary: --- [Data Resumption]:OnExitAllApplications(IGNITION_OFF) in terms of resumption +-- [Data Resumption]:OnExitAllApplications(IGNITION_OFF) in terms of resumption -- -- Description: --- In case SDL receives OnExitAllApplications(IGNITION_OFF), +-- In case SDL receives OnExitAllApplications(IGNITION_OFF), -- SDL must clean up any resumption-related data --- Obtained after OnExitAllApplications( SUSPEND). SDL must stop all its processes, +-- Obtained after OnExitAllApplications( SUSPEND). SDL must stop all its processes, -- notify HMI via OnSDLClose and shut down. -- -- 1. Used preconditions -- HMI is running -- One App is registered and activated on HMI --- +-- -- 2. Performed steps -- Perform ignition Off -- HMI sends OnExitAllApplications(IGNITION_OFF) --- +-- -- Expected result: -- 1. SDL sends to App OnAppInterfaceUnregistered -- 2. SDL sends to HMI OnSDLClose and stops working - +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') +local SDL = require('SDL') --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') @@ -44,7 +47,7 @@ function Test:Start_SDL_With_One_Activated_App() self:connectMobile():Do(function () commonFunctions:userPrint(35, "Mobile Connected") self:startSession():Do(function () - commonSteps:ActivateAppInSpecificLevel(self, + commonSteps:ActivateAppInSpecificLevel(self, self.applications[config.application1.registerAppInterfaceParams.appName]) EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "FULL", systemContext = "MAIN"}) end) @@ -63,11 +66,9 @@ function Test:ShutDown_IGNITION_OFF() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) - end) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose"):Do(function () - print("ONSDLClose") - StopSDL() + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + SDL:DeleteFile() end) end diff --git a/test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua b/test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua old mode 100755 new mode 100644 index 670f8a8d50..c05d9664a4 --- a/test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua +++ b/test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua @@ -2,7 +2,7 @@ -- [Policies] Master Reset -- -- Description: --- On Master Reset, Policy Manager must revert Local Policy Table +-- On Master Reset, Policy Manager must revert Local Policy Table -- to the Preload Policy Table. -- -- 1. Used preconditions @@ -15,12 +15,16 @@ -- -- Expected result: -- 1. SDL clear all Apps folder, app_info.dat file and shut down - +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local mobile_session = require('mobile_session') +local SDL = require('SDL') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") --[[ Local Variables ]] -- Hash id of AddCommand before MASTER_RESET @@ -57,7 +61,7 @@ end function Test:Activate_App_And_Put_File() local function addCommand() - local cid = self.mobileSession:SendRPC("AddCommand",{ cmdID = 1005, + local cid = self.mobileSession:SendRPC("AddCommand",{ cmdID = 1005, vrCommands = { "OnlyVRCommand"} }) EXPECT_HMICALL("VR.AddCommand", {cmdID = 1005, type = "Command", @@ -89,13 +93,12 @@ end commonFunctions:newTestCasesGroup("Check that SDL finish it's work properly by MASTER_RESET") function Test:ShutDown_MASTER_RESET() - self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "MASTER_RESET" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "MASTER_RESET" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose"):Do(function () - StopSDL() - end) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + SDL:DeleteFile() end --- Start SDL again then add mobile connection @@ -123,7 +126,7 @@ function Test:Check_Application_Not_Resume_When_Register_Again() local rai_params = config.application1.registerAppInterfaceParams rai_params.hashID = hash_id - local cid = self.mobileSession:SendRPC("RegisterAppInterface",rai_params) + local cid = self.mobileSession:SendRPC("RegisterAppInterface",rai_params) local on_app_registered = self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "RESUME_FAILED" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = {appName = default_app_name} }) @@ -132,20 +135,20 @@ function Test:Check_Application_Not_Resume_When_Register_Again() self.hmiConnection:SendResponse(data.id, "BasicCommunication.UpdateAppList", "SUCCESS", {}) end) - EXPECT_NOTIFICATION("OnHMIStatus", { systemContext = "MAIN", hmiLevel = "NONE", + EXPECT_NOTIFICATION("OnHMIStatus", { systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE"}) on_app_registered:Do(function() local cid1 = self.mobileSession:SendRPC("ListFiles", {}) EXPECT_RESPONSE(cid1, { success = true, resultCode = "SUCCESS" }) :ValidIf (function(_,data) - return not data.payload.filenames + return not data.payload.filenames end) EXPECT_HMICALL("BasicCommunication.ActivateApp"):Times(0) EXPECT_HMICALL("VR.AddCommand"):Times(0) - StopSDL() end) end) -end + commonTestCases:DelayedExp(3000) +end -- [[ Postconditions ]] commonFunctions:newTestCasesGroup("Postcondition") diff --git a/user_modules/shared_testcases/commonStepsResumption.lua b/user_modules/shared_testcases/commonStepsResumption.lua index 5cf4071206..f6c9a619da 100644 --- a/user_modules/shared_testcases/commonStepsResumption.lua +++ b/user_modules/shared_testcases/commonStepsResumption.lua @@ -1,5 +1,6 @@ local commonStepsResumption = {} local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") function commonStepsResumption:AddCommand() local cid = Test.mobileSession:SendRPC("AddCommand", { cmdID = 1, vrCommands = {"OnlyVRCommand"}}) @@ -17,7 +18,7 @@ end function commonStepsResumption:AddSubMenu() local cid = Test.mobileSession:SendRPC("AddSubMenu", { menuID = 1, position = 500, menuName = "SubMenu"}) - local on_hmi_call = EXPECT_HMICALL("UI.AddSubMenu", { menuID = 1, menuParams = + local on_hmi_call = EXPECT_HMICALL("UI.AddSubMenu", { menuID = 1, menuParams = { position = 500, menuName = "SubMenu"}}) on_hmi_call:Do(function(_, data) Test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) @@ -59,36 +60,50 @@ local function CheckTimeBoundaries(time) return false end elseif exp.occurences == 1 then - return true + return true end end end function commonStepsResumption:RegisterApp(app, additional_expectations , resume_vr_grammars) - local default_additional_expectations = function (app) + local default_additional_expectations = function (app) EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "NONE", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE"}) end - if (not additional_expectations) then + if (not additional_expectations) then additional_expectations = default_additional_expectations end local correlation_id = Test.mobileSession:SendRPC("RegisterAppInterface", app) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", - { application = {appName = app.appName}, resumeVrGrammars = resume_vr_grammars}):Do(function (_, data) + { application = {appName = app.appName } }):Do(function (_, data) app.hmi_app_id = data.params.application.appID end) - Test.mobileSession:ExpectResponse(correlation_id, { success = true}) + :ValidIf(function(_, d) + local pA = d.params.resumeVrGrammars + local pE = resume_vr_grammars + if pE == false then + if pA == nil or pA == false then + return true + end + else + if pA == pE then + return true + end + end + return false, "The value of " .. pA .. " (".. tostring(pA) .. ") is not as expected (" .. pE .. ")" + end) + Test.mobileSession:ExpectResponse(correlation_id, { success = true}) local exp = additional_expectations(Test, app) return exp end function commonStepsResumption:ExpectResumeAppFULL(app) local audio_streaming_state = "AUDIBLE" - if(app.isMediaApplication == false) then + if(app.isMediaApplication == false) then audio_streaming_state = "NOT_AUDIBLE" end local time = timestamp() - local app_activated = EXPECT_HMICALL("BasicCommunication.ActivateApp", + local app_activated = EXPECT_HMICALL("BasicCommunication.ActivateApp", {appID = Test.applications[app.appName]}):Do(function(_,data) Test.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) end) @@ -98,15 +113,15 @@ function commonStepsResumption:ExpectResumeAppFULL(app) :Do(function(_,data) Test.hmiLevel = data.payload.hmiLevel end):Times(2) - return app_activated + return app_activated end function commonStepsResumption:ExpectResumeAppLIMITED(app) local audio_streaming_state = "AUDIBLE" - if(app.isMediaApplication == false) then + if(app.isMediaApplication == false) then audio_streaming_state = "NOT_AUDIBLE" end - local time = timestamp() + local time = timestamp() local on_audio_source = EXPECT_HMINOTIFICATION("BasicCommunication.OnResumeAudioSource", {appID = Test.applications[app.appName]}) EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "NONE", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE"}, @@ -126,6 +141,7 @@ function commonStepsResumption:ExpectNoResumeApp(app) local exp = EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "NONE", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE"}) EXPECT_HMICALL("BasicCommunication.ActivateApp"):Times(0) EXPECT_HMINOTIFICATION("BasicCommunication.OnResumeAudioSource"):Times(0) + commonTestCases:DelayedExp(3000) return exp end @@ -135,15 +151,15 @@ function commonStepsResumption:Expect_Resumption_Data(app) Test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS") end) on_ui_sub_menu_added:ValidIf(function(_,data) - if (data.params.menuParams.menuName == "SubMenu" and data.params.menuID == 1) then + if (data.params.menuParams.menuName == "SubMenu" and data.params.menuID == 1) then if data.params.appID == app.hmi_app_id then return true - else + else commonFunctions:userPrint(31, "App is registered with wrong appID " ) return false end end - end) + end) local is_command_received = false local is_choice_received = false local on_vr_commands_added = EXPECT_HMICALL("VR.AddCommand"):Times(2) @@ -152,10 +168,10 @@ function commonStepsResumption:Expect_Resumption_Data(app) end) on_vr_commands_added:ValidIf(function(_,data) if (data.params.type == "Command" and data.params.cmdID == 1) then - if (data.params.appID == app.hmi_app_id and not is_command_received) then + if (data.params.appID == app.hmi_app_id and not is_command_received) then is_command_received = true return true - else + else commonFunctions:userPrint(31, "Received the same notification or App is registered with wrong appID") return false end @@ -163,7 +179,7 @@ function commonStepsResumption:Expect_Resumption_Data(app) if (data.params.appID == app.hmi_app_id and not is_choice_received) then is_choice_received = true return true - else + else commonFunctions:userPrint(31, "Received the same notification or App is registered with wrong appID") return false end From 9a5aa90c93ef7a9ea8a70cc0b2811a46cdc07d03 Mon Sep 17 00:00:00 2001 From: Masato Ogawa Date: Thu, 24 Aug 2017 15:14:32 +0900 Subject: [PATCH 143/681] Correct the file name according to the RPC name 'SendHapticData' --- .../API/{ATF_HapticRequest.lua => ATF_SendHapticData.lua} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test_scripts/API/{ATF_HapticRequest.lua => ATF_SendHapticData.lua} (100%) diff --git a/test_scripts/API/ATF_HapticRequest.lua b/test_scripts/API/ATF_SendHapticData.lua similarity index 100% rename from test_scripts/API/ATF_HapticRequest.lua rename to test_scripts/API/ATF_SendHapticData.lua From 45089990d5aae80f60a2e6cbc9a627814fa64e65 Mon Sep 17 00:00:00 2001 From: Masato Ogawa Date: Thu, 24 Aug 2017 16:23:22 +0900 Subject: [PATCH 144/681] Updated according to changing SendHapticData design --- test_scripts/API/ATF_SendHapticData.lua | 194 ++++++++++++------------ 1 file changed, 99 insertions(+), 95 deletions(-) diff --git a/test_scripts/API/ATF_SendHapticData.lua b/test_scripts/API/ATF_SendHapticData.lua index cf9945113e..254ab864bb 100644 --- a/test_scripts/API/ATF_SendHapticData.lua +++ b/test_scripts/API/ATF_SendHapticData.lua @@ -13,26 +13,26 @@ local commonFunctions = commonFunctions:newTestCasesGroup("Test suite: Check normal cases") function Test:SingleSpatialData() - -- mobiel side + -- mobile side local cid = self.mobileSession:SendRPC( "SendHapticData", { - HapticSpatialData = - { { id = 1, x = 2.0, y = 3.0, width = 4.0, height = 5.0 } } + hapticRectData = + { { id = 1, rect = { x = 2.0, y = 3.0, width = 4.0, height = 5.0 } } } } ) -- hmi side EXPECT_HMICALL( "UI.SendHapticData", { - HapticSpatialData = - { { id = 1, x = 2.0, y = 3.0, width = 4.0, height = 5.0, } } + hapticRectData = + { { id = 1, rect = { x = 2.0, y = 3.0, width = 4.0, height = 5.0 } } } } ) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) - -- mobiel side + -- mobile side EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) :ValidIf (function(_,data) return true @@ -40,28 +40,28 @@ function Test:SingleSpatialData() end function Test:MultiSpatialData() - -- mobiel side + -- mobile side local cid = self.mobileSession:SendRPC( "SendHapticData", { - HapticSpatialData = - { { id = 1, x = 2.0, y = 3.0, width = 4.0, height = 5.0 }, - { id = 2, x = 12.0, y = 13.0, width = 14.0, height = 15.0 } } + hapticRectData = + { { id = 1, rect = { x = 2.0, y = 3.0, width = 4.0, height = 5.0 } }, + { id = 2, rect = { x = 12.0, y = 13.0, width = 14.0, height = 15.0 } } } } ) -- hmi side EXPECT_HMICALL( "UI.SendHapticData", { - HapticSpatialData = - { { id = 1, x = 2.0, y = 3.0, width = 4.0, height = 5.0 }, - { id = 2, x = 12.0, y = 13.0, width = 14.0, height = 15.0 } } + hapticRectData = + { { id = 1, rect = { x = 2.0, y = 3.0, width = 4.0, height = 5.0 } }, + { id = 2, rect = { x = 12.0, y = 13.0, width = 14.0, height = 15.0 } } } } ) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) - -- mobiel side + -- mobile side EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) :ValidIf (function(_,data) return true @@ -73,24 +73,24 @@ function Test:MaxSpatialData() local spatial_data = {} for i= 1, 1000 do table.insert(spatial_data, - {id = i, x = i+2, y=i+3, width=i+4, height=i+5}) + {id = i, rect = { x = i+2, y=i+3, width=i+4, height=i+5 } }) end - -- mobiel side + -- mobile side local cid = self.mobileSession:SendRPC( - "SendHapticData", { HapticSpatialData = spatial_data } + "SendHapticData", { hapticRectData = spatial_data } ) -- hmi side EXPECT_HMICALL( "UI.SendHapticData", { - HapticSpatialData = spatial_data + hapticRectData = spatial_data } ) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) - -- mobiel side + -- mobile side EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) :ValidIf (function(_,data) return true @@ -98,7 +98,7 @@ function Test:MaxSpatialData() end function Test:NoSpatialData() - -- mobiel side + -- mobile side local cid = self.mobileSession:SendRPC( "SendHapticData", {} ) @@ -111,7 +111,7 @@ function Test:NoSpatialData() :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) - -- mobiel side + -- mobile side EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) :ValidIf (function(_,data) return true @@ -124,26 +124,26 @@ end commonFunctions:newTestCasesGroup("Test suite: Check error cases") function Test:GenericError() - -- mobiel side + -- mobile side local cid = self.mobileSession:SendRPC( "SendHapticData", { - HapticSpatialData = - { { id = 1, x = 2.0, y = 3.0, width = 4.0, height = 5.0 } } + hapticRectData = + { { id = 1, rect = { x = 2.0, y = 3.0, width = 4.0, height = 5.0 } } } } ) -- hmi side EXPECT_HMICALL( "UI.SendHapticData", { - HapticSpatialData = - { { id = 1, x = 2.0, y = 3.0, width = 4.0, height = 5.0, } } + hapticRectData = + { { id = 1, rect = { x = 2.0, y = 3.0, width = 4.0, height = 5.0, } } } } ) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "GENERIC_ERROR", {}) end) - -- mobiel side + -- mobile side EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) :ValidIf (function(_,data) return true @@ -151,15 +151,15 @@ function Test:GenericError() end function Test:InvalidDataNonExistId() - -- mobiel side + -- mobile side local cid = self.mobileSession:SendRPC( "SendHapticData", { - HapticSpatialData = - { { x = 2.0, y = 3.0, width = 4.0, height = 5.0, } } + hapticRectData = + { { rect = { x = 2.0, y = 3.0, width = 4.0, height = 5.0, } } } } ) - -- mobiel side + -- mobile side EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) :ValidIf (function(_,data) return true @@ -167,15 +167,15 @@ function Test:InvalidDataNonExistId() end function Test:InvalidDataNonExistX() - -- mobiel side + -- mobile side local cid = self.mobileSession:SendRPC( "SendHapticData", { - HapticSpatialData = - { { id = 1, y = 3.0, width = 4.0, height = 5.0, } } + hapticRectData = + { { id = 1, rect = { y = 3.0, width = 4.0, height = 5.0, } } } } ) - -- mobiel side + -- mobile side EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) :ValidIf (function(_,data) return true @@ -183,15 +183,15 @@ function Test:InvalidDataNonExistX() end function Test:InvalidDataNonExistY() - -- mobiel side + -- mobile side local cid = self.mobileSession:SendRPC( "SendHapticData", - { - HapticSpatialData = - { { id = 1, x = 2.0, width = 4.0, height = 5.0, } } - } + { + hapticRectData = + { { id = 1, rect = { x = 2.0, width = 4.0, height = 5.0, } } } + } ) - -- mobiel side + -- mobile side EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) :ValidIf (function(_,data) return true @@ -199,15 +199,15 @@ function Test:InvalidDataNonExistY() end function Test:InvalidDataNonExistWidth() - -- mobiel side + -- mobile side local cid = self.mobileSession:SendRPC( "SendHapticData", - { - HapticSpatialData = - { { id = 1, x = 2.0, y = 3.0, height = 5.0, } } - } + { + hapticRectData = + { { id = 1, rect = { x = 2.0, y = 3.0, height = 5.0, } } } + } ) - -- mobiel side + -- mobile side EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) :ValidIf (function(_,data) return true @@ -215,15 +215,15 @@ function Test:InvalidDataNonExistWidth() end function Test:InvalidDataNonExistHeight() - -- mobiel side + -- mobile side local cid = self.mobileSession:SendRPC( "SendHapticData", - { - HapticSpatialData = - { { id = 1, x = 2.0, y = 3.0, width = 4.0, } } - } + { + hapticRectData = + { { id = 1, rect = { x = 2.0, y = 3.0, width = 4.0, } } } + } ) - -- mobiel side + -- mobile side EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) :ValidIf (function(_,data) return true @@ -231,15 +231,15 @@ function Test:InvalidDataNonExistHeight() end function Test:InvalidDataWithUnknowItem() - -- mobiel side + -- mobile side local cid = self.mobileSession:SendRPC( "SendHapticData", - { - HapticSpatialData = - { { id = 1, a = 2.0, y = 3.0, width = 4.0, height = 5.0} } - } + { + hapticRectData = + { { id = 1, rect = { a = 2.0, y = 3.0, width = 4.0, height = 5.0 } } } + } ) - -- mobiel side + -- mobile side EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) :ValidIf (function(_,data) return true @@ -250,14 +250,15 @@ function Test:InvalidDataOverMaxSpatialData() local spatial_data = {} for i= 1, 1001 do - table.insert(spatial_data, {id = i, x = i+2, y=i+3, width=i+4, height=i+5}) + table.insert(spatial_data, {id = i, rect = + { x = i+2, y=i+3, width=i+4, height=i+5 } }) end - -- mobiel side + -- mobile side local cid = self.mobileSession:SendRPC( - "SendHapticData", { HapticSpatialData = spatial_data } + "SendHapticData", { hapticRectData = spatial_data } ) - -- mobiel side + -- mobile side EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) :ValidIf (function(_,data) return true @@ -265,26 +266,28 @@ function Test:InvalidDataOverMaxSpatialData() end function Test:SingleSpatialDataWithMaxID() - -- mobiel side + -- mobile side local cid = self.mobileSession:SendRPC( "SendHapticData", - { - HapticSpatialData = - { { id = 2000000000, x = 2.0, y = 3.0, width = 4.0, height = 5.0 } } - } + { + hapticRectData = + { { id = 2000000000, + rect = { x = 2.0, y = 3.0, width = 4.0, height = 5.0 } } } + } ) -- hmi side EXPECT_HMICALL( "UI.SendHapticData", { - HapticSpatialData = - { { id = 2000000000, x = 2.0, y = 3.0, width = 4.0, height = 5.0, } } + hapticRectData = + { { id = 2000000000, + rect = { x = 2.0, y = 3.0, width = 4.0, height = 5.0, } } } } ) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) - -- mobiel side + -- mobile side EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) :ValidIf (function(_,data) return true @@ -292,15 +295,16 @@ function Test:SingleSpatialDataWithMaxID() end function Test:InvalidDataOverMaxID() - -- mobiel side + -- mobile side local cid = self.mobileSession:SendRPC( "SendHapticData", - { - HapticSpatialData = - { { id = 2000000001, x = 2.0, y = 3.0, width = 5.0, height = 5.0, } } - } + { + hapticRectData = + { { id = 2000000001, + rect = { x = 2.0, y = 3.0, width = 5.0, height = 5.0, } } } + } ) - -- mobiel side + -- mobile side EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) :ValidIf (function(_,data) return true @@ -308,28 +312,28 @@ function Test:InvalidDataOverMaxID() end function Test:SingleSpatialDataWithLargeNumber() - -- mobiel side + -- mobile side local cid = self.mobileSession:SendRPC( "SendHapticData", - { - HapticSpatialData = - { { id = 2000000000, x = 2000000001, y = 2000000002, - width = 2000000003, height = 2000000004 } } - } + { + hapticRectData = + { { id = 2000000000, rect = { x = 2000000001, y = 2000000002, + width = 2000000003, height = 2000000004 } } } + } ) -- hmi side EXPECT_HMICALL( "UI.SendHapticData", { - HapticSpatialData = - { { id = 2000000000, x = 2000000001, y = 2000000002, - width = 2000000003, height = 2000000004, } } + hapticRectData = + { { id = 2000000000, rect = { x = 2000000001, y = 2000000002, + width = 2000000003, height = 2000000004, } } } } ) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) - -- mobiel side + -- mobile side EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) :ValidIf (function(_,data) return true @@ -337,26 +341,26 @@ function Test:SingleSpatialDataWithLargeNumber() end function Test:SingleSpatialDataWithFloatNumber() - -- mobiel side + -- mobile side local cid = self.mobileSession:SendRPC( "SendHapticData", - { - HapticSpatialData = - { { id = 1, x = 2.1, y = 3.3, width = 4.7, height = 5.9 } } - } + { + hapticRectData = + { { id = 1, rect = { x = 2.1, y = 3.3, width = 4.7, height = 5.9 } } } + } ) -- hmi side EXPECT_HMICALL( "UI.SendHapticData", { - HapticSpatialData = - { { id = 1, x = 2.1, y = 3.3, width = 4.7, height = 5.9, } } + hapticRectData = + { { id = 1, rect = { x = 2.1, y = 3.3, width = 4.7, height = 5.9, } } } } ) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) - -- mobiel side + -- mobile side EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) :ValidIf (function(_,data) return true From d5a362946a1da15af41e418a42a42fbc0b41d80b Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Mon, 28 Aug 2017 10:03:50 -0400 Subject: [PATCH 145/681] Use self instead of Test --- .../Resumption/ATF_Resumption_3rd_ignition_cycle.lua | 12 ++++++------ .../Resumption/ATF_Resumption_big_amount_of_data.lua | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua index 3ddf4ea934..d47ffc9a3e 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua @@ -90,11 +90,11 @@ end --[[ Test ]] commonFunctions:newTestCasesGroup("SDL should perform data resumption application is registered within 3 ign cycles") -function Test.IGNITION_OFF() - Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", +function Test:IGNITION_OFF() + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() - Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) @@ -107,11 +107,11 @@ function Test.Restart_SDL_And_Add_Mobile_Connection() Start_SDL_And_Add_Mobile_Connection() end -function Test.IGNITION_OFF() - Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", +function Test:IGNITION_OFF() + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() - Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") SDL:DeleteFile() diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua index 0ca0087c3e..2615d7ddcf 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua @@ -144,7 +144,7 @@ function Test:expect_Resumption_Data() local is_choice_received = 20 local on_vr_commands_added = EXPECT_HMICALL("VR.AddCommand"):Times(40) on_vr_commands_added:Do(function(_,data) - Test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS") end) on_vr_commands_added:ValidIf(function(_,data) if (data.params.type == "Command" and is_command_received ~= 0) then From 2df021a6430bf4b404347c3a53e89b9880985682 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 23 Aug 2017 19:37:54 -0400 Subject: [PATCH 146/681] Fix issues concerning StopSDL --- ..._does_not_send_HB_and_does_not_respond.lua | 10 ++-- ...tBeat_App_does_not_send_HB_but_respond.lua | 8 +-- .../HeartBeat/ATF_HeartBeat_App_send_HB.lua | 4 +- ...ATF_HeartBeat_no_heartbeat_v2_protocol.lua | 4 +- .../ATF_Register_5_connection.lua | 3 ++ .../Registration/ATF_Register_5_session.lua | 11 ++-- .../Smoke/Registration/ATF_Register_App.lua | 5 +- .../Smoke/Registration/ATF_Reregister_App.lua | 5 +- .../ATF_Reregister_App_after_disconnect.lua | 10 ++-- ...egister_App_if_two_apps_are_registered.lua | 12 +++-- .../ATF_Resumption_3rd_ignition_cycle.lua | 47 +++++++++-------- .../ATF_Resumption_App_Unregister_itself.lua | 20 +++----- .../ATF_Resumption_BACKGROUND_level.lua | 15 +++--- .../ATF_Resumption_FULL_IGNITION_OFF.lua | 13 +++-- .../ATF_Resumption_LIMITED_IGNITION_OFF.lua | 17 +++---- .../ATF_Resumption_LIMITED_level.lua | 13 ++--- ...ed_in_more_than_30sec_after_BC.OnReady.lua | 18 +++---- .../ATF_Resumption_big_amount_of_data.lua | 29 +++++------ ...isconnect_more_than_30s_before_SUSPEND.lua | 17 +++---- .../ATF_Resumption_heartbeat_disconnect.lua | 9 ++-- .../ATF_Resumption_unexpected_disconnect.lua | 11 ++-- .../ShutDown/ATF_ShutDown_IGNITION_OFF.lua | 25 +++++----- .../ShutDown/ATF_ShutDown_MASTER_RESET.lua | 27 +++++----- .../commonStepsResumption.lua | 50 ++++++++++++------- 24 files changed, 201 insertions(+), 182 deletions(-) mode change 100755 => 100644 test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua diff --git a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua index d65514bddb..6ba37d729d 100644 --- a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua +++ b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua @@ -20,7 +20,7 @@ -- Expected behavior: -- 1. App has successfully registered. -- 2. App is disconnected by SDL due to heartbeat timeout occurs. - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] config.defaultProtocolVersion = 3 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -72,13 +72,13 @@ function Test:Start_Session_And_Register_App() self.mobileSession.ignoreSDLHeartBeatACK = false self.mobileSession:StartRPC():Do(function() local correlation_id = self.mobileSession:SendRPC("RegisterAppInterface", default_app_params) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = default_app_params.appName}}):Do(function(_,data) default_app_params.hmi_app_id = data.params.application.appID end) self.mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "SUCCESS"}) self.mobileSession:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) - self.mobileSession:ExpectNotification("OnPermissionsChange", {}) + self.mobileSession:ExpectNotification("OnPermissionsChange", {}) end) end @@ -92,12 +92,12 @@ function Test:Register_Second_App_With_HeartBeat() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = default_app_params2.appName}}) self.mobileSession1:ExpectResponse(correlation_id, {success = true, resultCode = "SUCCESS"}) self.mobileSession1:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) - self.mobileSession1:ExpectNotification("OnPermissionsChange", {}) + self.mobileSession1:ExpectNotification("OnPermissionsChange", {}) end) end function Test:Wait_15_seconds_And_Verify_OnAppUnregistered() - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {appID = default_app_params.hmi_app_id, unexpectedDisconnect = true}):Timeout(15000):Do(function() self.mobileSession:StopHeartbeat() end) diff --git a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_but_respond.lua b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_but_respond.lua index 956e3c525e..5223012591 100644 --- a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_but_respond.lua +++ b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_but_respond.lua @@ -2,7 +2,7 @@ -- [HeartBeat][Genivi]: SDL must track sending of HeartBeat_request from/to mobile app -- -- Description: --- Check that no heartbeat timeout occurs if App uses v3 protocol version and doesn't send HB to SDL, +-- Check that no heartbeat timeout occurs if App uses v3 protocol version and doesn't send HB to SDL, -- but response to SDL heartbeat requests in time or less than HB timeout. -- 1. Used precondition @@ -19,7 +19,7 @@ -- Expected behavior: -- 1. App has successfully registered. -- 2. App is still registered on HU, no unexpected disconnect occurs. - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] config.defaultProtocolVersion = 3 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -71,13 +71,13 @@ function Test:Start_Session_And_Register_App() self.mobileSession.ignoreSDLHeartBeatACK = false self.mobileSession:StartRPC():Do(function() local correlation_id = self.mobileSession:SendRPC("RegisterAppInterface", default_app_params) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = default_app_params.appName}}):Do(function(_,data) default_app_params.hmi_app_id = data.params.application.appID end) self.mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "SUCCESS"}) self.mobileSession:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) - self.mobileSession:ExpectNotification("OnPermissionsChange", {}) + self.mobileSession:ExpectNotification("OnPermissionsChange", {}) end) end diff --git a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_send_HB.lua b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_send_HB.lua index 398b38e5ba..9c4ba44187 100644 --- a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_send_HB.lua +++ b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_send_HB.lua @@ -19,7 +19,7 @@ -- Expected behavior: -- 1. App has successfully registered. -- 2. App is still registered, no unexpected disconnect occurs. - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] config.defaultProtocolVersion = 3 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -73,7 +73,7 @@ function Test:Start_Session_And_Register_App() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = default_app_params.appName}}) self.mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "SUCCESS"}) self.mobileSession:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) - self.mobileSession:ExpectNotification("OnPermissionsChange", {}) + self.mobileSession:ExpectNotification("OnPermissionsChange", {}) end) end diff --git a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_no_heartbeat_v2_protocol.lua b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_no_heartbeat_v2_protocol.lua index cc9b84843a..b2ae7af7b5 100644 --- a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_no_heartbeat_v2_protocol.lua +++ b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_no_heartbeat_v2_protocol.lua @@ -16,7 +16,7 @@ -- Expected behavior: -- 1. App has successfully registered. -- 2. App is still registered, no unexpected disconnect occurs. - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -72,7 +72,7 @@ function Test:Start_Session_And_Register_App() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = default_app_params.appName}}) self.mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "SUCCESS"}) self.mobileSession:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) - self.mobileSession:ExpectNotification("OnPermissionsChange", {}) + self.mobileSession:ExpectNotification("OnPermissionsChange", {}) end) end diff --git a/test_scripts/Smoke/Registration/ATF_Register_5_connection.lua b/test_scripts/Smoke/Registration/ATF_Register_5_connection.lua index c81c87e6ef..ee92fcc433 100644 --- a/test_scripts/Smoke/Registration/ATF_Register_5_connection.lua +++ b/test_scripts/Smoke/Registration/ATF_Register_5_connection.lua @@ -26,6 +26,9 @@ -- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() -- 2. SDL assignes HMILevel after application registering: -- SDL->appID: OnHMIStatus(HMlLevel, audioStreamingState, systemContext) +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 -- [[ Required Shared Libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Smoke/Registration/ATF_Register_5_session.lua b/test_scripts/Smoke/Registration/ATF_Register_5_session.lua index a9e18fe02b..186ad7720a 100644 --- a/test_scripts/Smoke/Registration/ATF_Register_5_session.lua +++ b/test_scripts/Smoke/Registration/ATF_Register_5_session.lua @@ -9,7 +9,7 @@ -- 1. Used precondition -- SDL, HMI are running on system. -- Mobile device is connected to system. --- 1 session is added, 1 app is registered. +-- 1 session is added, 1 app is registered. -- -- 2. Performed steps -- Add 2 session @@ -22,11 +22,14 @@ -- appID_5->RegisterAppInterface(params) -- -- Expected behavior: --- 1. SDL successfully registers all four applications and notifies HMI and mobile +-- 1. SDL successfully registers all four applications and notifies HMI and mobile -- SDL->HMI: OnAppRegistered(params) --- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() +-- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() -- 2. SDL assignes HMILevel after application registering: -- SDL->appID: OnHMIStatus(HMlLevel, audioStreamingState, systemContext) +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 -- [[ Required Shared Libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') @@ -52,7 +55,7 @@ local function startSessionAndRegisterApp(self, app) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = app.appName}}) self.mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "SUCCESS"}) self.mobileSession:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) - self.mobileSession:ExpectNotification("OnPermissionsChange", {}) + self.mobileSession:ExpectNotification("OnPermissionsChange", {}) end) end diff --git a/test_scripts/Smoke/Registration/ATF_Register_App.lua b/test_scripts/Smoke/Registration/ATF_Register_App.lua index 91a8d9dac7..8f837a5a59 100644 --- a/test_scripts/Smoke/Registration/ATF_Register_App.lua +++ b/test_scripts/Smoke/Registration/ATF_Register_App.lua @@ -18,6 +18,9 @@ -- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() -- 2. SDL assignes HMILevel after application registering: -- SDL->appID: OnHMIStatus(HMlLevel, audioStreamingState, systemContext) +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 -- [[ Required Shared Libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') @@ -68,7 +71,7 @@ function Test:Register_App() EXPECT_NOTIFICATION("OnPermissionsChange") end) end - + -- [[ Postconditions ]] commonFunctions:newTestCasesGroup("Postcondition") function Test.Stop_SDL() diff --git a/test_scripts/Smoke/Registration/ATF_Reregister_App.lua b/test_scripts/Smoke/Registration/ATF_Reregister_App.lua index d2ee31ebaf..03215b042b 100644 --- a/test_scripts/Smoke/Registration/ATF_Reregister_App.lua +++ b/test_scripts/Smoke/Registration/ATF_Reregister_App.lua @@ -23,6 +23,9 @@ -- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() -- 3. SDL assignes HMILevel after application registering: -- SDL->appID: OnHMIStatus(HMlLevel, audioStreamingState, systemContext) +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 -- [[ Required Shared Libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') @@ -65,7 +68,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:Unregister_App() local cid = self.mobileSession:SendRPC("UnregisterAppInterface", default_app_params) EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = false, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = false, appID = self.applications[default_app_params.appName]}) end diff --git a/test_scripts/Smoke/Registration/ATF_Reregister_App_after_disconnect.lua b/test_scripts/Smoke/Registration/ATF_Reregister_App_after_disconnect.lua index f66540b2bb..3c85be08cc 100644 --- a/test_scripts/Smoke/Registration/ATF_Reregister_App_after_disconnect.lua +++ b/test_scripts/Smoke/Registration/ATF_Reregister_App_after_disconnect.lua @@ -22,15 +22,15 @@ -- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() -- 3. SDL assignes HMILevel after application registering: -- SDL->appID: OnHMIStatus(HMlLevel, audioStreamingState, systemContext) - +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 -- [[ Required Shared Libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local mobile_session = require('mobile_session') -config.defaultProtocolVersion = 2 - --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') require('cardinalities') @@ -66,7 +66,7 @@ end commonFunctions:newTestCasesGroup("Check that it is able to reregister App after disconnect") function Test:Close_Connection() - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = self.applications[default_app_params.appName]}) self.mobileSession:Stop() end @@ -75,7 +75,7 @@ function Test:Reregister_Application() local mobileSession = mobile_session.MobileSession(self, self.mobileConnection) local on_rpc_service_started = mobileSession:StartRPC() on_rpc_service_started:Do(function() - local cid = self.mobileSession:SendRPC("RegisterAppInterface", default_app_params) + local cid = self.mobileSession:SendRPC("RegisterAppInterface", default_app_params) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = {appName = default_app_params.appName} }) self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) diff --git a/test_scripts/Smoke/Registration/ATF_Reregister_App_if_two_apps_are_registered.lua b/test_scripts/Smoke/Registration/ATF_Reregister_App_if_two_apps_are_registered.lua index 37b53fe7ea..4803b63835 100644 --- a/test_scripts/Smoke/Registration/ATF_Reregister_App_if_two_apps_are_registered.lua +++ b/test_scripts/Smoke/Registration/ATF_Reregister_App_if_two_apps_are_registered.lua @@ -24,7 +24,9 @@ -- SDL->appID_1: SUCCESS, success:"true":RegisterAppInterface() -- 3. SDL assignes HMILevel after application registering: -- SDL->appID_1: OnHMIStatus(HMlLevel, audioStreamingState, systemContext) - +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 -- [[ Required Shared Libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') @@ -62,7 +64,7 @@ function Test:Start_SDL_With_One_Activated_App() end commonSteps:precondition_AddNewSession() -commonSteps:RegisterTheSecondMediaApp() +commonSteps:RegisterTheSecondMediaApp() --[[ Test ]] commonFunctions:newTestCasesGroup("Test") @@ -70,12 +72,12 @@ commonFunctions:newTestCasesGroup("Test") function Test:Unregister_App() local cid = self.mobileSession:SendRPC("UnregisterAppInterface", default_app_params1) EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = false, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = false, appID = self.applications[default_app_params1.appName]}) end function Test:Reregister_Application() - local cid = self.mobileSession:SendRPC("RegisterAppInterface", default_app_params1) + local cid = self.mobileSession:SendRPC("RegisterAppInterface", default_app_params1) self.mobileSession:ExpectResponse(cid, { success = true }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = {appName = default_app_params1.appName} }) @@ -84,7 +86,7 @@ function Test:Reregister_Application() self.hmiConnection:SendResponse(data.id, "BasicCommunication.UpdateAppList", "SUCCESS", {}) end) EXPECT_NOTIFICATION("OnHMIStatus", { systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE"}) - EXPECT_NOTIFICATION("OnPermissionsChange", {}) + EXPECT_NOTIFICATION("OnPermissionsChange", {}) end -- [[ Postconditions ]] diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua index a361eb8901..3ddf4ea934 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua @@ -3,7 +3,7 @@ -- [HMILevel Resumption]: Conditions to resume app to FULL in the next ignition cycle. -- Description: --- Check that: +-- Check that: -- 1. SDL performs App data resumption in case when media app tries to resume in 3rd ignition cycle. -- 2. SDL doesn't resumes App to FULL hmi level. -- @@ -19,10 +19,8 @@ -- -- Expected behavior: -- 1. In 3rd ignition cycle App is registered and get default HMI level, app data is resumed. - - +--------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] ---TODO(ilytvynenko): should be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -31,6 +29,7 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonStepsResumption = require('user_modules/shared_testcases/commonStepsResumption') local mobile_session = require('mobile_session') +local SDL = require('SDL') --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') @@ -42,20 +41,6 @@ local default_app_params = config.application1.registerAppInterfaceParams local default_app = nil -- will be initialized after application registration -- [[ Local Functions ]] -local function IGNITION_OFF() - Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", - { reason = "SUSPEND" }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() - Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", - { reason = "IGNITION_OFF" }) - EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) - end) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose"):Do(function() - StopSDL() - end) -end - local function Start_SDL_And_Add_Mobile_Connection() Test:runSDL() commonFunctions:waitForSDLStart(Test):Do(function() @@ -106,7 +91,16 @@ end commonFunctions:newTestCasesGroup("SDL should perform data resumption application is registered within 3 ign cycles") function Test.IGNITION_OFF() - IGNITION_OFF() + Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", + { reason = "SUSPEND" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() + Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", + { reason = "IGNITION_OFF" }) + EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + SDL:DeleteFile() + end) end function Test.Restart_SDL_And_Add_Mobile_Connection() @@ -114,7 +108,14 @@ function Test.Restart_SDL_And_Add_Mobile_Connection() end function Test.IGNITION_OFF() - IGNITION_OFF() + Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", + { reason = "SUSPEND" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() + Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", + { reason = "IGNITION_OFF" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + SDL:DeleteFile() + end) end function Test.Restart_SDL_And_Add_Mobile_Connection() @@ -126,10 +127,8 @@ function Test:Register_And_No_Resume_App() local on_rpc_service_started = mobile_session1:StartRPC() on_rpc_service_started:Do(function() default_app_params.hashID = self.currentHashID - commonStepsResumption:Expect_Resumption_Data(default_app_params) - commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectNoResumeApp, false):Do(function() - StopSDL() - end) + commonStepsResumption:Expect_Resumption_Data(default_app_params) + commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectResumeAppFULL, true) end) end diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_App_Unregister_itself.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_App_Unregister_itself.lua index 2087cedd0f..c1e8795ced 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_App_Unregister_itself.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_App_Unregister_itself.lua @@ -12,16 +12,18 @@ -- Start SPT again, Find Apps -- -- Expected behavior: --- 1. SPT sends UnregisterAppInterface and EndSession to SDL. +-- 1. SPT sends UnregisterAppInterface and EndSession to SDL. -- SPT register in usual way, no resumption occurs - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true -- [[ Required Shared Libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonStepsResumption = require('user_modules/shared_testcases/commonStepsResumption') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') @@ -85,20 +87,12 @@ commonFunctions:newTestCasesGroup("No resumption if App unregister itself") function Test:Unregister_App() local cid = self.mobileSession:SendRPC("UnregisterAppInterface", default_app_params) EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = false, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = false, appID = self.applications[default_app_params]}) end -function Test:Register_And_No_Resume_App_And_Data() - commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectNoResumeApp, false):Do(function() - local cid1 = self.mobileSession:SendRPC("ListFiles", {}) - EXPECT_RESPONSE(cid1, { success = true, resultCode = "SUCCESS" }):ValidIf (function(_,data) - return not data.payload.filenames - end) - EXPECT_HMICALL("VR.AddCommand"):Times(0) - end):Do(function() - StopSDL() - end) +function Test:Register_And_No_Resume_App() + commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectNoResumeApp, false) end -- [[ Postconditions ]] diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_BACKGROUND_level.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_BACKGROUND_level.lua index c4da2b64c7..4846ea7ac6 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_BACKGROUND_level.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_BACKGROUND_level.lua @@ -3,7 +3,7 @@ -- -- Description: -- Applications of BACKGROUND are not the case of HMILevel resumption in the next ignition cycle. --- Check that SDL performs app's data resumption and does not resume BACKGROUND HMI level +-- Check that SDL performs app's data resumption and does not resume BACKGROUND HMI level -- of media after transport unexpected disconnect on mobile side. -- 1. Used precondition @@ -18,8 +18,9 @@ -- Expected behavior: -- 1. App is unregistered from HMI. -- App is registered on HMI, SDL resumes all data and App gets default HMI level NONE. - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true config.application2.registerAppInterfaceParams.isMediaApplication = true @@ -79,17 +80,17 @@ end --[[ Test ]] commonFunctions:newTestCasesGroup("Transport unexpected disconnect. Media app not resume at BACKGROUND level") commonSteps:precondition_AddNewSession() -commonSteps:RegisterTheSecondMediaApp() +commonSteps:RegisterTheSecondMediaApp() commonSteps:ActivateTheSecondMediaApp() function Test:Close_Session2() - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = self.applications[default_app_params2.appName]}) self.mobileSession2:Stop() end function Test:Close_Session1() - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = self.applications[default_app_params1.appName]}) self.mobileSession:Stop() end @@ -100,9 +101,7 @@ function Test:Register_And_No_Resume_App_BACKGROUND_And_Resumes_Data() default_app_params1.hashID = self.currentHashID on_rpc_service_started:Do(function() commonStepsResumption:Expect_Resumption_Data(default_app_params1) - commonStepsResumption:RegisterApp(default_app_params1, commonStepsResumption.ExpectNoResumeApp, true):Do(function() - StopSDL() - end) + commonStepsResumption:RegisterApp(default_app_params1, commonStepsResumption.ExpectNoResumeApp, true) end) end diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua index 4fe3e28055..9b698c027e 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua @@ -16,11 +16,10 @@ -- -- Expected behavior: -- 1. SDL sends to HMI OnSDLClose --- 2. App is registered, SDL sends OnAppRegistered with the same HMI appID as in last ignition cycle, +-- 2. App is registered, SDL sends OnAppRegistered with the same HMI appID as in last ignition cycle, -- then sends BasicCommunication.ActivateApp to HMI and after success response from HMI, SDL sends to App OnHMIStatus(FULL) - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] ---TODO(ilytvynenko): should be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -29,6 +28,7 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonStepsResumption = require('user_modules/shared_testcases/commonStepsResumption') local mobile_session = require('mobile_session') +local SDL = require('SDL') --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') @@ -77,10 +77,9 @@ function Test:IGNITION_OFF() { reason = "IGNITION_OFF" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) end) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose"):Do(function() - StopSDL() - end) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + SDL:DeleteFile() end function Test:Restart_SDL_And_Add_Mobile_Connection() diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua index 71d2cc3fac..ca6efe9b35 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua @@ -3,8 +3,8 @@ -- [HMILevel Resumption]: Conditions to resume app to LIMITED in the next ignition cycle -- -- Description: --- Any application in LIMITED HMILevel during the time frame of 30 sec (inclusive) before --- BC.OnExitAllApplications(SUSPEND) from HMI +-- Any application in LIMITED HMILevel during the time frame of 30 sec (inclusive) before +-- BC.OnExitAllApplications(SUSPEND) from HMI -- SDL must resume LIMITED level, send OnResumeAudioSource to each application. -- -- 1. Used preconditions @@ -17,9 +17,8 @@ -- Expected result: -- 1. SDL sends to HMI OnSDLClose -- 2. App is registered, SDL sends OnAppRegistered with the same HMI appID as in last ignition cycle, then sets App to LIMITED HMI level - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] ---TODO(ilytvynenko):should be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -28,6 +27,7 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonStepsResumption = require('user_modules/shared_testcases/commonStepsResumption') local mobile_session = require('mobile_session') +local SDL = require('SDL') --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') @@ -52,7 +52,7 @@ function Test:Start_SDL_With_One_Activated_App() self:connectMobile():Do(function () commonFunctions:userPrint(35, "Mobile Connected") self:startSession():Do(function () - commonSteps:ActivateAppInSpecificLevel(self, + commonSteps:ActivateAppInSpecificLevel(self, self.applications[default_app_params.appName]) EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "FULL", systemContext = "MAIN"}) end) @@ -73,10 +73,9 @@ function Test:IGNITION_OFF() { reason = "IGNITION_OFF" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) end) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose"):Do(function () - StopSDL() - end) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + SDL:DeleteFile() end function Test:Restart_SDL_And_Add_Mobile_Connection() diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_level.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_level.lua index 2eee723c71..cbf30bb8a7 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_level.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_level.lua @@ -2,7 +2,7 @@ -- [HMILevel Resumption]: Conditions to resume app to LIMITED after "unexpected disconnect" event. -- -- Description: --- Check that SDL resumes LIMITED level of media App and it's data +-- Check that SDL resumes LIMITED level of media App and it's data -- after transport unexpected disconnect -- 1. Used precondition @@ -15,10 +15,11 @@ -- -- Expected behavior: -- 1. App is unregistered from HMI. --- 2. App is registered on HMI, SDL resumes all App's data and sends OnResumeAudioSource to HMI. +-- 2. App is registered on HMI, SDL resumes all App's data and sends OnResumeAudioSource to HMI. -- App gets LIMITED HMI Level - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true -- [[ Required Shared Libraries ]] @@ -78,7 +79,7 @@ commonFunctions:newTestCasesGroup("Transport unexpected disconnect. App resume a commonSteps:ChangeHMIToLimited("Change_app_to_Limited") function Test:Close_Session() - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = self.applications[default_app_params]}) self.mobileSession:Stop() end @@ -86,9 +87,9 @@ end function Test:Register_And_Resumes_App_And_Data() local mobileSession = mobile_session.MobileSession(self, self.mobileConnection) local on_rpc_service_started = mobileSession:StartRPC() - on_rpc_service_started:Do(function() + on_rpc_service_started:Do(function() default_app_params.hashID = self.currentHashID - commonStepsResumption:Expect_Resumption_Data(default_app_params) + commonStepsResumption:Expect_Resumption_Data(default_app_params) commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectResumeAppLIMITED, true) end) end diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua index 3cab7a812b..5d7f0e7f1c 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua @@ -2,7 +2,7 @@ -- [HMILevel Resumption]: Conditions to resume app to FULL in the next ignition cycle -- -- Description: --- Check that SDL does not perform App resumption in case when app is +-- Check that SDL does not perform App resumption in case when app is -- registered in more than 30 sec. after BC.OnReady from HMI in the very next ignition cycle -- -- 1. Used precondition @@ -16,9 +16,8 @@ -- Expected behavior: -- 1. SDL sends to HMI OnSDLClose. -- App is registered successfully and get default HMI level. - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] ---TODO(ilytvynenko): should be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -27,6 +26,7 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonStepsResumption = require('user_modules/shared_testcases/commonStepsResumption') local mobile_session = require('mobile_session') +local SDL = require('SDL') --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') @@ -73,11 +73,9 @@ function Test:IGNITION_OFF() { reason = "IGNITION_OFF" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) end) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose"):Do(function () - self.mobileSession:Stop() - StopSDL() - end) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + SDL:DeleteFile() end function Test:Restart_SDL_And_Add_Mobile_Connection() @@ -103,9 +101,7 @@ function Test:Register_And_No_Resume_App() local mobile_session1 = mobile_session.MobileSession(self, self.mobileConnection) local on_rpc_service_started = mobile_session1:StartRPC() on_rpc_service_started:Do(function() - commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectNoResumeApp, false):Do(function () - StopSDL() - end) + commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectNoResumeApp, false) end) end diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua index 9a33cb6f97..0ca0087c3e 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua @@ -15,10 +15,11 @@ -- -- Expected behavior: -- 1. App is unregistered successfully. --- App is registered successfully, SDL sends OnAppRegistered on HMI with "resumeVrGrammars"=true. +-- App is registered successfully, SDL sends OnAppRegistered on HMI with "resumeVrGrammars"=true. -- SDL resumes all app's data and sends BC.ActivateApp to HMI. App gets FULL HMI Level - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true -- [[ Required Shared Libraries ]] @@ -109,7 +110,7 @@ end commonFunctions:newTestCasesGroup("Transport unexpected disconnect. App resume at FULL level") function Test:Close_Session() - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = self.applications[default_app_params]}) self.mobileSession:Stop() end @@ -117,10 +118,10 @@ end function Test:Register_And_Resume_App_And_Data() local mobileSession = mobile_session.MobileSession(self, self.mobileConnection) local on_rpc_service_started = mobileSession:StartRPC() - on_rpc_service_started:Do(function() + on_rpc_service_started:Do(function() config.application1.registerAppInterfaceParams.hashID = self.currentHashID Test:expect_Resumption_Data() - commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectResumeAppFULL, true) + commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectResumeAppFULL, true) end) end @@ -133,12 +134,12 @@ function Test:expect_Resumption_Data() if data.params.menuParams.position == 500 then if data.params.appID == default_app_params.hmi_app_id then return true - else + else commonFunctions:userPrint(31, "App is registered with wrong appID " ) return false end end - end) + end) local is_command_received = 20 local is_choice_received = 20 local on_vr_commands_added = EXPECT_HMICALL("VR.AddCommand"):Times(40) @@ -147,10 +148,10 @@ function Test:expect_Resumption_Data() end) on_vr_commands_added:ValidIf(function(_,data) if (data.params.type == "Command" and is_command_received ~= 0) then - if (data.params.appID == default_app_params.hmi_app_id) then + if (data.params.appID == default_app_params.hmi_app_id) then is_command_received = is_command_received - 1 return true - else + else commonFunctions:userPrint(31, "Received the same notification or App is registered with wrong appID") return false end @@ -158,7 +159,7 @@ function Test:expect_Resumption_Data() if (data.params.appID == default_app_params.hmi_app_id) then is_choice_received = is_choice_received - 1 return true - else + else commonFunctions:userPrint(31, "Received the same notification or App is registered with wrong appID") return false end @@ -173,16 +174,16 @@ function Test:OnCommand() end function Test:PerformInteraction() - self.mobileSession:SendRPC("PerformInteraction",{ + self.mobileSession:SendRPC("PerformInteraction",{ initialText = "StartPerformInteraction", - initialPrompt = { + initialPrompt = { { text = "Makeyourchoice", type = "TEXT"}}, interactionMode = "BOTH", interactionChoiceSetIDList = { 20 }, timeout = 5000 }) - EXPECT_HMICALL("VR.PerformInteraction", {appID = default_app_params.hmi_app_id}):Do(function(_,data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {choiceID = 20}) + EXPECT_HMICALL("VR.PerformInteraction", {appID = default_app_params.hmi_app_id}):Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {choiceID = 20}) end) end diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua index f08eb1f816..61e9463b51 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua @@ -15,9 +15,8 @@ -- -- Expected behavior: -- 1. App is successfully registered and receive default HMI level - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] ---TODO(ilytvynenko): should be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true @@ -26,6 +25,7 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonStepsResumption = require('user_modules/shared_testcases/commonStepsResumption') local mobile_session = require('mobile_session') +local SDL = require('SDL') --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') @@ -67,7 +67,7 @@ end commonFunctions:newTestCasesGroup("App disconnect >30s before BC.OnExitAllApplications(SUSPEND). App not resume") function Test:Close_Session() - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = self.applications[default_app_params]}) self.mobileSession:Stop() end @@ -82,12 +82,9 @@ function Test:IGNITION_OFF() EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) - EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) - end) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose"):Do(function () - StopSDL() end) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + SDL:DeleteFile() end function Test:Restart_SDL_And_Add_Mobile_Connection() @@ -109,9 +106,7 @@ function Test:Register_And_No_Resume_App() local mobile_session1 = mobile_session.MobileSession(self, self.mobileConnection) local on_rpc_service_started = mobile_session1:StartRPC() on_rpc_service_started:Do(function() - commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectNoResumeApp, false):Do(function () - StopSDL() - end) + commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectNoResumeApp, false) end) end diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua index 7ffa632ad2..2c6a3b362e 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua @@ -17,8 +17,9 @@ -- Expected behavior: -- 1. SDL sends OnAppUnregistered to HMI. -- 2. App is registered and SDL resumes all App data, sends BC.ActivateApp to HMI, app gets FULL HMI level. - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 3 config.application1.registerAppInterfaceParams.isMediaApplication = true -- [[ Required Shared Libraries ]] @@ -76,7 +77,7 @@ end --[[ Test ]] commonFunctions:newTestCasesGroup("Check that SDL perform resumption after heartbeat disconnect") -function Test:Wait_20_sec() +function Test:Wait_20_sec() self.mobileSession:StopHeartbeat() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {appID = self.applications[default_app_params], unexpectedDisconnect = true }) :Timeout(20000) @@ -89,10 +90,10 @@ end function Test:Register_And_Resume_App_And_Data() local mobileSession = mobile_session.MobileSession(self, self.mobileConnection) local on_rpc_service_started = mobileSession:StartRPC() - on_rpc_service_started:Do(function() + on_rpc_service_started:Do(function() default_app_params.hashID = self.currentHashID commonStepsResumption:Expect_Resumption_Data(default_app_params) - commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectResumeAppFULL, true) + commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectResumeAppFULL, true) end) end diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_unexpected_disconnect.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_unexpected_disconnect.lua index ef84561be7..5d07396b5a 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_unexpected_disconnect.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_unexpected_disconnect.lua @@ -14,10 +14,11 @@ -- -- Expected behavior: -- 1. App is unregistered. --- 2. App is registered successfully, SDL resumes all App data and sends +-- 2. App is registered successfully, SDL resumes all App data and sends -- BC.ActivateApp to HMI. App gets FULL HMI Level. - +--------------------------------------------------------------------------------------------------- --[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.isMediaApplication = true -- [[ Required Shared Libraries ]] @@ -76,7 +77,7 @@ end commonFunctions:newTestCasesGroup("Transport unexpected disconnect. App resume at FULL level") function Test:Close_Session() - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = self.applications[default_app_params]}) self.mobileSession:Stop() end @@ -84,9 +85,9 @@ end function Test:Register_And_Resume_App_And_Data() local mobileSession = mobile_session.MobileSession(self, self.mobileConnection) local on_rpc_service_started = mobileSession:StartRPC() - on_rpc_service_started:Do(function() + on_rpc_service_started:Do(function() default_app_params.hashID = self.currentHashID - commonStepsResumption:Expect_Resumption_Data(default_app_params) + commonStepsResumption:Expect_Resumption_Data(default_app_params) commonStepsResumption:RegisterApp(default_app_params, commonStepsResumption.ExpectResumeAppFULL, true) end) end diff --git a/test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua b/test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua index 2bf85b8bcb..ecf80a0462 100644 --- a/test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua +++ b/test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua @@ -1,28 +1,31 @@ -- Requirement summary: --- [Data Resumption]:OnExitAllApplications(IGNITION_OFF) in terms of resumption +-- [Data Resumption]:OnExitAllApplications(IGNITION_OFF) in terms of resumption -- -- Description: --- In case SDL receives OnExitAllApplications(IGNITION_OFF), +-- In case SDL receives OnExitAllApplications(IGNITION_OFF), -- SDL must clean up any resumption-related data --- Obtained after OnExitAllApplications( SUSPEND). SDL must stop all its processes, +-- Obtained after OnExitAllApplications( SUSPEND). SDL must stop all its processes, -- notify HMI via OnSDLClose and shut down. -- -- 1. Used preconditions -- HMI is running -- One App is registered and activated on HMI --- +-- -- 2. Performed steps -- Perform ignition Off -- HMI sends OnExitAllApplications(IGNITION_OFF) --- +-- -- Expected result: -- 1. SDL sends to App OnAppInterfaceUnregistered -- 2. SDL sends to HMI OnSDLClose and stops working - +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') +local SDL = require('SDL') --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') @@ -44,7 +47,7 @@ function Test:Start_SDL_With_One_Activated_App() self:connectMobile():Do(function () commonFunctions:userPrint(35, "Mobile Connected") self:startSession():Do(function () - commonSteps:ActivateAppInSpecificLevel(self, + commonSteps:ActivateAppInSpecificLevel(self, self.applications[config.application1.registerAppInterfaceParams.appName]) EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "FULL", systemContext = "MAIN"}) end) @@ -63,11 +66,9 @@ function Test:ShutDown_IGNITION_OFF() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) - end) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose"):Do(function () - print("ONSDLClose") - StopSDL() + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + SDL:DeleteFile() end) end diff --git a/test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua b/test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua old mode 100755 new mode 100644 index 670f8a8d50..c05d9664a4 --- a/test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua +++ b/test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua @@ -2,7 +2,7 @@ -- [Policies] Master Reset -- -- Description: --- On Master Reset, Policy Manager must revert Local Policy Table +-- On Master Reset, Policy Manager must revert Local Policy Table -- to the Preload Policy Table. -- -- 1. Used preconditions @@ -15,12 +15,16 @@ -- -- Expected result: -- 1. SDL clear all Apps folder, app_info.dat file and shut down - +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local mobile_session = require('mobile_session') +local SDL = require('SDL') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") --[[ Local Variables ]] -- Hash id of AddCommand before MASTER_RESET @@ -57,7 +61,7 @@ end function Test:Activate_App_And_Put_File() local function addCommand() - local cid = self.mobileSession:SendRPC("AddCommand",{ cmdID = 1005, + local cid = self.mobileSession:SendRPC("AddCommand",{ cmdID = 1005, vrCommands = { "OnlyVRCommand"} }) EXPECT_HMICALL("VR.AddCommand", {cmdID = 1005, type = "Command", @@ -89,13 +93,12 @@ end commonFunctions:newTestCasesGroup("Check that SDL finish it's work properly by MASTER_RESET") function Test:ShutDown_MASTER_RESET() - self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "MASTER_RESET" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "MASTER_RESET" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose"):Do(function () - StopSDL() - end) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + SDL:DeleteFile() end --- Start SDL again then add mobile connection @@ -123,7 +126,7 @@ function Test:Check_Application_Not_Resume_When_Register_Again() local rai_params = config.application1.registerAppInterfaceParams rai_params.hashID = hash_id - local cid = self.mobileSession:SendRPC("RegisterAppInterface",rai_params) + local cid = self.mobileSession:SendRPC("RegisterAppInterface",rai_params) local on_app_registered = self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "RESUME_FAILED" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = {appName = default_app_name} }) @@ -132,20 +135,20 @@ function Test:Check_Application_Not_Resume_When_Register_Again() self.hmiConnection:SendResponse(data.id, "BasicCommunication.UpdateAppList", "SUCCESS", {}) end) - EXPECT_NOTIFICATION("OnHMIStatus", { systemContext = "MAIN", hmiLevel = "NONE", + EXPECT_NOTIFICATION("OnHMIStatus", { systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE"}) on_app_registered:Do(function() local cid1 = self.mobileSession:SendRPC("ListFiles", {}) EXPECT_RESPONSE(cid1, { success = true, resultCode = "SUCCESS" }) :ValidIf (function(_,data) - return not data.payload.filenames + return not data.payload.filenames end) EXPECT_HMICALL("BasicCommunication.ActivateApp"):Times(0) EXPECT_HMICALL("VR.AddCommand"):Times(0) - StopSDL() end) end) -end + commonTestCases:DelayedExp(3000) +end -- [[ Postconditions ]] commonFunctions:newTestCasesGroup("Postcondition") diff --git a/user_modules/shared_testcases/commonStepsResumption.lua b/user_modules/shared_testcases/commonStepsResumption.lua index 5cf4071206..f6c9a619da 100644 --- a/user_modules/shared_testcases/commonStepsResumption.lua +++ b/user_modules/shared_testcases/commonStepsResumption.lua @@ -1,5 +1,6 @@ local commonStepsResumption = {} local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") function commonStepsResumption:AddCommand() local cid = Test.mobileSession:SendRPC("AddCommand", { cmdID = 1, vrCommands = {"OnlyVRCommand"}}) @@ -17,7 +18,7 @@ end function commonStepsResumption:AddSubMenu() local cid = Test.mobileSession:SendRPC("AddSubMenu", { menuID = 1, position = 500, menuName = "SubMenu"}) - local on_hmi_call = EXPECT_HMICALL("UI.AddSubMenu", { menuID = 1, menuParams = + local on_hmi_call = EXPECT_HMICALL("UI.AddSubMenu", { menuID = 1, menuParams = { position = 500, menuName = "SubMenu"}}) on_hmi_call:Do(function(_, data) Test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) @@ -59,36 +60,50 @@ local function CheckTimeBoundaries(time) return false end elseif exp.occurences == 1 then - return true + return true end end end function commonStepsResumption:RegisterApp(app, additional_expectations , resume_vr_grammars) - local default_additional_expectations = function (app) + local default_additional_expectations = function (app) EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "NONE", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE"}) end - if (not additional_expectations) then + if (not additional_expectations) then additional_expectations = default_additional_expectations end local correlation_id = Test.mobileSession:SendRPC("RegisterAppInterface", app) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", - { application = {appName = app.appName}, resumeVrGrammars = resume_vr_grammars}):Do(function (_, data) + { application = {appName = app.appName } }):Do(function (_, data) app.hmi_app_id = data.params.application.appID end) - Test.mobileSession:ExpectResponse(correlation_id, { success = true}) + :ValidIf(function(_, d) + local pA = d.params.resumeVrGrammars + local pE = resume_vr_grammars + if pE == false then + if pA == nil or pA == false then + return true + end + else + if pA == pE then + return true + end + end + return false, "The value of " .. pA .. " (".. tostring(pA) .. ") is not as expected (" .. pE .. ")" + end) + Test.mobileSession:ExpectResponse(correlation_id, { success = true}) local exp = additional_expectations(Test, app) return exp end function commonStepsResumption:ExpectResumeAppFULL(app) local audio_streaming_state = "AUDIBLE" - if(app.isMediaApplication == false) then + if(app.isMediaApplication == false) then audio_streaming_state = "NOT_AUDIBLE" end local time = timestamp() - local app_activated = EXPECT_HMICALL("BasicCommunication.ActivateApp", + local app_activated = EXPECT_HMICALL("BasicCommunication.ActivateApp", {appID = Test.applications[app.appName]}):Do(function(_,data) Test.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) end) @@ -98,15 +113,15 @@ function commonStepsResumption:ExpectResumeAppFULL(app) :Do(function(_,data) Test.hmiLevel = data.payload.hmiLevel end):Times(2) - return app_activated + return app_activated end function commonStepsResumption:ExpectResumeAppLIMITED(app) local audio_streaming_state = "AUDIBLE" - if(app.isMediaApplication == false) then + if(app.isMediaApplication == false) then audio_streaming_state = "NOT_AUDIBLE" end - local time = timestamp() + local time = timestamp() local on_audio_source = EXPECT_HMINOTIFICATION("BasicCommunication.OnResumeAudioSource", {appID = Test.applications[app.appName]}) EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "NONE", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE"}, @@ -126,6 +141,7 @@ function commonStepsResumption:ExpectNoResumeApp(app) local exp = EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "NONE", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE"}) EXPECT_HMICALL("BasicCommunication.ActivateApp"):Times(0) EXPECT_HMINOTIFICATION("BasicCommunication.OnResumeAudioSource"):Times(0) + commonTestCases:DelayedExp(3000) return exp end @@ -135,15 +151,15 @@ function commonStepsResumption:Expect_Resumption_Data(app) Test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS") end) on_ui_sub_menu_added:ValidIf(function(_,data) - if (data.params.menuParams.menuName == "SubMenu" and data.params.menuID == 1) then + if (data.params.menuParams.menuName == "SubMenu" and data.params.menuID == 1) then if data.params.appID == app.hmi_app_id then return true - else + else commonFunctions:userPrint(31, "App is registered with wrong appID " ) return false end end - end) + end) local is_command_received = false local is_choice_received = false local on_vr_commands_added = EXPECT_HMICALL("VR.AddCommand"):Times(2) @@ -152,10 +168,10 @@ function commonStepsResumption:Expect_Resumption_Data(app) end) on_vr_commands_added:ValidIf(function(_,data) if (data.params.type == "Command" and data.params.cmdID == 1) then - if (data.params.appID == app.hmi_app_id and not is_command_received) then + if (data.params.appID == app.hmi_app_id and not is_command_received) then is_command_received = true return true - else + else commonFunctions:userPrint(31, "Received the same notification or App is registered with wrong appID") return false end @@ -163,7 +179,7 @@ function commonStepsResumption:Expect_Resumption_Data(app) if (data.params.appID == app.hmi_app_id and not is_choice_received) then is_choice_received = true return true - else + else commonFunctions:userPrint(31, "Received the same notification or App is registered with wrong appID") return false end From 6e956c6f7014d68c3bb170aca962e077c16f509e Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Mon, 28 Aug 2017 10:03:50 -0400 Subject: [PATCH 147/681] Use self instead of Test --- .../Resumption/ATF_Resumption_3rd_ignition_cycle.lua | 12 ++++++------ .../Resumption/ATF_Resumption_big_amount_of_data.lua | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua index 3ddf4ea934..d47ffc9a3e 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua @@ -90,11 +90,11 @@ end --[[ Test ]] commonFunctions:newTestCasesGroup("SDL should perform data resumption application is registered within 3 ign cycles") -function Test.IGNITION_OFF() - Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", +function Test:IGNITION_OFF() + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() - Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) @@ -107,11 +107,11 @@ function Test.Restart_SDL_And_Add_Mobile_Connection() Start_SDL_And_Add_Mobile_Connection() end -function Test.IGNITION_OFF() - Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", +function Test:IGNITION_OFF() + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() - Test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") SDL:DeleteFile() diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua index 0ca0087c3e..2615d7ddcf 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua @@ -144,7 +144,7 @@ function Test:expect_Resumption_Data() local is_choice_received = 20 local on_vr_commands_added = EXPECT_HMICALL("VR.AddCommand"):Times(40) on_vr_commands_added:Do(function(_,data) - Test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS") end) on_vr_commands_added:ValidIf(function(_,data) if (data.params.type == "Command" and is_command_received ~= 0) then From 2f2bf0595a7aa42cb7a17fbe22ec581100570e00 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Wed, 30 Aug 2017 20:11:57 +0300 Subject: [PATCH 148/681] Tests for use case 3 from resource allocation functionality were added --- ...20_Restore_accessMode_after_RC_disable.lua | 70 +++++++++++++++++++ .../021_Release_resource_on_exit_app.lua | 64 +++++++++++++++++ ...e_resource_on_PTU_with_module_disallow.lua | 56 +++++++++++++++ ...lease_resource_on_PTU_with_app_revoked.lua | 49 +++++++++++++ test_scripts/RC/commonRC.lua | 68 +++++++++++++++--- test_sets/rc_OnRemoteControlSettings.txt | 4 ++ 6 files changed, 300 insertions(+), 11 deletions(-) create mode 100644 test_scripts/RC/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua create mode 100644 test_scripts/RC/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua create mode 100644 test_scripts/RC/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua create mode 100644 test_scripts/RC/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua b/test_scripts/RC/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua new file mode 100644 index 0000000000..dbd0b813d9 --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- RC_functionality is disabled on HMI and HMI sends notification OnRemoteControlSettings (allowed:true, ) +-- +-- SDL must: +-- 1) store RC state allowed:true received from HMI internally +-- 2) allow RC functionality for applications with REMOTE_CONTROL appHMIType +-- +-- Additional checks: +-- - -> Disable -> +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local rcRpcs = { "SetInteriorVehicleData", "ButtonPress" } +local accessModes = { "AUTO_ALLOW", "AUTO_DENY", "ASK_DRIVER" } + + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() +end + +local function disableRcFromHmi(self) + commonRC.defineRAMode(false, nil, self) +end + +local function enableRcFromHmi(self) + commonRC.defineRAMode(true, nil, self) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("RAI2", commonRC.rai_n, { 2 }) + +runner.Title("Test") + +for _, accessMode in pairs(accessModes) do + runner.Title(accessMode .. " -> Disable RC -> " .. accessMode) + runner.Step("Enable RC from HMI with " .. accessMode .." access mode", commonRC.defineRAMode, { true, accessMode }) + runner.Step("Disable RC from HMI", disableRcFromHmi) + runner.Step("Enable RC from HMI without access mode", enableRcFromHmi) + runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Check module " .. modules[1] .." App1 " .. rcRpcs[2] .. " allowed", commonRC.rpcAllowed, { modules[1], 1, rcRpcs[2] }) + runner.Step("Check module " .. modules[2] .." App1 " .. rcRpcs[1] .. " allowed", commonRC.rpcAllowed, { modules[2], 1, rcRpcs[1] }) + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + if accessMode == "AUTO_ALLOW" then + runner.Step("Check module " .. modules[1] .." App2 " .. rcRpcs[2] .. " allowed", commonRC.rpcAllowed, { modules[1], 2, rcRpcs[2] }) + runner.Step("Check module " .. modules[2] .." App1 " .. rcRpcs[1] .. " allowed", commonRC.rpcAllowed, { modules[2], 2, rcRpcs[1] }) + elseif accessMode == "AUTO_DENY" then + runner.Step("Check module " .. modules[1] .." App2 " .. rcRpcs[2] .. " denied", commonRC.rpcDenied, { modules[1], 2, rcRpcs[2], "IN_USE" }) + runner.Step("Check module " .. modules[2] .." App2 " .. rcRpcs[1] .. " denied", commonRC.rpcDenied, { modules[2], 2, rcRpcs[1], "IN_USE" }) + elseif accessMode == "ASK_DRIVER" then + runner.Step("Check module " .. modules[1] .." App2 " .. rcRpcs[1] .. " allowed with driver consent", commonRC.rpcAllowedWithConsent, { modules[1], 2, rcRpcs[1] }) + runner.Step("Check module " .. modules[2] .." App2 " .. rcRpcs[2] .. " allowed with driver consent", commonRC.rpcAllowedWithConsent, { modules[2], 2, rcRpcs[2] }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua b/test_scripts/RC/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua new file mode 100644 index 0000000000..a2749a5ce0 --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua @@ -0,0 +1,64 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 3: Alternative Flow 1 +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- SDL received OnExitApplication (either user exits RC_app_1 vis HMI or due to driver distraction violation) +-- +-- SDL must: +-- 1) SDL assigns HMILevel NONE to RC_app_1 and releases module_1 from RC_app_1 control +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local exitAppReasons = {"USER_EXIT", "DRIVER_DISTRACTION_VIOLATION"} + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + table.insert(tbl.policy_table.functional_groupings.RemoteControl.rpcs.OnInteriorVehicleData.hmi_levels, "NONE") +end + +local function exitApp(pReason, pAppId, self) + local hmiAppId = commonRC.getHMIAppId(pAppId) + local mobSession = commonRC.getMobileSession(self, pAppId) + self.hmiConnection:SendNotification("BasicCommunication.OnExitApplication", + { appID = hmiAppId, reason = pReason }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("RAI2", commonRC.rai_n, { 2 }) + +runner.Title("Test") +runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) +for _, reason in pairs(exitAppReasons) do + runner.Title("Exit reason " .. reason) + runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App1", commonRC.activate_app) + -- App1: FULL, App2: BACKGROUND + runner.Step("Module CLIMATE App1 ButtonPress allowed", commonRC.rpcAllowed, { "CLIMATE", 1, "ButtonPress" }) + runner.Step("Subscribe App1 to CLIMATE", commonRC.subscribeToModule, { "CLIMATE", 1 }) + runner.Step("Send notification OnInteriorVehicleData CLIMATE. App1 is subscribed", commonRC.isSubscribed, { "CLIMATE", 1 }) + runner.Step("Module CLIMATE App2 SetInteriorVehicleData denied", commonRC.rpcDenied, { "CLIMATE", 2, "SetInteriorVehicleData", "REJECTED" }) + runner.Step("Exit App1 with reason " .. reason, exitApp, { reason, 1}) + -- App1: NONE, App2: BACKGROUND + runner.Step("Send notification OnInteriorVehicleData CLIMATE. App1 is unsubscribed", commonRC.isUnsubscribed, { "CLIMATE", 1 }) + runner.Step("Module CLIMATE App2 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "CLIMATE", 2, "SetInteriorVehicleData"}) + runner.Step("Exit App2 with reason " .. reason, exitApp, { reason, 2}) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua b/test_scripts/RC/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua new file mode 100644 index 0000000000..124b20cf90 --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 3: Alternative Flow 2 +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- Any trigger of Policy Table Update happened and in received PTU module_1 is not in the list of assigned moduleTypes for RC_app_1 +-- +-- SDL must: +-- 1) SDL disallows all RPC for module_1 from RC_app_1 and releases module_1 from RC_app_1 control +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + moduleType = { "CLIMATE" }, + groups = { "Base-4", "RemoteControl" }, + AppHMIType = { "REMOTE_CONTROL" } + } + table.insert(tbl.policy_table.functional_groupings.RemoteControl.rpcs.OnInteriorVehicleData.hmi_levels, "NONE") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU with RADIO for App1", commonRC.rai_ptu) + +runner.Title("Test") +runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) +runner.Step("Activate App1", commonRC.activate_app) +-- App1: FULL +runner.Step("Module RADIO App1 ButtonPress allowed", commonRC.rpcAllowed, { "RADIO", 1, "ButtonPress" }) +runner.Step("Subscribe App1 to RADIO", commonRC.subscribeToModule, { "RADIO", 1 }) +runner.Step("Send notification OnInteriorVehicleData RADIO. App1 is subscribed", commonRC.isSubscribed, { "RADIO", 1 }) +runner.Step("RAI2, PTU without RADIO for App1", commonRC.rai_ptu_n, { ptu_update_func, 2 }) +runner.Step("Module RADIO App1 SetInteriorVehicleData disallowed", commonRC.rpcDenied, { "RADIO", 1, "SetInteriorVehicleData", "DISALLOWED"}) +runner.Step("Module CLIMATE App1 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "CLIMATE", 1, "SetInteriorVehicleData"}) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) +-- App1: BACKGROUND, App2: FULL +runner.Step("Send notification OnInteriorVehicleData RADIO. App1 is unsubscribed", commonRC.isUnsubscribed, { "RADIO", 1 }) +runner.Step("Module RADIO App2 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "RADIO", 2, "SetInteriorVehicleData"}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua b/test_scripts/RC/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua new file mode 100644 index 0000000000..1f4e704605 --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 3: Excpetion 2.1 +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- Any trigger of Policy Table Update happened and in received PTU RC_app_1 is revoked +-- +-- SDL must: +-- 1) SDL releases module_1 from RC_app_1 control +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local json = require("modules/json") + + +--[[ Local Functions ]] +local function ptu_update_func_1(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = json.null +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU with RADIO for App1", commonRC.rai_ptu) + +runner.Title("Test") +runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) +runner.Step("Activate App1", commonRC.activate_app) +-- App1: FULL +runner.Step("Module RADIO App1 ButtonPress allowed", commonRC.rpcAllowed, { "RADIO", 1, "ButtonPress" }) +runner.Step("Subscribe App1 to RADIO", commonRC.subscribeToModule, { "RADIO", 1 }) +runner.Step("Send notification OnInteriorVehicleData RADIO. App1 is subscribed", commonRC.isSubscribed, { "RADIO", 1 }) +runner.Step("RAI2, PTU App1 permissions revoked", commonRC.rai_ptu_n, { ptu_update_func_1, 2 }) +runner.Step("Module RADIO App1 SetInteriorVehicleData disallowed", commonRC.rpcDenied, { "RADIO", 1, "SetInteriorVehicleData", "DISALLOWED"}) +runner.Step("Module CLIMATE App1 SetInteriorVehicleData disallowed", commonRC.rpcDenied, { "CLIMATE", 1, "SetInteriorVehicleData", "DISALLOWED"}) +runner.Step("Activate App2", commonRC.activate_app, { 2 }) +-- App1: BACKGROUND, App2: FULL +runner.Step("Send notification OnInteriorVehicleData RADIO. App1 is unsubscribed", commonRC.isUnsubscribed, { "RADIO", 1 }) +runner.Step("Module RADIO App2 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "RADIO", 2, "SetInteriorVehicleData"}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 06327ac5c1..542b5d84bd 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -74,6 +74,14 @@ local function checkIfPTSIsSentAsBinary(bin_data) end local function ptu(self, ptu_update_func) + local function getAppsCount() + local count = 0 + for _, _ in pairs(hmiAppIds) do + count = count + 1 + end + return count + end + local policy_file_name = "PolicyTableUpdate" local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") @@ -88,17 +96,29 @@ local function ptu(self, ptu_update_func) ptu_update_func(ptu_table) end tableToJsonFile(ptu_table, ptu_file_name) - self.mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) - :Do(function(_, d2) - checkIfPTSIsSentAsBinary(d2.binaryData) - local corIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) - EXPECT_HMICALL("BasicCommunication.SystemRequest") - :Do(function(_, d3) - self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) - self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = policy_file_path .. "/" .. policy_file_name }) - end) - self.mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) - end) + + local event = events.Event() + event.matches = function(self, e) return self == e end + EXPECT_EVENT(event, "PTU event") + :Timeout(11000) + + for id = 1, getAppsCount() do + local mobileSession = commonRC.getMobileSession(self, id) + mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :Do(function(_, d2) + print("App ".. id .. " was used for PTU") + RAISE_EVENT(event, event, "PTU event") + checkIfPTSIsSentAsBinary(d2.binaryData) + local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, d3) + self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = policy_file_path .. "/" .. policy_file_name }) + end) + mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + end) + :Times(AtMost(1)) + end end) os.remove(ptu_file_name) end @@ -158,6 +178,32 @@ function commonRC.rai_ptu(ptu_update_func, self) end) end +function commonRC.rai_ptu_n(ptu_update_func, id, self) + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :Do(function(_, d2) + self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptu_table = jsonFileToTable(d2.params.file) + ptu(self, ptu_update_func) + end) + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + end) + end) +end + function commonRC.rai_n(id, self) self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) self["mobileSession" .. id]:StartService(7) diff --git a/test_sets/rc_OnRemoteControlSettings.txt b/test_sets/rc_OnRemoteControlSettings.txt index 1296318a16..4c9f26847c 100644 --- a/test_sets/rc_OnRemoteControlSettings.txt +++ b/test_sets/rc_OnRemoteControlSettings.txt @@ -17,3 +17,7 @@ ./test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua ./test_scripts/RC/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua ./test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua +./test_scripts/RC/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua +./test_scripts/RC/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua +./test_scripts/RC/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua +./test_scripts/RC/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua From 02b68713ff339f35e85a944d4319981095932814 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Thu, 31 Aug 2017 18:56:28 -0400 Subject: [PATCH 149/681] New version of template of script --- test_scripts/template_of_script.lua | 59 +++++++++++++---------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/test_scripts/template_of_script.lua b/test_scripts/template_of_script.lua index a77aa757bb..7570469323 100644 --- a/test_scripts/template_of_script.lua +++ b/test_scripts/template_of_script.lua @@ -1,23 +1,26 @@ ---------------------------------------------------------------------------------------------- +--------------------------------------------------------------------------------------------------- -- Requirement summary: --- Name(s) of requirement that is covered. +-- Name(s) of requirement that is covered -- Name(s) of additional non-functional requirement(s) if applicable -- -- Description: --- Describe correctly the CASE of requirement that is covered, conditions that will be used. --- 1. Used preconditions(if applicable) --- 2. Performed steps +-- Description of the particular CASE of requirement that is covered +-- and conditions that will be used +-- +-- Preconditions: (if applicable) +-- +-- Steps: -- -- Expected result: -- Expected SDL behaviour ---------------------------------------------------------------------------------------------- +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') --[[ General configuration parameters ]] config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" ---[[ Required Shared libraries ]] -local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') - --[[ Local Variables ]] -- if not applicable remove this section @@ -28,39 +31,29 @@ local commonFunctions = require ('user_modules/shared_testcases/commonFunctions' --[[ @Example: the function gets.... --! @parameters: --! func_param ]] -local function Example(func_param) +local function preconditions() -- body end ---[[ General Precondition before ATF start ]] --- General precondition for restoring configuration files of SDL: -commonFunctions:SDLForceStop() - ---[[ General Settings for configuration ]] --- if not applicable remove this section --- This part is under clarification, based on section for using common functions -Test = require('connecttest') -require('user_modules/AppTypes') - ---[[ Preconditions ]] --- if not applicable remove this section -commonFunctions:newTestCasesGroup("Preconditions") -function Test:Precondition_DESCRIPTION() +local function postconditions() -- body end ---[[ Test ]] -commonFunctions:newTestCasesGroup("Test") --- Each Test will be separate and defined as one or few TestSteps -function Test:TestStep_DESCRIPTION() +local function positiveScenario() -- body end ---[[ Postconditions ]] --- if not applicable remove this section -commonFunctions:newTestCasesGroup("Postconditions") -function Test:Postcondition_DESCRIPTION() +local function negativeScenario() -- body end -return Test +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment, start SDL, HMI", preconditions) + +runner.Title("Test") +runner.Step("Positive scenario", positiveScenario) +runner.Step("Negative scenario", negativeScenario) + +runner.Title("Postconditions") +runner.Step("Stop SDL", postconditions) From 9301232d449c19b46728b8e91860c0ddca185683 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 1 Sep 2017 16:13:20 -0400 Subject: [PATCH 150/681] Fix for non RC application --- .../004_check_processing_button_press_for_nonRC_App.lua | 2 -- ...4_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua | 2 -- ...4_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua | 2 -- 3 files changed, 6 deletions(-) diff --git a/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua b/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua index 02a0b1884c..88439b91a1 100644 --- a/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua +++ b/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua @@ -54,8 +54,6 @@ end local function ptu_update_func(tbl) local appId = config.application1.registerAppInterfaceParams.appID - tbl.policy_table.app_policies[appId].moduleType = nil - tbl.policy_table.app_policies[appId].groups_primaryRC = nil tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } end diff --git a/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 846ec34890..28c68eae52 100644 --- a/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -40,8 +40,6 @@ end local function ptu_update_func(tbl) local appId = config.application1.registerAppInterfaceParams.appID - tbl.policy_table.app_policies[appId].moduleType = nil - tbl.policy_table.app_policies[appId].groups_primaryRC = nil tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } end diff --git a/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 18c8964459..2561308d93 100644 --- a/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -40,8 +40,6 @@ end local function ptu_update_func(tbl) local appId = config.application1.registerAppInterfaceParams.appID - tbl.policy_table.app_policies[appId].moduleType = nil - tbl.policy_table.app_policies[appId].groups_primaryRC = nil tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } end From 24fe8400ceba594ea54ac0ac7a47c3c48a34c99e Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 1 Sep 2017 16:17:41 -0400 Subject: [PATCH 151/681] Additional script on disable RC functionality --- .../024_Allowed_false_no_PTU.lua | 94 +++++++++++++++++++ test_sets/rc_OnRemoteControlSettings.txt | 1 + 2 files changed, 95 insertions(+) create mode 100644 test_scripts/RC/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua b/test_scripts/RC/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua new file mode 100644 index 0000000000..f3e8812b5c --- /dev/null +++ b/test_scripts/RC/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua @@ -0,0 +1,94 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- SDL received OnRemoteControlSettings (allowed:false) from HMI +-- +-- SDL must: +-- 1) store RC state allowed:false internally +-- 2) assign HMILevel none to all registered applications with appHMIType REMOTE_CONTROL +-- and send OnHMIStatus (NONE) to such apps +-- 3) keep all applications with appHMIType REMOTE_CONTROL registered +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +local mobile_session = require("mobile_session") + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application3.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Variables ]] +local hmiAppIds = { } + +--[[ Local Functions ]] +local function register_app(pAppId, self) + self["mobileSession" .. pAppId] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. pAppId]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. pAppId]:SendRPC("RegisterAppInterface", + config["application" .. pAppId].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = d1.params.application.appID + end) + self["mobileSession" .. pAppId]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. pAppId]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + self["mobileSession" .. pAppId]:ExpectNotification("OnPermissionsChange") + end) + end) +end + +local function activate_app(pAppId, self) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", + { appID = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] }) + EXPECT_HMIRESPONSE(requestId) + + self["mobileSession" .. pAppId]:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + commonTestCases:DelayedExp(commonRC.minTimeout) +end + +local function disableRCFromHMI(self) + commonRC.defineRAMode(false, nil, self) + + self.mobileSession1:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE" }) + :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + self.mobileSession2:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE" }) + :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + self.mobileSession3:ExpectNotification("OnHMIStatus") + :Times(0) + + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered") + :Times(0) + commonTestCases:DelayedExp(commonRC.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) + +for i = 1, 3 do + runner.Step("RAI " .. i, register_app, { i }) + runner.Step("Activate App " .. i, activate_app, { i }) +end + +runner.Title("Test") +runner.Step("Disable RC from HMI", disableRCFromHMI) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_OnRemoteControlSettings.txt b/test_sets/rc_OnRemoteControlSettings.txt index 4c9f26847c..a0cac4d503 100644 --- a/test_sets/rc_OnRemoteControlSettings.txt +++ b/test_sets/rc_OnRemoteControlSettings.txt @@ -21,3 +21,4 @@ ./test_scripts/RC/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua ./test_scripts/RC/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua ./test_scripts/RC/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua +./test_scripts/RC/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua From b37170e163c5c9444caad4f2b1d420d198174fff Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Sat, 2 Sep 2017 10:46:59 -0400 Subject: [PATCH 152/681] Refactoring of RC Common module --- ...001_success_flow_for_climate_and_radio.lua | 8 +- ...02_disallow_flow_by_policy_for_climate.lua | 4 +- .../003_disallow_flow_by_policy_for_radio.lua | 4 +- ..._processing_button_press_for_nonRC_App.lua | 8 +- ...e_and_moduleType_for_radio_and_climate.lua | 8 +- ..._check_rpc_parameters_for_button_press.lua | 8 +- ...n_press_allowed_if_moduleType_is_empty.lua | 4 +- ...ess_disallowed_if_moduleType_is_absent.lua | 4 +- ...f_moduleType_is_disallowed_by_policies.lua | 4 +- ..._generic_error_if_no_response_from_hmi.lua | 4 +- ...or_if_read_only_response_come_from_hmi.lua | 4 +- ...ric_error_if_invalid_response_from_hmi.lua | 4 +- ...ransfering_of_HMI_resultCode_to_mobile.lua | 8 +- ..._supported_parameter_and_reject_others.lua | 6 +- .../005_Resend_only_supported_parameters.lua | 6 +- ...supported_and_not_supported_parameters.lua | 4 +- .../002_Disallow_flow_by_policy_CLIMATE.lua | 4 +- .../003_Disallow_flow_by_policy_RADIO.lua | 4 +- ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 4 +- ...ransfering_of_HMI_resultCode_to_mobile.lua | 8 +- .../006_RPC_parameters_values.lua | 16 ++-- ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 4 +- ..._in_case_HMI_respond_with_invalid_data.lua | 8 +- ...se_moduleType_is_an_empty_array_in_LPT.lua | 4 +- ...ow_in_case_moduleType_is_absent_in_LPT.lua | 4 +- ...ROR_in_case_HMI_respond_with_READ_ONLY.lua | 4 +- ...response_from_HMI_without_isSubscribed.lua | 4 +- ...ut_response_from_HMI_with_isSubscribed.lua | 4 +- ...ase_of_2nd_Subscription_UnSubscription.lua | 4 +- ...ribing_with_isSubscribe_false_from_HMI.lua | 4 +- ...bscribing_without_isSubscribe_from_HMI.lua | 4 +- ...ase_of_subscribing_with_error_from_HMI.lua | 4 +- ..._subscribing_with_no_response_from_HMI.lua | 4 +- ...cribing_with_invalid_response_from_HMI.lua | 4 +- ...cribing_with_isSubscribe_true_from_HMI.lua | 4 +- ...bscribing_without_isSubscribe_from_HMI.lua | 4 +- ...bscribing_without_isSubscribe_from_HMI.lua | 4 +- .../016_RPC_parameters_values.lua | 6 +- .../006_IN_USE_in_case_2_requests.lua | 6 +- ...e_resource_on_PTU_with_module_disallow.lua | 2 +- ...lease_resource_on_PTU_with_app_revoked.lua | 4 +- .../001_Success_flow.lua | 4 +- .../002_Disallow_flow_by_policy_CLIMATE.lua | 4 +- .../003_Disallow_flow_by_policy_RADIO.lua | 4 +- ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 4 +- ...rams_does_not_correspond_to_moduleType.lua | 4 +- .../006_RPC_parameters_values.lua | 16 ++-- ...se_moduleType_is_an_empty_array_in_LPT.lua | 4 +- ...ow_in_case_moduleType_is_absent_in_LPT.lua | 4 +- ...09_Cut-off_of_fake_parameters_from_App.lua | 2 +- ...cle_data_if_read_only_params_requested.lua | 4 +- ...read-only_and_not_read-only_parameters.lua | 4 +- ...y_parameters_and_HMI_returns_READ_ONLY.lua | 4 +- ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 4 +- ..._in_case_HMI_respond_with_invalid_data.lua | 8 +- ...ransfering_of_HMI_resultCode_to_mobile.lua | 8 +- test_scripts/RC/commonRC.lua | 92 +++++++------------ user_modules/script_runner.lua | 4 +- 58 files changed, 178 insertions(+), 206 deletions(-) diff --git a/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua b/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua index 80fc237d8d..916f2d7ad1 100644 --- a/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua +++ b/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua @@ -20,7 +20,7 @@ local runner = require('user_modules/script_runner') --[[ Local Functions ]] local function step1(self) - local cid = self.mobileSession:SendRPC("ButtonPress", { + local cid = self.mobileSession1:SendRPC("ButtonPress", { moduleType = "CLIMATE", buttonName = "AC", buttonPressMode = "SHORT" @@ -36,11 +36,11 @@ local function step1(self) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end local function step2(self) - local cid = self.mobileSession:SendRPC("ButtonPress", { + local cid = self.mobileSession1:SendRPC("ButtonPress", { moduleType = "RADIO", buttonName = "VOLUME_UP", buttonPressMode = "LONG" @@ -56,7 +56,7 @@ local function step2(self) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end --[[ Scenario ]] diff --git a/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua b/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua index 3a31b03697..c393bd0497 100644 --- a/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua +++ b/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua @@ -25,7 +25,7 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ Local Functions ]] local function step1(self) - local cid = self.mobileSession:SendRPC("ButtonPress", { + local cid = self.mobileSession1:SendRPC("ButtonPress", { moduleType = "CLIMATE", buttonName = "AC", buttonPressMode = "SHORT" @@ -34,7 +34,7 @@ local function step1(self) EXPECT_HMICALL("Buttons.ButtonPress") :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) commonTestCases:DelayedExp(commonRC.timeout) end diff --git a/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua b/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua index fc1b720efb..71c37d1a46 100644 --- a/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua +++ b/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua @@ -25,7 +25,7 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ Local Functions ]] local function step1(self) - local cid = self.mobileSession:SendRPC("ButtonPress", { + local cid = self.mobileSession1:SendRPC("ButtonPress", { moduleType = "RADIO", buttonName = "VOLUME_UP", buttonPressMode = "LONG" @@ -34,7 +34,7 @@ local function step1(self) EXPECT_HMICALL("Buttons.ButtonPress") :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) commonTestCases:DelayedExp(commonRC.timeout) end diff --git a/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua b/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua index 02a0b1884c..0b8c5ea40e 100644 --- a/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua +++ b/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua @@ -23,7 +23,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } --[[ Local Functions ]] local function step1(self) - local cid = self.mobileSession:SendRPC("ButtonPress", { + local cid = self.mobileSession1:SendRPC("ButtonPress", { moduleType = "CLIMATE", buttonName = "AC", buttonPressMode = "SHORT" @@ -32,13 +32,13 @@ local function step1(self) EXPECT_HMICALL("Buttons.ButtonPress") :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) commonTestCases:DelayedExp(commonRC.timeout) end local function step2(self) - local cid = self.mobileSession:SendRPC("ButtonPress", { + local cid = self.mobileSession1:SendRPC("ButtonPress", { moduleType = "RADIO", buttonName = "VOLUME_UP", buttonPressMode = "LONG" @@ -47,7 +47,7 @@ local function step2(self) EXPECT_HMICALL("Buttons.ButtonPress") :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) commonTestCases:DelayedExp(commonRC.timeout) end diff --git a/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua b/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua index 9d81ee4570..3669dfc574 100644 --- a/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua +++ b/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua @@ -21,7 +21,7 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ Local Functions ]] local function step1(self) - local cid = self.mobileSession:SendRPC("ButtonPress", { + local cid = self.mobileSession1:SendRPC("ButtonPress", { moduleType = "CLIMATE", buttonName = "VOLUME_UP", buttonPressMode = "SHORT" @@ -30,13 +30,13 @@ local function step1(self) EXPECT_HMICALL("Buttons.ButtonPress") :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) commonTestCases:DelayedExp(commonRC.timeout) end local function step2(self) - local cid = self.mobileSession:SendRPC("ButtonPress", { + local cid = self.mobileSession1:SendRPC("ButtonPress", { moduleType = "RADIO", buttonName = "AC", buttonPressMode = "LONG" @@ -45,7 +45,7 @@ local function step2(self) EXPECT_HMICALL("Buttons.ButtonPress") :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) commonTestCases:DelayedExp(commonRC.timeout) end diff --git a/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua b/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua index cf95a000cb..e09ae541d5 100644 --- a/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua +++ b/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua @@ -53,7 +53,7 @@ local function reset_radio_params() end local function SendButtonPressPositive(button_press_params, self) - local cid = self.mobileSession:SendRPC("ButtonPress", button_press_params) + local cid = self.mobileSession1:SendRPC("ButtonPress", button_press_params) EXPECT_HMICALL("Buttons.ButtonPress", { appID = self.applications["Test Application"], @@ -66,16 +66,16 @@ local function SendButtonPressPositive(button_press_params, self) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end local function SendButtonPressNegative(button_press_params, self) - local cid = self.mobileSession:SendRPC("ButtonPress", button_press_params) + local cid = self.mobileSession1:SendRPC("ButtonPress", button_press_params) EXPECT_HMICALL("Buttons.ButtonPress") :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) commonTestCases:DelayedExp(commonRC.timeout) end diff --git a/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua b/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua index 92cbf20024..3727afa44e 100644 --- a/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua +++ b/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua @@ -24,7 +24,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("ButtonPress", { + local cid = self.mobileSession1:SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" @@ -40,7 +40,7 @@ local function getDataForModule(pModuleType, self) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end local function ptu_update_func(tbl) diff --git a/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua b/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua index bcb2775abc..0f1f877f7d 100644 --- a/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua +++ b/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua @@ -24,7 +24,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("ButtonPress", { + local cid = self.mobileSession1:SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" @@ -33,7 +33,7 @@ local function getDataForModule(pModuleType, self) EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) commonTestCases:DelayedExp(commonRC.timeout) end diff --git a/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua b/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua index fba9f50492..f5963de3d5 100644 --- a/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua +++ b/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua @@ -24,7 +24,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("ButtonPress", { + local cid = self.mobileSession1:SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" @@ -33,7 +33,7 @@ local function getDataForModule(pModuleType, self) EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) commonTestCases:DelayedExp(commonRC.timeout) end diff --git a/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua b/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua index d8c67add71..06414f3e8c 100644 --- a/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua +++ b/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua @@ -23,7 +23,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("ButtonPress", { + local cid = self.mobileSession1:SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" @@ -39,7 +39,7 @@ local function getDataForModule(pModuleType, self) -- HMI does not respond end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR"}) commonTestCases:DelayedExp(11000) end diff --git a/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua b/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua index a8d9cdbda3..26a9f4c59c 100644 --- a/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua +++ b/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua @@ -22,7 +22,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("ButtonPress", { + local cid = self.mobileSession1:SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" @@ -38,7 +38,7 @@ local function getDataForModule(pModuleType, self) self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Info message") end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Info message" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Info message" }) end --[[ Scenario ]] diff --git a/test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua b/test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua index 72a63b3468..b72ec8d3cc 100644 --- a/test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua +++ b/test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua @@ -22,7 +22,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("ButtonPress", { + local cid = self.mobileSession1:SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" @@ -38,7 +38,7 @@ local function getDataForModule(pModuleType, self) self.hmiConnection:Send('{"jsonrpc";"2.0","result":{"cod":0,"method":"Buttons.ButtonPress"},"id":32}') end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR"}) end --[[ Scenario ]] diff --git a/test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua index 236c1a665d..03d0ed51a7 100644 --- a/test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua @@ -25,7 +25,7 @@ local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTE --[[ Local Functions ]] local function stepSuccessfull(pModuleType, pResultCode, self) - local cid = self.mobileSession:SendRPC("ButtonPress", { + local cid = self.mobileSession1:SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" @@ -43,11 +43,11 @@ local function stepSuccessfull(pModuleType, pResultCode, self) }) end) - self.mobileSession:ExpectResponse(cid, { success = true, resultCode = pResultCode }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = pResultCode }) end local function stepUnsuccessfull(pModuleType, pResultCode, self) - local cid = self.mobileSession:SendRPC("ButtonPress", { + local cid = self.mobileSession1:SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" @@ -63,7 +63,7 @@ local function stepUnsuccessfull(pModuleType, pResultCode, self) self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") end) - self.mobileSession:ExpectResponse(cid, { success = false, resultCode = pResultCode }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = pResultCode }) end --[[ Scenario ]] diff --git a/test_scripts/RC/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua b/test_scripts/RC/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua index 5c5171d259..0453e038df 100644 --- a/test_scripts/RC/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua +++ b/test_scripts/RC/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua @@ -26,7 +26,7 @@ local absent_params = {moduleType = "CLIMATE", climateControlData = {acMaxEnable --[[ Local Functions ]] local function setVehicleData(params, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", {moduleData = params}) + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", {moduleData = params}) if params.climateControlData.fanSpeed then EXPECT_HMICALL("RC.SetInteriorVehicleData", { @@ -36,10 +36,10 @@ local function setVehicleData(params, self) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { moduleData = params}) end) - self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) else EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) - self.mobileSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) common_functions:DelayedExp(commonRC.timeout) end end diff --git a/test_scripts/RC/Capabilities/005_Resend_only_supported_parameters.lua b/test_scripts/RC/Capabilities/005_Resend_only_supported_parameters.lua index fea57c4a9b..79de9fdfb1 100644 --- a/test_scripts/RC/Capabilities/005_Resend_only_supported_parameters.lua +++ b/test_scripts/RC/Capabilities/005_Resend_only_supported_parameters.lua @@ -31,7 +31,7 @@ local absent_params = {moduleType = "RADIO", radioControlData = {frequencyIntege --[[ Local Functions ]] local function setVehicleData(params, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", {moduleData = params}) + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", {moduleData = params}) if params.radioControlData.frequencyInteger then EXPECT_HMICALL("RC.SetInteriorVehicleData", { @@ -41,10 +41,10 @@ local function setVehicleData(params, self) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { moduleData = params}) end) - self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) else EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) - self.mobileSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) common_functions.DelayedExp(commonRC.timeout) end end diff --git a/test_scripts/RC/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua b/test_scripts/RC/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua index 1c65c0ebe0..42e4540f3d 100644 --- a/test_scripts/RC/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua +++ b/test_scripts/RC/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua @@ -39,10 +39,10 @@ local climate_params = --[[ Local Functions ]] local function setVehicleData(params, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", {moduleData = params}) + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", {moduleData = params}) EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) - self.mobileSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) end --[[ Scenario ]] diff --git a/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index d62b9a7150..7746ffaefd 100644 --- a/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -24,14 +24,14 @@ local mod = "CLIMATE" --[[ Local Functions ]] local function getDataForModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType }) EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) commonTestCases:DelayedExp(commonRC.timeout) end diff --git a/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index 9eaa2fcd57..e163bbe968 100644 --- a/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -24,14 +24,14 @@ local mod = "RADIO" --[[ Local Functions ]] local function getDataForModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType }) EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) commonTestCases:DelayedExp(commonRC.timeout) end diff --git a/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 846ec34890..0ad3efa168 100644 --- a/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -26,14 +26,14 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType }) EXPECT_HMICALL("RC.GetInteriorVehicleData") :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) commonTestCases:DelayedExp(commonRC.timeout) end diff --git a/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua index 76f5c0f876..526623cfe3 100644 --- a/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua @@ -24,7 +24,7 @@ local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTE --[[ Local Functions ]] local function stepSuccessfull(pModuleType, pResultCode, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -41,14 +41,14 @@ local function stepSuccessfull(pModuleType, pResultCode, self) }) end) - EXPECT_RESPONSE(cid, { success = true, resultCode = pResultCode, + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = pResultCode, isSubscribed = false, moduleData = commonRC.getModuleControlData(pModuleType) }) end local function stepUnsuccessfull(pModuleType, pResultCode, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -62,7 +62,7 @@ local function stepUnsuccessfull(pModuleType, pResultCode, self) self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") end) - EXPECT_RESPONSE(cid, { success = false, resultCode = pResultCode}) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = pResultCode}) end --[[ Scenario ]] diff --git a/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua index d02e60213b..e1d3029d74 100644 --- a/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua @@ -26,7 +26,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function invalidParamName(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { modduleType = pModuleType, -- invalid name of parameter subscribe = true }) @@ -34,13 +34,13 @@ local function invalidParamName(pModuleType, self) EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) commonTestCases:DelayedExp(commonRC.timeout) end local function invalidParamType(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = 17 -- invalid type of parameter }) @@ -48,13 +48,13 @@ local function invalidParamType(pModuleType, self) EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) commonTestCases:DelayedExp(commonRC.timeout) end local function missingMandatoryParam(self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { -- moduleType = "CLIMATE", -- mandatory parameter absent subscribe = true }) @@ -62,13 +62,13 @@ local function missingMandatoryParam(self) EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) commonTestCases:DelayedExp(commonRC.timeout) end local function fakeParam(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, fakeParam = 7, subscribe = true @@ -86,7 +86,7 @@ local function fakeParam(pModuleType, self) }) end) - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true, moduleData = commonRC.getModuleControlData(pModuleType) }) diff --git a/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index f6270a7ed4..63f7745089 100644 --- a/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -23,7 +23,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -37,7 +37,7 @@ local function getDataForModule(pModuleType, self) -- HMI does not respond end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR"}) commonTestCases:DelayedExp(11000) end diff --git a/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index 292397a71c..fbc263a9be 100644 --- a/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -24,7 +24,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function invalidParamType(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -41,11 +41,11 @@ local function invalidParamType(pModuleType, self) }) end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) end local function missingMandatoryParam(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -64,7 +64,7 @@ local function missingMandatoryParam(pModuleType, self) }) end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) end --[[ Scenario ]] diff --git a/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index f1f20db70b..274b130e87 100644 --- a/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -24,7 +24,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -41,7 +41,7 @@ local function getDataForModule(pModuleType, self) }) end) - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true, moduleData = commonRC.getModuleControlData(pModuleType) }) diff --git a/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 532a44037e..2d3e1389e5 100644 --- a/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -24,7 +24,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(module_type, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = module_type, subscribe = true }) @@ -32,7 +32,7 @@ local function getDataForModule(module_type, self) EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) commonTestCases:DelayedExp(commonRC.timeout) end diff --git a/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua index f5cdc82b84..8f9be4b91f 100644 --- a/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +++ b/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -22,7 +22,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(module_type, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = module_type, subscribe = true }) @@ -36,7 +36,7 @@ local function getDataForModule(module_type, self) self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Info message") end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Info message" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Info message" }) end --[[ Scenario ]] diff --git a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua index 668b521690..278301a339 100644 --- a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -24,7 +24,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = pSubscribe }) @@ -51,7 +51,7 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, s return false, 'Parameter "subscribe" is transfered to HMI with value: ' .. tostring(data.params.subscribe) end) - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", isSubscribed = isSubscriptionActive, -- return current value of subscription moduleData = commonRC.getModuleControlData(pModuleType) }) diff --git a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index abd936ec07..772546121d 100644 --- a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -24,7 +24,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function getDataForModule(pModuleType, isSubscriptionActive, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType -- no subscribe parameter }) @@ -46,7 +46,7 @@ local function getDataForModule(pModuleType, isSubscriptionActive, self) return false, 'Parameter "subscribe" is transfered with to HMI value: ' .. tostring(data.params.subscribe) end) - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = commonRC.getModuleControlData(pModuleType) }) :ValidIf(function(_, data) -- no isSubscribed parameter diff --git a/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua b/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua index ce964aa2b3..5f5dcccff9 100644 --- a/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +++ b/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua @@ -35,7 +35,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function subscriptionToModule(pModuleType, pSubscribe, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = pSubscribe }) @@ -57,7 +57,7 @@ local function subscriptionToModule(pModuleType, pSubscribe, self) return false, 'Parameter "subscribe" is transfered to HMI with value: ' .. tostring(data.params.subscribe) end) - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = pSubscribe }) diff --git a/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua index 87ead490bf..726cd2e61f 100644 --- a/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -24,7 +24,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function subscriptionToModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -41,7 +41,7 @@ local function subscriptionToModule(pModuleType, self) }) end) - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = false }) diff --git a/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua index 2d7c137bda..c62ef3b4d9 100644 --- a/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua @@ -24,7 +24,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function subscriptionToModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -41,7 +41,7 @@ local function subscriptionToModule(pModuleType, self) }) end) - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = false }) diff --git a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua index 7d78222d58..c9e3e6bb24 100644 --- a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua @@ -26,7 +26,7 @@ local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTE --[[ Local Functions ]] local function subscriptionToModule(pModuleType, pResultCode, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -40,7 +40,7 @@ local function subscriptionToModule(pModuleType, pResultCode, self) self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") end) - EXPECT_RESPONSE(cid, { success = false, resultCode = pResultCode }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = pResultCode }) :ValidIf(function(_, data) -- no isSubscribed parameter if data.payload.isSubscribed == nil then return true diff --git a/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua index becec9d8f4..498709502a 100644 --- a/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua @@ -25,7 +25,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function subscriptionToModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -39,7 +39,7 @@ local function subscriptionToModule(pModuleType, self) -- no response from HMI end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) commonTestCases:DelayedExp(11000) end diff --git a/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua index 4d1e24d559..42828120a6 100644 --- a/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua @@ -24,7 +24,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function subscriptionToModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -41,7 +41,7 @@ local function subscriptionToModule(pModuleType, self) }) end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) end --[[ Scenario ]] diff --git a/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua index 143e41f14b..e086fe1e54 100644 --- a/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua @@ -25,7 +25,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function unSubscriptionToModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = false }) @@ -42,7 +42,7 @@ local function unSubscriptionToModule(pModuleType, self) }) end) - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = true }) diff --git a/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua index 6a6edc4de1..9340337d82 100644 --- a/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -25,7 +25,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function unSubscriptionToModule(pModuleType, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = false }) @@ -42,7 +42,7 @@ local function unSubscriptionToModule(pModuleType, self) }) end) - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = true }) diff --git a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua index b59384ce69..40d8fc4907 100644 --- a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -27,7 +27,7 @@ local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTE --[[ Local Functions ]] local function unSubscriptionToModule(pModuleType, pResultCode, self) - local cid = self.mobileSession:SendRPC("GetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = false }) @@ -42,7 +42,7 @@ local function unSubscriptionToModule(pModuleType, pResultCode, self) -- no isSubscribed parameter end) - EXPECT_RESPONSE(cid, { success = false, resultCode = pResultCode }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = pResultCode }) :ValidIf(function(_, data) -- no isSubscribed parameter if data.payload.isSubscribed == nil then return true diff --git a/test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua b/test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua index ebd0d340e0..e51beb981b 100644 --- a/test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua +++ b/test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua @@ -31,7 +31,7 @@ local function invalidParamName(pModuleType, self) modduleData = commonRC.getAnotherModuleControlData(pModuleType) -- invalid name of parameter }) - EXPECT_NOTIFICATION("OnInteriorVehicleData") + self.mobileSession1:ExpectNotification("OnInteriorVehicleData") :Times(0) commonTestCases:DelayedExp(commonRC.timeout) @@ -45,7 +45,7 @@ local function invalidParamType(pModuleType, self) moduleData = moduleData }) - EXPECT_NOTIFICATION("OnInteriorVehicleData") + self.mobileSession1:ExpectNotification("OnInteriorVehicleData") :Times(0) commonTestCases:DelayedExp(commonRC.timeout) @@ -59,7 +59,7 @@ local function missingMandatoryParam(pModuleType, self) moduleData = moduleData }) - EXPECT_NOTIFICATION("OnInteriorVehicleData") + self.mobileSession1:ExpectNotification("OnInteriorVehicleData") :Times(0) commonTestCases:DelayedExp(commonRC.timeout) diff --git a/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua b/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua index 49b849803a..a2c026b1cc 100644 --- a/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua +++ b/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua @@ -42,7 +42,7 @@ end local function step(pModuleType, pRPC1, pRPC2, self) local cid1 if pRPC1 == "SetInteriorVehicleData" then - cid1 = self.mobileSession:SendRPC("SetInteriorVehicleData", { + cid1 = self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData", { @@ -58,7 +58,7 @@ local function step(pModuleType, pRPC1, pRPC2, self) RUN_AFTER(hmiRespond, 2000) end) elseif pRPC1 == "ButtonPress" then - cid1 = self.mobileSession:SendRPC("ButtonPress", { + cid1 = self.mobileSession1:SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" @@ -76,7 +76,7 @@ local function step(pModuleType, pRPC1, pRPC2, self) RUN_AFTER(hmiRespond, 2000) end) end - self.mobileSession:ExpectResponse(cid1, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectResponse(cid1, { success = true, resultCode = "SUCCESS" }) local req2_func = function() local cid2 diff --git a/test_scripts/RC/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua b/test_scripts/RC/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua index 124b20cf90..ca5d712a0f 100644 --- a/test_scripts/RC/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua +++ b/test_scripts/RC/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua @@ -44,7 +44,7 @@ runner.Step("Activate App1", commonRC.activate_app) runner.Step("Module RADIO App1 ButtonPress allowed", commonRC.rpcAllowed, { "RADIO", 1, "ButtonPress" }) runner.Step("Subscribe App1 to RADIO", commonRC.subscribeToModule, { "RADIO", 1 }) runner.Step("Send notification OnInteriorVehicleData RADIO. App1 is subscribed", commonRC.isSubscribed, { "RADIO", 1 }) -runner.Step("RAI2, PTU without RADIO for App1", commonRC.rai_ptu_n, { ptu_update_func, 2 }) +runner.Step("RAI2, PTU without RADIO for App1", commonRC.rai_ptu_n, { 2, ptu_update_func }) runner.Step("Module RADIO App1 SetInteriorVehicleData disallowed", commonRC.rpcDenied, { "RADIO", 1, "SetInteriorVehicleData", "DISALLOWED"}) runner.Step("Module CLIMATE App1 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "CLIMATE", 1, "SetInteriorVehicleData"}) runner.Step("Activate App2", commonRC.activate_app, { 2 }) diff --git a/test_scripts/RC/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua b/test_scripts/RC/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua index 1f4e704605..fdff679c92 100644 --- a/test_scripts/RC/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua +++ b/test_scripts/RC/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua @@ -20,7 +20,7 @@ local json = require("modules/json") --[[ Local Functions ]] -local function ptu_update_func_1(tbl) +local function ptu_update_func(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = json.null end @@ -37,7 +37,7 @@ runner.Step("Activate App1", commonRC.activate_app) runner.Step("Module RADIO App1 ButtonPress allowed", commonRC.rpcAllowed, { "RADIO", 1, "ButtonPress" }) runner.Step("Subscribe App1 to RADIO", commonRC.subscribeToModule, { "RADIO", 1 }) runner.Step("Send notification OnInteriorVehicleData RADIO. App1 is subscribed", commonRC.isSubscribed, { "RADIO", 1 }) -runner.Step("RAI2, PTU App1 permissions revoked", commonRC.rai_ptu_n, { ptu_update_func_1, 2 }) +runner.Step("RAI2, PTU App1 permissions revoked", commonRC.rai_ptu_n, { 2, ptu_update_func }) runner.Step("Module RADIO App1 SetInteriorVehicleData disallowed", commonRC.rpcDenied, { "RADIO", 1, "SetInteriorVehicleData", "DISALLOWED"}) runner.Step("Module CLIMATE App1 SetInteriorVehicleData disallowed", commonRC.rpcDenied, { "CLIMATE", 1, "SetInteriorVehicleData", "DISALLOWED"}) runner.Step("Activate App2", commonRC.activate_app, { 2 }) diff --git a/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua index 04c849ac8e..e5dea60edc 100644 --- a/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua @@ -23,7 +23,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function setVehicleData(pModuleType, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) @@ -37,7 +37,7 @@ local function setVehicleData(pModuleType, self) }) end) - self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end --[[ Scenario ]] diff --git a/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index db68e3496c..044a6748cb 100644 --- a/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -24,14 +24,14 @@ local mod = "CLIMATE" --[[ Local Functions ]] local function setVehicleData(pModuleType, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData") :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) commonTestCases:DelayedExp(commonRC.timeout) end diff --git a/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index e4b62ed5ab..06b5067914 100644 --- a/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -24,14 +24,14 @@ local mod = "RADIO" --[[ Local Functions ]] local function setVehicleData(pModuleType, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData") :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) commonTestCases:DelayedExp(commonRC.timeout) end diff --git a/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 18c8964459..edda9722c8 100644 --- a/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -26,14 +26,14 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function setVehicleData(pModuleType, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData") :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) commonTestCases:DelayedExp(commonRC.timeout) end diff --git a/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua b/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua index fea4a1ab33..7c011d9a98 100644 --- a/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua +++ b/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua @@ -36,14 +36,14 @@ local function setVehicleData(pModuleType, self) local moduleData = commonRC.getSettableModuleControlData(moduleType2) moduleData.moduleType = pModuleType - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleData = moduleData }) EXPECT_HMICALL("RC.SetInteriorVehicleData") :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) commonTestCases:DelayedExp(commonRC.timeout) end diff --git a/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua index 6adcf4971d..a69e0d3ff8 100644 --- a/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua @@ -26,14 +26,14 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function invalidParamName(pModuleType, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleDData = commonRC.getSettableModuleControlData(pModuleType) -- invalid name of parameter }) EXPECT_HMICALL("RC.SetInteriorVehicleData", {}) :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) commonTestCases:DelayedExp(commonRC.timeout) end @@ -42,14 +42,14 @@ local function invalidParamType(pModuleType, self) local moduleData = commonRC.getSettableModuleControlData(pModuleType) moduleData.moduleType = {} -- invalid type of parameter - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { modduleData = moduleData }) EXPECT_HMICALL("RC.SetInteriorVehicleData", {}) :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) commonTestCases:DelayedExp(commonRC.timeout) end @@ -58,20 +58,20 @@ local function missingMandatoryParam(pModuleType, self) local moduleData = commonRC.getSettableModuleControlData(pModuleType) moduleData.moduleType = nil -- mandatory parameter missing - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { modduleData = moduleData }) EXPECT_HMICALL("RC.SetInteriorVehicleData", {}) :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) commonTestCases:DelayedExp(commonRC.timeout) end local function fakeParam(pModuleType, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType), fakeParam = 6 }) @@ -86,7 +86,7 @@ local function fakeParam(pModuleType, self) }) end) - self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end --[[ Scenario ]] diff --git a/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index cfb3adabfa..40d3aecc34 100644 --- a/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -24,7 +24,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function setVehicleData(pModuleType, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) @@ -38,7 +38,7 @@ local function setVehicleData(pModuleType, self) }) end) - self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end local function ptu_update_func(tbl) diff --git a/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index a24e350823..591d1b8195 100644 --- a/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -24,14 +24,14 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function setVehicleData(pModuleType, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData") :Times(0) - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) commonTestCases:DelayedExp(commonRC.timeout) end diff --git a/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua b/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua index 24396118a6..59c2c2691a 100644 --- a/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua +++ b/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua @@ -24,7 +24,7 @@ local modules = { "CLIMATE", "RADIO" } local function setVehicleData(pModuleType, self) local moduleData = commonRC.getSettableModuleControlData(pModuleType) moduleData.fakeParam = 123 - self.mobileSession:SendRPC("SetInteriorVehicleData", { + self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleData = moduleData }) diff --git a/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua b/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua index d5b89f0eb8..e900c86a20 100644 --- a/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +++ b/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua @@ -25,11 +25,11 @@ local module_data_radio = commonRC.getReadOnlyParamsByModule("RADIO") --[[ Local Functions ]] local function setVehicleData(module_data, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", {moduleData = module_data}) + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", {moduleData = module_data}) EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) - self.mobileSession:ExpectResponse(cid, { success = false, resultCode = "READ_ONLY" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "READ_ONLY" }) commonTestCases:DelayedExp(commonRC.timeout) end diff --git a/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua b/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua index 3f9c3c6177..bf14213497 100644 --- a/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua +++ b/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua @@ -46,7 +46,7 @@ local function setVehicleData(pModuleType, pParams, self) commonRC.getModuleParams(moduleDataSettable)[k] = v end - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleData = moduleDataCombined }) @@ -63,7 +63,7 @@ local function setVehicleData(pModuleType, pParams, self) return true end) - self.mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) :ValidIf(function(_, data) if not isModuleDataCorrect(pModuleType, data.payload.moduleData) then return false, "Test step failed, see prints" diff --git a/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua b/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua index 137a30883b..95cce203fc 100644 --- a/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua +++ b/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua @@ -22,7 +22,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function setVehicleData(pModuleType, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) @@ -34,7 +34,7 @@ local function setVehicleData(pModuleType, self) self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Info message") end) - self.mobileSession:ExpectResponse(cid, { success = false, resultCode = "READ_ONLY", info = "Info message" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "READ_ONLY", info = "Info message" }) end --[[ Scenario ]] diff --git a/test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index bcebb5f509..004e995989 100644 --- a/test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -23,7 +23,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function setVehicleData(pModuleType, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) @@ -35,7 +35,7 @@ local function setVehicleData(pModuleType, self) -- HMI does not respond end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR"}) commonTestCases:DelayedExp(11000) end diff --git a/test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index 2da8ade57e..16657e564e 100644 --- a/test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -22,7 +22,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function invalidParamType(pModuleType, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) @@ -39,11 +39,11 @@ local function invalidParamType(pModuleType, self) }) end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) end local function missingMandatoryParam(pModuleType, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) @@ -59,7 +59,7 @@ local function missingMandatoryParam(pModuleType, self) }) end) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) end --[[ Scenario ]] diff --git a/test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua index b437cffa2d..46d7b72042 100644 --- a/test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua @@ -25,7 +25,7 @@ local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTE --[[ Local Functions ]] local function stepSuccessfull(pModuleType, pResultCode, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) @@ -39,12 +39,12 @@ local function stepSuccessfull(pModuleType, pResultCode, self) }) end) - self.mobileSession:ExpectResponse(cid, + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = pResultCode, moduleData = commonRC.getSettableModuleControlData(pModuleType) }) end local function stepUnsuccessfull(pModuleType, pResultCode, self) - local cid = self.mobileSession:SendRPC("SetInteriorVehicleData", { + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) @@ -56,7 +56,7 @@ local function stepUnsuccessfull(pModuleType, pResultCode, self) self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") end) - self.mobileSession:ExpectResponse(cid, { success = false, resultCode = pResultCode }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = pResultCode }) end --[[ Scenario ]] diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 542b5d84bd..329c261bca 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -143,11 +143,6 @@ function commonRC.start(pHMIParams, self) self:connectMobile() :Do(function() commonFunctions:userPrint(35, "Mobile connected") - self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) - self.mobileSession:StartService(7) - :Do(function() - commonFunctions:userPrint(35, "Session started") - end) end) end) end) @@ -156,29 +151,12 @@ end function commonRC.rai_ptu(ptu_update_func, self) self, ptu_update_func = commonRC.getSelfAndParams(ptu_update_func, self) - - local corId = self.mobileSession:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config.application1.registerAppInterfaceParams.appName } }) - :Do(function(_, d1) - hmiAppIds[config.application1.registerAppInterfaceParams.appID] = d1.params.application.appID - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) - :Times(3) - EXPECT_HMICALL("BasicCommunication.PolicyUpdate") - :Do(function(_, d2) - self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) - ptu_table = jsonFileToTable(d2.params.file) - ptu(self, ptu_update_func) - end) - end) - self.mobileSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) - :Do(function() - self.mobileSession:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice - self.mobileSession:ExpectNotification("OnPermissionsChange") - end) + commonRC.rai_ptu_n(1, ptu_update_func, self) end -function commonRC.rai_ptu_n(ptu_update_func, id, self) +function commonRC.rai_ptu_n(id, ptu_update_func, self) + self, id, ptu_update_func = commonRC.getSelfAndParams(id, ptu_update_func, self) + if not id then id = 1 end self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) self["mobileSession" .. id]:StartService(7) :Do(function() @@ -205,6 +183,8 @@ function commonRC.rai_ptu_n(ptu_update_func, id, self) end function commonRC.rai_n(id, self) + self, id = commonRC.getSelfAndParams(id, self) + if not id then id = 1 end self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) self["mobileSession" .. id]:StartService(7) :Do(function() @@ -232,30 +212,11 @@ end function commonRC.activate_app(pAppId, self) self, pAppId = commonRC.getSelfAndParams(pAppId, self) - - local pHMIAppId = hmiAppIds[config.application1.registerAppInterfaceParams.appID] - local mobSession = self["mobileSession"] - if pAppId and pAppId > 1 then - mobSession = self["mobileSession" .. pAppId] - pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] - end - local requestId1 = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) - EXPECT_HMIRESPONSE(requestId1) - :Do(function(_, data1) - if data1.result.isSDLAllowed ~= true then - local requestId2 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", - { language = "EN-US", messageCodes = { "DataConsent" } }) - EXPECT_HMIRESPONSE(requestId2) - :Do(function() - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) - EXPECT_HMICALL("BasicCommunication.ActivateApp") - :Do(function(_, data2) - self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", { }) - end) - end) - end - end) + if not pAppId then pAppId = 1 end + local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + local mobSession = commonRC.getMobileSession(self, pAppId) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + EXPECT_HMIRESPONSE(requestId) mobSession:ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) commonTestCases:DelayedExp(commonRC.minTimeout) end @@ -264,11 +225,24 @@ function commonRC.postconditions() StopSDL() end -function commonRC.getSelfAndParams(param, self) - if not self then - return param, nil +function commonRC.getSelfAndParams(...) + local out = { } + local selfIdx = nil + for i,v in pairs({...}) do + if type(v) == "table" and v.isTest then + table.insert(out, v) + selfIdx = i + break + end end - return self, param + local idx = 2 + for i = 1, table.maxn({...}) do + if i ~= selfIdx then + out[idx] = ({...})[i] + idx = idx + 1 + end + end + return table.unpack(out, 1, table.maxn(out)) end function commonRC.getModuleControlData(module_type) @@ -617,17 +591,13 @@ function commonRC.isUnsubscribed(pModuleType, pAppId, self) end function commonRC.getHMIAppId(pAppId) - if not pAppId then - pAppId = 1 - end + if not pAppId then pAppId = 1 end return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] end function commonRC.getMobileSession(self, pAppId) - if pAppId and pAppId > 1 then - return self["mobileSession" .. pAppId] - end - return self["mobileSession"] + if not pAppId then pAppId = 1 end + return self["mobileSession" .. pAppId] end function commonRC.defineRAMode(pAllowed, pAccessMode, self) diff --git a/user_modules/script_runner.lua b/user_modules/script_runner.lua index ecaaacfd6d..6a25ee3f63 100644 --- a/user_modules/script_runner.lua +++ b/user_modules/script_runner.lua @@ -5,6 +5,8 @@ local isPrintTitle = false local title local runner = {} +Test.isTest = true + --[ATF] local function buildStepName(testStepName) if type(testStepName) == "string" and testStepName ~= "" then @@ -53,7 +55,7 @@ local function extendedAddTestStep(testStepName, testStepImplFunction, paramsTab local newTestStepImplFunction = function(self) for _, func in pairs(implFunctionsListWithParams) do table.insert(func.params, self) - func.implFunc(unpack(func.params)) + func.implFunc(unpack(func.params, 1, table.maxn(func.params))) end end addTestStep(testStepName, newTestStepImplFunction) From 6cbda4f63b45393ce509957a63d79a899e4b845f Mon Sep 17 00:00:00 2001 From: Masato Ogawa Date: Mon, 4 Sep 2017 17:39:17 +0900 Subject: [PATCH 153/681] Updated a license header --- test_scripts/API/ATF_SendHapticData.lua | 37 ++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/test_scripts/API/ATF_SendHapticData.lua b/test_scripts/API/ATF_SendHapticData.lua index 254ab864bb..63795b4aba 100644 --- a/test_scripts/API/ATF_SendHapticData.lua +++ b/test_scripts/API/ATF_SendHapticData.lua @@ -1,7 +1,36 @@ --------------------------------------------------------------------------------- --- Copyright (c) 2017 Xevo Inc. --- All rights reserved. --------------------------------------------------------------------------------- +--[[ + + Copyright (c) 2017 Xevo Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Xevo Inc. nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +--]] Test = require('connecttest') local commonFunctions = From 9158befab982085f9e0016f6b410711e5be6aa06 Mon Sep 17 00:00:00 2001 From: Masato Ogawa Date: Mon, 4 Sep 2017 17:42:50 +0900 Subject: [PATCH 154/681] Added manual policy table change to allow SendHapticData --- test_scripts/API/ATF_SendHapticData.lua | 129 ++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/test_scripts/API/ATF_SendHapticData.lua b/test_scripts/API/ATF_SendHapticData.lua index 63795b4aba..407f10c1f9 100644 --- a/test_scripts/API/ATF_SendHapticData.lua +++ b/test_scripts/API/ATF_SendHapticData.lua @@ -33,8 +33,137 @@ --]] Test = require('connecttest') +local mobile_session = require('mobile_session') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local json = require("modules/json") + +-------------------------------------------------------------------------------- +-- PRECONDITIONS +-------------------------------------------------------------------------------- +commonFunctions:newTestCasesGroup("Preconditions: Change policy table, " .. + "restart SDL and activate application ") + +function DelayedExp() + local event = events.Event() + event.matches = function(self, e) return self == e end + EXPECT_EVENT(event, "Delayed event") + RUN_AFTER(function() RAISE_EVENT(event, event) end, 2000) +end + +function AddHapticGroupToPolicyTable(policyTable) + policyTable.functional_groupings.HapticGroup = {} + policyTable.functional_groupings.HapticGroup.rpcs = {} + policyTable.functional_groupings.HapticGroup.rpcs. + OnTouchEvent = {} + policyTable.functional_groupings.HapticGroup.rpcs. + OnTouchEvent.hmi_levels = {'FULL'} + policyTable.functional_groupings.HapticGroup.rpcs. + SendHapticData = {} + policyTable.functional_groupings.HapticGroup.rpcs. + SendHapticData.hmi_levels = {'FULL'} + policyTable.app_policies.default.groups = {"Base-4", "HapticGroup"} +end + +local ModifyPolicyTable = AddHapticGroupToPolicyTable + +function Test:StopSDLToBackUpPreloadedPt( ... ) + self.mobileSession:Stop() + StopSDL() + DelayedExp(1000) +end + +function Test:BackUpPreloadedPt() + os.execute('cp ' .. config.pathToSDL .. '/sdl_preloaded_pt.json' .. ' ' .. + config.pathToSDL .. '/backup_sdl_preloaded_pt.json') + os.execute('rm ' .. config.pathToSDL .. '/storage/policy.sqlite') +end + +function Test:ModifyPreloadedPt() + pathToFile = config.pathToSDL .. '/sdl_preloaded_pt.json' + local file = io.open(pathToFile, "r") + local json_data = file:read("*all") + file:close() + + local data = json.decode(json_data) + for k,v in pairs(data.policy_table.functional_groupings) do + if (data.policy_table.functional_groupings[k].rpcs == nil) then + data.policy_table.functional_groupings[k] = nil + else + local count = 0 + for _ in pairs(data.policy_table.functional_groupings[k].rpcs) do + count = count + 1 + end + if (count < 30) then + data.policy_table.functional_groupings[k] = nil + end + end + end + ModifyPolicyTable(data.policy_table) + data = json.encode(data) + + file = io.open(pathToFile, "w") + file:write(data) + file:close() +end + +function Test:Precondition_StartSDL() + StartSDL(config.pathToSDL, config.ExitOnCrash) + DelayedExp(1000) +end + +function Test:Precondition_InitHMI_1() + self:initHMI() +end + +function Test:Precondition_InitHMI_onReady_1() + self:initHMI_onReady() +end + +function Test:Precondition_ConnectMobile_1() + self:connectMobile() +end + +function Test:Precondition_StartSession_1() + self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) +end + +function Test:RestorePreloadedPt() + os.execute('cp ' .. config.pathToSDL .. '/backup_sdl_preloaded_pt.json' .. + ' ' .. config.pathToSDL .. '/sdl_preloaded_pt.json') + os.execute('rm ' .. config.pathToSDL .. '/backup_sdl_preloaded_pt.json') +end + +local myAppID = 0 + +function Test:RegisterApp() + self.mobileSession:StartService(7) + :Do(function (_, data) + -- mobile side + local corrID = self.mobileSession:SendRPC("RegisterAppInterface", + config.application1.registerAppInterfaceParams) + + -- hmi side + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered") + :Do(function (_, data) + myAppID = data.params.application.appID + end) + + -- mobile side + EXPECT_RESPONSE(corrID, {success = true}) + end) +end + +function Test:ActivationApp() + --hmi side + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", + { appID = myAppID}) + EXPECT_HMIRESPONSE(requestId) + + --mobile side + EXPECT_NOTIFICATION("OnHMIStatus", + {hmiLevel = "FULL", systemContext = "MAIN"}) +end -------------------------------------------------------------------------------- -- TEST BLOCK I : Check normal cases From 48704ea52a41ef89f7c4f0cd3c373197c0c73bd1 Mon Sep 17 00:00:00 2001 From: Masato Ogawa Date: Mon, 4 Sep 2017 17:43:43 +0900 Subject: [PATCH 155/681] Fixed test break for NoSpatialData --- test_scripts/API/ATF_SendHapticData.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test_scripts/API/ATF_SendHapticData.lua b/test_scripts/API/ATF_SendHapticData.lua index 407f10c1f9..2a7758a04b 100644 --- a/test_scripts/API/ATF_SendHapticData.lua +++ b/test_scripts/API/ATF_SendHapticData.lua @@ -262,9 +262,7 @@ function Test:NoSpatialData() ) -- hmi side EXPECT_HMICALL( - "UI.SendHapticData", - { - } + "UI.SendHapticData" ) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) From 1bb1e582c082450db279514f3b6651c9559f2513 Mon Sep 17 00:00:00 2001 From: "Oleksandr Deriabin (GitHub)" Date: Mon, 4 Sep 2017 15:26:46 +0300 Subject: [PATCH 156/681] Information about RC app2 was added to PTU --- .../022_Release_resource_on_PTU_with_module_disallow.lua | 1 + .../023_Release_resource_on_PTU_with_app_revoked.lua | 1 + 2 files changed, 2 insertions(+) diff --git a/test_scripts/RC/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua b/test_scripts/RC/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua index 124b20cf90..42272ea3c5 100644 --- a/test_scripts/RC/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua +++ b/test_scripts/RC/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua @@ -29,6 +29,7 @@ local function ptu_update_func(tbl) AppHMIType = { "REMOTE_CONTROL" } } table.insert(tbl.policy_table.functional_groupings.RemoteControl.rpcs.OnInteriorVehicleData.hmi_levels, "NONE") + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua b/test_scripts/RC/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua index 1f4e704605..07e8abb900 100644 --- a/test_scripts/RC/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua +++ b/test_scripts/RC/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua @@ -22,6 +22,7 @@ local json = require("modules/json") --[[ Local Functions ]] local function ptu_update_func_1(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = json.null + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() end --[[ Scenario ]] From 2a1384b9ec78d87b07fe38631ec053d3a754e0c1 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 1 Sep 2017 15:49:26 -0400 Subject: [PATCH 157/681] Add support of EXTERNAL flow --- test_scripts/RC/commonRC.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 329c261bca..b2863e2739 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -123,6 +123,11 @@ local function ptu(self, ptu_update_func) os.remove(ptu_file_name) end +local function allow_sdl(self) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", + { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) +end + function commonRC.preconditions() commonFunctions:SDLForceStop() commonSteps:DeletePolicyTable() @@ -143,6 +148,7 @@ function commonRC.start(pHMIParams, self) self:connectMobile() :Do(function() commonFunctions:userPrint(35, "Mobile connected") + allow_sdl(self) end) end) end) From 1aeaa411d18ed7917bf2cd105212e8a12f7d515b Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 8 Sep 2017 16:24:47 -0400 Subject: [PATCH 158/681] Style fix --- .../shared_testcases/commonTestCases.lua | 138 +++++++++--------- 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/user_modules/shared_testcases/commonTestCases.lua b/user_modules/shared_testcases/commonTestCases.lua index d13cff59f8..ff760d4f50 100644 --- a/user_modules/shared_testcases/commonTestCases.lua +++ b/user_modules/shared_testcases/commonTestCases.lua @@ -3,7 +3,7 @@ --1. local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --2. commonTestCases:createString(500) --example --------------------------------------------------------------------------------------------- - + local commonTestCases = {} local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') @@ -33,50 +33,50 @@ local mobile_session = require('mobile_session') --Verify request with invalid JSON function commonTestCases:VerifyInvalidJsonRequest(RPCFunctionId, Payload, TestCaseName) - + if TestCaseName == nil or TestCaseName == "" then TestCaseName = APIName .."_InvalidJSON_INVALID_DATA" end - + Test[TestCaseName] = function(self) commonTestCases:DelayedExp(1000) --1 second self.mobileSession.correlationId = self.mobileSession.correlationId + 1 - local msg = + local msg = { serviceType = 7, frameInfo = 0, rpcType = 0, rpcFunctionId = RPCFunctionId, - rpcCorrelationId = self.mobileSession.correlationId, + rpcCorrelationId = self.mobileSession.correlationId, --payload = '{"ttsChunks":{{"text":"a","type":"TEXT"}}}' payload = Payload } self.mobileSession:Send(msg) self.mobileSession:ExpectResponse(self.mobileSession.correlationId, { success = false, resultCode = "INVALID_DATA" }) - + --mobile side: expect OnHashChange notification is not send to mobile EXPECT_NOTIFICATION("OnHashChange") - :Times(0) - end + :Times(0) + end end --Verify request missed all parameters function commonTestCases:VerifyRequestIsMissedAllParameters() - + Test[APIName .."_IsMissedAllParameters_INVALID_DATA"] = function(self) - - --mobile side: sending request + + --mobile side: sending request local cid = self.mobileSession:SendRPC(APIName, {} ) - + --mobile side: expect the response EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA" }) - - end - + + end + end @@ -99,44 +99,44 @@ end --Send request, check HMI Status and resultCode local function SendRequestInDifferentHMIStatus(HMIStatus, ResultCode) - + Test[APIName .. "_" .. HMIStatus .. "_HMILevel_" .. ResultCode] = function(self) - + --create default request local RequestParams = self.createRequest() - - + + if ResultCode == "DISALLOWED" then - - --mobile side: send request + + --mobile side: send request local cid = self.mobileSession:SendRPC(APIName, RequestParams) - - --mobile side: expect response + + --mobile side: expect response EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED"}) - + elseif ResultCode == "SUCCESS" then - + --mobile sends request receives SUCCESS result code self:verify_SUCCESS_Case(RequestParams, HMIStatus) else - print("Error: ResultCode is not SUCCESS or DISALLOWED") + print("Error: ResultCode is not SUCCESS or DISALLOWED") end - - end -end + end + +end --Send request, check resultCode in NONE hmi level local function VerifyRequestInNoneHmiLevel(ResultCode) - --Precondition: Deactivate app to NONE HMI level + --Precondition: Deactivate app to NONE HMI level commonSteps:DeactivateAppToNoneHmiLevel() - + --Send request, check HMI Status and resultCode - SendRequestInDifferentHMIStatus("NONE", ResultCode) - + SendRequestInDifferentHMIStatus("NONE", ResultCode) + --Postcondition: Activate app - commonSteps:ActivationApp() + commonSteps:ActivationApp() end @@ -145,32 +145,32 @@ local function VerifyRequestInLimitedHmiLevel(ResultCode) -- Precondition: Change app to LIMITED commonSteps:ChangeHMIToLimited() - + --Send request, check HMI Status and resultCode - SendRequestInDifferentHMIStatus("LIMITED", ResultCode) - + SendRequestInDifferentHMIStatus("LIMITED", ResultCode) + end function commonTestCases:ChangeAppToBackgroundHmiLevel() - + if commonFunctions:isMediaApp() then -- Precondition 1: Opening new session commonSteps:precondition_AddNewSession() -- Precondition 2: Register app2 - commonSteps:RegisterTheSecondMediaApp() + commonSteps:RegisterTheSecondMediaApp() -- Precondition 3: Activate an other media app to change app to BACKGROUND - commonSteps:ActivateTheSecondMediaApp() - + commonSteps:ActivateTheSecondMediaApp() + else -- Precondition: Deactivate non-media app to BACKGROUND - commonSteps:DeactivateToBackground() - + commonSteps:DeactivateToBackground() + end - -end + +end --Verify resultCode in NONE, LIMITED, BACKGROUND hmi level function commonTestCases:verifyDifferentHMIStatus(NoneHmiResultCode, LimitedHmiResultCode, BackgroundHmiResultCode) @@ -178,23 +178,23 @@ function commonTestCases:verifyDifferentHMIStatus(NoneHmiResultCode, LimitedHmiR --Print new line to separate new test cases group commonFunctions:newTestCasesGroup("Test suite: Different HMI Level Checks") ---------------------------------------------------------------------------------------------- - + --Test case 1: Check resultCode when HMI level is NONE VerifyRequestInNoneHmiLevel(NoneHmiResultCode) - + --Test case 2: Check resultCode when HMI level is LIMITED if commonFunctions:isMediaApp() then VerifyRequestInLimitedHmiLevel(LimitedHmiResultCode) end - + --Test case 3: Check resultCode when HMI level is BACKGROUND commonTestCases:ChangeAppToBackgroundHmiLevel() - + --Send request, check HMI Status and resultCode SendRequestInDifferentHMIStatus("BACKGROUND", BackgroundHmiResultCode) - - --VerifyRequestInBackgroundHmiLevel(BackgroundHmiResultCode) - + + --VerifyRequestInBackgroundHmiLevel(BackgroundHmiResultCode) + end @@ -215,45 +215,45 @@ function commonTestCases:verifyResultCode_APPLICATION_NOT_REGISTERED() --self.expectations_list, self, self.mobileConnection - ) + ) end - + Test[APIName .."_resultCode_APPLICATION_NOT_REGISTERED"] = function(self) --mobile side: sending the request local RequestParams = self.createRequest() local cid = self.mobileSession2:SendRPC(APIName, RequestParams) - - --mobile side: expect response + + --mobile side: expect response self.mobileSession2:ExpectResponse(cid, { success = false, resultCode = "APPLICATION_NOT_REGISTERED"}) - - end -end + end + +end --Verify TOO_MANY_PENDING_REQUESTS resultCode function commonTestCases:verifyResultCode_TOO_MANY_PENDING_REQUESTS(numberOfRequest) - + --Test[APIName .."_resultCode_TOO_MANY_PENDING_REQUESTS"] = function(self) - + commonTestCases:DelayedExp(1000) - + local n = 0 --mobile side: expect response EXPECT_RESPONSE(APIName) :ValidIf(function(exp,data) - if + if data.payload.resultCode == "TOO_MANY_PENDING_REQUESTS" then n = n+1 print(" \27[32m "..APIName.." response came with resultCode TOO_MANY_PENDING_REQUESTS \27[0m") return true - elseif - exp.occurences == numberOfRequest-1 and n == 0 then + elseif + exp.occurences == numberOfRequest-1 and n == 0 then print(" \27[36m Response "..APIName.." with resultCode TOO_MANY_PENDING_REQUESTS did not came \27[0m") return false - elseif + elseif data.payload.resultCode == "GENERIC_ERROR" then print(" \27[32m "..APIName.." response came with resultCode GENERIC_ERROR \27[0m") return true @@ -272,10 +272,10 @@ function commonTestCases:verifyResultCode_TOO_MANY_PENDING_REQUESTS(numberOfRequ --expect absence of BasicCommunication.OnAppUnregistered EXPECT_HMICALL("BasicCommunication.OnAppUnregistered") :Times(0) - --- end + +-- end end - + return commonTestCases \ No newline at end of file From 77a2a5e984655ae4b9e5ec0eaaf9f60a11f16128 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 8 Sep 2017 16:25:11 -0400 Subject: [PATCH 159/681] Timeout fix --- user_modules/shared_testcases/commonTestCases.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_modules/shared_testcases/commonTestCases.lua b/user_modules/shared_testcases/commonTestCases.lua index ff760d4f50..cac75f875c 100644 --- a/user_modules/shared_testcases/commonTestCases.lua +++ b/user_modules/shared_testcases/commonTestCases.lua @@ -84,7 +84,7 @@ function commonTestCases:DelayedExp(time) local event = events.Event() event.matches = function(self, e) return self == e end EXPECT_EVENT(event, "Delayed event") - :Timeout(time+1000) + :Timeout(time+5000) RUN_AFTER(function() RAISE_EVENT(event, event) end, time) From b6bfbd977a6aef6cc04e2eb6dbb789d4bee58a3d Mon Sep 17 00:00:00 2001 From: "Oleksandr Deriabin (GitHub)" Date: Mon, 4 Sep 2017 18:49:33 +0300 Subject: [PATCH 160/681] Test script runner was updated to check SDL and script compatibility. Test settings were added. --- user_modules/dummy_connecttest.lua | 1 + user_modules/script_runner.lua | 119 +++++++++++++++++++++++++---- user_modules/test_settings.lua | 10 +++ 3 files changed, 115 insertions(+), 15 deletions(-) create mode 100644 user_modules/test_settings.lua diff --git a/user_modules/dummy_connecttest.lua b/user_modules/dummy_connecttest.lua index f0f815a1cc..8cd9c3864b 100644 --- a/user_modules/dummy_connecttest.lua +++ b/user_modules/dummy_connecttest.lua @@ -31,6 +31,7 @@ module.mobileConnection = mobile.MobileConnection(fileConnection) event_dispatcher:AddConnection(module.hmiConnection) event_dispatcher:AddConnection(module.mobileConnection) module.notification_counter = 1 +module.sdlBuildOptions = SDL.buildOptions function module.hmiConnection:EXPECT_HMIRESPONSE(id, args) local event = events.Event() diff --git a/user_modules/script_runner.lua b/user_modules/script_runner.lua index 6a25ee3f63..19edd783ac 100644 --- a/user_modules/script_runner.lua +++ b/user_modules/script_runner.lua @@ -1,13 +1,45 @@ local Test = require('user_modules/dummy_connecttest') +local testSettings = require('user_modules/test_settings') +local consts = require('user_modules/consts') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local isInitialStep = true local isPrintTitle = false local title local runner = {} +runner.testSettings = testSettings + Test.isTest = true +--[Utils] +local function existsInList (pList, pValue) + for _, value in pairs(pList) do + if value == pValue then + return true + end + end + return false +end + --[ATF] +local function buildTitle(titleText) + local maxLength = 101 + local filler = "-" + local resultTable = {} + for line in titleText:gmatch("[^\n]+") do + local lineLength = #line + if lineLength >= maxLength then + table.insert(resultTable, line) + else + local tailLength = math.fmod(maxLength - lineLength, 2) + local emtyLineSideLength = math.floor((maxLength - lineLength) / 2) + table.insert(resultTable, filler:rep(emtyLineSideLength) .. line .. filler:rep(emtyLineSideLength + tailLength)) + end + end + return table.concat(resultTable, "\n") +end + local function buildStepName(testStepName) if type(testStepName) == "string" and testStepName ~= "" then testStepName = testStepName:gsub("%W", "_") @@ -61,24 +93,63 @@ local function extendedAddTestStep(testStepName, testStepImplFunction, paramsTab addTestStep(testStepName, newTestStepImplFunction) end ---[[ Title + Step approach]] -local function buildTitle(titleText) - local maxLength = 101 - local filler = "-" - local resultTable = {} - for line in titleText:gmatch("[^\n]+") do - local lineLength = #line - if lineLength >= maxLength then - table.insert(resultTable, line) - else - local tailLength = math.fmod(maxLength - lineLength, 2) - local emtyLineSideLength = math.floor((maxLength - lineLength) / 2) - table.insert(resultTable, filler:rep(emtyLineSideLength) .. line .. filler:rep(emtyLineSideLength + tailLength)) +local function isTestApplicable(testApplicableSdlSettings) + if next(testApplicableSdlSettings) == nil then + return true + end + local isMatched = true + for _, sdlSettingsSet in pairs(testApplicableSdlSettings) do + for sdlSettingsItem, listOfValuesForItem in pairs(sdlSettingsSet) do + local sdlBuildOptionValue = Test.sdlBuildOptions[sdlSettingsItem] + if sdlBuildOptionValue then + if not existsInList(listOfValuesForItem, sdlBuildOptionValue) then + isMatched = false + break + end + else + isMatched = false + break + end end + if isMatched then + return true + end + isMatched = true end - return table.concat(resultTable, "\n") + return false +end + +local function skipTest(reason) + title = "" + runner.Title("TEST SKIPPED") + runner.Step( + "Skip reason", + function(skipReason, self) + commonFunctions:userPrint(consts.color.cyan, skipReason) + self:SkipTest() + end, + { reason } + ) +end + +local function prepareDescription(text, maxLength) + if text:find("\n") or text:len() >= maxLength then + return "\n" .. text + end + return text +end + +local function printTestInformation() + local maxLength = 101 + local filler = "=" + print(filler:rep(maxLength) .. + "\nDescription: " .. + prepareDescription(runner.testSettings.description, maxLength - string.len("Description")) .. + "\nSeverity: " .. runner.testSettings.severity .. "\n" .. + filler:rep(maxLength)) end +--[[ Title + Step approach]] function runner.Title(titleText) if isPrintTitle == true then title = title .. "\n" .. titleText @@ -90,7 +161,25 @@ function runner.Title(titleText) end function runner.Step(testStepName, testStepImplFunction, paramsTable) - extendedAddTestStep(testStepName, testStepImplFunction, paramsTable) + local maxLength = 101 + local filler = "=" + if isInitialStep then + printTestInformation() + if not isTestApplicable(runner.testSettings.restrictions.sdlBuildOptions) then + local message = "Test is incompatible with current build configuration of SDL:\n" .. + commonFunctions:convertTableToString(Test.sdlBuildOptions, 1) .. + "\n\nTest is possible to run with SDL that was built with next build options:\n" .. + commonFunctions:convertTableToString(runner.testSettings.restrictions.sdlBuildOptions, 1) .. "\n" .. + filler:rep(maxLength) + isInitialStep = false + skipTest(message) + else + extendedAddTestStep(testStepName, testStepImplFunction, paramsTable) + isInitialStep = false + end + else + extendedAddTestStep(testStepName, testStepImplFunction, paramsTable) + end end return runner diff --git a/user_modules/test_settings.lua b/user_modules/test_settings.lua new file mode 100644 index 0000000000..7c9e4550b1 --- /dev/null +++ b/user_modules/test_settings.lua @@ -0,0 +1,10 @@ +local testSettings = { + description = "ATF test script", + severity = "Major", + restrictions = { + sdlBuildOptions = {} -- no restrictions on SDL configuration + }, + defaultTimeout = 10000 +} + +return testSettings From 158f75ca4462a8fa33d6f55e0779259b02244a2e Mon Sep 17 00:00:00 2001 From: "Oleksandr Deriabin (GitHub)" Date: Mon, 4 Sep 2017 18:53:14 +0300 Subject: [PATCH 161/681] HMI on ready values was updated with logic RC on/off --- user_modules/hmi_values.lua | 132 ++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 65 deletions(-) diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index 7b6b6e3b96..7ba0271a07 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -1,3 +1,4 @@ +local SDL = require('SDL') local module = { } --[[ Functions for Values' Creation ]] @@ -58,8 +59,7 @@ function module.getDefaultHMITable() TTS = { }, VehicleInfo = { }, Buttons = { }, - Navigation = { }, - RC = { } + Navigation = { } } -- "params" subtables contain values to be passed for creating expectations in -- initHMI_onReady() function of "connecttest"/"dummy_connecttest" file. @@ -308,63 +308,73 @@ function module.getDefaultHMITable() pinned = false } - hmi_table.RC.GetCapabilities = { - params = { - remoteControlCapability = { - climateControlCapabilities = { - { - moduleName = "Climate", - currentTemperatureAvailable = true, - fanSpeedAvailable = true, - desiredTemperatureAvailable = true, - acEnableAvailable = true, - acMaxEnableAvailable = true, - circulateAirEnableAvailable = true, - autoModeEnableAvailable = true, - dualModeEnableAvailable = true, - defrostZoneAvailable = true, - defrostZone = { - "FRONT", "REAR", "ALL", "NONE" - }, - ventilationModeAvailable = true, - ventilationMode = { - "UPPER", "LOWER", "BOTH", "NONE" + if SDL.buildOptions.remoteControl == "ON" then + hmi_table.RC = { } + hmi_table.RC.GetCapabilities = { + params = { + remoteControlCapability = { + climateControlCapabilities = { + { + moduleName = "Climate", + currentTemperatureAvailable = true, + fanSpeedAvailable = true, + desiredTemperatureAvailable = true, + acEnableAvailable = true, + acMaxEnableAvailable = true, + circulateAirEnableAvailable = true, + autoModeEnableAvailable = true, + dualModeEnableAvailable = true, + defrostZoneAvailable = true, + defrostZone = { + "FRONT", "REAR", "ALL", "NONE" + }, + ventilationModeAvailable = true, + ventilationMode = { + "UPPER", "LOWER", "BOTH", "NONE" + } } + }, + radioControlCapabilities = { + { + moduleName = "Radio", + radioEnableAvailable = true, + radioBandAvailable = true, + radioFrequencyAvailable = true, + hdChannelAvailable = true, + rdsDataAvailable = true, + availableHDsAvailable = true, + stateAvailable = true, + signalStrengthAvailable = true, + signalChangeThresholdAvailable = true + } + }, + buttonCapabilities = (function() + local buttons = { + -- climate + "AC_MAX", "AC", "RECIRCULATE", "FAN_UP", "FAN_DOWN", "TEMP_UP", "TEMP_DOWN", "DEFROST_MAX", "DEFROST", + "DEFROST_REAR", "UPPER_VENT", "LOWER_VENT", + -- radio + "VOLUME_UP", "VOLUME_DOWN", "EJECT", "SOURCE", "SHUFFLE", "REPEAT" } - }, - radioControlCapabilities = { - { - moduleName = "Radio", - radioEnableAvailable = true, - radioBandAvailable = true, - radioFrequencyAvailable = true, - hdChannelAvailable = true, - rdsDataAvailable = true, - availableHDsAvailable = true, - stateAvailable = true, - signalStrengthAvailable = true, - signalChangeThresholdAvailable = true - } - }, - buttonCapabilities = (function() - local buttons = { - -- climate - "AC_MAX", "AC", "RECIRCULATE", "FAN_UP", "FAN_DOWN", "TEMP_UP", "TEMP_DOWN", "DEFROST_MAX", "DEFROST", - "DEFROST_REAR", "UPPER_VENT", "LOWER_VENT", - -- radio - "VOLUME_UP", "VOLUME_DOWN", "EJECT", "SOURCE", "SHUFFLE", "REPEAT" - } - local out = { } - for _, button in pairs(buttons) do - table.insert(out, module.createButtonCapability(button, true, true, true)) - end - return out - end)() - } - }, - mandatory = true, - pinned = false - } + local out = { } + for _, button in pairs(buttons) do + table.insert(out, module.createButtonCapability(button, true, true, true)) + end + return out + end)() + } + }, + mandatory = true, + pinned = false + } + hmi_table.RC.IsReady = { + params = { + available = true + }, + mandatory = true, + pinned = false + } + end hmi_table.UI.IsReady = { params = { @@ -406,14 +416,6 @@ function module.getDefaultHMITable() pinned = false } - hmi_table.RC.IsReady = { - params = { - available = true - }, - mandatory = true, - pinned = false - } - hmi_table.BasicCommunication.UpdateAppList = { params = { }, mandatory = false, From b694fffb8177d97c5cac75ffdb8778be87d1268b Mon Sep 17 00:00:00 2001 From: "Oleksandr Deriabin (GitHub)" Date: Thu, 14 Sep 2017 16:40:08 +0300 Subject: [PATCH 162/681] String related common functions were refactored --- .../shared_testcases/commonFunctions.lua | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/user_modules/shared_testcases/commonFunctions.lua b/user_modules/shared_testcases/commonFunctions.lua index ad20efa7e9..b6682ba387 100644 --- a/user_modules/shared_testcases/commonFunctions.lua +++ b/user_modules/shared_testcases/commonFunctions.lua @@ -130,11 +130,6 @@ function commonFunctions:createMultipleExpectationsWaiter(test, name) return exp_waiter end -function commonFunctions:userPrint( color, message, delimeter) - delimeter = delimeter or "\n" - io.write("\27[" .. tostring(color) .. "m" .. tostring(message) .. "\27[0m", delimeter) -end - --1. Functions for String --------------------------------------------------------------------------------------------- function commonFunctions:createString(length) @@ -171,6 +166,18 @@ function commonFunctions:createArrayInteger(size, value) return temp end + +function commonFunctions:buildColoredString(color, message) + if config.color then + return "\27[" .. tostring(color) .. "m" .. tostring(message) .. "\27[0m" + end + return message +end + +function commonFunctions:userPrint( color, message, delimeter) + delimeter = delimeter or "\n" + io.write(commonFunctions:buildColoredString(color, message), delimeter) +end --------------------------------------------------------------------------------------------- From 93ce76816ccc9285015e5ae981d121efe6137cae Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Tue, 19 Sep 2017 16:42:56 +0300 Subject: [PATCH 163/681] Remove extended API test from smoke --- test_sets/smoke_tests.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/test_sets/smoke_tests.txt b/test_sets/smoke_tests.txt index 0fe3c72da5..dc2b859f65 100644 --- a/test_sets/smoke_tests.txt +++ b/test_sets/smoke_tests.txt @@ -22,4 +22,3 @@ ./test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_but_respond.lua ./test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua ./test_scripts/smoke_api.lua -./test_scripts/ATF_Expanded_smoke_test_Genivi.lua From 028cd35bdb824b36aa8cdd529954fc2c7aec0a2e Mon Sep 17 00:00:00 2001 From: ChrisB-Elektrobit Date: Fri, 22 Sep 2017 20:57:00 -0400 Subject: [PATCH 164/681] - adding ATF test scripts for Show RPC's metadata tagging feature --- test_scripts/API/ATF_Show.lua | 112 ++++++++++++++++- .../shared_testcases/commonFunctions.lua | 10 ++ .../testCasesForArrayEnumParameter.lua | 119 ++++++++++++++++++ .../testCasesForMetadataTagsParameter.lua | 88 +++++++++++++ 4 files changed, 325 insertions(+), 4 deletions(-) create mode 100644 user_modules/shared_testcases/testCasesForArrayEnumParameter.lua create mode 100644 user_modules/shared_testcases/testCasesForMetadataTagsParameter.lua diff --git a/test_scripts/API/ATF_Show.lua b/test_scripts/API/ATF_Show.lua index 6f11f3e558..c8e6c77c96 100644 --- a/test_scripts/API/ATF_Show.lua +++ b/test_scripts/API/ATF_Show.lua @@ -30,6 +30,7 @@ local enumerationParameter = require('user_modules/shared_testcases/testCasesFor local imageParameter = require('user_modules/shared_testcases/testCasesForImageParameter') local arraySoftButtonsParameter = require('user_modules/shared_testcases/testCasesForArraySoftButtonsParameter') local arrayStringParameter = require('user_modules/shared_testcases/testCasesForArrayStringParameter') +local metadataTagsParameter = require('user_modules/shared_testcases/testCasesForMetadataTagsParameter') require('user_modules/AppTypes') --------------------------------------------------------------------------------------------- @@ -89,6 +90,17 @@ function Test:createUIParameters(Request) fieldName = "mainField" .. i, fieldText = Request["mainField" .. i] } + if (Request["metadataTags"] ~= nil and + Request["metadataTags"]["mainField" .. i] ~= nil) then + if param["showStrings"][j]["fieldTypes"] == nil then + param["showStrings"][j]["fieldTypes"] = {} + end + local numTypes = #Request["metadataTags"]["mainField" .. i] + local k = 0 + for k = 1, numTypes do + param["showStrings"][j]["fieldTypes"][k] = Request["metadataTags"]["mainField" .. i][k] + end + end end end @@ -342,8 +354,15 @@ end value = "a" }, softButtons = {}, - customPresets = {} - } + customPresets = {}, + metadataTags = + { + mainField1 = {}, + mainField2 = {}, + mainField3 = {}, + mainField4 = {} + } + } self:verify_SUCCESS_Case(RequestParams) @@ -484,7 +503,42 @@ end "6" .. string499Characters, "7" .. string499Characters, "8" .. string499Characters, - } + }, + metadataTags = + { + mainField1 = + { + "mediaTitle", + "mediaArtist", + "mediaAlbum", + "mediaYear", + "mediaGenre" + }, + mainField2 = + { + "mediaTitle", + "mediaArtist", + "mediaAlbum", + "mediaYear", + "mediaGenre" + }, + mainField3 = + { + "mediaTitle", + "mediaArtist", + "mediaAlbum", + "mediaYear", + "mediaGenre" + }, + mainField4 = + { + "mediaTitle", + "mediaArtist", + "mediaAlbum", + "mediaYear", + "mediaGenre" + } + } } self:verify_SUCCESS_Case(RequestParams) @@ -596,6 +650,26 @@ end local ElementBoundary = {1, 500} arrayStringParameter:verify_Array_String_Parameter(Request, {"customPresets"}, ArrayBoundary, ElementBoundary, false) +----------------------------------------------------------------------------------------------- +--List of test cases for parameter 13: metadataTags, type=MetadataTags, mandatory=false +----------------------------------------------------------------------------------------------- +--List of test cases for metadataTags type parameter: + --1. IsMissed + --2. IsEmpty + --3. IsWrongType + --4. IsLowerBound + --5. IsUpperBound + --6. IsOutLowerBound + --7. IsOutUpperBound +----------------------------------------------------------------------------------------------- + + local Request = Test:createRequest() + Request.mainField1 = "mainField1" + Request.mainField2 = "mainField2" + Request.mainField3 = "mainField3" + Request.mainField4 = "mainField4" + + metadataTagsParameter:verify_MetadataTags_Parameter(Request, {"metadataTags"}, false) ---------------------------------------------------------------------------------------------- @@ -1712,9 +1786,39 @@ end --End Test case PositiveRequestCheck --end +]===]-- + --Begin Test case Show_MetadataTags_withNoFieldsProvided + --Description: metadataTag parameter is provided, but no corresponding "mainField" is provided -> the request will receive a WARNINGS result code -SpecialRequestChecks() + function Test:Show_MetadataTags_withNoFieldsProvided() + + --mobile side: sending the request + + local Request = { + metadataTags = { + mainField1 = {"mediaTitle"} + } + } + local cid = self.mobileSession:SendRPC("Show", Request) + + --hmi side: expect the request + local UIParams = self:createUIParameters(Request) + EXPECT_HMICALL("UI.Show", UIParams) + :Times(1) + + :Do(function(_,data) + --hmi side: sending the response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + --mobile side: expect response + EXPECT_RESPONSE(cid, { success = true, resultCode = "WARNINGS"}) + + end + --End Test case Show_MetadataTags_withNoFieldsProvided + +SpecialRequestChecks() ----------------------------------------------------------------------------------------------- -------------------------------------------TEST BLOCK III-------------------------------------- diff --git a/user_modules/shared_testcases/commonFunctions.lua b/user_modules/shared_testcases/commonFunctions.lua index b6682ba387..f08ce897a6 100644 --- a/user_modules/shared_testcases/commonFunctions.lua +++ b/user_modules/shared_testcases/commonFunctions.lua @@ -167,6 +167,16 @@ function commonFunctions:createArrayInteger(size, value) end +function commonFunctions:createArrayEnum(size, value) + + local temp = {} + for i = 1, size do + table.insert(temp, value) + end + return temp + +end + function commonFunctions:buildColoredString(color, message) if config.color then return "\27[" .. tostring(color) .. "m" .. tostring(message) .. "\27[0m" diff --git a/user_modules/shared_testcases/testCasesForArrayEnumParameter.lua b/user_modules/shared_testcases/testCasesForArrayEnumParameter.lua new file mode 100644 index 0000000000..b82707b4d9 --- /dev/null +++ b/user_modules/shared_testcases/testCasesForArrayEnumParameter.lua @@ -0,0 +1,119 @@ +--This script contains all test cases for a parameter consisting of an array of enums +--How to use: + --1. local arrayEnumParameter = require('user_modules/shared_testcases/testCasesForArrayEnumParameter') + --2. arrayEnumParameter:verify_Array_Enum_Parameter(Request, Parameter, Boundary, ElementExistentValues, Mandatory) +--------------------------------------------------------------------------------------------- + +local testCasesForArrayEnumParameter = {} +local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local enumerationParameter = require('user_modules/shared_testcases/testCasesForEnumerationParameter') + + +--------------------------------------------------------------------------------------------- +--Test cases to verify Array Enum Parameter +--------------------------------------------------------------------------------------------- +--List of test cases for Enum type Parameter: + --1. IsMissed + --2. IsLowerBound + --3. IsUpperBound + --4. OutLowerBound/IsEmpty + --5. OutUpperBound + --6. IsWrongType + ------------------------ + --7. Check an element of array Enum + + + +--Verify array only: + --1. IsMissed + --2. IsLowerBound + --3. IsUpperBound + --4. OutLowerBound/IsEmpty + --5. OutUpperBound + --6. IsWrongType +function testCasesForArrayEnumParameter:verify_Array_Enum_Parameter_Only(Request, Parameter, Boundary, ElementExistentValues, Mandatory) + + + --Print new line to separate new test cases group + commonFunctions:newTestCasesGroup(Parameter) + + --1. IsMissed + local resultCode + if Mandatory == true then + resultCode = "INVALID_DATA" + else + resultCode = "SUCCESS" + end + + + commonFunctions:TestCase(self, Request, Parameter, "IsMissed", nil, resultCode) + + local defaultEnumValue = ElementExistentValues[i] + + --2. IsLowerBound + local verification = "IsLowerBound" + if Boundary[1] > 0 then + verification = "IsLowerBound_IsEmpty" + local value = commonFunctions:createArrayEnum(Boundary[1], defaultEnumValue) + commonFunctions:TestCase(self, Request, Parameter, verification, value, "SUCCESS") + else + -- Boundary = 0 ==> Is covered by _element_IsMissed_ + end + + + + --3. IsUpperBound + local value = commonFunctions:createArrayEnum(Boundary[2], defaultEnumValue) + commonFunctions:TestCase(self, Request, Parameter, "IsUpperBound", value, "SUCCESS") + + --4. IsOutLowerBound/IsEmpty + if Boundary[1] ==1 then + local value = commonFunctions:createArrayEnum(Boundary[1]-1, defaultEnumValue) + commonFunctions:TestCase(self, Request, Parameter, "IsOutLowerBound_IsEmpty", value, "INVALID_DATA") + + elseif Boundary[1] >1 then + local value = commonFunctions:createArrayEnum(Boundary[1]-1, defaultEnumValue) + commonFunctions:TestCase(self, Request, Parameter, "IsOutLowerBound", value, "INVALID_DATA") + + commonFunctions:TestCase(self, Request, Parameter, "IsEmpty", {}, "INVALID_DATA") + else + --minsize = 0, no check out lower bound + end + + --5. IsOutUpperBound + local value = commonFunctions:createArrayEnum(Boundary[2]+1, defaultEnumValue) + commonFunctions:TestCase(self, Request, Parameter, "IsOutUpperBound", value, "INVALID_DATA") + + --6. IsWrongType + commonFunctions:TestCase(self, Request, Parameter, "IsWrongDataType", 123, "INVALID_DATA") + + +end +--------------------------------------------------------------------------------------------- + + +--Contains all test cases +function testCasesForArrayEnumParameter:verify_Array_Enum_Parameter(Request, Parameter, Boundary, ElementExistentValues, Mandatory) + + --Verify array only + testCasesForArrayEnumParameter:verify_Array_Enum_Parameter_Only(Request, Parameter, Boundary, ElementExistentValues, Mandatory) + + + --Verify an element in array + local TestingRequest = commonFunctions:cloneTable(Request) + commonFunctions:setValueForParameter(TestingRequest, Parameter, {}) + + local parameter_arrayElement = commonFunctions:BuildChildParameter(Parameter, 1)--ElementExistentValues[1]) + + --Verify an element in a Enum array. + --2. IsWrongType + --3. IsExistentValues + --4. IsNonExistentValue + --5. IsEmpty + enumerationParameter:verify_Enum_String_Parameter(TestingRequest, parameter_arrayElement, ElementExistentValues, false) + + +end + +return testCasesForArrayEnumParameter +--------------------------------------------------------------------------------------------- diff --git a/user_modules/shared_testcases/testCasesForMetadataTagsParameter.lua b/user_modules/shared_testcases/testCasesForMetadataTagsParameter.lua new file mode 100644 index 0000000000..4856899421 --- /dev/null +++ b/user_modules/shared_testcases/testCasesForMetadataTagsParameter.lua @@ -0,0 +1,88 @@ +--This script contains all test cases to verify MetadataTags parameter +--How to use: + --1. local MetadataTagsParameter = require('user_modules/shared_testcases/testCasesForMetadataTagsParameter') + --2. MetadataTagsParameter:verify_MetadataTags_Parameter(Request, Parameter, Mandatory) +--------------------------------------------------------------------------------------------- + + +local testCasesForMetadataTagsParameter= {} + +local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local arrayEnumerationParameter = require('user_modules/shared_testcases/testCasesForArrayEnumParameter') + + + + +--------------------------------------------------------------------------------------------- +--Test cases to verify a MetadataTags parameter +--------------------------------------------------------------------------------------------- + --1. IsMissed + --2. IsWrongDataType + --3. mainField1: type="MetadataType", minsize="0" maxsize="5" array="true" mandatory="false" + + +function testCasesForMetadataTagsParameter:verify_MetadataTags_Parameter(Request, Parameter, Mandatory) + + --Print new line to separate new test cases group + commonFunctions:newTestCasesGroup(Parameter) + + --1. IsMissed + local resultCode = "INVALID_DATA" + if Mandatory == false then + resultCode = "SUCCESS" + end + + commonFunctions:TestCase(self, Request, Parameter, "IsMissed", nil, resultCode) + + + --2. IsEmpty +-- commonFunctions:TestCase(self, Request, Parameter, "IsEmpty", {}, "INVALID_DATA") + + + --2. IsWrongDataType + commonFunctions:TestCase(self, Request, Parameter, "IsWrongDataType", 123, "INVALID_DATA") + + --Check parameters in side MetadataTags: + + --3. mainField1: type="MetadataType", minsize="0", maxsize="5", array="true", mandatory="false" + local Boundary = {0, 5} + local ExistentValues = { + "mediaTitle", + "mediaArtist", + "mediaAlbum", + "mediaYear", + "mediaGenre", + "mediaStation", + "rating", + "currentTemperature", + "maximumTemperature", + "minimumTemperature", + "weatherTerm", + "humidity" + } + local Request2 = commonFunctions:cloneTable(Request) + local metadataTags = { + mainField1 = {"rating"}, + mainField2 = {"rating"}, + mainField3 = {"rating"}, + mainField4 = {"rating"}, + } + commonFunctions:setValueForParameter(Request2, Parameter, metadataTags) + + local parameter_mainField1 = commonFunctions:BuildChildParameter(Parameter, "mainField1") + arrayEnumerationParameter:verify_Array_Enum_Parameter(Request2, parameter_mainField1, Boundary, ExistentValues, false) + + local parameter_mainField2 = commonFunctions:BuildChildParameter(Parameter, "mainField2") + arrayEnumerationParameter:verify_Array_Enum_Parameter(Request2, parameter_mainField2, Boundary, ExistentValues, false) + + local parameter_mainField3 = commonFunctions:BuildChildParameter(Parameter, "mainField3") + arrayEnumerationParameter:verify_Array_Enum_Parameter(Request2, parameter_mainField3, Boundary, ExistentValues, false) + + local parameter_mainField4 = commonFunctions:BuildChildParameter(Parameter, "mainField4") + arrayEnumerationParameter:verify_Array_Enum_Parameter(Request2, parameter_mainField4, Boundary, ExistentValues, false) + + +end + + +return testCasesForMetadataTagsParameter From 9d013fe5b41ee2477e654e247ededfaf78b1e130 Mon Sep 17 00:00:00 2001 From: ChrisB-Elektrobit Date: Mon, 25 Sep 2017 15:18:21 -0400 Subject: [PATCH 165/681] - fixing a comment ending tag that was accidentally left in the last commit --- test_scripts/API/ATF_Show.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/test_scripts/API/ATF_Show.lua b/test_scripts/API/ATF_Show.lua index c8e6c77c96..ae5e045e4b 100644 --- a/test_scripts/API/ATF_Show.lua +++ b/test_scripts/API/ATF_Show.lua @@ -1786,7 +1786,6 @@ end --End Test case PositiveRequestCheck --end -]===]-- --Begin Test case Show_MetadataTags_withNoFieldsProvided --Description: metadataTag parameter is provided, but no corresponding "mainField" is provided -> the request will receive a WARNINGS result code From 5b7c8a23563e1b023d4e5a21171180546a214a0c Mon Sep 17 00:00:00 2001 From: ChrisB-Elektrobit Date: Wed, 27 Sep 2017 16:30:24 -0400 Subject: [PATCH 166/681] - fixing some mixed tabs and spaces in the testcase files --- test_scripts/API/ATF_Show.lua | 139 +++++++++--------- .../testCasesForArrayEnumParameter.lua | 4 +- .../testCasesForMetadataTagsParameter.lua | 70 ++++----- 3 files changed, 106 insertions(+), 107 deletions(-) diff --git a/test_scripts/API/ATF_Show.lua b/test_scripts/API/ATF_Show.lua index ae5e045e4b..a99405a5c5 100644 --- a/test_scripts/API/ATF_Show.lua +++ b/test_scripts/API/ATF_Show.lua @@ -90,17 +90,17 @@ function Test:createUIParameters(Request) fieldName = "mainField" .. i, fieldText = Request["mainField" .. i] } - if (Request["metadataTags"] ~= nil and - Request["metadataTags"]["mainField" .. i] ~= nil) then - if param["showStrings"][j]["fieldTypes"] == nil then - param["showStrings"][j]["fieldTypes"] = {} - end - local numTypes = #Request["metadataTags"]["mainField" .. i] - local k = 0 - for k = 1, numTypes do - param["showStrings"][j]["fieldTypes"][k] = Request["metadataTags"]["mainField" .. i][k] - end - end + if (Request["metadataTags"] ~= nil and + Request["metadataTags"]["mainField" .. i] ~= nil) then + if param["showStrings"][j]["fieldTypes"] == nil then + param["showStrings"][j]["fieldTypes"] = {} + end + local numTypes = #Request["metadataTags"]["mainField" .. i] + local k = 0 + for k = 1, numTypes do + param["showStrings"][j]["fieldTypes"][k] = Request["metadataTags"]["mainField" .. i][k] + end + end end end @@ -355,14 +355,14 @@ end }, softButtons = {}, customPresets = {}, - metadataTags = - { - mainField1 = {}, - mainField2 = {}, - mainField3 = {}, - mainField4 = {} - } - } + metadataTags = + { + mainField1 = {}, + mainField2 = {}, + mainField3 = {}, + mainField4 = {} + } + } self:verify_SUCCESS_Case(RequestParams) @@ -504,41 +504,41 @@ end "7" .. string499Characters, "8" .. string499Characters, }, - metadataTags = - { - mainField1 = - { - "mediaTitle", - "mediaArtist", - "mediaAlbum", - "mediaYear", - "mediaGenre" - }, - mainField2 = - { - "mediaTitle", - "mediaArtist", - "mediaAlbum", - "mediaYear", - "mediaGenre" - }, - mainField3 = - { - "mediaTitle", - "mediaArtist", - "mediaAlbum", - "mediaYear", - "mediaGenre" - }, - mainField4 = - { - "mediaTitle", - "mediaArtist", - "mediaAlbum", - "mediaYear", - "mediaGenre" - } - } + metadataTags = + { + mainField1 = + { + "mediaTitle", + "mediaArtist", + "mediaAlbum", + "mediaYear", + "mediaGenre" + }, + mainField2 = + { + "mediaTitle", + "mediaArtist", + "mediaAlbum", + "mediaYear", + "mediaGenre" + }, + mainField3 = + { + "mediaTitle", + "mediaArtist", + "mediaAlbum", + "mediaYear", + "mediaGenre" + }, + mainField4 = + { + "mediaTitle", + "mediaArtist", + "mediaAlbum", + "mediaYear", + "mediaGenre" + } + } } self:verify_SUCCESS_Case(RequestParams) @@ -664,12 +664,12 @@ end ----------------------------------------------------------------------------------------------- local Request = Test:createRequest() - Request.mainField1 = "mainField1" - Request.mainField2 = "mainField2" - Request.mainField3 = "mainField3" - Request.mainField4 = "mainField4" + Request.mainField1 = "mainField1" + Request.mainField2 = "mainField2" + Request.mainField3 = "mainField3" + Request.mainField4 = "mainField4" - metadataTagsParameter:verify_MetadataTags_Parameter(Request, {"metadataTags"}, false) + metadataTagsParameter:verify_MetadataTags_Parameter(Request, {"metadataTags"}, false) ---------------------------------------------------------------------------------------------- @@ -1786,7 +1786,7 @@ end --End Test case PositiveRequestCheck --end - --Begin Test case Show_MetadataTags_withNoFieldsProvided + --Begin Test case Show_MetadataTags_withNoFieldsProvided --Description: metadataTag parameter is provided, but no corresponding "mainField" is provided -> the request will receive a WARNINGS result code function Test:Show_MetadataTags_withNoFieldsProvided() @@ -1794,26 +1794,25 @@ end --mobile side: sending the request local Request = { - metadataTags = { - mainField1 = {"mediaTitle"} - } - } + metadataTags = { + mainField1 = {"mediaTitle"} + } + } local cid = self.mobileSession:SendRPC("Show", Request) --hmi side: expect the request local UIParams = self:createUIParameters(Request) EXPECT_HMICALL("UI.Show", UIParams) - :Times(1) + :Times(1) - :Do(function(_,data) - --hmi side: sending the response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) + :Do(function(_,data) + --hmi side: sending the response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) --mobile side: expect response EXPECT_RESPONSE(cid, { success = true, resultCode = "WARNINGS"}) - end --End Test case Show_MetadataTags_withNoFieldsProvided diff --git a/user_modules/shared_testcases/testCasesForArrayEnumParameter.lua b/user_modules/shared_testcases/testCasesForArrayEnumParameter.lua index b82707b4d9..3b3c6696fd 100644 --- a/user_modules/shared_testcases/testCasesForArrayEnumParameter.lua +++ b/user_modules/shared_testcases/testCasesForArrayEnumParameter.lua @@ -48,7 +48,7 @@ function testCasesForArrayEnumParameter:verify_Array_Enum_Parameter_Only(Request commonFunctions:TestCase(self, Request, Parameter, "IsMissed", nil, resultCode) - local defaultEnumValue = ElementExistentValues[i] + local defaultEnumValue = ElementExistentValues[i] --2. IsLowerBound local verification = "IsLowerBound" @@ -100,7 +100,7 @@ function testCasesForArrayEnumParameter:verify_Array_Enum_Parameter(Request, Par --Verify an element in array - local TestingRequest = commonFunctions:cloneTable(Request) + local TestingRequest = commonFunctions:cloneTable(Request) commonFunctions:setValueForParameter(TestingRequest, Parameter, {}) local parameter_arrayElement = commonFunctions:BuildChildParameter(Parameter, 1)--ElementExistentValues[1]) diff --git a/user_modules/shared_testcases/testCasesForMetadataTagsParameter.lua b/user_modules/shared_testcases/testCasesForMetadataTagsParameter.lua index 4856899421..70663467eb 100644 --- a/user_modules/shared_testcases/testCasesForMetadataTagsParameter.lua +++ b/user_modules/shared_testcases/testCasesForMetadataTagsParameter.lua @@ -45,41 +45,41 @@ function testCasesForMetadataTagsParameter:verify_MetadataTags_Parameter(Request --Check parameters in side MetadataTags: --3. mainField1: type="MetadataType", minsize="0", maxsize="5", array="true", mandatory="false" - local Boundary = {0, 5} - local ExistentValues = { - "mediaTitle", - "mediaArtist", - "mediaAlbum", - "mediaYear", - "mediaGenre", - "mediaStation", - "rating", - "currentTemperature", - "maximumTemperature", - "minimumTemperature", - "weatherTerm", - "humidity" - } - local Request2 = commonFunctions:cloneTable(Request) - local metadataTags = { - mainField1 = {"rating"}, - mainField2 = {"rating"}, - mainField3 = {"rating"}, - mainField4 = {"rating"}, - } - commonFunctions:setValueForParameter(Request2, Parameter, metadataTags) - - local parameter_mainField1 = commonFunctions:BuildChildParameter(Parameter, "mainField1") - arrayEnumerationParameter:verify_Array_Enum_Parameter(Request2, parameter_mainField1, Boundary, ExistentValues, false) - - local parameter_mainField2 = commonFunctions:BuildChildParameter(Parameter, "mainField2") - arrayEnumerationParameter:verify_Array_Enum_Parameter(Request2, parameter_mainField2, Boundary, ExistentValues, false) - - local parameter_mainField3 = commonFunctions:BuildChildParameter(Parameter, "mainField3") - arrayEnumerationParameter:verify_Array_Enum_Parameter(Request2, parameter_mainField3, Boundary, ExistentValues, false) - - local parameter_mainField4 = commonFunctions:BuildChildParameter(Parameter, "mainField4") - arrayEnumerationParameter:verify_Array_Enum_Parameter(Request2, parameter_mainField4, Boundary, ExistentValues, false) + local Boundary = {0, 5} + local ExistentValues = { + "mediaTitle", + "mediaArtist", + "mediaAlbum", + "mediaYear", + "mediaGenre", + "mediaStation", + "rating", + "currentTemperature", + "maximumTemperature", + "minimumTemperature", + "weatherTerm", + "humidity" + } + local Request2 = commonFunctions:cloneTable(Request) + local metadataTags = { + mainField1 = {"rating"}, + mainField2 = {"rating"}, + mainField3 = {"rating"}, + mainField4 = {"rating"}, + } + commonFunctions:setValueForParameter(Request2, Parameter, metadataTags) + + local parameter_mainField1 = commonFunctions:BuildChildParameter(Parameter, "mainField1") + arrayEnumerationParameter:verify_Array_Enum_Parameter(Request2, parameter_mainField1, Boundary, ExistentValues, false) + + local parameter_mainField2 = commonFunctions:BuildChildParameter(Parameter, "mainField2") + arrayEnumerationParameter:verify_Array_Enum_Parameter(Request2, parameter_mainField2, Boundary, ExistentValues, false) + + local parameter_mainField3 = commonFunctions:BuildChildParameter(Parameter, "mainField3") + arrayEnumerationParameter:verify_Array_Enum_Parameter(Request2, parameter_mainField3, Boundary, ExistentValues, false) + + local parameter_mainField4 = commonFunctions:BuildChildParameter(Parameter, "mainField4") + arrayEnumerationParameter:verify_Array_Enum_Parameter(Request2, parameter_mainField4, Boundary, ExistentValues, false) end From e7bfed767aea8ef717224da588f6f9ea89df6d95 Mon Sep 17 00:00:00 2001 From: Alexandr Deriabin Date: Mon, 2 Oct 2017 11:33:14 +0300 Subject: [PATCH 167/681] Folder for check was changed --- tools/lua_style_and_check.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/lua_style_and_check.sh b/tools/lua_style_and_check.sh index 59bb781900..fd50816696 100755 --- a/tools/lua_style_and_check.sh +++ b/tools/lua_style_and_check.sh @@ -26,7 +26,7 @@ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - + TEXT_DEFAULT="\\033[0;39m" TEXT_INFO="\\033[1;32m" TEXT_ERROR="\\033[1;31m" @@ -36,7 +36,7 @@ EXIT_WHITESPACES_ERRORS=1 EXIT_LUACHECK_NOT_FOUND=2 EXIT_LUA_SCRIPT_HAS_ISSUES=3 -GIT_DIFF_CHECK_LIST="/test_scripts/Polices" +GIT_DIFF_CHECK_LIST="/test_scripts" # Check for odd whitespace @@ -59,8 +59,8 @@ LUA_FILES=$(git diff --cached --name-only --diff-filter=ACM -- .$GIT_DIFF_CHECK_ echo -e $TEXT_INFO "Auto-update lua style with lua-beautifier" $TEXT_DEFAULT if [ -n "$LUA_FILES" ]; then - for lua_file in $LUA_FILES; - do + for lua_file in $LUA_FILES; + do ./tools/lua-beautifier/beautifier.sh $lua_file done git add $LUA_FILES @@ -72,7 +72,7 @@ echo -e $TEXT_INFO "PASSED" $TEXT_DEFAULT echo -e $TEXT_INFO "Checking lua code with luacheck" $TEXT_DEFAULT -LUA_CHECK=$(command -v luacheck) +LUA_CHECK=$(command -v luacheck) if [ ! -x "$LUA_CHECK" ]; then echo -e $TEXT_ERROR "Error: luacheck executable not found." $TEXT_DEFAULT From 8116d7c8703e760787199a7a52a85b6b0b82fd74 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 11 Oct 2017 13:55:04 +0300 Subject: [PATCH 168/681] Fix EXPECT_HMIRESPONSE issue with expected result validation --- user_modules/dummy_connecttest.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/user_modules/dummy_connecttest.lua b/user_modules/dummy_connecttest.lua index 8cd9c3864b..1b1da5a0ae 100644 --- a/user_modules/dummy_connecttest.lua +++ b/user_modules/dummy_connecttest.lua @@ -64,8 +64,6 @@ function module.hmiConnection:EXPECT_HMIRESPONSE(id, args) end if results_args2 and results_args2.method then results_args2 = table.removeKey(results_args2, 'method') - elseif results_args2 and results_args2.data.method then - results_args2 = table.removeKey(results_args2.data, 'method') end if func_name == nil and type(data.result) == 'table' then From 5d4a24c9ef124500af24ca0fc65605a2127d369b Mon Sep 17 00:00:00 2001 From: AKalinich-Luxoft Date: Thu, 12 Oct 2017 10:55:06 +0300 Subject: [PATCH 169/681] Add new common module for smoke API testing --- test_scripts/Smoke/commonSmokeApi.lua | 238 ++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 test_scripts/Smoke/commonSmokeApi.lua diff --git a/test_scripts/Smoke/commonSmokeApi.lua b/test_scripts/Smoke/commonSmokeApi.lua new file mode 100644 index 0000000000..e0302cbd1b --- /dev/null +++ b/test_scripts/Smoke/commonSmokeApi.lua @@ -0,0 +1,238 @@ +--------------------------------------------------------------------------------------------------- +-- Smoke API common module +--------------------------------------------------------------------------------------------------- + +--[[ General configuration parameters ]] +config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 + +--[[ Required Shared libraries ]] +local mobile_session = require("mobile_session") +local json = require("modules/json") + +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') + +-- local mobile_api_loader = require("modules/api_loader") +-- local mobile_api = mobile_api_loader.init("data/MOBILE_API.xml") +-- local mobile_api_schema = mobile_api.interface["Ford Sync RAPI"] + +-- local hmi_api_loader = require("modules/api_loader") +-- local hmi_api = hmi_api_loader.init("data/HMI_API.xml") +-- local hmi_api_schema = hmi_api.interface["Common"] + +--[[ Local Variables ]] +local ptu_table = {} +local hmiAppIds = {} + +local commonSmokeApi = {} + +commonSmokeApi.timeout = 5000 +commonSmokeApi.minTimeout = 500 + +local function allowSDL(self) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", + { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) +end + +local function jsonFileToTable(pFileName) + local f = io.open(pFileName, "r") + local content = f:read("*all") + f:close() + return json.decode(content) +end + +local function checkIfPTSIsSentAsBinary(bin_data) + if not (bin_data ~= nil and string.len(bin_data) > 0) then + commonFunctions:userPrint(31, "PTS was not sent to Mobile in payload of OnSystemRequest") + end +end + +local function getPTUFromPTS(tbl) + tbl.policy_table.consumer_friendly_messages.messages = nil + tbl.policy_table.device_data = nil + tbl.policy_table.module_meta = nil + tbl.policy_table.usage_and_error_counts = nil + tbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + tbl.policy_table.module_config.preloaded_pt = nil + tbl.policy_table.module_config.preloaded_date = nil +end + +local function ptu(self, id, pUpdateFunction) + local function getAppsCount() + local count = 0 + for _ in pairs(hmiAppIds) do + count = count + 1 + end + return count + end + + local policy_file_name = "PolicyTableUpdate" + local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + local ptu_file_name = os.tmpname() + local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) + EXPECT_HMIRESPONSE(requestId) + :Do(function() + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + { requestType = "PROPRIETARY", fileName = pts_file_name }) + getPTUFromPTS(ptu_table) + if pUpdateFunction then + pUpdateFunction(ptu_table) + end + local function tableToJsonFile(tbl, file_name) + local f = io.open(file_name, "w") + f:write(json.encode(tbl)) + f:close() + end + tableToJsonFile(ptu_table, ptu_file_name) + + local event = events.Event() + event.matches = function(self, e) return self == e end + EXPECT_EVENT(event, "PTU event") + :Timeout(11000) + + for id = 1, getAppsCount() do + local mobileSession = commonSmokeApi.getMobileSession(id, self) + mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :Do(function(_, d2) + print("App ".. id .. " was used for PTU") + RAISE_EVENT(event, event, "PTU event") + checkIfPTSIsSentAsBinary(d2.binaryData) + local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, d3) + self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", + { policyfile = policy_file_path .. "/" .. policy_file_name }) + end) + mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + :Do(function() os.remove(ptu_file_name) end) + end) + :Times(AtMost(1)) + end + end) +end + +--[[Module functions]] + +function commonSmokeApi.preconditions() + commonFunctions:SDLForceStop() + commonSteps:DeletePolicyTable() + commonSteps:DeleteLogsFiles() +end + +function commonSmokeApi.getDeviceMAC() + return config.deviceMAC +end + +function commonSmokeApi.getPathToSDL() + return config.pathToSDL +end + +function commonSmokeApi.getMobileAppId(pAppId) + if not pAppId then pAppId = 1 end + return config["application" .. pAppId].registerAppInterfaceParams.appID +end + +function commonSmokeApi.getSelfAndParams(...) + local out = { } + local selfIdx = nil + for i,v in pairs({...}) do + if type(v) == "table" and v.isTest then + table.insert(out, v) + selfIdx = i + break + end + end + local idx = 2 + for i = 1, table.maxn({...}) do + if i ~= selfIdx then + out[idx] = ({...})[i] + idx = idx + 1 + end + end + return table.unpack(out, 1, table.maxn(out)) +end + +function commonSmokeApi.getMobileSession(pAppId, self) + self, pAppId = commonSmokeApi.getSelfAndParams(pAppId, self) + if not pAppId then pAppId = 1 end + return self["mobileSession" .. pAppId] +end + +function commonSmokeApi.activateApp(pAppId, self) + self, pAppId = commonSmokeApi.getSelfAndParams(pAppId, self) + if not pAppId then pAppId = 1 end + local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + local mobSession = commonSmokeApi.getMobileSession(pAppId, self) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + EXPECT_HMIRESPONSE(requestId) + mobSession:ExpectNotification("OnHMIStatus", + {hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN"}) + commonTestCases:DelayedExp(commonSmokeApi.minTimeout) +end + +function commonSmokeApi.start(pHMIParams, self) + self, pHMIParams = commonSmokeApi.getSelfAndParams(pHMIParams, self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady(pHMIParams) + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + self:connectMobile() + :Do(function() + commonFunctions:userPrint(35, "Mobile connected") + allowSDL(self) + end) + end) + end) + end) +end + +function commonSmokeApi.registerApplicationWithPTU(pAppId, pUpdateFunction, self) + self, pAppId, pUpdateFunction = commonSmokeApi.getSelfAndParams(pAppId, pUpdateFunction, self) + if not pAppId then pAppId = 1 end + self["mobileSession" .. pAppId] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. pAppId]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. pAppId]:SendRPC("RegisterAppInterface", + config["application" .. pAppId].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = d1.params.application.appID + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + {status = "UPDATE_NEEDED"}, {status = "UPDATING"}, {status = "UP_TO_DATE" }) + :Times(3) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :Do(function(_, d2) + self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptu_table = jsonFileToTable(d2.params.file) + ptu(self, pAppId, pUpdateFunction) + end) + end) + self["mobileSession" .. pAppId]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. pAppId]:ExpectNotification("OnHMIStatus", + {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) + :Times(1) + self["mobileSession" .. pAppId]:ExpectNotification("OnPermissionsChange") + :Times(AtLeast(1)) -- todo: issue with SDL --> notification is sent twice + end) + end) +end + +function commonSmokeApi.postconditions() + StopSDL() +end + +return commonSmokeApi + + From bbb03717cba458ef97a10c0e2d0677aa1e7216b6 Mon Sep 17 00:00:00 2001 From: AKalinich-Luxoft Date: Thu, 12 Oct 2017 10:55:35 +0300 Subject: [PATCH 170/681] Add SetGlobalProperties test script for testing happy path --- ...tGlobalProperties_PositiveCase_SUCCESS.lua | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..d2074ee29f --- /dev/null +++ b/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua @@ -0,0 +1,136 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: SetGlobalProperties +-- Item: Happy path +-- +-- Requirement summary: +-- [SetGlobalProperties] SUCCESS on TTS.SetGlobalProperties and UI.SetGlobalProperties +-- +-- Description: +-- In case mobile application sends valid SetGlobalproperties_request with "timeoutPrompt" +-- and/or "helpPrompt" and at least one other valid parameter, SDL must transfer from mobile +-- app to HMI the both UI.SetGlobalProperties and TTS.SetGlobalProperties. On getting "SUCCESS" +-- result code from the both HMI-portions, SDL must transfer "resutCode:SUCCESS", success:"true" +-- to mobile application. + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and on SDL +-- c. appID is in Background, Full or Limited HMI level + +-- Steps: +-- appID requests SetGlobalproperties with timeoutPrompt, helpPrompt and other valid parameters + +-- Expected: + +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if TTS interface is available on HMI +-- SDL checks if SetGlobalproperties is allowed by Policies +-- SDL checks if all parameters is allowed by Policies +-- SDL transfers the UI part of request with allowed parameters to HMI +-- SDL transfers the TTS part of request with allowed parameters to HMI +-- SDL receives UI and TTS part of response from HMI with "SUCCESS" result code +-- SDL transfers response to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmokeApi = require('test_scripts/Smoke/commonSmokeApi') + +--[[ Local Variables ]] +local requestParams = { + helpPrompt = { + { + text = "Help prompt", + type = "TEXT" + } + }, + timeoutPrompt = { + { + text = "Timeout prompt", + type = "TEXT" + } + }, + vrHelpTitle = "VR help title", + vrHelp = { + { + position = 1, + image = { + value = "icon.png", + imageType = "DYNAMIC" + }, + text = "VR help item" + } + }, + menuTitle = "Menu Title", + menuIcon = { + value = "icon.png", + imageType = "DYNAMIC" + }, + keyboardProperties = { + keyboardLayout = "QWERTY", + keypressMode = "SINGLE_KEYPRESS", + limitedCharacterList = {"a"}, + language = "EN-US", + autoCompleteText = "Daemon, Freedom" + } +} + +--[[ Local Functions ]] +local function put_file(fileName, self) + local cid = self.mobileSession1:SendRPC("PutFile", { + syncFileName = fileName, + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false}, + "files/icon.png") + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +local function setGlobalProperties(params, self) + local cid = self.mobileSession1:SendRPC("SetGlobalProperties", params) + + local deviceID = commonSmokeApi.getDeviceMAC() + params.vrHelp[1].image.value = commonSmokeApi.getPathToSDL() .. "storage/" + .. commonSmokeApi.getMobileAppId() .. "_" .. deviceID .. "/icon.png" + params.menuIcon.value = params.vrHelp[1].image.value + + EXPECT_HMICALL("TTS.SetGlobalProperties", { + timeoutPrompt = params.timeoutPrompt, + helpPrompt = params.helpPrompt + }) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + EXPECT_HMICALL("UI.SetGlobalProperties", { + vrHelpTitle = params.vrHelpTitle, + vrHelp = params.vrHelp, + menuTitle = params.menuTitle, + menuIcon = params.menuIcon, + keyboardProperties = params.keyboardProperties + }) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + + self.mobileSession1:ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmokeApi.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmokeApi.start) +runner.Step("RAI, PTU", commonSmokeApi.registerApplicationWithPTU) +runner.Step("Activate App", commonSmokeApi.activateApp) +runner.Step("Upload icon file", put_file, {"icon.png"}) + +runner.Title("Test") +runner.Step("SetGlobalProperties Positive Case", setGlobalProperties, {requestParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmokeApi.postconditions) From 5320c5539bfe24a781724ca9cf32e4ea14839897 Mon Sep 17 00:00:00 2001 From: AKalinich-Luxoft Date: Thu, 12 Oct 2017 13:46:26 +0300 Subject: [PATCH 171/681] Fix after review comments --- ...tGlobalProperties_PositiveCase_SUCCESS.lua | 67 +++++++++++-------- test_scripts/Smoke/commonSmokeApi.lua | 13 +++- 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua index d2074ee29f..669f386ed5 100644 --- a/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua @@ -39,6 +39,16 @@ local runner = require('user_modules/script_runner') local commonSmokeApi = require('test_scripts/Smoke/commonSmokeApi') --[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + local requestParams = { helpPrompt = { { @@ -77,41 +87,40 @@ local requestParams = { } } ---[[ Local Functions ]] -local function put_file(fileName, self) - local cid = self.mobileSession1:SendRPC("PutFile", { - syncFileName = fileName, - fileType = "GRAPHIC_PNG", - persistentFile = false, - systemFile = false}, - "files/icon.png") - - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) -end +local responseUiParams = { + vrHelpTitle = requestParams.vrHelpTitle, + vrHelp = requestParams.vrHelp, + menuTitle = requestParams.menuTitle, + menuIcon = requestParams.menuIcon, + keyboardProperties = requestParams.keyboardProperties +} +local responseTtsParams = { + timeoutPrompt = requestParams.timeoutPrompt, + helpPrompt = requestParams.helpPrompt +} + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams, + responseTtsParams = responseTtsParams +} + +--[[ Local Functions ]] local function setGlobalProperties(params, self) - local cid = self.mobileSession1:SendRPC("SetGlobalProperties", params) + local cid = self.mobileSession1:SendRPC("SetGlobalProperties", params.requestParams) - local deviceID = commonSmokeApi.getDeviceMAC() - params.vrHelp[1].image.value = commonSmokeApi.getPathToSDL() .. "storage/" - .. commonSmokeApi.getMobileAppId() .. "_" .. deviceID .. "/icon.png" - params.menuIcon.value = params.vrHelp[1].image.value + params.responseUiParams.vrHelp[1].image.value = commonSmokeApi.getPathToSDL() + .. "storage/" .. commonSmokeApi.getMobileAppId() .. "_" + .. commonSmokeApi.getDeviceMAC() .. "/icon.png" + params.responseUiParams.menuIcon.value = params.responseUiParams.vrHelp[1].image.value - EXPECT_HMICALL("TTS.SetGlobalProperties", { - timeoutPrompt = params.timeoutPrompt, - helpPrompt = params.helpPrompt - }) + EXPECT_HMICALL("UI.SetGlobalProperties", params.responseUiParams) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) - EXPECT_HMICALL("UI.SetGlobalProperties", { - vrHelpTitle = params.vrHelpTitle, - vrHelp = params.vrHelp, - menuTitle = params.menuTitle, - menuIcon = params.menuIcon, - keyboardProperties = params.keyboardProperties - }) + EXPECT_HMICALL("TTS.SetGlobalProperties", params.responseTtsParams) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) @@ -127,10 +136,10 @@ runner.Step("Clean environment", commonSmokeApi.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmokeApi.start) runner.Step("RAI, PTU", commonSmokeApi.registerApplicationWithPTU) runner.Step("Activate App", commonSmokeApi.activateApp) -runner.Step("Upload icon file", put_file, {"icon.png"}) +runner.Step("Upload icon file", commonSmokeApi.putFile, {putFileParams}) runner.Title("Test") -runner.Step("SetGlobalProperties Positive Case", setGlobalProperties, {requestParams}) +runner.Step("SetGlobalProperties Positive Case", setGlobalProperties, {allParams}) runner.Title("Postconditions") runner.Step("Stop SDL", commonSmokeApi.postconditions) diff --git a/test_scripts/Smoke/commonSmokeApi.lua b/test_scripts/Smoke/commonSmokeApi.lua index e0302cbd1b..ebde7ebb4f 100644 --- a/test_scripts/Smoke/commonSmokeApi.lua +++ b/test_scripts/Smoke/commonSmokeApi.lua @@ -229,10 +229,17 @@ function commonSmokeApi.registerApplicationWithPTU(pAppId, pUpdateFunction, self end) end -function commonSmokeApi.postconditions() - StopSDL() +function commonSmokeApi.putFile(params, pAppId, self) + if not pAppId then pAppId = 1 end + local mobileSession = commonSmokeApi.getMobileSession(pAppId, self); + local cid = mobileSession:SendRPC("PutFile", params.requestParams, params.filePath) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) end -return commonSmokeApi +function commonSmokeApi.postconditions() + StopSDL() +end +return commonSmokeApi \ No newline at end of file From ded97b933ff26be028d8b7af330a6a5961f7642c Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 12 Oct 2017 14:28:27 +0300 Subject: [PATCH 172/681] Remove unused code --- user_modules/dummy_connecttest.lua | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/user_modules/dummy_connecttest.lua b/user_modules/dummy_connecttest.lua index 1b1da5a0ae..10667760c0 100644 --- a/user_modules/dummy_connecttest.lua +++ b/user_modules/dummy_connecttest.lua @@ -50,29 +50,17 @@ function module.hmiConnection:EXPECT_HMIRESPONSE(id, args) xmlReporter.AddMessage("EXPECT_HMIRESPONSE", {["Id"] = tostring(id),["Type"] = "AVALIABLE_RESULT"},data) local func_name = data.method local results_args = arguments - local results_args2 = arguments if(table2str(arguments):match('result')) then results_args = arguments.result - results_args2 = arguments.result elseif(table2str(arguments):match('error')) then results_args = arguments.error - results_args2 = arguments.error end - - if results_args2 and results_args2.code then - results_args2 = table.removeKey(results_args2, 'code') - end - if results_args2 and results_args2.method then - results_args2 = table.removeKey(results_args2, 'method') - end - if func_name == nil and type(data.result) == 'table' then func_name = data.result.method elseif func_name == nil and type(data.error) == 'table' then print_table(data) func_name = data.error.data.method end - local _res, _err _res = true if not (table2str(arguments):match('error')) then @@ -81,7 +69,6 @@ function module.hmiConnection:EXPECT_HMIRESPONSE(id, args) if (not _res) then return _res,_err end - if func_name and results_args and data.result then return compareValues(results_args, data.result, "result") elseif func_name and results_args and data.error then From 1f9a96a07f40b1051bd1cd0e5a3b77a979c40def Mon Sep 17 00:00:00 2001 From: AKalinich-Luxoft Date: Thu, 12 Oct 2017 15:11:31 +0300 Subject: [PATCH 173/681] Fix after review comments --- ...tGlobalProperties_PositiveCase_SUCCESS.lua | 3 +- test_scripts/Smoke/commonSmokeApi.lua | 59 +++++++++++++------ 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua index 669f386ed5..5fb63d2906 100644 --- a/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua @@ -27,7 +27,7 @@ -- SDL checks if UI interface is available on HMI -- SDL checks if TTS interface is available on HMI -- SDL checks if SetGlobalproperties is allowed by Policies --- SDL checks if all parameters is allowed by Policies +-- SDL checks if all parameters are allowed by Policies -- SDL transfers the UI part of request with allowed parameters to HMI -- SDL transfers the TTS part of request with allowed parameters to HMI -- SDL receives UI and TTS part of response from HMI with "SUCCESS" result code @@ -126,7 +126,6 @@ local function setGlobalProperties(params, self) end) self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) - self.mobileSession1:ExpectNotification("OnHashChange") end diff --git a/test_scripts/Smoke/commonSmokeApi.lua b/test_scripts/Smoke/commonSmokeApi.lua index ebde7ebb4f..b762dc31c0 100644 --- a/test_scripts/Smoke/commonSmokeApi.lua +++ b/test_scripts/Smoke/commonSmokeApi.lua @@ -10,6 +10,7 @@ config.defaultProtocolVersion = 2 local mobile_session = require("mobile_session") local json = require("modules/json") +local consts = require("user_modules/consts") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") @@ -46,7 +47,8 @@ end local function checkIfPTSIsSentAsBinary(bin_data) if not (bin_data ~= nil and string.len(bin_data) > 0) then - commonFunctions:userPrint(31, "PTS was not sent to Mobile in payload of OnSystemRequest") + commonFunctions:userPrint(consts.color.red, + "PTS was not sent to Mobile in payload of OnSystemRequest") end end @@ -97,14 +99,14 @@ local function ptu(self, id, pUpdateFunction) for id = 1, getAppsCount() do local mobileSession = commonSmokeApi.getMobileSession(id, self) mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) - :Do(function(_, d2) + :Do(function(_, data) print("App ".. id .. " was used for PTU") RAISE_EVENT(event, event, "PTU event") - checkIfPTSIsSentAsBinary(d2.binaryData) + checkIfPTSIsSentAsBinary(data.binaryData) local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) EXPECT_HMICALL("BasicCommunication.SystemRequest") - :Do(function(_, d3) - self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = policy_file_path .. "/" .. policy_file_name }) end) @@ -157,12 +159,30 @@ function commonSmokeApi.getSelfAndParams(...) return table.unpack(out, 1, table.maxn(out)) end +function commonSmokeApi.getPathToFileInStorage(fileName) + return commonSmokeApi.getPathToSDL() .. "storage/" + .. commonSmokeApi.getMobileAppId() .. "_" + .. commonSmokeApi.getDeviceMAC() .. "/" .. fileName +end + function commonSmokeApi.getMobileSession(pAppId, self) self, pAppId = commonSmokeApi.getSelfAndParams(pAppId, self) if not pAppId then pAppId = 1 end return self["mobileSession" .. pAppId] end +function commonSmokeApi.splitString(inputStr, sep) + if sep == nil then + sep = "%s" + end + local splitted = {}; i = 1 + for str in string.gmatch(inputStr, "([^"..sep.."]+)") do + splitted[i] = str + i = i + 1 + end + return splitted +end + function commonSmokeApi.activateApp(pAppId, self) self, pAppId = commonSmokeApi.getSelfAndParams(pAppId, self) if not pAppId then pAppId = 1 end @@ -182,13 +202,13 @@ function commonSmokeApi.start(pHMIParams, self) :Do(function() self:initHMI(self) :Do(function() - commonFunctions:userPrint(35, "HMI initialized") + commonFunctions:userPrint(consts.color.magenta, "HMI initialized") self:initHMI_onReady(pHMIParams) :Do(function() - commonFunctions:userPrint(35, "HMI is ready") + commonFunctions:userPrint(consts.color.magenta, "HMI is ready") self:connectMobile() :Do(function() - commonFunctions:userPrint(35, "Mobile connected") + commonFunctions:userPrint(consts.color.magenta, "Mobile connected") allowSDL(self) end) end) @@ -206,15 +226,15 @@ function commonSmokeApi.registerApplicationWithPTU(pAppId, pUpdateFunction, self config["application" .. pAppId].registerAppInterfaceParams) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) - :Do(function(_, d1) - hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = d1.params.application.appID + :Do(function(_, data) + hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = data.params.application.appID EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATE_NEEDED"}, {status = "UPDATING"}, {status = "UP_TO_DATE" }) :Times(3) EXPECT_HMICALL("BasicCommunication.PolicyUpdate") - :Do(function(_, d2) - self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) - ptu_table = jsonFileToTable(d2.params.file) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + ptu_table = jsonFileToTable(data.params.file) ptu(self, pAppId, pUpdateFunction) end) end) @@ -230,16 +250,19 @@ function commonSmokeApi.registerApplicationWithPTU(pAppId, pUpdateFunction, self end function commonSmokeApi.putFile(params, pAppId, self) - if not pAppId then pAppId = 1 end - local mobileSession = commonSmokeApi.getMobileSession(pAppId, self); - local cid = mobileSession:SendRPC("PutFile", params.requestParams, params.filePath) + if not pAppId then pAppId = 1 end + local mobileSession = commonSmokeApi.getMobileSession(pAppId, self); + local cid = mobileSession:SendRPC("PutFile", params.requestParams, params.filePath) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) end +function commonSmokeApi.readParameterFromSmartDeviceLinkIni(paramName) + return commonFunctions:read_parameter_from_smart_device_link_ini(paramName) +end function commonSmokeApi.postconditions() StopSDL() end -return commonSmokeApi \ No newline at end of file +return commonSmokeApi From 078e3c0a894bd108d9e9a0062929733ac00bb27a Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 13 Oct 2017 14:48:29 +0300 Subject: [PATCH 174/681] Fix for ResetGlobalProperties regarding helpPrompt --- test_scripts/smoke_api.lua | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/test_scripts/smoke_api.lua b/test_scripts/smoke_api.lua index 742a0b06b1..b391edfbf5 100644 --- a/test_scripts/smoke_api.lua +++ b/test_scripts/smoke_api.lua @@ -679,17 +679,7 @@ function Test:ResetGlobalProperties_PositiveCase() --hmi side: expect TTS.SetGlobalProperties request EXPECT_HMICALL("TTS.SetGlobalProperties", { - helpPrompt = - { - { - type = "TEXT", - text = textPromtValue[1] - }, - { - type = "TEXT", - text = textPromtValue[2] - } - }, + helpPrompt = { }, timeoutPrompt = { { From 634fec395a26259c88ea60ae9ba80371d8857531 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Mon, 16 Oct 2017 16:01:55 -0400 Subject: [PATCH 175/681] Replace Ford interface with SmartDeviceLink --- test_scripts/API/ATF_syncMsgVersion.lua | 2 +- user_modules/utils.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test_scripts/API/ATF_syncMsgVersion.lua b/test_scripts/API/ATF_syncMsgVersion.lua index 8230d25877..2ab91876b8 100644 --- a/test_scripts/API/ATF_syncMsgVersion.lua +++ b/test_scripts/API/ATF_syncMsgVersion.lua @@ -128,7 +128,7 @@ end function SDL_Core.getAPIFileVersion() for line in io.lines(sdl_core_config.api_file_path) do - local major, minor = string.match(line, "^%s* Date: Mon, 16 Oct 2017 16:56:32 -0400 Subject: [PATCH 176/681] Add Shutdown to Sendhapticdata test --- test_scripts/API/ATF_SendHapticData.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test_scripts/API/ATF_SendHapticData.lua b/test_scripts/API/ATF_SendHapticData.lua index 2a7758a04b..47903818a9 100644 --- a/test_scripts/API/ATF_SendHapticData.lua +++ b/test_scripts/API/ATF_SendHapticData.lua @@ -523,4 +523,8 @@ function Test:SingleSpatialDataWithFloatNumber() end) end +function Test:Postconditions() + StopSDL() +end + return Test From f2c903293464469ebdf036ca148182d0c2bb5501 Mon Sep 17 00:00:00 2001 From: AKalinich-Luxoft Date: Tue, 17 Oct 2017 10:51:08 +0300 Subject: [PATCH 177/681] Rename commonSmokeApi unit --- .../{commonSmokeApi.lua => commonSmoke.lua} | 74 +++++++++++-------- 1 file changed, 44 insertions(+), 30 deletions(-) rename test_scripts/Smoke/{commonSmokeApi.lua => commonSmoke.lua} (82%) diff --git a/test_scripts/Smoke/commonSmokeApi.lua b/test_scripts/Smoke/commonSmoke.lua similarity index 82% rename from test_scripts/Smoke/commonSmokeApi.lua rename to test_scripts/Smoke/commonSmoke.lua index b762dc31c0..4c695f4bff 100644 --- a/test_scripts/Smoke/commonSmokeApi.lua +++ b/test_scripts/Smoke/commonSmoke.lua @@ -28,10 +28,10 @@ local commonPreconditions = require('user_modules/shared_testcases/commonPrecond local ptu_table = {} local hmiAppIds = {} -local commonSmokeApi = {} +local commonSmoke = {} -commonSmokeApi.timeout = 5000 -commonSmokeApi.minTimeout = 500 +commonSmoke.timeout = 5000 +commonSmoke.minTimeout = 500 local function allowSDL(self) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", @@ -81,6 +81,10 @@ local function ptu(self, id, pUpdateFunction) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = pts_file_name }) getPTUFromPTS(ptu_table) + local function updatePTU(tbl) + tbl.policy_table.app_policies[commonSmoke.getMobileAppId(id)] = commonSmoke.getSmokeAppPoliciesConfig() + end + updatePTU(ptu_table) if pUpdateFunction then pUpdateFunction(ptu_table) end @@ -97,7 +101,7 @@ local function ptu(self, id, pUpdateFunction) :Timeout(11000) for id = 1, getAppsCount() do - local mobileSession = commonSmokeApi.getMobileSession(id, self) + local mobileSession = commonSmoke.getMobileSession(id, self) mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) :Do(function(_, data) print("App ".. id .. " was used for PTU") @@ -120,26 +124,26 @@ end --[[Module functions]] -function commonSmokeApi.preconditions() +function commonSmoke.preconditions() commonFunctions:SDLForceStop() commonSteps:DeletePolicyTable() commonSteps:DeleteLogsFiles() end -function commonSmokeApi.getDeviceMAC() +function commonSmoke.getDeviceMAC() return config.deviceMAC end -function commonSmokeApi.getPathToSDL() +function commonSmoke.getPathToSDL() return config.pathToSDL end -function commonSmokeApi.getMobileAppId(pAppId) +function commonSmoke.getMobileAppId(pAppId) if not pAppId then pAppId = 1 end return config["application" .. pAppId].registerAppInterfaceParams.appID end -function commonSmokeApi.getSelfAndParams(...) +function commonSmoke.getSelfAndParams(...) local out = { } local selfIdx = nil for i,v in pairs({...}) do @@ -159,23 +163,33 @@ function commonSmokeApi.getSelfAndParams(...) return table.unpack(out, 1, table.maxn(out)) end -function commonSmokeApi.getPathToFileInStorage(fileName) - return commonSmokeApi.getPathToSDL() .. "storage/" - .. commonSmokeApi.getMobileAppId() .. "_" - .. commonSmokeApi.getDeviceMAC() .. "/" .. fileName +function commonSmoke.getPathToFileInStorage(fileName) + return commonSmoke.getPathToSDL() .. "storage/" + .. commonSmoke.getMobileAppId() .. "_" + .. commonSmoke.getDeviceMAC() .. "/" .. fileName end -function commonSmokeApi.getMobileSession(pAppId, self) - self, pAppId = commonSmokeApi.getSelfAndParams(pAppId, self) +function commonSmoke.getMobileSession(pAppId, self) + self, pAppId = commonSmoke.getSelfAndParams(pAppId, self) if not pAppId then pAppId = 1 end return self["mobileSession" .. pAppId] end -function commonSmokeApi.splitString(inputStr, sep) +function commonSmoke.getSmokeAppPoliciesConfig() + return { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + groups = { "Base-4" } + } +end + +function commonSmoke.splitString(inputStr, sep) if sep == nil then sep = "%s" end - local splitted = {}; i = 1 + local splitted, i = {}, 1 for str in string.gmatch(inputStr, "([^"..sep.."]+)") do splitted[i] = str i = i + 1 @@ -183,20 +197,20 @@ function commonSmokeApi.splitString(inputStr, sep) return splitted end -function commonSmokeApi.activateApp(pAppId, self) - self, pAppId = commonSmokeApi.getSelfAndParams(pAppId, self) +function commonSmoke.activateApp(pAppId, self) + self, pAppId = commonSmoke.getSelfAndParams(pAppId, self) if not pAppId then pAppId = 1 end local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] - local mobSession = commonSmokeApi.getMobileSession(pAppId, self) + local mobSession = commonSmoke.getMobileSession(pAppId, self) local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) EXPECT_HMIRESPONSE(requestId) mobSession:ExpectNotification("OnHMIStatus", {hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN"}) - commonTestCases:DelayedExp(commonSmokeApi.minTimeout) + commonTestCases:DelayedExp(commonSmoke.minTimeout) end -function commonSmokeApi.start(pHMIParams, self) - self, pHMIParams = commonSmokeApi.getSelfAndParams(pHMIParams, self) +function commonSmoke.start(pHMIParams, self) + self, pHMIParams = commonSmoke.getSelfAndParams(pHMIParams, self) self:runSDL() commonFunctions:waitForSDLStart(self) :Do(function() @@ -216,8 +230,8 @@ function commonSmokeApi.start(pHMIParams, self) end) end -function commonSmokeApi.registerApplicationWithPTU(pAppId, pUpdateFunction, self) - self, pAppId, pUpdateFunction = commonSmokeApi.getSelfAndParams(pAppId, pUpdateFunction, self) +function commonSmoke.registerApplicationWithPTU(pAppId, pUpdateFunction, self) + self, pAppId, pUpdateFunction = commonSmoke.getSelfAndParams(pAppId, pUpdateFunction, self) if not pAppId then pAppId = 1 end self["mobileSession" .. pAppId] = mobile_session.MobileSession(self, self.mobileConnection) self["mobileSession" .. pAppId]:StartService(7) @@ -249,20 +263,20 @@ function commonSmokeApi.registerApplicationWithPTU(pAppId, pUpdateFunction, self end) end -function commonSmokeApi.putFile(params, pAppId, self) +function commonSmoke.putFile(params, pAppId, self) if not pAppId then pAppId = 1 end - local mobileSession = commonSmokeApi.getMobileSession(pAppId, self); + local mobileSession = commonSmoke.getMobileSession(pAppId, self); local cid = mobileSession:SendRPC("PutFile", params.requestParams, params.filePath) mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) end -function commonSmokeApi.readParameterFromSmartDeviceLinkIni(paramName) +function commonSmoke.readParameterFromSmartDeviceLinkIni(paramName) return commonFunctions:read_parameter_from_smart_device_link_ini(paramName) end -function commonSmokeApi.postconditions() +function commonSmoke.postconditions() StopSDL() end -return commonSmokeApi +return commonSmoke From 6075f7000bab1e04c24699b2e18067a05a0c7126 Mon Sep 17 00:00:00 2001 From: AKalinich-Luxoft Date: Tue, 17 Oct 2017 10:55:32 +0300 Subject: [PATCH 178/681] Fixed after review comments --- ...tGlobalProperties_PositiveCase_SUCCESS.lua | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua index 5fb63d2906..439c197075 100644 --- a/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua @@ -36,7 +36,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonSmokeApi = require('test_scripts/Smoke/commonSmokeApi') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') --[[ Local Variables ]] local putFileParams = { @@ -110,10 +110,8 @@ local allParams = { local function setGlobalProperties(params, self) local cid = self.mobileSession1:SendRPC("SetGlobalProperties", params.requestParams) - params.responseUiParams.vrHelp[1].image.value = commonSmokeApi.getPathToSDL() - .. "storage/" .. commonSmokeApi.getMobileAppId() .. "_" - .. commonSmokeApi.getDeviceMAC() .. "/icon.png" - params.responseUiParams.menuIcon.value = params.responseUiParams.vrHelp[1].image.value + params.responseUiParams.vrHelp[1].image.value = commonSmoke.getPathToFileInStorage("icon.png") + params.responseUiParams.menuIcon.value = commonSmoke.getPathToFileInStorage("icon.png") EXPECT_HMICALL("UI.SetGlobalProperties", params.responseUiParams) :Do(function(_,data) @@ -131,14 +129,14 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonSmokeApi.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmokeApi.start) -runner.Step("RAI, PTU", commonSmokeApi.registerApplicationWithPTU) -runner.Step("Activate App", commonSmokeApi.activateApp) -runner.Step("Upload icon file", commonSmokeApi.putFile, {putFileParams}) +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) runner.Title("Test") runner.Step("SetGlobalProperties Positive Case", setGlobalProperties, {allParams}) runner.Title("Postconditions") -runner.Step("Stop SDL", commonSmokeApi.postconditions) +runner.Step("Stop SDL", commonSmoke.postconditions) From b6bb404a5b25c9eb18ae66278115c53d5abc9fe5 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 17 Oct 2017 15:19:46 -0400 Subject: [PATCH 179/681] Remove timeout A 50 ms timeout was causing a lot of false negatives for certain test cases. Looking at the blame, I believe that this line had been changed to a higher value but then was readded as 50ms via a copy and paste error. I have decided to remove the timeout entirerly and let ATF use the default timeout instead. --- user_modules/shared_testcases/commonFunctions.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/user_modules/shared_testcases/commonFunctions.lua b/user_modules/shared_testcases/commonFunctions.lua index f08ce897a6..5fa75964f6 100644 --- a/user_modules/shared_testcases/commonFunctions.lua +++ b/user_modules/shared_testcases/commonFunctions.lua @@ -497,7 +497,6 @@ function commonFunctions:verify_Unsuccess_Case(self, Request, ResultCode) --mobile side: expect the response EXPECT_RESPONSE(cid, { success = false, resultCode = ResultCode }) - :Timeout(50) messageflag = true end From 327926a4da944a98427e22bc4aa901a77bd06f0e Mon Sep 17 00:00:00 2001 From: Ira Lytvynenko Date: Mon, 23 Oct 2017 15:31:24 +0300 Subject: [PATCH 180/681] Check that the SDL sends binary data using the OnSystemRequest RPC for any requestType --- ...st_send_binaryData_for_any_requestType.lua | 86 +++++ test_scripts/API/System/commonSystem.lua | 340 ++++++++++++++++++ 2 files changed, 426 insertions(+) create mode 100644 test_scripts/API/System/OnSystemRequest/001_OnSystemRequest_send_binaryData_for_any_requestType.lua create mode 100644 test_scripts/API/System/commonSystem.lua diff --git a/test_scripts/API/System/OnSystemRequest/001_OnSystemRequest_send_binaryData_for_any_requestType.lua b/test_scripts/API/System/OnSystemRequest/001_OnSystemRequest_send_binaryData_for_any_requestType.lua new file mode 100644 index 0000000000..e101b64c34 --- /dev/null +++ b/test_scripts/API/System/OnSystemRequest/001_OnSystemRequest_send_binaryData_for_any_requestType.lua @@ -0,0 +1,86 @@ +--------------------------------------------------------------------------------------------------- +-- Script covers https://github.com/SmartDeviceLink/sdl_core/issues/1714 +-- SDL core should be capable of sending binary data using the OnSystemRequest RPC for any requestType. +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/System/commonSystem') +local json = require("modules/json") + +--[[ Local Variables ]] +local request_types = { + "HTTP" , + "FILE_RESUME" , + "AUTH_REQUEST" , + "AUTH_CHALLENGE" , + "AUTH_ACK" , + "QUERY_APPS" , + "LAUNCH_APP" , + "LOCK_SCREEN_ICON_URL" , + "TRAFFIC_MESSAGE_CHANNEL" , + "DRIVER_PROFILE" , + "VOICE_SEARCH" , + "NAVIGATION" , + "PHONE" , + "CLIMATE" , + "SETTINGS" , + "VEHICLE_DIAGNOSTICS" , + "EMERGENCY" , + "MEDIA" , + "FOTA" , +} + +local f_name = os.tmpname() +local exp_binary_data = "{ \"policy_table\": { } }" + +--[[ Local Functions ]] +local function onSystemRequest(request_type, self) + local f = io.open(f_name, "w") + f:write(exp_binary_data) + f:close() + + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + { requestType = request_type, fileName = f_name, appID = self.applications["Test Application"] }) + self.mobileSession1:ExpectNotification("OnSystemRequest", { requestType = request_type }) + :ValidIf(function(_, d) + local actual_binary_data = common.convertTableToString(d.binaryData, 1) + return exp_binary_data == actual_binary_data + end) +end + +local function onSystemRequest_PROPRIETARY(self) + local f = io.open(f_name, "w") + f:write(exp_binary_data) + f:close() + + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + { requestType = "PROPRIETARY", fileName = f_name, appID = self.applications["Test Application"] }) + self.mobileSession1:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :ValidIf(function(_, d) + local binary_data = json.decode(d.binaryData) + local actual_binary_data = common.convertTableToString(binary_data["HTTPRequest"]["body"], 1) + return exp_binary_data == actual_binary_data + end) +end + +local function deleteFile() + os.remove(f_name) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, value in pairs(request_types) do + runner.Step("OnSystemRequest_with_request_type_" .. tostring(value), onSystemRequest, { value }) +end +runner.Step("OnSystemRequest_with_request_type_PROPRIETARY", onSystemRequest_PROPRIETARY) + +runner.Title("Postconditions") +runner.Step("Delete file", deleteFile) +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/System/commonSystem.lua b/test_scripts/API/System/commonSystem.lua new file mode 100644 index 0000000000..1c12c75e60 --- /dev/null +++ b/test_scripts/API/System/commonSystem.lua @@ -0,0 +1,340 @@ +--------------------------------------------------------------------------------------------------- +-- System common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 + +--[[ Required Shared libraries ]] +local mobile_session = require("mobile_session") +local json = require("modules/json") + +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +local common = {} + +--[[ Constants ]] +common.timeout = 2000 +common.minTimeout = 500 + +--[[ Variables ]] +local ptu_table = {} +local hmiAppIds = {} + +--[[ Functions ]] + +--[[ @checkIfPTSIsSentAsBinary: check if binary data is not empty +--! @parameters: +--! pBinData - binary data +--]] +local function checkIfPTSIsSentAsBinary(pBinData) + if not (pBinData ~= nil and string.len(pBinData) > 0) then + commonFunctions:userPrint(31, "PTS was not sent to Mobile in payload of OnSystemRequest") + end +end + +--[[ @getPTUFromPTS: create policy table update table (PTU) +--! @parameters: +--! pTbl - table with policy table snapshot (PTS) +--! @return: table with PTU +--]] +local function getPTUFromPTS(pTbl) + pTbl.policy_table.consumer_friendly_messages.messages = nil + pTbl.policy_table.device_data = nil + pTbl.policy_table.module_meta = nil + pTbl.policy_table.usage_and_error_counts = nil + pTbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + pTbl.policy_table.module_config.preloaded_pt = nil + pTbl.policy_table.module_config.preloaded_date = nil +end + +--[[ @jsonFileToTable: convert .json file to table +--! @parameters: +--! pFileName - file name +--! @return: table +--]] +local function jsonFileToTable(pFileName) + local f = io.open(pFileName, "r") + local content = f:read("*all") + f:close() + return json.decode(content) +end + +--[[ @tableToJsonFile: convert table to .json file +--! @parameters: +--! pTbl - table +--! pFileName - file name +--]] +local function tableToJsonFile(pTbl, pFileName) + local f = io.open(pFileName, "w") + f:write(json.encode(pTbl)) + f:close() +end + +--[[ @ptu: perform policy table update +--! @parameters: +--! pPTUpdateFunc - additional function for update +--! self - test object +--]] +local function ptu(pPTUpdateFunc, self) + local policy_file_name = "PolicyTableUpdate" + local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + local ptu_file_name = os.tmpname() + local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) + EXPECT_HMIRESPONSE(requestId) + :Do(function() + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + { requestType = "PROPRIETARY", fileName = pts_file_name }) + getPTUFromPTS(ptu_table) + + if pPTUpdateFunc then + pPTUpdateFunc(ptu_table) + end + + tableToJsonFile(ptu_table, ptu_file_name) + + local event = events.Event() + event.matches = function(self, e) return self == e end + EXPECT_EVENT(event, "PTU event") + :Timeout(11000) + + local function getAppsCount() + local count = 0 + for _ in pairs(hmiAppIds) do + count = count + 1 + end + return count + end + for id = 1, getAppsCount() do + local mobileSession = common.getMobileSession(id, self) + mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :Do(function(_, d2) + print("App ".. id .. " was used for PTU") + RAISE_EVENT(event, event, "PTU event") + checkIfPTSIsSentAsBinary(d2.binaryData) + local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", + { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, d3) + self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", + { policyfile = policy_file_path .. "/" .. policy_file_name }) + end) + mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + end) + :Times(AtMost(1)) + end + end) + os.remove(ptu_file_name) +end + +--[[ @preconditions: precondition steps +--! @parameters: none +--]] +function common.preconditions() + commonFunctions:SDLForceStop() + commonSteps:DeletePolicyTable() + commonSteps:DeleteLogsFiles() +end + +--[[ @activateApp: activate application +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! self - test object +--]] +function common.activateApp(pAppId, self) + self, pAppId = common.getSelfAndParams(pAppId, self) + if not pAppId then pAppId = 1 end + local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + local mobSession = common.getMobileSession(pAppId, self) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + EXPECT_HMIRESPONSE(requestId) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + commonTestCases:DelayedExp(common.minTimeout) +end + +--[[ @getSelfAndParams: shifting parameters in order to move self at 1st position +--! @parameters: +--! ... - various parameters and self +--! @return: self and other parameters +--]] +function common.getSelfAndParams(...) + local out = { } + local selfIdx = nil + for i,v in pairs({...}) do + if type(v) == "table" and v.isTest then + table.insert(out, v) + selfIdx = i + break + end + end + local idx = 2 + for i = 1, table.maxn({...}) do + if i ~= selfIdx then + out[idx] = ({...})[i] + idx = idx + 1 + end + end + return table.unpack(out, 1, table.maxn(out)) +end + +--[[ @getMobileSession: get mobile session +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! self - test object +--! @return: mobile session +--]] +function common.getMobileSession(pAppId, self) + if not pAppId then pAppId = 1 end + return self["mobileSession" .. pAppId] +end + +--[[ @postconditions: postcondition steps +--! @parameters: none +--]] +function common.postconditions() + StopSDL() +end + +--[[ @registerAppWithPTU: register mobile application and perform PTU +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! pPTUpdateFunc - additional function for update +--! self - test object +--]] +function common.registerAppWithPTU(pAppId, pPTUpdateFunc, self) + self, pAppId, pPTUpdateFunc = common.getSelfAndParams(pAppId, pPTUpdateFunc, self) + if not pAppId then pAppId = 1 end + self["mobileSession" .. pAppId] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. pAppId]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. pAppId]:SendRPC("RegisterAppInterface", + config["application" .. pAppId].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = d1.params.application.appID + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :Do(function(_, d2) + self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptu_table = jsonFileToTable(d2.params.file) + ptu(pPTUpdateFunc, self) + end) + end) + self["mobileSession" .. pAppId]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. pAppId]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(1) + self["mobileSession" .. pAppId]:ExpectNotification("OnPermissionsChange") + :Times(AtLeast(1)) -- TODO: Change to exact 1 occurence when SDL issue is fixed + end) + end) +end + +--[[ @allowSDL: sequence that allows SDL functionality +--! @parameters: +--! self - test object +--]] +local function allowSDL(self) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", + { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) +end + +--[[ @start: starting sequence: starting of SDL, initialization of HMI, connect mobile +--! @parameters: +--! pHMIParams - table with parameters for HMI initialization +--! self - test object +--]] +function common.start(pHMIParams, self) + self, pHMIParams = common.getSelfAndParams(pHMIParams, self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady(pHMIParams) + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + self:connectMobile() + :Do(function() + commonFunctions:userPrint(35, "Mobile connected") + allowSDL(self) + end) + end) + end) + end) +end + +function common.convertTableToString(tbl, i) + local strIndex = "" + local strReturn = "" + for j = 1, i do + strIndex = strIndex .. "\t" + end + local strIndex2 = strIndex .."\t" + local x = 0 + if type(tbl) == "table" then + strReturn = strReturn .. strIndex .. "{\n" + for k,v in pairs(tbl) do + x = x + 1 + if type(k) == "number" then + if type(v) == "table" then + if x ~=1 then + strReturn = strReturn .. ",\n" + end + else + if x ==1 then + strReturn = strReturn .. strIndex2 + else + strReturn = strReturn .. ",\n" .. strIndex2 + end + end + else + if x ==1 then + strReturn = strReturn .. strIndex2 .. k .. " = " + else + strReturn = strReturn .. ",\n" .. strIndex2 .. k .. " = " + end + if type(v) == "table" then + strReturn = strReturn .. "\n" + end + end + strReturn = strReturn .. common.convertTableToString(v, i+1) + end + strReturn = strReturn .. "\n" + strReturn = strReturn .. strIndex .. "}" + else + if type(tbl) == "number" then + strReturn = strReturn .. tbl + elseif type(tbl) == "boolean" then + strReturn = strReturn .. tostring(tbl) + elseif type(tbl) == "string" then + strReturn = strReturn .. tbl + end + end + return strReturn +end +--[[ @protect: make table immutable +--! @parameters: +--! pTbl - mutable table +--! @return: immutable table +--]] +local function protect(pTbl) + local mt = { + __index = pTbl, + __newindex = function(_, k, v) + error("Attempting to change item " .. tostring(k) .. " to " .. tostring(v), 2) + end + } + return setmetatable({}, mt) +end + +return protect(common) From 426ee2f261e8ca77dbe7c17b87f056bab8456981 Mon Sep 17 00:00:00 2001 From: AKalinich-Luxoft Date: Thu, 19 Oct 2017 13:13:13 +0300 Subject: [PATCH 181/681] Add new smoke test scripts --- ...tGlobalProperties_PositiveCase_SUCCESS.lua | 7 +- ...tGlobalProperties_PositiveCase_SUCCESS.lua | 124 ++++++++++ .../003_AddCommand_PositiveCase_SUCCESS.lua | 124 ++++++++++ ...004_DeleteCommand_PositiveCase_SUCCESS.lua | 152 ++++++++++++ .../005_AddSubMenu_PositiveCase_SUCCESS.lua | 79 +++++++ ...006_DeleteSubMenu_PositiveCase_SUCCESS.lua | 98 ++++++++ .../API/007_Alert_PositiveCase_SUCCESS.lua | 218 ++++++++++++++++++ ...eractionChoiceSet_PositiveCase_SUCCESS.lua | 110 +++++++++ ...eractionChoiceSet_PositiveCase_SUCCESS.lua | 138 +++++++++++ .../010_DeleteFile_PositiveCase_SUCCESS.lua | 83 +++++++ .../011_ListFiles_PositiveCase_SUCCESS.lua | 96 ++++++++ test_scripts/Smoke/commonSmoke.lua | 51 ++++ 12 files changed, 1277 insertions(+), 3 deletions(-) create mode 100644 test_scripts/Smoke/API/002_ResetGlobalProperties_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/003_AddCommand_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/004_DeleteCommand_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/005_AddSubMenu_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/006_DeleteSubMenu_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/007_Alert_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/009_DeleteInteractionChoiceSet_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/010_DeleteFile_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/011_ListFiles_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua index 439c197075..91e13a915f 100644 --- a/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua @@ -15,8 +15,8 @@ -- Pre-conditions: -- a. HMI and SDL are started --- b. appID is registered and on SDL --- c. appID is in Background, Full or Limited HMI level +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level -- Steps: -- appID requests SetGlobalproperties with timeoutPrompt, helpPrompt and other valid parameters @@ -110,14 +110,15 @@ local allParams = { local function setGlobalProperties(params, self) local cid = self.mobileSession1:SendRPC("SetGlobalProperties", params.requestParams) + params.responseUiParams.appID = commonSmoke.getHMIAppId() params.responseUiParams.vrHelp[1].image.value = commonSmoke.getPathToFileInStorage("icon.png") params.responseUiParams.menuIcon.value = commonSmoke.getPathToFileInStorage("icon.png") - EXPECT_HMICALL("UI.SetGlobalProperties", params.responseUiParams) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) + params.responseTtsParams.appID = commonSmoke.getHMIAppId() EXPECT_HMICALL("TTS.SetGlobalProperties", params.responseTtsParams) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) diff --git a/test_scripts/Smoke/API/002_ResetGlobalProperties_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/002_ResetGlobalProperties_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..70caa5145b --- /dev/null +++ b/test_scripts/Smoke/API/002_ResetGlobalProperties_PositiveCase_SUCCESS.lua @@ -0,0 +1,124 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: ResetGlobalProperties +-- Item: Happy path +-- +-- Requirement summary: +-- [ResetGlobalProperties] SUCCESS on UI.SetGlobalProperties and TTS.SetGlobalPrtoperties +-- +-- Description: +-- Mobile app sends valid ResetGlobalProperties with "HELPPROMPT" and "TIMEOUTPROMPT" +-- and at least one other valid parameter in "properties" array + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests ResetGlobalProperties with timeoutPrompt, helpPrompt and other valid parameters + +-- Expected: + +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if TTS interface is available on HMI +-- SDL checks if ResetGlobalProperties is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL setup the value of helpPrompt to an empty array and retrieve the value of timeoutPrompt +-- parameter from .ini file correspondingly +-- SDL transfer the items requested ("HELPPROMPT" and "TIMEOUTPROMPT"): +-- TTS.SetGlobalProperties(helpPrompt:"", and timeoutPrompt:<'TimeOutPrompt' from ini.file>) to HMI +-- SDL responds (resultCode:SUCCESS, success:true) to mobile application on getting the both +-- SUCCESS:UI.SetGlobalProperties and SUCCESS:TTS.SetGlobalProperties from HMI +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local requestParams = { + properties = { + "VRHELPTITLE", + "MENUNAME", + "MENUICON", + "KEYBOARDPROPERTIES", + "VRHELPITEMS", + "HELPPROMPT", + "TIMEOUTPROMPT" + } +} + +local responseUiParams = { + menuTitle = "", + vrHelpTitle = "Test Application", + keyboardProperties = { + keyboardLayout = "QWERTY", + autoCompleteText = "", + language = "EN-US" + } +} + +local responseTtsParams = { + helpPrompt = {}, + timeoutPrompt = {} +} + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams, + responseTtsParams = responseTtsParams +} + +--[[ Local Functions ]] +local function resetGlobalProperties(params, self) + local cid = self.mobileSession1:SendRPC("ResetGlobalProperties", params.requestParams) + + params.responseUiParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("UI.SetGlobalProperties", params.responseUiParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + if data.params.vrHelp == nil then + return true + else + return false, "vrHelp array in UI.SetGlobalProperties request is not empty." .. + " Expected array size 0, actual " .. tostring(#data.params.vrHelp) + end + end) + + local ttsDelimiter = commonSmoke.readParameterFromSmartDeviceLinkIni("TTSDelimiter") + local helpPromptString = commonSmoke.readParameterFromSmartDeviceLinkIni("HelpPromt") + local helpPromptList = commonSmoke.splitString(helpPromptString, ttsDelimiter); + + for key,value in pairs(helpPromptList) do + params.responseTtsParams.timeoutPrompt[key] = { + type = "TEXT", + text = value .. ttsDelimiter + } + end + + params.responseTtsParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("TTS.SetGlobalProperties", params.responseTtsParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("ResetGlobalProperties Positive Case", resetGlobalProperties, {allParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/003_AddCommand_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/003_AddCommand_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..a8447dbef3 --- /dev/null +++ b/test_scripts/Smoke/API/003_AddCommand_PositiveCase_SUCCESS.lua @@ -0,0 +1,124 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: AddComand +-- Item: Happy path +-- +-- Requirement summary: +-- [AddCommand] SUCCESS: getting SUCCESS on VR and UI.AddCommand() +-- +-- Description: +-- Mobile application sends valid AddCommand request with the both "vrCommands" +-- and "menuParams" data and gets "SUCCESS" for the both VR.AddCommand and VR.AddCommand +-- responses from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests AddCommand with the both vrCommands and menuParams + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if VR interface is available on HMI +-- SDL checks if AddCommand is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the UI part of request with allowed parameters to HMI +-- SDL transfers the VR part of request with allowed parameters to HMI +-- SDL receives UI and VR part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local requestParams = { + cmdID = 11, + menuParams = { + position = 0, + menuName ="Commandpositive" + }, + vrCommands = { + "VRCommandonepositive", + "VRCommandonepositivedouble" + }, + grammarID = 1, + cmdIcon = { + value ="icon.png", + imageType ="DYNAMIC" + } +} + +local responseUiParams = { + cmdID = requestParams.cmdID, + cmdIcon = requestParams.cmdIcon, + menuParams = requestParams.menuParams +} + +local responseVrParams = { + cmdID = requestParams.cmdID, + type = "Command", + vrCommands = requestParams.vrCommands +} + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams, + responseVrParams = responseVrParams +} + +--[[ Local Functions ]] +local function addCommand(params, self) + local cid = self.mobileSession1:SendRPC("AddCommand", params.requestParams) + + params.responseUiParams.appID = commonSmoke.getHMIAppId() + params.responseUiParams.cmdIcon.value = commonSmoke.getPathToFileInStorage("icon.png") + EXPECT_HMICALL("UI.AddCommand", params.responseUiParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + params.responseVrParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("VR.AddCommand", params.responseVrParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + if data.params.grammarID ~= nil then + return true + else + return false, "grammarID should not be empty" + end + end) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) + +runner.Title("Test") +runner.Step("AddCommand Positive Case", addCommand, {allParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/004_DeleteCommand_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/004_DeleteCommand_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..adef04d2ca --- /dev/null +++ b/test_scripts/Smoke/API/004_DeleteCommand_PositiveCase_SUCCESS.lua @@ -0,0 +1,152 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: DeleteCommand +-- Item: Happy path +-- +-- Requirement summary: +-- [DeleteCommand] SUCCESS: getting SUCCESS from VR.DeleteCommand() and UI.DeleteCommand() +-- +-- Description: +-- Mobile application sends DeleteCommand request for a command created with both "vrCommands" +-- and "menuParams", and SDL gets VR and UI.DeleteCommand "SUCCESS" response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level +-- d. Command with both vrCommands and menuParams was created + +-- Steps: +-- appID requests DeleteCommand with the both vrCommands and menuParams + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if VR interface is available on HMI +-- SDL checks if DeleteCommand is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the UI part of request with allowed parameters to HMI +-- SDL transfers the VR part of request with allowed parameters to HMI +-- SDL receives UI and VR part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local addCommandRequestParams = { + cmdID = 11, + menuParams = { + position = 0, + menuName ="Commandpositive" + }, + vrCommands = { + "VRCommandonepositive", + "VRCommandonepositivedouble" + }, + cmdIcon = { + value ="icon.png", + imageType ="DYNAMIC" + } +} + +local addCommandGrammarID = 0 + +local addCommandResponseUiParams = { + cmdID = addCommandRequestParams.cmdID, + cmdIcon = addCommandRequestParams.cmdIcon, + menuParams = addCommandRequestParams.menuParams +} + +local addCommandResponseVrParams = { + cmdID = addCommandRequestParams.cmdID, + type = "Command", + vrCommands = addCommandRequestParams.vrCommands +} + +local addCommandAllParams = { + requestParams = addCommandRequestParams, + responseUiParams = addCommandResponseUiParams, + responseVrParams = addCommandResponseVrParams +} + +local deleteCommandRequestParams = { + cmdID = addCommandRequestParams.cmdID +} + +--[[ Local Functions ]] +local function addCommand(params, self) + local cid = self.mobileSession1:SendRPC("AddCommand", params.requestParams) + + params.responseUiParams.appID = commonSmoke.getHMIAppId() + params.responseUiParams.cmdIcon.value = commonSmoke.getPathToFileInStorage("icon.png") + EXPECT_HMICALL("UI.AddCommand", params.responseUiParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + params.responseVrParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("VR.AddCommand", params.responseVrParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + if data.params.grammarID == nil then + return false, "grammarID should not be empty" + end + addCommandGrammarID = data.params.grammarID + return true + end) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +local function deleteCommand(params, self) + local cid = self.mobileSession1:SendRPC("DeleteCommand", params) + + params.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("UI.DeleteCommand", params) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + local responseVrParams = { + cmdID = params.cmdID, + grammarID = addCommandGrammarID + } + EXPECT_HMICALL("VR.DeleteCommand", responseVrParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) +runner.Step("AddCommand", addCommand, {addCommandAllParams}) + +runner.Title("Test") +runner.Step("DeleteCommand Positive Case", deleteCommand, {deleteCommandRequestParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/005_AddSubMenu_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/005_AddSubMenu_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..e043e6afbe --- /dev/null +++ b/test_scripts/Smoke/API/005_AddSubMenu_PositiveCase_SUCCESS.lua @@ -0,0 +1,79 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: AddSubMenu +-- Item: Happy path +-- +-- Requirement summary: +-- [AddSubMenu] SUCCESS: getting SUCCESS:UI.AddSubMenu() +-- +-- Description: +-- Mobile application sends valid AddSubMenu request and gets UI.AddSubMenu "SUCCESS" response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests AddSubMenu with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if AddSubMenu is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the UI part of request with allowed parameters to HMI +-- SDL receives UI part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local requestParams = { + menuID = 1000, + position = 500, + menuName ="SubMenupositive" +} + +local responseUiParams = { + menuID = requestParams.menuID, + menuParams = { + position = requestParams.position, + menuName = requestParams.menuName + } +} + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams +} + +--[[ Local Functions ]] +local function addSubMenu(params, self) + local cid = self.mobileSession1:SendRPC("AddSubMenu", params.requestParams) + + params.responseUiParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("UI.AddSubMenu", params.responseUiParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("AddSubMenu Positive Case", addSubMenu, {allParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/006_DeleteSubMenu_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/006_DeleteSubMenu_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..e9f7475c05 --- /dev/null +++ b/test_scripts/Smoke/API/006_DeleteSubMenu_PositiveCase_SUCCESS.lua @@ -0,0 +1,98 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: DeleteSubMenu +-- Item: Happy path +-- +-- Requirement summary: +-- [DeleteSubMenu] SUCCESS: getting SUCCESS:UI.DeleteSubMenu() and all related UI or/and VR.DeleteCommand() +-- +-- Description: +-- Mobile application sends valid DeleteSubMenu request and gets UI.DeleteSubMenu "SUCCESS" response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level +-- d. SubMenu with related menuID was created + +-- Steps: +-- appID requests DeleteSubMenu with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if DeleteSubMenu is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the UI part of request with allowed parameters to HMI +-- SDL receives UI part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local addSubMenuRequestParams = { + menuID = 1000, + position = 500, + menuName ="SubMenupositive" +} + +local addSubMenuResponseUiParams = { + menuID = addSubMenuRequestParams.menuID, + menuParams = { + position = addSubMenuRequestParams.position, + menuName = addSubMenuRequestParams.menuName + } +} + +local addSubMenuAllParams = { + requestParams = addSubMenuRequestParams, + responseUiParams = addSubMenuResponseUiParams +} + +local deleteSubMenuRequestParams = { + menuID = addSubMenuRequestParams.menuID +} + +--[[ Local Functions ]] +local function addSubMenu(params, self) + local cid = self.mobileSession1:SendRPC("AddSubMenu", params.requestParams) + + params.responseUiParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("UI.AddSubMenu", params.responseUiParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +local function deleteSubMenu(params, self) + local cid = self.mobileSession1:SendRPC("DeleteSubMenu", params) + + params.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("UI.DeleteSubMenu", params) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("AddSubMenu", addSubMenu, {addSubMenuAllParams}) + +runner.Title("Test") +runner.Step("DeleteSubMenu Positive Case", deleteSubMenu, {deleteSubMenuRequestParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/007_Alert_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/007_Alert_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..8cd94f296b --- /dev/null +++ b/test_scripts/Smoke/API/007_Alert_PositiveCase_SUCCESS.lua @@ -0,0 +1,218 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: Alert +-- Item: Happy path +-- +-- Requirement summary: +-- [Alert] SUCCESS: request with UI portion and TTSChunks +-- +-- Description: +-- Mobile application sends valid Alert request with UI-related-params & with TTSChunks +-- and gets SUCCESS resultCode to both UI.Alert and TTS.Speak from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests Alert with UI-related-params & with TTSChunks + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if TTS interface is available on HMI +-- SDL checks if Alert is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the UI.Alert part of request with allowed parameters to HMI +-- SDL transfers the TTS.Speak part of request with allowed parameters to HMI +-- SDL receives UI.Alert part of response from HMI with "SUCCESS" result code +-- SDL receives TTS.Speak part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local step1SpecificParams = { + softButtons = { + { + type = "BOTH", + text = "Close", + image = { + value = "icon.png", + imageType = "DYNAMIC", + }, + isHighlighted = true, + softButtonID = 3, + systemAction = "DEFAULT_ACTION", + }, + { + type = "TEXT", + text = "Keep", + isHighlighted = true, + softButtonID = 4, + systemAction = "KEEP_CONTEXT", + }, + { + type = "IMAGE", + image = { + value = "icon.png", + imageType = "DYNAMIC", + }, + softButtonID = 5, + systemAction = "STEAL_FOCUS", + } + } +} + +local step2SpecificParams = { + duration = 5000 +} + +local requestParams = { + alertText1 = "alertText1", + alertText2 = "alertText2", + alertText3 = "alertText3", + ttsChunks = { + { + text = "TTSChunk", + type = "TEXT", + } + }, + playTone = true, + progressIndicator = true +} + +local responseUiParams = { + alertStrings = { + { + fieldName = requestParams.alertText1, + fieldText = requestParams.alertText1 + }, + { + fieldName = requestParams.alertText2, + fieldText = requestParams.alertText2 + }, + { + fieldName = requestParams.alertText3, + fieldText = requestParams.alertText3 + } + }, + alertType = "BOTH", + progressIndicator = requestParams.progressIndicator, +} + +local ttsSpeakRequestParams = { + ttsChunks = requestParams.ttsChunks, + speakType = "ALERT", + playTone = requestParams.playTone +} + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams, + ttsSpeakRequestParams = ttsSpeakRequestParams +} + +--[[ Local Functions ]] +local function sendOnSystemContext(self, ctx) + self.hmiConnection:SendNotification("UI.OnSystemContext", + { + appID = commonSmoke.getHMIAppId(), + systemContext = ctx + }) +end + +local function prepareAlertParams(params, additionalParams) + params.responseUiParams.appID = commonSmoke.getHMIAppId() + + if additionalParams.softButtons ~= nil then + params.requestParams.duration = nil + params.requestParams.softButtons = additionalParams.softButtons + params.responseUiParams.duration = nil; + params.responseUiParams.softButtons = additionalParams.softButtons + params.responseUiParams.softButtons[1].image.value = + commonSmoke.getPathToFileInStorage(putFileParams.requestParams.syncFileName) + params.responseUiParams.softButtons[3].image.value = + commonSmoke.getPathToFileInStorage(putFileParams.requestParams.syncFileName) + elseif additionalParams.duration ~= nil then + params.requestParams.softButtons = nil + params.requestParams.duration = additionalParams.duration + params.responseUiParams.softButtons = nil + params.responseUiParams.duration = additionalParams.duration + end +end + +local function alert(params, additionalParams, self) + prepareAlertParams(params, additionalParams) + + local responseDelay = 3000 + local cid = self.mobileSession1:SendRPC("Alert", params.requestParams) + + EXPECT_HMICALL("UI.Alert", params.responseUiParams) + :Do(function(_,data) + sendOnSystemContext(self, "ALERT") + + local alertId = data.id + local function alertResponse() + self.hmiConnection:SendResponse(alertId, "UI.Alert", "SUCCESS", { }) + sendOnSystemContext(self, "MAIN") + end + + RUN_AFTER(alertResponse, responseDelay) + end) + + params.ttsSpeakRequestParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("TTS.Speak", params.ttsSpeakRequestParams) + :Do(function(_,data) + self.hmiConnection:SendNotification("TTS.Started") + + local speakId = data.id + local function speakResponse() + self.hmiConnection:SendResponse(speakId, "TTS.Speak", "SUCCESS", { }) + self.hmiConnection:SendNotification("TTS.Stopped") + end + + RUN_AFTER(speakResponse, responseDelay - 1000) + end) + :ValidIf(function(_,data) + if #data.params.ttsChunks == 1 then + return true + else + return false, "ttsChunks array in TTS.Speak request has wrong element number." .. + " Expected 1, actual " .. tostring(#data.params.ttsChunks) + end + end) + + commonSmoke.expectOnHMIStatusWithAudioStateChanged(self) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) + +runner.Title("Test") +runner.Step("Alert with soft buttons Positive Case", alert, {allParams, step1SpecificParams}) +runner.Step("Alert with duration Positive Case", alert, {allParams, step2SpecificParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..a9c211df14 --- /dev/null +++ b/test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua @@ -0,0 +1,110 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: CreateInteractionChoiceSet +-- Item: Happy path +-- +-- Requirement summary: +-- [CreateInteractionChoiceSet] SUCCESS +-- +-- Description: +-- Mobile application sends valid CreateInteractionChoiceSet request with +-- {interactionChoiceSetID, ChoiceSet: [(choiceID1, vrCommands, params), +-- (choiceID2, vrCommands, params)] and SDL successfully stores UI-related +-- choices and gets successful responses to corresponding VR.AddCommands +-- (VR-related choices) from HMI. + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests CreateInteractionChoiceSet with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if VR interface is available on HMI +-- SDL checks if CreateInteractionChoiceSet is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the VR.AddCommand with allowed parameters to HMI +-- SDL receives successful responses to corresponding VR.AddCommands from HMI +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local requestParams = { + interactionChoiceSetID = 1001, + choiceSet = { + { + choiceID = 1001, + menuName ="Choice1001", + vrCommands = { + "Choice1001" + }, + image = { + value ="icon.png", + imageType ="DYNAMIC" + } + } + } +} + +local responseVrParams = { + cmdID = requestParams.interactionChoiceSetID, + type = "Choice", + vrCommands = requestParams.vrCommands +} + +local allParams = { + requestParams = requestParams, + responseVrParams = responseVrParams +} + +--[[ Local Functions ]] +local function createInteractionChoiceSet(params, self) + local cid = self.mobileSession1:SendRPC("CreateInteractionChoiceSet", params.requestParams) + + params.responseVrParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("VR.AddCommand", params.responseVrParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + if data.params.grammarID ~= nil then + return true + else + return false, "grammarID should not be empty" + end + end) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) + +runner.Title("Test") +runner.Step("CreateInteractionChoiceSet Positive Case", createInteractionChoiceSet, {allParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/009_DeleteInteractionChoiceSet_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/009_DeleteInteractionChoiceSet_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..6619d60c59 --- /dev/null +++ b/test_scripts/Smoke/API/009_DeleteInteractionChoiceSet_PositiveCase_SUCCESS.lua @@ -0,0 +1,138 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: DeleteInteractionChoiceSet +-- Item: Happy path +-- +-- Requirement summary: +-- [DeleteInteractionChoiceSet] SUCCESS choiceSet removal +-- +-- Description: +-- Mobile application sends valid DeleteInteractionChoiceSet request to SDL +-- and interactionChoiceSet with was successfully +-- removed on SDL and HMI for the application. + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level +-- d. Choice set with is created + +-- Steps: +-- appID requests DeleteInteractionChoiceSet request with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if VR interface is available on HMI +-- SDL checks if DeleteInteractionChoiceSet is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the VR.DeleteCommand with allowed parameters to HMI +-- SDL receives successful responses to corresponding VR.DeleteCommand from HMI +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local createRequestParams = { + interactionChoiceSetID = 1001, + choiceSet = { + { + choiceID = 1001, + menuName ="Choice1001", + vrCommands = { + "Choice1001" + }, + image = { + value ="icon.png", + imageType ="DYNAMIC" + } + } + } +} + +local createResponseVrParams = { + cmdID = createRequestParams.interactionChoiceSetID, + type = "Choice", + vrCommands = createRequestParams.vrCommands +} + +local createAllParams = { + requestParams = createRequestParams, + responseVrParams = createResponseVrParams +} + +local deleteRequestParams = { + interactionChoiceSetID = createRequestParams.interactionChoiceSetID +} + +local deleteResponseVrParams = { + cmdID = createRequestParams.interactionChoiceSetID, + type = "Choice" +} + +local deleteAllParams = { + requestParams = deleteRequestParams, + responseVrParams = deleteResponseVrParams +} + +--[[ Local Functions ]] +local function createInteractionChoiceSet(params, self) + local cid = self.mobileSession1:SendRPC("CreateInteractionChoiceSet", params.requestParams) + + params.responseVrParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("VR.AddCommand", params.responseVrParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + if data.params.grammarID ~= nil then + deleteResponseVrParams.grammarID = data.params.grammarID + return true + else + return false, "grammarID should not be empty" + end + end) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +local function deleteInteractionChoiceSet(params, self) + local cid = self.mobileSession1:SendRPC("DeleteInteractionChoiceSet", params.requestParams) + + params.responseVrParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("VR.DeleteCommand", params.responseVrParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) +runner.Step("CreateInteractionChoiceSet", createInteractionChoiceSet, {createAllParams}) + +runner.Title("Test") +runner.Step("DeleteInteractionChoiceSet Positive Case", deleteInteractionChoiceSet, {deleteAllParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/010_DeleteFile_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/010_DeleteFile_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..2b68c689fa --- /dev/null +++ b/test_scripts/Smoke/API/010_DeleteFile_PositiveCase_SUCCESS.lua @@ -0,0 +1,83 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: DeleteFile +-- Item: Happy path +-- +-- Requirement summary: +-- [DeleteFile] SUCCESS on successful file removal from an application folder +-- +-- Description: +-- Mobile application sends valid DeleteFile request with syncFileName + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level +-- d. File with syncFileName is exists + +-- Steps: +-- appID requests DeleteFile request with syncFileName + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if DeleteFile is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL removes an appropriate file with "syncFileName" in AppStorageFolder +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +-- SDL notifies HMI with OnFileRemoved(syncFileName) notification about the file has been removed +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local requestParams = { + syncFileName = putFileParams.requestParams.syncFileName +} + +local responseBcParams = { + fileName = putFileParams.requestParams.syncFileName, + fileType = putFileParams.requestParams.fileType +} + +local createAllParams = { + requestParams = requestParams, + responseBcParams = responseBcParams +} + +--[[ Local Functions ]] +local function deleteFile(params, self) + local cid = self.mobileSession1:SendRPC("DeleteFile", params.requestParams) + + params.responseBcParams.appID = commonSmoke.getHMIAppId() + params.responseBcParams.fileName = + commonSmoke.getPathToFileInStorage(params.responseBcParams.fileName) + EXPECT_HMINOTIFICATION("BasicCommunication.OnFileRemoved", params.responseBcParams) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) + +runner.Title("Test") +runner.Step("DeleteFile Positive Case", deleteFile, {createAllParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/011_ListFiles_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/011_ListFiles_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..e018036722 --- /dev/null +++ b/test_scripts/Smoke/API/011_ListFiles_PositiveCase_SUCCESS.lua @@ -0,0 +1,96 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: ListFiles +-- Item: Happy path +-- +-- Requirement summary: +-- [ListFiles]: SUCCESS result code +-- +-- Description: +-- Mobile application sends ListFiles request with valid parameters to SDL + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests ListFiles with valid parameters to SDL + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if ListFiles is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL provides the list of filenames which are stored in the app`s folder +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") + +--[[ Local Variables ]] +local testFileNamesList = { + string.rep("a", 251) .. ".png", + " SpaceBefore", + "icon.png" +} + +local putFileParams = { + requestParams = { + syncFileName = "", + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local requestParams = {} + +local responseParams = { + success = true, + resultCode = "SUCCESS", + spaceAvailable = 103878520 +} + +local allParams = { + requestParams = requestParams, + responseParams = responseParams +} + +--[[ Local Functions ]] +local function putFile(fileName, self) + putFileParams.requestParams.syncFileName = fileName + commonSmoke.putFile(putFileParams, 1, self) +end + +local function listFiles(params, self) + local cid = self.mobileSession1:SendRPC("ListFiles", params.requestParams) + + self.mobileSession1:ExpectResponse(cid, params.responseParams) + :ValidIf(function(_, data) + if not commonFunctions:is_table_equal(data.payload.filenames, testFileNamesList) then + return false, "\nExpected files:\n" .. commonFunctions:convertTableToString(testFileNamesList, 1) + .. "\nActual files:\n" .. commonFunctions:convertTableToString(data.payload.filenames, 1) + end + return true + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +for i, fileName in ipairs(testFileNamesList) do + runner.Step("Upload test file #" .. i, putFile, {fileName}) +end + +runner.Title("Test") +runner.Step("ListFiles Positive Case", listFiles, {allParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/commonSmoke.lua b/test_scripts/Smoke/commonSmoke.lua index 4c695f4bff..0705dfbf54 100644 --- a/test_scripts/Smoke/commonSmoke.lua +++ b/test_scripts/Smoke/commonSmoke.lua @@ -163,6 +163,11 @@ function commonSmoke.getSelfAndParams(...) return table.unpack(out, 1, table.maxn(out)) end +function commonSmoke.getHMIAppId(pAppId) + if not pAppId then pAppId = 1 end + return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] +end + function commonSmoke.getPathToFileInStorage(fileName) return commonSmoke.getPathToSDL() .. "storage/" .. commonSmoke.getMobileAppId() .. "_" @@ -197,6 +202,52 @@ function commonSmoke.splitString(inputStr, sep) return splitted end +function commonSmoke.expectOnHMIStatusWithAudioStateChanged(self, pAppId, request, level) + if pAppId == nil then pAppId = 1 end + if request == nil then request = "BOTH" end + if level == nil then level = "FULL" end + + local mobSession = commonSmoke.getMobileSession(pAppId, self) + local appParams = config["application" .. pAppId].registerAppInterfaceParams + + if appParams.isMediaApplication == true then + if request == "BOTH" then + mobSession:ExpectNotification("OnHMIStatus", + { systemContext = "ALERT", hmiLevel = level, audioStreamingState = "AUDIBLE" }, + { systemContext = "ALERT", hmiLevel = level, audioStreamingState = "ATTENUATED" }, + { systemContext = "ALERT", hmiLevel = level, audioStreamingState = "AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "AUDIBLE" }) + :Times(4) + elseif request == "speak" then + mobSession:ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "ATTENUATED" }, + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "AUDIBLE" }) + :Times(2) + elseif request == "alert" then + mobSession:ExpectNotification("OnHMIStatus", + { systemContext = "ALERT", hmiLevel = level, audioStreamingState = "AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "AUDIBLE" }) + :Times(2) + end + elseif appParams.isMediaApplication == false then + if request == "BOTH" then + mobSession:ExpectNotification("OnHMIStatus", + { systemContext = "ALERT", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }) + :Times(2) + elseif request == "speak" then + mobSession:ExpectNotification("OnHMIStatus") + :Times(0) + elseif request == "alert" then + mobSession:ExpectNotification("OnHMIStatus", + { systemContext = "ALERT", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }) + :Times(2) + end + end + +end + function commonSmoke.activateApp(pAppId, self) self, pAppId = commonSmoke.getSelfAndParams(pAppId, self) if not pAppId then pAppId = 1 end From c10d56e77cc00e56ac2c212a36656b192fa0d7db Mon Sep 17 00:00:00 2001 From: "Aleksandr Stasiuk (GitHub)" Date: Fri, 3 Nov 2017 11:57:37 -0400 Subject: [PATCH 182/681] Update template_of_script.lua --- test_scripts/template_of_script.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test_scripts/template_of_script.lua b/test_scripts/template_of_script.lua index 7570469323..dee6b29425 100644 --- a/test_scripts/template_of_script.lua +++ b/test_scripts/template_of_script.lua @@ -1,4 +1,7 @@ --------------------------------------------------------------------------------------------------- +-- User story: Link to Github +-- Use case: Link to Github + -- Requirement summary: -- Name(s) of requirement that is covered -- Name(s) of additional non-functional requirement(s) if applicable From 38abfa9b583c01a6bcf304699368f383e13ef344 Mon Sep 17 00:00:00 2001 From: "Aleksandr Stasiuk (GitHub)" Date: Fri, 3 Nov 2017 12:00:49 -0400 Subject: [PATCH 183/681] Update template_of_script.lua --- test_scripts/template_of_script.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/template_of_script.lua b/test_scripts/template_of_script.lua index dee6b29425..d59f4018cf 100644 --- a/test_scripts/template_of_script.lua +++ b/test_scripts/template_of_script.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- User story: Link to Github -- Use case: Link to Github - +-- -- Requirement summary: -- Name(s) of requirement that is covered -- Name(s) of additional non-functional requirement(s) if applicable From 0492e1f9aa4ef4d855ecb7ebd65db382b842f2f6 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Tue, 14 Nov 2017 10:55:23 +0200 Subject: [PATCH 184/681] Fix max file name length --- test_scripts/smoke_api.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test_scripts/smoke_api.lua b/test_scripts/smoke_api.lua index b391edfbf5..e004ac7537 100644 --- a/test_scripts/smoke_api.lua +++ b/test_scripts/smoke_api.lua @@ -24,7 +24,7 @@ require('user_modules/AppTypes') --[[ Local Variables ]] local iTimeout = 5000 -local strMaxLengthFileName255 = string.rep("a", 251) .. ".png" -- set max length file name +local strMaxLengthFileName242 = string.rep("a", 238) .. ".png" -- max is 242 since docker limitation local textPromtValue = {"Please speak one of the following commands,", "Please say a command,"} local storagePath = commonPreconditions:GetPathToSDL() .. "storage/" .. config.application1.registerAppInterfaceParams.appID .. "_" .. config.deviceMAC .. "/" @@ -514,7 +514,7 @@ end -- 2. PutFiles commonSteps:PutFile("PutFile_action.png", "action.png") - commonSteps:PutFile("PutFile_MaxLength_255Characters", strMaxLengthFileName255) + commonSteps:PutFile("PutFile_MaxLength_255Characters", strMaxLengthFileName242) commonSteps:PutFile("Putfile_SpaceBefore", " SpaceBefore") commonSteps:PutFile("Putfile_Icon.png", "icon.png") @@ -1219,7 +1219,7 @@ function Test:ListFiles() spaceAvailable = 103878520 }) :ValidIf(function(_, data) - local files_expected = { " SpaceBefore", strMaxLengthFileName255, "icon.png" } + local files_expected = { " SpaceBefore", strMaxLengthFileName242, "icon.png" } if not commonFunctions:is_table_equal(data.payload.filenames, files_expected) then return false, "\nExpected files:\n" .. commonFunctions:convertTableToString(files_expected, 1) .. "\nActual files:\n" .. commonFunctions:convertTableToString(data.payload.filenames, 1) From 4e2a84caeac1be1e09c829aa3ac3102356505168 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Tue, 14 Nov 2017 11:27:26 +0200 Subject: [PATCH 185/681] Increase duration for resumption --- user_modules/shared_testcases/commonStepsResumption.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_modules/shared_testcases/commonStepsResumption.lua b/user_modules/shared_testcases/commonStepsResumption.lua index f6c9a619da..882d5471b3 100644 --- a/user_modules/shared_testcases/commonStepsResumption.lua +++ b/user_modules/shared_testcases/commonStepsResumption.lua @@ -52,7 +52,7 @@ local function CheckTimeBoundaries(time) if exp.occurences == 2 then local time2 = timestamp() local time_to_resumption = time2 - time - if time_to_resumption >= timeout and time_to_resumption < (timeout + 500) then + if time_to_resumption >= timeout and time_to_resumption < (timeout + 1000) then commonFunctions:userPrint(33, "Time to HMI level resumption is " .. tostring(time_to_resumption) ..", expected ~ " .. timeout ) return true else From dd6fa7c43e290d4ce04bd79e1bf981b881ded965 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Tue, 14 Nov 2017 12:23:46 +0200 Subject: [PATCH 186/681] Stabilize script --- .../ATF_Resumption_heartbeat_disconnect.lua | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua index 2c6a3b362e..b3784329a2 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua @@ -36,6 +36,12 @@ require('user_modules/AppTypes') -- [[Local variables]] local default_app_params = config.application1.registerAppInterfaceParams +-- [[Local functions]] +local function connectMobile(self) + self.mobileConnection:Connect() + return EXPECT_EVENT(events.connectedEvent, "Connected") +end + --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") commonSteps:DeletePolicyTable() @@ -48,7 +54,7 @@ function Test:StartSDL_With_One_Activated_App() commonFunctions:userPrint(35, "HMI initialized") self:initHMI_onReady():Do(function () commonFunctions:userPrint(35, "HMI is ready") - self:connectMobile():Do(function () + connectMobile(self):Do(function () commonFunctions:userPrint(35, "Mobile Connected") self:startSession():Do(function () commonFunctions:userPrint(35, "App is registered") @@ -81,10 +87,15 @@ function Test:Wait_20_sec() self.mobileSession:StopHeartbeat() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {appID = self.applications[default_app_params], unexpectedDisconnect = true }) :Timeout(20000) + EXPECT_EVENT(events.disconnectedEvent, "Disconnected") + :Do(function() + print("Disconnected!!!") + end) + :Timeout(20000) end function Test:Connect_Mobile() - self:connectMobile() + connectMobile(self) end function Test:Register_And_Resume_App_And_Data() From 5f0a102a906c213d1094438ebbaf82c9d4324a82 Mon Sep 17 00:00:00 2001 From: Ira Lytvynenko Date: Tue, 14 Nov 2017 13:46:25 +0200 Subject: [PATCH 187/681] Fix script --- ..._Timeout_wait_response_PTU_PROPRIETARY.lua | 91 +++++++++++-------- 1 file changed, 51 insertions(+), 40 deletions(-) diff --git a/test_scripts/Policies/build_options/103_ATF_Timeout_wait_response_PTU_PROPRIETARY.lua b/test_scripts/Policies/build_options/103_ATF_Timeout_wait_response_PTU_PROPRIETARY.lua index 4cdf630067..638ce7accf 100644 --- a/test_scripts/Policies/build_options/103_ATF_Timeout_wait_response_PTU_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/103_ATF_Timeout_wait_response_PTU_PROPRIETARY.lua @@ -21,70 +21,81 @@ config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd40 --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') -local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') -local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local testCasesForPTS = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local mobile_session = require('mobile_session') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() testCasesForPolicyTable.Delete_Policy_table_snapshot() -commonPreconditions:Connecttest_without_ExitBySDLDisconnect_WithoutOpenConnectionRegisterApp("connecttest_ConnectMobile.lua") --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 --[[ General Settings for configuration ]] -Test = require('user_modules/connecttest_ConnectMobile') +Test = require('user_modules/dummy_connecttest') require('cardinalities') require('user_modules/AppTypes') -local mobile_session = require('mobile_session') +local default_app_params = config.application1.registerAppInterfaceParams --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") -function Test:Precondition_ConnectMobile() - self:connectMobile() -end - -function Test:Precondition_StartSession() - self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) - self.mobileSession:StartService(7) +function Test:Start_SDL() + self:runSDL() + commonFunctions:waitForSDLStart(self):Do(function() + self:initHMI():Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady():Do(function () + commonFunctions:userPrint(35, "HMI is ready") + self:connectMobile():Do(function () + commonFunctions:userPrint(35, "Mobile Connected") + end) + end) + end) + end) end --[[ Test ]] commonFunctions:newTestCasesGroup("Test") function Test:TestStep_PTS_Timeout_wait_response_PTU() - local correlationId = self.mobileSession:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered") - :Do(function(_,data) - self.HMIAppID = data.params.application.appID - end) - self.mobileSession:ExpectResponse(correlationId, { success = true, resultCode = "SUCCESS" }) - self.mobileSession:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) + self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) + local on_rpc_service_started = self.mobileSession:StartRPC() + on_rpc_service_started:Do(function() + local correlationId = self.mobileSession:SendRPC("RegisterAppInterface", default_app_params) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Do(function(_,data) + self.HMIAppID = data.params.application.appID + end) + self.mobileSession:ExpectResponse(correlationId, { success = true, resultCode = "SUCCESS" }) + self.mobileSession:ExpectNotification("OnHMIStatus", + {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATE_NEEDED"}) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATE_NEEDED"}) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate", {file = "/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json"}) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + local timeout_after_x_seconds_preloaded = + testCasesForPTS:get_data_from_Preloaded_PT("module_config.timeout_after_x_seconds") + local timeout_after_x_seconds = testCasesForPTS:get_data_from_PTS("module_config.timeout_after_x_seconds") - EXPECT_HMICALL("BasicCommunication.PolicyUpdate", {file = "/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json"}) - :Do(function(_,data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + if(timeout_after_x_seconds_preloaded ~= timeout_after_x_seconds) then + commonFunctions:printError("Error: PTS: timeout_after_x_seconds = "..data.params.timeout.. + "ms is not as expected. Expected: "..timeout_after_x_seconds_preloaded.."ms.") + return false + else + if(data.params.timeout ~= timeout_after_x_seconds) then + commonFunctions:printError("Error: data.params.timeout = "..data.params.timeout.. + "ms. Expected: "..timeout_after_x_seconds.."ms.") + return false + else + return true + end + end + end) end) - :ValidIf(function(_,data) - local timeout_after_x_seconds_preloaded = testCasesForPolicyTableSnapshot:get_data_from_Preloaded_PT("module_config.timeout_after_x_seconds") - local timeout_after_x_seconds = testCasesForPolicyTableSnapshot:get_data_from_PTS("module_config.timeout_after_x_seconds") - - if(timeout_after_x_seconds_preloaded ~= timeout_after_x_seconds) then - commonFunctions:printError("Error: PTS: timeout_after_x_seconds = "..data.params.timeout.."ms is not as expected. Expected: "..timeout_after_x_seconds_preloaded.."ms.") - return false - else - if(data.params.timeout ~= timeout_after_x_seconds) then - commonFunctions:printError("Error: data.params.timeout = "..data.params.timeout.."ms. Expected: "..timeout_after_x_seconds.."ms.") - return false - else - return true - end - end - end) end --[[ Postconditions ]] @@ -93,4 +104,4 @@ function Test.Postcondition_StopSDL() StopSDL() end -return Test \ No newline at end of file +return Test From e67c03fb5e5bf0cca1f11aebb2848aed9bc2e208 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Tue, 14 Nov 2017 17:05:38 +0200 Subject: [PATCH 188/681] ListFiles: Disable check on spaceAvailable parameter --- test_scripts/smoke_api.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/smoke_api.lua b/test_scripts/smoke_api.lua index e004ac7537..5134a64a95 100644 --- a/test_scripts/smoke_api.lua +++ b/test_scripts/smoke_api.lua @@ -1216,7 +1216,7 @@ function Test:ListFiles() { success = true, resultCode = "SUCCESS", - spaceAvailable = 103878520 + -- spaceAvailable = 103878520 -- disabled due to CI issue }) :ValidIf(function(_, data) local files_expected = { " SpaceBefore", strMaxLengthFileName242, "icon.png" } From 598449afc0f26de317baf97ae75df00c35d4455d Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 15 Nov 2017 12:50:19 +0200 Subject: [PATCH 189/681] Add additional data for structures --- test_scripts/smoke_api.lua | 52 +++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/test_scripts/smoke_api.lua b/test_scripts/smoke_api.lua index 5134a64a95..a03e98210b 100644 --- a/test_scripts/smoke_api.lua +++ b/test_scripts/smoke_api.lua @@ -3249,7 +3249,23 @@ local function setGVDResponse(paramsSend) gps = { longitudeDegrees = 25.5, - latitudeDegrees = 45.5 + latitudeDegrees = 45.5, + utcYear = 2010, + utcMonth = 1, + utcDay = 1, + utcHours = 2, + utcMinutes = 3, + utcSeconds = 4, + compassDirection = "NORTH", + pdop = 1.1, + hdop = 2.2, + vdop = 3.3, + actual = true, + satellites = 5, + dimension = "NO_FIX", + altitude = 4.4, + heading = 5.5, + speed = 100 }, speed = 100.5, rpm = 1000, @@ -3261,10 +3277,30 @@ local function setGVDResponse(paramsSend) prndl="DRIVE", tirePressure={ pressureTelltale = "ON", + leftFront = { status = "NORMAL" }, + rightFront = { status = "NORMAL" }, + leftRear = { status = "NORMAL" }, + rightRear = { status = "NORMAL" }, + innerLeftRear = { status = "NORMAL" }, + innerRightRear = { status = "NORMAL" } }, odometer= 8888, beltStatus={ - driverBeltDeployed = "NOT_SUPPORTED" + driverBeltDeployed = "NOT_SUPPORTED", + passengerBeltDeployed = "YES", + passengerBuckleBelted = "YES", + driverBuckleBelted = "YES", + leftRow2BuckleBelted = "YES", + passengerChildDetected = "YES", + rightRow2BuckleBelted = "YES", + middleRow2BuckleBelted = "YES", + middleRow3BuckleBelted = "YES", + leftRow3BuckleBelted = "YES", + rightRow3BuckleBelted = "YES", + leftRearInflatableBelted = "YES", + rightRearInflatableBelted = "YES", + middleRow1BeltDeployed = "YES", + middleRow1BuckleBelted = "YES" }, bodyInformation={ parkBrakeActive = true, @@ -3272,7 +3308,17 @@ local function setGVDResponse(paramsSend) ignitionStatus = "UNKNOWN" }, deviceStatus={ - voiceRecOn = true + voiceRecOn = true, + btIconOn = true, + callActive = true, + phoneRoaming = true, + textMsgAvailable = true, + battLevelStatus = "ONE_LEVEL_BARS", + stereoAudioOutputMuted = true, + monoAudioOutputMuted = true, + signalLevelStatus = "TWO_LEVEL_BARS", + primaryAudioSource = "USB", + eCallEventActive = true }, driverBraking="NOT_SUPPORTED", wiperStatus="MAN_LOW", From 9433be5aeb68bdc68874893a27c6dd8e8b4aab1c Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 15 Nov 2017 16:05:51 +0200 Subject: [PATCH 190/681] Remove turnText item --- test_scripts/smoke_api.lua | 10 ++-------- user_modules/hmi_values.lua | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/test_scripts/smoke_api.lua b/test_scripts/smoke_api.lua index a03e98210b..c6af915f6a 100644 --- a/test_scripts/smoke_api.lua +++ b/test_scripts/smoke_api.lua @@ -2771,12 +2771,6 @@ local function displayCap_textFields_Value() rows = 1, width = 500 }, - { - characterSet = "TYPE2SET", - name = "turnText", - rows = 1, - width = 500 - }, { characterSet = "TYPE2SET", name = "menuTitle", @@ -3452,7 +3446,7 @@ local function setExTurnList(size) navigationText = { fieldText = "Text", - fieldName = "turnText" + fieldName = "navigationText" }, turnIcon = { @@ -3469,7 +3463,7 @@ local function setExTurnList(size) navigationText = { fieldText = "Text"..i, - fieldName = "turnText" + fieldName = "navigationText" }, turnIcon = { diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index 7ba0271a07..e4d9fc261a 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -201,7 +201,7 @@ function module.getDefaultHMITable() "alertText1", "alertText2", "alertText3", "scrollableMessageBody", "initialInteractionText", "navigationText1", "navigationText2", "ETA", "totalDistance", "navigationText", "audioPassThruDisplayText1", "audioPassThruDisplayText2", "sliderHeader", "sliderFooter", "notificationText", "menuName", - "secondaryText", "tertiaryText", "timeToDestination", "turnText", "menuTitle", "locationName", + "secondaryText", "tertiaryText", "timeToDestination", "menuTitle", "locationName", "locationDescription", "addressLines", "phoneNumber" } local out = { } From f4a196f47c1e10901f8403bf4008f353aa669eb6 Mon Sep 17 00:00:00 2001 From: "Aleksandr Stasiuk (GitHub)" Date: Wed, 6 Dec 2017 12:07:04 +0200 Subject: [PATCH 191/681] Create .gitignore --- test_scripts/Core4.5_defects/.gitignore | 41 +++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 test_scripts/Core4.5_defects/.gitignore diff --git a/test_scripts/Core4.5_defects/.gitignore b/test_scripts/Core4.5_defects/.gitignore new file mode 100644 index 0000000000..6fd0a376de --- /dev/null +++ b/test_scripts/Core4.5_defects/.gitignore @@ -0,0 +1,41 @@ +# Compiled Lua sources +luac.out + +# luarocks build files +*.src.rock +*.zip +*.tar.gz + +# Object files +*.o +*.os +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo +*.def +*.exp + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + From 2b51c48940044edd7501efbfbf24f7983d326945 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 6 Dec 2017 12:17:50 +0200 Subject: [PATCH 192/681] Rename folder for 4.5 defects --- test_scripts/{Core4.5_defects => Defects}/.gitignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test_scripts/{Core4.5_defects => Defects}/.gitignore (100%) diff --git a/test_scripts/Core4.5_defects/.gitignore b/test_scripts/Defects/.gitignore similarity index 100% rename from test_scripts/Core4.5_defects/.gitignore rename to test_scripts/Defects/.gitignore From f0c19f251ef11e2774a42a7546865a44fbfb4cf2 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 6 Dec 2017 12:20:00 +0200 Subject: [PATCH 193/681] Create folder for 4.5 defects --- test_scripts/Defects/{ => 4.5}/.gitignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test_scripts/Defects/{ => 4.5}/.gitignore (100%) diff --git a/test_scripts/Defects/.gitignore b/test_scripts/Defects/4.5/.gitignore similarity index 100% rename from test_scripts/Defects/.gitignore rename to test_scripts/Defects/4.5/.gitignore From af1b7f2b7ebb0b4a12f977751487024e75edf3b9 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 6 Dec 2017 13:53:58 +0200 Subject: [PATCH 194/681] Renamed folder 4.5 to 4_5 --- test_scripts/Defects/{4.5 => 4_5}/.gitignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test_scripts/Defects/{4.5 => 4_5}/.gitignore (100%) diff --git a/test_scripts/Defects/4.5/.gitignore b/test_scripts/Defects/4_5/.gitignore similarity index 100% rename from test_scripts/Defects/4.5/.gitignore rename to test_scripts/Defects/4_5/.gitignore From a852d9256aa9eae893afbb7c58e853d60517ee30 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 6 Dec 2017 14:27:54 +0200 Subject: [PATCH 195/681] Script for 1772 issue --- .../4_5/1772_update_default_section.lua | 55 ++++ test_scripts/Defects/4_5/commonDefects.lua | 301 ++++++++++++++++++ 2 files changed, 356 insertions(+) create mode 100644 test_scripts/Defects/4_5/1772_update_default_section.lua create mode 100644 test_scripts/Defects/4_5/commonDefects.lua diff --git a/test_scripts/Defects/4_5/1772_update_default_section.lua b/test_scripts/Defects/4_5/1772_update_default_section.lua new file mode 100644 index 0000000000..0a353d3911 --- /dev/null +++ b/test_scripts/Defects/4_5/1772_update_default_section.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------- +-- 1. Make sure SDL is built with PROPRIETARY flag +-- 2. Start SDL and HMI, first ignition cycle +-- 3. Connect device +-- Steps: +-- 1. Register new application +-- 2. Perform PTU with updated default section(can use attached file ptu.json) +-- Expected result: +-- SDL performs update and sends OnPermissionsChange to mobile app with updated permissions. +-- DB has updated info. +-- Actual result: +-- SDL sends to HMI UP_TO_DATE status, but does not update permissions internally. +-- DB is not updated according to new permissions. +-- SDL does not send OnPermissionsChange to mobile app with new permissions. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonDefects = require('test_scripts/Defects/4_5/commonDefects') + +--[[ Local Functions ]] +local function ptuUpdateFunc(tbl) + local VDgroup = { + rpcs = { + GetVehicleData = { + hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, + parameters = {"gps"} + } + } + } + tbl.policy_table.functional_groupings["NewTestCaseGroup"] = VDgroup + tbl.policy_table.app_policies.default.groups = {"Base-4", "NewTestCaseGroup"} + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = nil +end + +local function GetVD(self) + local cid = self.mobileSession1:SendRPC("GetVehicleData", {gps = true}) + EXPECT_HMICALL("VehicleInfo.GetVehicleData") + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonDefects.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start) +runner.Step("RAI, PTU", commonDefects.rai_ptu, { ptuUpdateFunc }) +runner.Step("Activate App", commonDefects.activate_app) + +runner.Title("Test") +runner.Step("GetVD_requet_is_success", GetVD) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonDefects.postconditions) diff --git a/test_scripts/Defects/4_5/commonDefects.lua b/test_scripts/Defects/4_5/commonDefects.lua new file mode 100644 index 0000000000..0755febe0e --- /dev/null +++ b/test_scripts/Defects/4_5/commonDefects.lua @@ -0,0 +1,301 @@ +--------------------------------------------------------------------------------------------------- +-- RC common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 +config.ValidateSchema = false + +--[[ Required Shared libraries ]] +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +local mobile_session = require("mobile_session") +local json = require("modules/json") +local events = require("events") + +--[[ Local Variables ]] +local ptu_table = {} +local hmiAppIds = {} + +local commonDefect = {} + +commonDefect.timeout = 2000 +commonDefect.minTimeout = 500 +commonDefect.DEFAULT = "Default" +commonDefect.buttons = { climate = "FAN_UP", radio = "VOLUME_UP" } + +local function getPTUFromPTS(tbl) + tbl.policy_table.consumer_friendly_messages.messages = nil + tbl.policy_table.device_data = nil + tbl.policy_table.module_meta = nil + tbl.policy_table.usage_and_error_counts = nil + tbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + tbl.policy_table.module_config.preloaded_pt = nil + tbl.policy_table.module_config.preloaded_date = nil +end + +function commonDefect.DefaultStruct() + return { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + groups = { "Base-4"}, + } +end + +local function updatePTU(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonDefect.DefaultStruct() +end + +local function jsonFileToTable(file_name) + local f = io.open(file_name, "r") + local content = f:read("*all") + f:close() + return json.decode(content) +end + +local function tableToJsonFile(tbl, file_name) + local f = io.open(file_name, "w") + f:write(json.encode(tbl)) + f:close() +end + +local function checkIfPTSIsSentAsBinary(bin_data) + if not (bin_data ~= nil and string.len(bin_data) > 0) then + commonFunctions:userPrint(31, "PTS was not sent to Mobile in payload of OnSystemRequest") + end +end + +local function ptu(self, ptu_update_func) + local function getAppsCount() + local count = 0 + for _, _ in pairs(hmiAppIds) do + count = count + 1 + end + return count + end + + local policy_file_name = "PolicyTableUpdate" + local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + local ptu_file_name = os.tmpname() + local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) + EXPECT_HMIRESPONSE(requestId) + :Do(function() + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + { requestType = "PROPRIETARY", fileName = pts_file_name }) + getPTUFromPTS(ptu_table) + updatePTU(ptu_table) + if ptu_update_func then + ptu_update_func(ptu_table) + end + tableToJsonFile(ptu_table, ptu_file_name) + + local event = events.Event() + event.matches = function(e1, e2) return e1 == e2 end + EXPECT_EVENT(event, "PTU event") + :Timeout(11000) + + for id = 1, getAppsCount() do + local mobileSession = commonDefect.getMobileSession(self, id) + mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :Do(function(_, d2) + print("App ".. id .. " was used for PTU") + RAISE_EVENT(event, event, "PTU event") + checkIfPTSIsSentAsBinary(d2.binaryData) + local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", + { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, d3) + self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", + { policyfile = policy_file_path .. "/" .. policy_file_name }) + end) + mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + end) + :Times(AtMost(1)) + end + end) + os.remove(ptu_file_name) +end + +local function allow_sdl(self) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", + { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) +end + +function commonDefect.preconditions() + commonFunctions:SDLForceStop() + commonSteps:DeletePolicyTable() + commonSteps:DeleteLogsFiles() +end + +function commonDefect.start(pHMIParams, self) + self, pHMIParams = commonDefect.getSelfAndParams(pHMIParams, self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady(pHMIParams) + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + self:connectMobile() + :Do(function() + commonFunctions:userPrint(35, "Mobile connected") + allow_sdl(self) + end) + end) + end) + end) +end + +function commonDefect.startWithoutMobile(pHMIParams, self) + self, pHMIParams = commonDefect.getSelfAndParams(pHMIParams, self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady(pHMIParams) + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + end) + end) + end) +end + +function commonDefect.rai_ptu(ptu_update_func, self) + self, ptu_update_func = commonDefect.getSelfAndParams(ptu_update_func, self) + commonDefect.rai_ptu_n(1, ptu_update_func, self) +end + +function commonDefect.rai_ptu_n(id, ptu_update_func, self) + self, id, ptu_update_func = commonDefect.getSelfAndParams(id, ptu_update_func, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC + ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :Do(function(_, d2) + self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptu_table = jsonFileToTable(d2.params.file) + ptu(self, ptu_update_func) + end) + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + end) + end) +end + +function commonDefect.rai_n(id, self) + self, id = commonDefect.getSelfAndParams(id, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC + ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + end) + end) +end + +function commonDefect.delayedExp(timeout) + if not timeout then timeout = commonDefect.timeout end + commonTestCases:DelayedExp(timeout) +end + +function commonDefect.unregisterApp(pAppId, self) + local mobSession = commonDefect.getMobileSession(self, pAppId) + local hmiAppId = commonDefect.getHMIAppId(pAppId) + local cid = mobSession:SendRPC("UnregisterAppInterface",{}) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = hmiAppId, unexpectedDisconnect = false }) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +function commonDefect.activate_app(pAppId, self) + self, pAppId = commonDefect.getSelfAndParams(pAppId, self) + if not pAppId then pAppId = 1 end + local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + local mobSession = commonDefect.getMobileSession(self, pAppId) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + EXPECT_HMIRESPONSE(requestId) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + commonTestCases:DelayedExp(commonDefect.minTimeout) +end + +function commonDefect.putFile(pFileName, self) + self, pFileName = commonDefect.getSelfAndParams(pFileName, self) + local cid = self.mobileSession1:SendRPC( + "PutFile", + {syncFileName = pFileName, fileType = "GRAPHIC_PNG", persistentFile = false, systemFile = false}, + "files/icon.png") + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +function commonDefect.postconditions() + StopSDL() +end + +function commonDefect.getSelfAndParams(...) + local out = { } + local selfIdx = nil + for i,v in pairs({...}) do + if type(v) == "table" and v.isTest then + table.insert(out, v) + selfIdx = i + break + end + end + local idx = 2 + for i = 1, table.maxn({...}) do + if i ~= selfIdx then + out[idx] = ({...})[i] + idx = idx + 1 + end + end + return table.unpack(out, 1, table.maxn(out)) +end + +function commonDefect.getHMIAppId(pAppId) + if not pAppId then pAppId = 1 end + return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] +end + +function commonDefect.getMobileSession(self, pAppId) + if not pAppId then pAppId = 1 end + return self["mobileSession" .. pAppId] +end + +return commonDefect From e778fec5bdeb4de2f7baefc92a7278530b27a88e Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 7 Dec 2017 17:26:07 +0200 Subject: [PATCH 196/681] Script for reproducing issue 1881 --- ...tion_After_changing_HMIlevel_from_NONE.lua | 114 +++++++ test_scripts/Defects/4_5/commonDefects.lua | 301 ++++++++++++++++++ 2 files changed, 415 insertions(+) create mode 100644 test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua create mode 100644 test_scripts/Defects/4_5/commonDefects.lua diff --git a/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua b/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua new file mode 100644 index 0000000000..0583406010 --- /dev/null +++ b/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua @@ -0,0 +1,114 @@ +--------------------------------------------------------------------------------------------- +-- GitHub issue: https://github.com/SmartDeviceLink/sdl_core/issues/1881 +-- In case +-- mobile app registers and gets NONE HMILevel +-- and SDL receives OnDriverDistraction () fom HMI +-- SDL must: +-- transfer the last known (actual) OnDriverDistraction () to this mobile app right after this mobile app +-- changes HMILevel to any other than NONE +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonDefects = require('test_scripts/Defects/4_5/commonDefects') +local mobile_session = require("mobile_session") + +--[[ Local Variables ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true +config.application1.registerAppInterfaceParams.appHMIType = {"DEFAULT"} +config.application2.registerAppInterfaceParams.isMediaApplication = false +config.application2.registerAppInterfaceParams.appHMIType = {"DEFAULT"} + +--[[ Local Functions ]] +local function OnDDinNONE(id, params, self) + self.hmiConnection:SendNotification("UI.OnDriverDistraction", params) + self["mobileSession" .. id]:ExpectNotification("OnDriverDistraction") + :Times(0) + commonDefects.delayedExp(2000) +end + +local function OnDD(id, params, self) + self.hmiConnection:SendNotification("UI.OnDriverDistraction", params) + self["mobileSession" .. id]:ExpectNotification("OnDriverDistraction", params) +end + +local function OnDD2Apps(idres, id, params, self) + self.hmiConnection:SendNotification("UI.OnDriverDistraction", params) + self["mobileSession" .. id]:ExpectNotification("OnDriverDistraction") + :Times(0) + self["mobileSession" .. idres]:ExpectNotification("OnDriverDistraction", params) + commonDefects.delayedExp(2000) +end + +local function ActivationAppWithOnDD( params, self) + local hmiAppId = commonDefects.getHMIAppId(1) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = hmiAppId }) + EXPECT_HMIRESPONSE(requestId) + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + self.mobileSession1:ExpectNotification("OnDriverDistraction", params) +end + +local function RegisterAppWithOnDDResumption( params, self) + self.mobileSession1 = mobile_session.MobileSession(self, self.mobileConnection) + self.mobileSession1:StartService(7) + :Do(function() + local corId = self.mobileSession1:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config.application1.registerAppInterfaceParams.appName } }) + self.mobileSession1:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE" }, + { hmiLevel = "LIMITED" }) + :Times(2) + self.mobileSession1:ExpectNotification("OnPermissionsChange") + self.mobileSession2:ExpectNotification("OnDriverDistraction") + :Times(0) + self.mobileSession1:ExpectNotification("OnDriverDistraction", params) + commonDefects.delayedExp(1000) + end) + end) +end + +local function ActivationAppWithOnDD2Apps( params, self) + local hmiAppId = commonDefects.getHMIAppId(2) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = hmiAppId }) + EXPECT_HMIRESPONSE(requestId) + self.mobileSession2:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL"}) + self.mobileSession2:ExpectNotification("OnDriverDistraction", params) + self.mobileSession1:ExpectNotification("OnDriverDistraction") + :Times(0) + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "LIMITED"}) + commonDefects.delayedExp(1000) +end + +local function CloseSession(self) + self.mobileSession1:Stop() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonDefects.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start) +runner.Step("RAI, PTU", commonDefects.rai_ptu) + +runner.Title("Test") +runner.Step("Absence_OnDriverDistraction_in_NONE", OnDDinNONE, {1, {state = "DD_ON"}}) +runner.Step("OnDriverDistraction_in_FULL", ActivationAppWithOnDD, {{state = "DD_ON"}}) +runner.Step("UnregisterRegisterApp", commonDefects.unregisterApp, {1}) + +runner.Step("RAI_first_app", commonDefects.rai_n, {1}) +runner.Step("RAI_second_app", commonDefects.rai_ptu_n, {2}) +runner.Step("Activate_first_app", commonDefects.activate_app) +runner.Step("OnDriverDistraction_in_FULL_ansence_in_NONE", OnDD2Apps, {1, 2, {state = "DD_ON"}}) +runner.Step("OnDriverDistraction_changed_in_FULL_ansence_in_NONE", OnDD2Apps, {1, 2, {state = "DD_OFF"}}) +runner.Step("OnDriverDistraction_after_app_activation", ActivationAppWithOnDD2Apps, {{state = "DD_OFF"}}) + +runner.Step("CloseSession", CloseSession) +runner.Step("OnDriverDistraction_change_in_FULL", OnDD, {2,{state = "DD_ON"}}) +runner.Step("OnDriverDistraction_in_LIMITED_after_resumption", RegisterAppWithOnDDResumption, {{state = "DD_ON"}}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonDefects.postconditions) diff --git a/test_scripts/Defects/4_5/commonDefects.lua b/test_scripts/Defects/4_5/commonDefects.lua new file mode 100644 index 0000000000..0755febe0e --- /dev/null +++ b/test_scripts/Defects/4_5/commonDefects.lua @@ -0,0 +1,301 @@ +--------------------------------------------------------------------------------------------------- +-- RC common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 +config.ValidateSchema = false + +--[[ Required Shared libraries ]] +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +local mobile_session = require("mobile_session") +local json = require("modules/json") +local events = require("events") + +--[[ Local Variables ]] +local ptu_table = {} +local hmiAppIds = {} + +local commonDefect = {} + +commonDefect.timeout = 2000 +commonDefect.minTimeout = 500 +commonDefect.DEFAULT = "Default" +commonDefect.buttons = { climate = "FAN_UP", radio = "VOLUME_UP" } + +local function getPTUFromPTS(tbl) + tbl.policy_table.consumer_friendly_messages.messages = nil + tbl.policy_table.device_data = nil + tbl.policy_table.module_meta = nil + tbl.policy_table.usage_and_error_counts = nil + tbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + tbl.policy_table.module_config.preloaded_pt = nil + tbl.policy_table.module_config.preloaded_date = nil +end + +function commonDefect.DefaultStruct() + return { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + groups = { "Base-4"}, + } +end + +local function updatePTU(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonDefect.DefaultStruct() +end + +local function jsonFileToTable(file_name) + local f = io.open(file_name, "r") + local content = f:read("*all") + f:close() + return json.decode(content) +end + +local function tableToJsonFile(tbl, file_name) + local f = io.open(file_name, "w") + f:write(json.encode(tbl)) + f:close() +end + +local function checkIfPTSIsSentAsBinary(bin_data) + if not (bin_data ~= nil and string.len(bin_data) > 0) then + commonFunctions:userPrint(31, "PTS was not sent to Mobile in payload of OnSystemRequest") + end +end + +local function ptu(self, ptu_update_func) + local function getAppsCount() + local count = 0 + for _, _ in pairs(hmiAppIds) do + count = count + 1 + end + return count + end + + local policy_file_name = "PolicyTableUpdate" + local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + local ptu_file_name = os.tmpname() + local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) + EXPECT_HMIRESPONSE(requestId) + :Do(function() + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + { requestType = "PROPRIETARY", fileName = pts_file_name }) + getPTUFromPTS(ptu_table) + updatePTU(ptu_table) + if ptu_update_func then + ptu_update_func(ptu_table) + end + tableToJsonFile(ptu_table, ptu_file_name) + + local event = events.Event() + event.matches = function(e1, e2) return e1 == e2 end + EXPECT_EVENT(event, "PTU event") + :Timeout(11000) + + for id = 1, getAppsCount() do + local mobileSession = commonDefect.getMobileSession(self, id) + mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :Do(function(_, d2) + print("App ".. id .. " was used for PTU") + RAISE_EVENT(event, event, "PTU event") + checkIfPTSIsSentAsBinary(d2.binaryData) + local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", + { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, d3) + self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", + { policyfile = policy_file_path .. "/" .. policy_file_name }) + end) + mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + end) + :Times(AtMost(1)) + end + end) + os.remove(ptu_file_name) +end + +local function allow_sdl(self) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", + { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) +end + +function commonDefect.preconditions() + commonFunctions:SDLForceStop() + commonSteps:DeletePolicyTable() + commonSteps:DeleteLogsFiles() +end + +function commonDefect.start(pHMIParams, self) + self, pHMIParams = commonDefect.getSelfAndParams(pHMIParams, self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady(pHMIParams) + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + self:connectMobile() + :Do(function() + commonFunctions:userPrint(35, "Mobile connected") + allow_sdl(self) + end) + end) + end) + end) +end + +function commonDefect.startWithoutMobile(pHMIParams, self) + self, pHMIParams = commonDefect.getSelfAndParams(pHMIParams, self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady(pHMIParams) + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + end) + end) + end) +end + +function commonDefect.rai_ptu(ptu_update_func, self) + self, ptu_update_func = commonDefect.getSelfAndParams(ptu_update_func, self) + commonDefect.rai_ptu_n(1, ptu_update_func, self) +end + +function commonDefect.rai_ptu_n(id, ptu_update_func, self) + self, id, ptu_update_func = commonDefect.getSelfAndParams(id, ptu_update_func, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC + ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :Do(function(_, d2) + self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptu_table = jsonFileToTable(d2.params.file) + ptu(self, ptu_update_func) + end) + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + end) + end) +end + +function commonDefect.rai_n(id, self) + self, id = commonDefect.getSelfAndParams(id, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC + ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + end) + end) +end + +function commonDefect.delayedExp(timeout) + if not timeout then timeout = commonDefect.timeout end + commonTestCases:DelayedExp(timeout) +end + +function commonDefect.unregisterApp(pAppId, self) + local mobSession = commonDefect.getMobileSession(self, pAppId) + local hmiAppId = commonDefect.getHMIAppId(pAppId) + local cid = mobSession:SendRPC("UnregisterAppInterface",{}) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = hmiAppId, unexpectedDisconnect = false }) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +function commonDefect.activate_app(pAppId, self) + self, pAppId = commonDefect.getSelfAndParams(pAppId, self) + if not pAppId then pAppId = 1 end + local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + local mobSession = commonDefect.getMobileSession(self, pAppId) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + EXPECT_HMIRESPONSE(requestId) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + commonTestCases:DelayedExp(commonDefect.minTimeout) +end + +function commonDefect.putFile(pFileName, self) + self, pFileName = commonDefect.getSelfAndParams(pFileName, self) + local cid = self.mobileSession1:SendRPC( + "PutFile", + {syncFileName = pFileName, fileType = "GRAPHIC_PNG", persistentFile = false, systemFile = false}, + "files/icon.png") + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +function commonDefect.postconditions() + StopSDL() +end + +function commonDefect.getSelfAndParams(...) + local out = { } + local selfIdx = nil + for i,v in pairs({...}) do + if type(v) == "table" and v.isTest then + table.insert(out, v) + selfIdx = i + break + end + end + local idx = 2 + for i = 1, table.maxn({...}) do + if i ~= selfIdx then + out[idx] = ({...})[i] + idx = idx + 1 + end + end + return table.unpack(out, 1, table.maxn(out)) +end + +function commonDefect.getHMIAppId(pAppId) + if not pAppId then pAppId = 1 end + return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] +end + +function commonDefect.getMobileSession(self, pAppId) + if not pAppId then pAppId = 1 end + return self["mobileSession" .. pAppId] +end + +return commonDefect From 8a293918c268653ad34bd3276fe68c3423c452f9 Mon Sep 17 00:00:00 2001 From: Ira Lytvynenko Date: Thu, 7 Dec 2017 17:58:41 +0200 Subject: [PATCH 197/681] Script to verify that SDL attach binary data to OnSystemRequest notification during PTU --- .../Defects/4_5/1376_PTU_all_flows.lua | 269 ++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 test_scripts/Defects/4_5/1376_PTU_all_flows.lua diff --git a/test_scripts/Defects/4_5/1376_PTU_all_flows.lua b/test_scripts/Defects/4_5/1376_PTU_all_flows.lua new file mode 100644 index 0000000000..a6cf65136e --- /dev/null +++ b/test_scripts/Defects/4_5/1376_PTU_all_flows.lua @@ -0,0 +1,269 @@ +--------------------------------------------------------------------------------------------- +-- Script verifies PTU sequence +-- Supported PROPRIETARY, EXTERNAL_PROPRIETARY and HTTP flows +--------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local mobile_session = require("mobile_session") +local json = require("modules/json") +local atf_logger = require("atf_logger") +local sdl = require("SDL") +local commonSteps = require("user_modules/shared_testcases/commonSteps") + +--[[ General configuration parameters ]] +config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 + +--[[ Local Variables ]] +local flowType = { + PROPRIETARY = 1, + EXTERNAL_PROPRIETARY = 2, + HTTP = 3 +} + +--[[ Local Functions ]] +local function preconditions() + commonFunctions:SDLForceStop() + commonSteps:DeletePolicyTable() + commonSteps:DeleteLogsFiles() +end + +local function allowSDL(self) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", + { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) +end + +local function start(self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady() + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + self:connectMobile() + :Do(function() + commonFunctions:userPrint(35, "Mobile connected") + allowSDL(self) + end) + end) + end) + end) +end + +local function log(...) + local str = "[" .. atf_logger.formated_time(true) .. "]" + for i, p in pairs({...}) do + local delimiter = "\t" + if i == 1 then delimiter = " " end + str = str .. delimiter .. p + end + commonFunctions:userPrint(35, str) +end + +local function ptsToTable(pts_f) + local f = io.open(pts_f, "r") + local content = f:read("*all") + f:close() + return json.decode(content) +end + +local function getPTUFromPTS(ptu) + ptu.policy_table.consumer_friendly_messages.messages = nil + ptu.policy_table.device_data = nil + ptu.policy_table.module_meta = nil + ptu.policy_table.usage_and_error_counts = nil + ptu.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + ptu.policy_table.module_config.preloaded_pt = nil + ptu.policy_table.module_config.preloaded_date = nil + -- + ptu.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE" + } + ptu.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID]["groups"] = { + "Base-4", "Base-6" + } +end + +local function storePTUInFile(ptu, ptu_file_name) + local f = io.open(ptu_file_name, "w") + f:write(json.encode(ptu)) + f:close() +end + +local function checkIfPTSIsSentAsBinary(bin_data, pFlow) + local pt = nil + if flowType[pFlow] == flowType.PROPRIETARY then + pt = json.decode(bin_data).HTTPRequest.body + elseif flowType[pFlow] == flowType.EXTERNAL_PROPRIETARY or flowType[pFlow] == flowType.HTTP then + pt = bin_data + end + pt = json.decode(pt) + if not pt.policy_table then + commonFunctions:userPrint(31, "PTS was not sent to Mobile in payload of OnSystemRequest") + end +end + +local function ptuProprietary(ptu_table, self, pFlow) + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" + .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + local ptu_file_name = os.tmpname() + local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) + log("HMI->SDL: RQ: SDL.GetURLS") + EXPECT_HMIRESPONSE(requestId) + :Do(function() + log("SDL->HMI: RS: SDL.GetURLS") + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + { requestType = "PROPRIETARY", fileName = pts_file_name }) + log("HMI->SDL: N: BC.OnSystemRequest") + getPTUFromPTS(ptu_table) + storePTUInFile(ptu_table, ptu_file_name) + self.mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :Do(function(_, d) + checkIfPTSIsSentAsBinary(d.binaryData, pFlow) + log("SDL->MOB: N: OnSystemRequest") + local corIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", + { requestType = "PROPRIETARY" }, ptu_file_name) + log("MOB->SDL: RQ: SystemRequest") + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, dd) + log("SDL->HMI: RQ: BC.SystemRequest") + self.hmiConnection:SendResponse(dd.id, dd.method, "SUCCESS", { }) + log("HMI->SDL: RS: SUCCESS: BC.SystemRequest") + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", + { policyfile = dd.params.fileName }) + log("HMI->SDL: N: SDL.OnReceivedPolicyUpdate") + end) + self.mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS"}) + :Do(function() os.remove(ptu_file_name) end) + log("SDL->MOB: RS: SUCCESS: SystemRequest") + end) + end) +end + +local function ptuHttp(ptu_table, self) + local policy_file_name = "PolicyTableUpdate" + local ptu_file_name = os.tmpname() + getPTUFromPTS(ptu_table) + storePTUInFile(ptu_table, ptu_file_name) + local corId = self.mobileSession:SendRPC("SystemRequest", + { requestType = "HTTP", fileName = policy_file_name }, ptu_file_name) + log("MOB->SDL: RQ: SystemRequest") + self.mobileSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + log("SDL->MOB: RS: SUCCESS: SystemRequest") + end) + os.remove(ptu_file_name) +end + +local function expOnStatusUpdate() + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, {status = "UP_TO_DATE" }) + :Do(function(_, d) + log("SDL->HMI: N: SDL.OnStatusUpdate", d.params.status) + end) + :Times(3) +end + +local function failInCaseIncorrectPTU(pRequestName, self) + self:FailTestCase(pRequestName .. " was sent more than once (PTU update was incorrect)") +end + +local function raiPTU(self) + expOnStatusUpdate() -- temp solution due to issue in SDL: + -- SDL.OnStatusUpdate(UPDATE_NEEDED) notification is sent before BC.OnAppRegistered (EXTERNAL_PROPRIETARY flow) + + self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) + self.mobileSession:StartService(7) + :Do(function() + local corId = self.mobileSession:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) + log("MOB->SDL: RQ: RegisterAppInterface") + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config.application1.registerAppInterfaceParams.appName } }) + :Do(function() + log("SDL->HMI: N: BC.OnAppRegistered") + if sdl.buildOptions.extendedPolicy == "PROPRIETARY" + or sdl.buildOptions.extendedPolicy == "EXTERNAL_PROPRIETARY" then + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :Do(function(e, d) + if e.occurences == 1 then -- SDL send BC.PolicyUpdate more than once if PTU update was incorrect + log("SDL->HMI: RQ: BC.PolicyUpdate") + local ptu_table = ptsToTable(d.params.file) + self.hmiConnection:SendResponse(d.id, d.method, "SUCCESS", { }) + log("HMI->SDL: RS: BC.PolicyUpdate") + ptuProprietary(ptu_table, self, sdl.buildOptions.extendedPolicy) + else + failInCaseIncorrectPTU("BC.PolicyUpdate", self) + end + end) + elseif sdl.buildOptions.extendedPolicy == "HTTP" then + self.mobileSession:ExpectNotification("OnSystemRequest") + :Do(function(e, d) + log("SDL->MOB: N: OnSystemRequest", e.occurences, d.payload.requestType) + if d.payload.requestType == "HTTP" then + if e.occurences <= 2 then -- SDL send OnSystemRequest more than once if PTU update was incorrect + checkIfPTSIsSentAsBinary(d.binaryData, sdl.buildOptions.extendedPolicy) + if d.binaryData then + local ptu_table = json.decode(d.binaryData) + ptuHttp(ptu_table, self) + end + else + failInCaseIncorrectPTU("OnSystemRequest", self) + end + end + end) + :Times(2) + end + end) + self.mobileSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + log("SDL->MOB: RS: RegisterAppInterface") + self.mobileSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Do(function(_, d) + log("SDL->MOB: N: OnHMIStatus", d.payload.hmiLevel) + end) + self.mobileSession:ExpectNotification("OnPermissionsChange") + :Do(function() + log("SDL->MOB: N: OnPermissionsChange") + end) + :Times(2) + end) + end) +end + +local function checkPTUStatus(self) + local reqId = self.hmiConnection:SendRequest("SDL.GetStatusUpdate") + log("HMI->SDL: RQ: SDL.GetStatusUpdate") + EXPECT_HMIRESPONSE(reqId, { result = { status = "UP_TO_DATE" }}) + :Do(function(_, d) + log("HMI->SDL: RS: SDL.GetStatusUpdate", tostring(d.result.status)) + end) +end + +local function printSDLConfig() + commonFunctions:printTable(sdl.buildOptions) +end + +local function postconditions() + StopSDL() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", preconditions) +runner.Step("Start SDL, HMI, connect Mobile", start) +runner.Step("SDL Configuration", printSDLConfig) + +runner.Title("Test") +runner.Step("RAI, PTU", raiPTU) +runner.Step("Check Status", checkPTUStatus) + +runner.Title("Postconditions") +runner.Step("Stop SDL", postconditions) From 5e263af92ed4f923da298038ced738a828884da2 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Sun, 10 Dec 2017 09:46:26 +0200 Subject: [PATCH 198/681] Script for issue 1921 --- ...Invalid_PT_after_cutting_unknow_values.lua | 126 ++++++ test_scripts/Defects/4_5/commonDefects.lua | 389 ++++++++++++++++++ 2 files changed, 515 insertions(+) create mode 100644 test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua create mode 100644 test_scripts/Defects/4_5/commonDefects.lua diff --git a/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua b/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua new file mode 100644 index 0000000000..d43655ef3d --- /dev/null +++ b/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua @@ -0,0 +1,126 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1921 +-- Precondition: +-- 1. SDL and HMI are started. +-- 2. App is registered. +-- Steps: +-- 1. SDL received UpdatedPT with at least one or +-- and after cutting off or UpdatedPT is invalid +-- Expected result: SDL must log the error internally and discard Policy Table Update +-- Actual result:N/A +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonDefects = require('test_scripts/Defects/4_5/commonDefects') +local commonFunctions = require('user_modules/shared_testcases/commonFunctions') + +--[[ Local Functions ]] +local CuttingUnknownStatus = false + +--[[ Local Functions ]] +local function ptuUpdateFunc(tbl) + local VDgroup = { + rpcs = { + GetVehicleData = { + hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, + parameters = {"gps"} + }, + SubscribeVehicleData = { + hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, + newParameter = {"value"} + }, + UnknownAPI = { + hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, + parameters = {"gps"} + }, + SendLocation = { + hmi_levels = {"BACKGROUND", "FULL", "LIMITED"} + } + } + } + tbl.policy_table.functional_groupings["NewTestCaseGroup"] = VDgroup + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = + {"Base-4", "NewTestCaseGroup"} +end + +local function NotValidPtuUpdateFunc(tbl) + local VDgroup = { + rpcs = { + GetVehicleData = { + hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, + parameters = {"gps"} + }, + SubscribeVehicleData = { + hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, + newParameter = {"value"} + }, + UnknownAPI = { + hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, + parameters = {"gps"} + }, + SendLocation = { + -- missed mandatory hmi_levels parameter + } + } + } + tbl.policy_table.functional_groupings["NewTestCaseGroup"] = VDgroup + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = + {"Base-4", "NewTestCaseGroup"} +end + +local function CheckCuttingUnknowValues(self) + commonDefects.rai_ptu_n_without_OnPermissionsChange(1, ptuUpdateFunc,self) + self.mobileSession1:ExpectNotification("OnPermissionsChange") + :Times(2) + :ValidIf(function(_,data) + local ErrorStatus = false + local ErrorMessage = "" + if #data.payload.permissionItem ~= 0 then + for i=1, #data.payload.permissionItem do + if data.payload.permissionItem[i].rpcName == "UnknownAPI" then + ErrorStatus = true + CuttingUnknownStatus = true + ErrorMessage = ErrorMessage .. " OnPermissionsChange contains unknown_RPC value.\n" + end + if data.payload.permissionItem[i].newParameter then + ErrorStatus = true + CuttingUnknownStatus = true + ErrorMessage = ErrorMessage .. " OnPermissionsChange contains unknown_parameter value.\n" + end + end + else + ErrorStatus = true + ErrorMessage = ErrorMessage .. "OnPermissionsChange is not contain permissionItem elements" + end + if ErrorStatus == true then + return false, ErrorMessage + else + return true + end + end) + commonFunctions:userPrint(33, "Check PTU content of PTU attempt in SDL log by message 'PTU content is'.\n" + .. "'policy_table' must not contain 'newParameter' and 'UnknownAPI' values.") +end + +local function InvalidPTAfterCutingUnknownValues(self) + if CuttingUnknownStatus == true then + self:FailTestCase("Unknown values are not cut from PT, so test case is not executed.") + else + commonDefects.UnsuccessPTU(NotValidPtuUpdateFunc,self) + commonFunctions:userPrint(33, "Check PTU content of second PTU attempt in SDL log by message" .. + " 'PTU content is'.\n'policy_table' must not contain 'newParameter' and 'UnknownAPI' values.") + end +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonDefects.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start) + +runner.Title("Test") +runner.Step("Check_cutting_unknown_values_from_PT", CheckCuttingUnknowValues) +runner.Step("Invalid_PTU_after_cuting_unknown_values", InvalidPTAfterCutingUnknownValues) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonDefects.postconditions) + diff --git a/test_scripts/Defects/4_5/commonDefects.lua b/test_scripts/Defects/4_5/commonDefects.lua new file mode 100644 index 0000000000..464589873d --- /dev/null +++ b/test_scripts/Defects/4_5/commonDefects.lua @@ -0,0 +1,389 @@ +--------------------------------------------------------------------------------------------------- +-- RC common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 +config.ValidateSchema = false + +--[[ Required Shared libraries ]] +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +local mobile_session = require("mobile_session") +local json = require("modules/json") +local events = require("events") + +--[[ Local Variables ]] +local ptu_table = {} +local hmiAppIds = {} + +local commonDefect = {} + +commonDefect.timeout = 2000 +commonDefect.minTimeout = 500 +commonDefect.DEFAULT = "Default" +commonDefect.buttons = { climate = "FAN_UP", radio = "VOLUME_UP" } + +local function getPTUFromPTS(tbl) + tbl.policy_table.consumer_friendly_messages.messages = nil + tbl.policy_table.device_data = nil + tbl.policy_table.module_meta = nil + tbl.policy_table.usage_and_error_counts = nil + tbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + tbl.policy_table.module_config.preloaded_pt = nil + tbl.policy_table.module_config.preloaded_date = nil +end + +function commonDefect.DefaultStruct() + return { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + groups = { "Base-4"}, + } +end + +local function updatePTU(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonDefect.DefaultStruct() +end + +local function jsonFileToTable(file_name) + local f = io.open(file_name, "r") + local content = f:read("*all") + f:close() + return json.decode(content) +end + +local function tableToJsonFile(tbl, file_name) + local f = io.open(file_name, "w") + f:write(json.encode(tbl)) + f:close() +end + +local function checkIfPTSIsSentAsBinary(bin_data) + if not (bin_data ~= nil and string.len(bin_data) > 0) then + commonFunctions:userPrint(31, "PTS was not sent to Mobile in payload of OnSystemRequest") + end +end + +local function ptu(self, ptu_update_func) + local function getAppsCount() + local count = 0 + for _, _ in pairs(hmiAppIds) do + count = count + 1 + end + return count + end + + local policy_file_name = "PolicyTableUpdate" + local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + local ptu_file_name = os.tmpname() + local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) + EXPECT_HMIRESPONSE(requestId) + :Do(function() + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + { requestType = "PROPRIETARY", fileName = pts_file_name }) + getPTUFromPTS(ptu_table) + updatePTU(ptu_table) + if ptu_update_func then + ptu_update_func(ptu_table) + end + tableToJsonFile(ptu_table, ptu_file_name) + + local event = events.Event() + event.matches = function(e1, e2) return e1 == e2 end + EXPECT_EVENT(event, "PTU event") + :Timeout(11000) + + for id = 1, getAppsCount() do + local mobileSession = commonDefect.getMobileSession(self, id) + mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :Do(function(_, d2) + print("App ".. id .. " was used for PTU") + RAISE_EVENT(event, event, "PTU event") + checkIfPTSIsSentAsBinary(d2.binaryData) + local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", + { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, d3) + self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", + { policyfile = policy_file_path .. "/" .. policy_file_name }) + end) + mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + end) + :Times(AtMost(1)) + end + end) + os.remove(ptu_file_name) +end + +local function allow_sdl(self) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", + { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) +end + +function commonDefect.preconditions() + commonFunctions:SDLForceStop() + commonSteps:DeletePolicyTable() + commonSteps:DeleteLogsFiles() +end + +function commonDefect.start(pHMIParams, self) + self, pHMIParams = commonDefect.getSelfAndParams(pHMIParams, self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady(pHMIParams) + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + self:connectMobile() + :Do(function() + commonFunctions:userPrint(35, "Mobile connected") + allow_sdl(self) + end) + end) + end) + end) +end + +function commonDefect.startWithoutMobile(pHMIParams, self) + self, pHMIParams = commonDefect.getSelfAndParams(pHMIParams, self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady(pHMIParams) + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + end) + end) + end) +end + +function commonDefect.rai_ptu(ptu_update_func, self) + self, ptu_update_func = commonDefect.getSelfAndParams(ptu_update_func, self) + commonDefect.rai_ptu_n(1, ptu_update_func, self) +end + +function commonDefect.rai_ptu_n(id, ptu_update_func, self) + self, id, ptu_update_func = commonDefect.getSelfAndParams(id, ptu_update_func, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC + ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :Do(function(_, d2) + self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptu_table = jsonFileToTable(d2.params.file) + ptu(self, ptu_update_func) + end) + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + end) + end) +end + +function commonDefect.rai_ptu_n_without_OnPermissionsChange(id, ptu_update_func, self) + self, id, ptu_update_func = commonDefect.getSelfAndParams(id, ptu_update_func, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC + ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :Do(function(_, d2) + self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptu_table = jsonFileToTable(d2.params.file) + ptu(self, ptu_update_func) + end) + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + end) + end) +end + +function commonDefect.UnsuccessPTU(ptu_update_func, self) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UPDATE_NEEDED" }) + :Times(AtLeast(1)) + + local function getAppsCount() + local count = 0 + for _, _ in pairs(hmiAppIds) do + count = count + 1 + end + return count + end + + local policy_file_name = "PolicyTableUpdate" + local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + local ptu_file_name = os.tmpname() + local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) + EXPECT_HMIRESPONSE(requestId) + :Do(function() + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + { requestType = "PROPRIETARY", fileName = pts_file_name }) + getPTUFromPTS(ptu_table) + updatePTU(ptu_table) + if ptu_update_func then + ptu_update_func(ptu_table) + end + tableToJsonFile(ptu_table, ptu_file_name) + + local event = events.Event() + event.matches = function(e1, e2) return e1 == e2 end + EXPECT_EVENT(event, "PTU event") + :Timeout(11000) + + for id = 1, getAppsCount() do + local mobileSession = commonDefect.getMobileSession(self, id) + mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :Do(function(_, d2) + print("App ".. id .. " was used for PTU") + RAISE_EVENT(event, event, "PTU event") + checkIfPTSIsSentAsBinary(d2.binaryData) + local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", + { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, d3) + self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", + { policyfile = policy_file_path .. "/" .. policy_file_name }) + end) + mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + end) + :Times(AtMost(1)) + end + end) + os.remove(ptu_file_name) +end + +function commonDefect.rai_n(id, self) + self, id = commonDefect.getSelfAndParams(id, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC + ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + end) + end) +end + +function commonDefect.delayedExp(timeout) + if not timeout then timeout = commonDefect.timeout end + commonTestCases:DelayedExp(timeout) +end + +function commonDefect.unregisterApp(pAppId, self) + local mobSession = commonDefect.getMobileSession(self, pAppId) + local hmiAppId = commonDefect.getHMIAppId(pAppId) + local cid = mobSession:SendRPC("UnregisterAppInterface",{}) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = hmiAppId, unexpectedDisconnect = false }) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +function commonDefect.activate_app(pAppId, self) + self, pAppId = commonDefect.getSelfAndParams(pAppId, self) + if not pAppId then pAppId = 1 end + local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + local mobSession = commonDefect.getMobileSession(self, pAppId) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + EXPECT_HMIRESPONSE(requestId) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + commonTestCases:DelayedExp(commonDefect.minTimeout) +end + +function commonDefect.putFile(pFileName, self) + self, pFileName = commonDefect.getSelfAndParams(pFileName, self) + local cid = self.mobileSession1:SendRPC( + "PutFile", + {syncFileName = pFileName, fileType = "GRAPHIC_PNG", persistentFile = false, systemFile = false}, + "files/icon.png") + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +function commonDefect.postconditions() + StopSDL() +end + +function commonDefect.getSelfAndParams(...) + local out = { } + local selfIdx = nil + for i,v in pairs({...}) do + if type(v) == "table" and v.isTest then + table.insert(out, v) + selfIdx = i + break + end + end + local idx = 2 + for i = 1, table.maxn({...}) do + if i ~= selfIdx then + out[idx] = ({...})[i] + idx = idx + 1 + end + end + return table.unpack(out, 1, table.maxn(out)) +end + +function commonDefect.getHMIAppId(pAppId) + if not pAppId then pAppId = 1 end + return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] +end + +function commonDefect.getMobileSession(self, pAppId) + if not pAppId then pAppId = 1 end + return self["mobileSession" .. pAppId] +end + +return commonDefect From 9054ed78149ae9aa6d87d5655ae3400552809430 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Mon, 11 Dec 2017 12:27:28 +0200 Subject: [PATCH 199/681] Updated script according review comments --- ...Invalid_PT_after_cutting_unknow_values.lua | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua b/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua index d43655ef3d..de2d88672d 100644 --- a/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua +++ b/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua @@ -15,7 +15,9 @@ local commonDefects = require('test_scripts/Defects/4_5/commonDefects') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') --[[ Local Functions ]] -local CuttingUnknownStatus = false +local isCuttingUnknownError = false +local isError +local ErrorMessage --[[ Local Functions ]] local function ptuUpdateFunc(tbl) @@ -68,31 +70,33 @@ local function NotValidPtuUpdateFunc(tbl) {"Base-4", "NewTestCaseGroup"} end +local function ErrorOccurred(Message) + isError = true + ErrorMessage = ErrorMessage .. Message +end + local function CheckCuttingUnknowValues(self) commonDefects.rai_ptu_n_without_OnPermissionsChange(1, ptuUpdateFunc,self) self.mobileSession1:ExpectNotification("OnPermissionsChange") :Times(2) :ValidIf(function(_,data) - local ErrorStatus = false - local ErrorMessage = "" + isError = false + ErrorMessage = "" if #data.payload.permissionItem ~= 0 then for i=1, #data.payload.permissionItem do if data.payload.permissionItem[i].rpcName == "UnknownAPI" then - ErrorStatus = true - CuttingUnknownStatus = true - ErrorMessage = ErrorMessage .. " OnPermissionsChange contains unknown_RPC value.\n" + isCuttingUnknownError = true + ErrorOccurred(" OnPermissionsChange contains unknown_RPC value.\n") end if data.payload.permissionItem[i].newParameter then - ErrorStatus = true - CuttingUnknownStatus = true - ErrorMessage = ErrorMessage .. " OnPermissionsChange contains unknown_parameter value.\n" + isCuttingUnknownError = true + ErrorOccurred(" OnPermissionsChange contains unknown_parameter value.\n") end end else - ErrorStatus = true - ErrorMessage = ErrorMessage .. "OnPermissionsChange is not contain permissionItem elements" + ErrorOccurred("OnPermissionsChange is not contain permissionItem elements") end - if ErrorStatus == true then + if isError == true then return false, ErrorMessage else return true @@ -103,7 +107,7 @@ local function CheckCuttingUnknowValues(self) end local function InvalidPTAfterCutingUnknownValues(self) - if CuttingUnknownStatus == true then + if isCuttingUnknownError == true then self:FailTestCase("Unknown values are not cut from PT, so test case is not executed.") else commonDefects.UnsuccessPTU(NotValidPtuUpdateFunc,self) From 9cfffc529794740cd3d555d1482d5956552f1c50 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 11 Dec 2017 14:29:32 +0200 Subject: [PATCH 200/681] Scrips on defects verification - Drop1 --- ...PTU_Trigger_PTU_failed_previous_IGN_ON.lua | 42 ++++++++ ...havior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua | 79 +++++++++++++++ ..._does_not_send_HB_and_does_not_respond.lua | 96 +++++++++++++++++++ test_scripts/Defects/4_5/commonDefects.lua | 80 ++++++++++++++++ 4 files changed, 297 insertions(+) create mode 100644 test_scripts/Defects/4_5/1206_REQUEST_PTU_Trigger_PTU_failed_previous_IGN_ON.lua create mode 100644 test_scripts/Defects/4_5/1211_ATF_Check_count_of_removals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua create mode 100644 test_scripts/Defects/4_5/1893_ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua create mode 100644 test_scripts/Defects/4_5/commonDefects.lua diff --git a/test_scripts/Defects/4_5/1206_REQUEST_PTU_Trigger_PTU_failed_previous_IGN_ON.lua b/test_scripts/Defects/4_5/1206_REQUEST_PTU_Trigger_PTU_failed_previous_IGN_ON.lua new file mode 100644 index 0000000000..da93b612fa --- /dev/null +++ b/test_scripts/Defects/4_5/1206_REQUEST_PTU_Trigger_PTU_failed_previous_IGN_ON.lua @@ -0,0 +1,42 @@ +---------------------------------------------------------------------------------------------------- +-- Script verifies issue https://github.com/SmartDeviceLink/sdl_core/issues/1206 +-- Flow: HTTP +---------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require("user_modules/script_runner") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local mobile_session = require("mobile_session") +local common = require("test_scripts/Defects/4_5/commonDefects") +local color = require("user_modules/consts").color + +--[[ Local Functions ]] +local function registerApplicationAndWaitPTUStart(self) + self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) + self.mobileSession:StartService(7) + :Do(function() + local corId = self.mobileSession:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) + self.mobileSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { + application = { appName = config.application1.registerAppInterfaceParams.appName } + }) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }) + :Do(function() + commonFunctions:userPrint(color.blue, "Received OnStatusUpdate: UPDATE_NEEDED") + end) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("SDL Configuration", common.printSDLConfig) + +runner.Title("Test") +runner.Step("Application Registration and wait for UPDATE_NEEDED", registerApplicationAndWaitPTUStart) +runner.Step("Ignition Off", common.ignitionOff) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Application Registration and wait for UPDATE_NEEDED", registerApplicationAndWaitPTUStart) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/4_5/1211_ATF_Check_count_of_removals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua b/test_scripts/Defects/4_5/1211_ATF_Check_count_of_removals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua new file mode 100644 index 0000000000..412f9c8b8f --- /dev/null +++ b/test_scripts/Defects/4_5/1211_ATF_Check_count_of_removals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua @@ -0,0 +1,79 @@ +---------------------------------------------------------------------------------------------------- +-- Script verifies issue https://github.com/SmartDeviceLink/sdl_core/issues/1211 +-- Flow: EXTERNAL_PROPRIETARY +---------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require("user_modules/script_runner") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local mobile_session = require("mobile_session") +local common = require("test_scripts/Defects/4_5/commonDefects") +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") + +--[[ General configuration parameters ]] +config.ExitOnCrash = false + +-- [[Local variables]] +local count_of_requests = 10 + +local function updateINIFile() + common.backupINIFile() + commonFunctions:write_parameter_to_smart_device_link_ini("AppHMILevelNoneTimeScaleMaxRequests", count_of_requests) + commonFunctions:write_parameter_to_smart_device_link_ini("AppHMILevelNoneRequestsTimeScale", 30000) +end + +local function registerApp(self) + self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) + self.mobileSession:StartService(7) + :Do(function () + local cid = self.mobileSession:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered") + EXPECT_RESPONSE(cid, { success = true }) + EXPECT_NOTIFICATION("OnPermissionsChange") + end) +end + +local function Send_TOO_MANY_REQUESTS_WHILE_IN_NONE_HMI_LEVEL(self) + local count_of_sending_requests = count_of_requests + 10 + for i = 1, count_of_sending_requests do + self.mobileSession:SendRPC("AddCommand", { + cmdID = i, + menuParams = + { + position = 0, + menuName ="Command" .. tostring(i) + } + }) + end + EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", {reason = "REQUEST_WHILE_IN_NONE_HMI_LEVEL"}) +end + +local function Wait() + commonTestCases:DelayedExp(3000) +end + +local function Check_TOO_MANY_REQUESTS_in_DB(self) + local db_path = config.pathToSDL.."storage/policy.sqlite" + local sql_query = "SELECT count_of_removals_for_bad_behavior FROM app_level WHERE application_id = '" + .. config.application1.registerAppInterfaceParams.appID .. "'" + local exp_result = {"1"} + if commonFunctions:is_db_contains(db_path, sql_query, exp_result) == false then + self:FailTestCase("DB doesn't include expected value") + end +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Update INI file", updateINIFile) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("SDL Configuration", common.printSDLConfig) + +runner.Title("Test") +runner.Step("Register App", registerApp) +runner.Step("Send_TOO_MANY_REQUESTS_WHILE_IN_NONE_HMI_LEVEL", Send_TOO_MANY_REQUESTS_WHILE_IN_NONE_HMI_LEVEL) +runner.Step("Wait 3sec", Wait) +runner.Step("Check_TOO_MANY_REQUESTS_in_DB", Check_TOO_MANY_REQUESTS_in_DB) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) +runner.Step("Restore INI file", common.restoreINIFile) diff --git a/test_scripts/Defects/4_5/1893_ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua b/test_scripts/Defects/4_5/1893_ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua new file mode 100644 index 0000000000..19c94dab5c --- /dev/null +++ b/test_scripts/Defects/4_5/1893_ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua @@ -0,0 +1,96 @@ +---------------------------------------------------------------------------------------------------- +-- Script verifies issue https://github.com/SmartDeviceLink/sdl_core/issues/1893 +-- Flow: PROPRIETARY +---------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require("user_modules/script_runner") +local common = require("test_scripts/Defects/4_5/commonDefects") +local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local mobile_session = require('mobile_session') + +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.isMediaApplication = true + +-- [[Local variables]] +local default_app_params = config.application1.registerAppInterfaceParams +local default_app_params2 = config.application2.registerAppInterfaceParams + +--[[ Local Functions ]] +local function updateINIFile() + common.backupINIFile() + commonFunctions:write_parameter_to_smart_device_link_ini("HeartBeatTimeout", 5000) +end + +local function Start_Session_And_Register_App(self) + self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) + self.mobileSession.sendHeartbeatToSDL = false + self.mobileSession.answerHeartbeatFromSDL = false + self.mobileSession.ignoreSDLHeartBeatACK = false + self.mobileSession:StartRPC() + :Do(function() + local correlation_id = self.mobileSession:SendRPC("RegisterAppInterface", default_app_params) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { + application = { appName = default_app_params.appName } + }) + :Do(function(_,data) + default_app_params.hmi_app_id = data.params.application.appID + end) + self.mobileSession:ExpectResponse(correlation_id, { success = true, resultCode = "SUCCESS" }) + self.mobileSession:ExpectNotification("OnHMIStatus", { + hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" + }) + self.mobileSession:ExpectNotification("OnPermissionsChange", {}) + end) +end + +local function Register_Second_App_With_HeartBeat(self) + self.mobileSession1 = mobile_session.MobileSession(self, self.mobileConnection) + self.mobileSession1.sendHeartbeatToSDL = false + self.mobileSession1.answerHeartbeatFromSDL = true + self.mobileSession1.ignoreSDLHeartBeatACK = false + self.mobileSession1:StartRPC() + :Do(function() + local correlation_id = self.mobileSession1:SendRPC("RegisterAppInterface", default_app_params2) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { + application = { appName = default_app_params2.appName } + }) + self.mobileSession1:ExpectResponse(correlation_id, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectNotification("OnHMIStatus", { + hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" + }) + self.mobileSession1:ExpectNotification("OnPermissionsChange", {}) + end) +end + +local function Wait_15_seconds_And_Verify_OnAppUnregistered(self) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { + appID = default_app_params.hmi_app_id, unexpectedDisconnect = true + }) + :Timeout(15000) + :Do(function() + self.mobileSession:StopHeartbeat() + end) +end + +local function Verify_That_Second_App_Still_Registered(self) + local cor_id = self.mobileSession1:SendRPC("RegisterAppInterface", default_app_params2) + self.mobileSession1:ExpectResponse(cor_id, { success = false, resultCode = "APPLICATION_REGISTERED_ALREADY"}) +end + +-- [[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Update INI file", updateINIFile) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("SDL Configuration", common.printSDLConfig) + +runner.Title("Test") +runner.Step("Start_Session_And_Register_App", Start_Session_And_Register_App) +runner.Step("Register_Second_App_With_HeartBeat", Register_Second_App_With_HeartBeat) +runner.Step("Wait_15_seconds_And_Verify_OnAppUnregistered", Wait_15_seconds_And_Verify_OnAppUnregistered) +runner.Step("Verify_That_Second_App_Still_Registered", Verify_That_Second_App_Still_Registered) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) +runner.Step("Restore INI file", common.restoreINIFile) diff --git a/test_scripts/Defects/4_5/commonDefects.lua b/test_scripts/Defects/4_5/commonDefects.lua new file mode 100644 index 0000000000..658cdc5950 --- /dev/null +++ b/test_scripts/Defects/4_5/commonDefects.lua @@ -0,0 +1,80 @@ +--------------------------------------------------------------------------------------------------- +-- RC common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 +config.ValidateSchema = false + +--[[ Required Shared libraries ]] +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local sdl = require("SDL") + +--[[ Local Variables ]] +local commonDefect = {} + +local function allowSdl(self) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { + allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } + }) +end + +function commonDefect.preconditions() + commonFunctions:SDLForceStop() + commonSteps:DeletePolicyTable() + commonSteps:DeleteLogsFiles() +end + +function commonDefect.start(self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady() + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + self:connectMobile() + :Do(function() + commonFunctions:userPrint(35, "Mobile connected") + allowSdl(self) + end) + end) + end) + end) +end + +function commonDefect.postconditions() + StopSDL() +end + +function commonDefect.printSDLConfig() + commonFunctions:printTable(sdl.buildOptions) +end + +function commonDefect.ignitionOff(self) + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete") + :Do(function() + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) + self.mobileSession:ExpectNotification("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + :Do(function() + sdl:DeleteFile() + end) + end) +end + +function commonDefect.backupINIFile() + commonPreconditions:BackupFile("smartDeviceLink.ini") +end + +function commonDefect.restoreINIFile() + commonPreconditions:RestoreFile("smartDeviceLink.ini") +end + +return commonDefect From 418e96c0a01641dd83e5835d03bf97b4b56a7d10 Mon Sep 17 00:00:00 2001 From: "Dmytro Boltovskyi (GitHub)" Date: Tue, 12 Dec 2017 15:53:46 +0200 Subject: [PATCH 201/681] Revert "Script for issue1772 "Default app policies are never updated after a PTU"" --- .../4_5/1772_update_default_section.lua | 55 ---- test_scripts/Defects/4_5/commonDefects.lua | 301 ------------------ 2 files changed, 356 deletions(-) delete mode 100644 test_scripts/Defects/4_5/1772_update_default_section.lua delete mode 100644 test_scripts/Defects/4_5/commonDefects.lua diff --git a/test_scripts/Defects/4_5/1772_update_default_section.lua b/test_scripts/Defects/4_5/1772_update_default_section.lua deleted file mode 100644 index 0a353d3911..0000000000 --- a/test_scripts/Defects/4_5/1772_update_default_section.lua +++ /dev/null @@ -1,55 +0,0 @@ ---------------------------------------------------------------------------------------------- --- 1. Make sure SDL is built with PROPRIETARY flag --- 2. Start SDL and HMI, first ignition cycle --- 3. Connect device --- Steps: --- 1. Register new application --- 2. Perform PTU with updated default section(can use attached file ptu.json) --- Expected result: --- SDL performs update and sends OnPermissionsChange to mobile app with updated permissions. --- DB has updated info. --- Actual result: --- SDL sends to HMI UP_TO_DATE status, but does not update permissions internally. --- DB is not updated according to new permissions. --- SDL does not send OnPermissionsChange to mobile app with new permissions. ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local commonDefects = require('test_scripts/Defects/4_5/commonDefects') - ---[[ Local Functions ]] -local function ptuUpdateFunc(tbl) - local VDgroup = { - rpcs = { - GetVehicleData = { - hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, - parameters = {"gps"} - } - } - } - tbl.policy_table.functional_groupings["NewTestCaseGroup"] = VDgroup - tbl.policy_table.app_policies.default.groups = {"Base-4", "NewTestCaseGroup"} - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = nil -end - -local function GetVD(self) - local cid = self.mobileSession1:SendRPC("GetVehicleData", {gps = true}) - EXPECT_HMICALL("VehicleInfo.GetVehicleData") - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonDefects.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start) -runner.Step("RAI, PTU", commonDefects.rai_ptu, { ptuUpdateFunc }) -runner.Step("Activate App", commonDefects.activate_app) - -runner.Title("Test") -runner.Step("GetVD_requet_is_success", GetVD) - -runner.Title("Postconditions") -runner.Step("Stop SDL", commonDefects.postconditions) diff --git a/test_scripts/Defects/4_5/commonDefects.lua b/test_scripts/Defects/4_5/commonDefects.lua deleted file mode 100644 index 0755febe0e..0000000000 --- a/test_scripts/Defects/4_5/commonDefects.lua +++ /dev/null @@ -1,301 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RC common module ---------------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" -config.defaultProtocolVersion = 2 -config.ValidateSchema = false - ---[[ Required Shared libraries ]] -local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local commonSteps = require("user_modules/shared_testcases/commonSteps") -local commonTestCases = require("user_modules/shared_testcases/commonTestCases") -local mobile_session = require("mobile_session") -local json = require("modules/json") -local events = require("events") - ---[[ Local Variables ]] -local ptu_table = {} -local hmiAppIds = {} - -local commonDefect = {} - -commonDefect.timeout = 2000 -commonDefect.minTimeout = 500 -commonDefect.DEFAULT = "Default" -commonDefect.buttons = { climate = "FAN_UP", radio = "VOLUME_UP" } - -local function getPTUFromPTS(tbl) - tbl.policy_table.consumer_friendly_messages.messages = nil - tbl.policy_table.device_data = nil - tbl.policy_table.module_meta = nil - tbl.policy_table.usage_and_error_counts = nil - tbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null - tbl.policy_table.module_config.preloaded_pt = nil - tbl.policy_table.module_config.preloaded_date = nil -end - -function commonDefect.DefaultStruct() - return { - keep_context = false, - steal_focus = false, - priority = "NONE", - default_hmi = "NONE", - groups = { "Base-4"}, - } -end - -local function updatePTU(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonDefect.DefaultStruct() -end - -local function jsonFileToTable(file_name) - local f = io.open(file_name, "r") - local content = f:read("*all") - f:close() - return json.decode(content) -end - -local function tableToJsonFile(tbl, file_name) - local f = io.open(file_name, "w") - f:write(json.encode(tbl)) - f:close() -end - -local function checkIfPTSIsSentAsBinary(bin_data) - if not (bin_data ~= nil and string.len(bin_data) > 0) then - commonFunctions:userPrint(31, "PTS was not sent to Mobile in payload of OnSystemRequest") - end -end - -local function ptu(self, ptu_update_func) - local function getAppsCount() - local count = 0 - for _, _ in pairs(hmiAppIds) do - count = count + 1 - end - return count - end - - local policy_file_name = "PolicyTableUpdate" - local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") - local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") - local ptu_file_name = os.tmpname() - local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(requestId) - :Do(function() - self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", - { requestType = "PROPRIETARY", fileName = pts_file_name }) - getPTUFromPTS(ptu_table) - updatePTU(ptu_table) - if ptu_update_func then - ptu_update_func(ptu_table) - end - tableToJsonFile(ptu_table, ptu_file_name) - - local event = events.Event() - event.matches = function(e1, e2) return e1 == e2 end - EXPECT_EVENT(event, "PTU event") - :Timeout(11000) - - for id = 1, getAppsCount() do - local mobileSession = commonDefect.getMobileSession(self, id) - mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) - :Do(function(_, d2) - print("App ".. id .. " was used for PTU") - RAISE_EVENT(event, event, "PTU event") - checkIfPTSIsSentAsBinary(d2.binaryData) - local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", - { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) - EXPECT_HMICALL("BasicCommunication.SystemRequest") - :Do(function(_, d3) - self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) - self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", - { policyfile = policy_file_path .. "/" .. policy_file_name }) - end) - mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) - end) - :Times(AtMost(1)) - end - end) - os.remove(ptu_file_name) -end - -local function allow_sdl(self) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) -end - -function commonDefect.preconditions() - commonFunctions:SDLForceStop() - commonSteps:DeletePolicyTable() - commonSteps:DeleteLogsFiles() -end - -function commonDefect.start(pHMIParams, self) - self, pHMIParams = commonDefect.getSelfAndParams(pHMIParams, self) - self:runSDL() - commonFunctions:waitForSDLStart(self) - :Do(function() - self:initHMI(self) - :Do(function() - commonFunctions:userPrint(35, "HMI initialized") - self:initHMI_onReady(pHMIParams) - :Do(function() - commonFunctions:userPrint(35, "HMI is ready") - self:connectMobile() - :Do(function() - commonFunctions:userPrint(35, "Mobile connected") - allow_sdl(self) - end) - end) - end) - end) -end - -function commonDefect.startWithoutMobile(pHMIParams, self) - self, pHMIParams = commonDefect.getSelfAndParams(pHMIParams, self) - self:runSDL() - commonFunctions:waitForSDLStart(self) - :Do(function() - self:initHMI(self) - :Do(function() - commonFunctions:userPrint(35, "HMI initialized") - self:initHMI_onReady(pHMIParams) - :Do(function() - commonFunctions:userPrint(35, "HMI is ready") - end) - end) - end) -end - -function commonDefect.rai_ptu(ptu_update_func, self) - self, ptu_update_func = commonDefect.getSelfAndParams(ptu_update_func, self) - commonDefect.rai_ptu_n(1, ptu_update_func, self) -end - -function commonDefect.rai_ptu_n(id, ptu_update_func, self) - self, id, ptu_update_func = commonDefect.getSelfAndParams(id, ptu_update_func, self) - if not id then id = 1 end - self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) - self["mobileSession" .. id]:StartService(7) - :Do(function() - local corId = self["mobileSession" .. id]:SendRPC - ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", - { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) - :Do(function(_, d1) - hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) - :Times(3) - EXPECT_HMICALL("BasicCommunication.PolicyUpdate") - :Do(function(_, d2) - self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) - ptu_table = jsonFileToTable(d2.params.file) - ptu(self, ptu_update_func) - end) - end) - self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) - :Do(function() - self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", - { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice - self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") - end) - end) -end - -function commonDefect.rai_n(id, self) - self, id = commonDefect.getSelfAndParams(id, self) - if not id then id = 1 end - self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) - self["mobileSession" .. id]:StartService(7) - :Do(function() - local corId = self["mobileSession" .. id]:SendRPC - ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", - { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) - :Do(function(_, d1) - hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID - end) - self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) - :Do(function() - self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", - { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice - self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") - end) - end) -end - -function commonDefect.delayedExp(timeout) - if not timeout then timeout = commonDefect.timeout end - commonTestCases:DelayedExp(timeout) -end - -function commonDefect.unregisterApp(pAppId, self) - local mobSession = commonDefect.getMobileSession(self, pAppId) - local hmiAppId = commonDefect.getHMIAppId(pAppId) - local cid = mobSession:SendRPC("UnregisterAppInterface",{}) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = hmiAppId, unexpectedDisconnect = false }) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) -end - -function commonDefect.activate_app(pAppId, self) - self, pAppId = commonDefect.getSelfAndParams(pAppId, self) - if not pAppId then pAppId = 1 end - local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] - local mobSession = commonDefect.getMobileSession(self, pAppId) - local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) - EXPECT_HMIRESPONSE(requestId) - mobSession:ExpectNotification("OnHMIStatus", - { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) - commonTestCases:DelayedExp(commonDefect.minTimeout) -end - -function commonDefect.putFile(pFileName, self) - self, pFileName = commonDefect.getSelfAndParams(pFileName, self) - local cid = self.mobileSession1:SendRPC( - "PutFile", - {syncFileName = pFileName, fileType = "GRAPHIC_PNG", persistentFile = false, systemFile = false}, - "files/icon.png") - - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) -end - -function commonDefect.postconditions() - StopSDL() -end - -function commonDefect.getSelfAndParams(...) - local out = { } - local selfIdx = nil - for i,v in pairs({...}) do - if type(v) == "table" and v.isTest then - table.insert(out, v) - selfIdx = i - break - end - end - local idx = 2 - for i = 1, table.maxn({...}) do - if i ~= selfIdx then - out[idx] = ({...})[i] - idx = idx + 1 - end - end - return table.unpack(out, 1, table.maxn(out)) -end - -function commonDefect.getHMIAppId(pAppId) - if not pAppId then pAppId = 1 end - return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] -end - -function commonDefect.getMobileSession(self, pAppId) - if not pAppId then pAppId = 1 end - return self["mobileSession" .. pAppId] -end - -return commonDefect From 440b71383d0db7595bd7564afc97bfbea0cbd9c2 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 12 Dec 2017 16:00:53 +0200 Subject: [PATCH 202/681] Update according to review comments --- ...movals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test_scripts/Defects/4_5/1211_ATF_Check_count_of_removals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua b/test_scripts/Defects/4_5/1211_ATF_Check_count_of_removals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua index 412f9c8b8f..08f701bbf1 100644 --- a/test_scripts/Defects/4_5/1211_ATF_Check_count_of_removals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua +++ b/test_scripts/Defects/4_5/1211_ATF_Check_count_of_removals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua @@ -29,6 +29,9 @@ local function registerApp(self) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered") EXPECT_RESPONSE(cid, { success = true }) EXPECT_NOTIFICATION("OnPermissionsChange") + self.mobileSession:ExpectNotification("OnHMIStatus", { + hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" + }) end) end From e7f7b229bfb026c3d0aa812c4b8f6b5a3ecabcb5 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 13 Dec 2017 10:23:17 +0200 Subject: [PATCH 203/681] Script for 1772 issue --- .../4_5/1772_update_default_section.lua | 56 ++++++ test_scripts/Defects/4_5/commonDefects.lua | 178 ++++++++++++++++++ 2 files changed, 234 insertions(+) create mode 100644 test_scripts/Defects/4_5/1772_update_default_section.lua diff --git a/test_scripts/Defects/4_5/1772_update_default_section.lua b/test_scripts/Defects/4_5/1772_update_default_section.lua new file mode 100644 index 0000000000..751d940376 --- /dev/null +++ b/test_scripts/Defects/4_5/1772_update_default_section.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------- +-- Script verifies issue https://github.com/SmartDeviceLink/sdl_core/issues/1772 +-- 1. Make sure SDL is built with PROPRIETARY flag +-- 2. Start SDL and HMI, first ignition cycle +-- 3. Connect device +-- Steps: +-- 1. Register new application +-- 2. Perform PTU with updated default section(can use attached file ptu.json) +-- Expected result: +-- SDL performs update and sends OnPermissionsChange to mobile app with updated permissions. +-- DB has updated info. +-- Actual result: +-- SDL sends to HMI UP_TO_DATE status, but does not update permissions internally. +-- DB is not updated according to new permissions. +-- SDL does not send OnPermissionsChange to mobile app with new permissions. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonDefects = require('test_scripts/Defects/4_5/commonDefects') + +--[[ Local Functions ]] +local function ptuUpdateFunc(tbl) + local VDgroup = { + rpcs = { + GetVehicleData = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, + parameters = { "gps" } + } + } + } + tbl.policy_table.functional_groupings["NewTestCaseGroup"] = VDgroup + tbl.policy_table.app_policies.default.groups = { "Base-4", "NewTestCaseGroup" } + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = nil +end + +local function GetVD(self) + local cid = self.mobileSession1:SendRPC("GetVehicleData", { gps = true }) + EXPECT_HMICALL("VehicleInfo.GetVehicleData") + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonDefects.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start) +runner.Step("RAI, PTU", commonDefects.rai_ptu, { ptuUpdateFunc }) +runner.Step("Activate App", commonDefects.activate_app) + +runner.Title("Test") +runner.Step("GetVD_requet_is_success", GetVD) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonDefects.postconditions) diff --git a/test_scripts/Defects/4_5/commonDefects.lua b/test_scripts/Defects/4_5/commonDefects.lua index 658cdc5950..b1b116244e 100644 --- a/test_scripts/Defects/4_5/commonDefects.lua +++ b/test_scripts/Defects/4_5/commonDefects.lua @@ -10,17 +10,116 @@ config.ValidateSchema = false local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") local sdl = require("SDL") +local mobile_session = require("mobile_session") +local events = require("events") +local json = require("modules/json") --[[ Local Variables ]] +local ptu_table = {} +local hmiAppIds = {} local commonDefect = {} +--[[ Module Constants ]] +commonDefect.timeout = 2000 +commonDefect.minTimeout = 500 + local function allowSdl(self) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) end +local function getPTUFromPTS(tbl) + tbl.policy_table.consumer_friendly_messages.messages = nil + tbl.policy_table.device_data = nil + tbl.policy_table.module_meta = nil + tbl.policy_table.usage_and_error_counts = nil + tbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + tbl.policy_table.module_config.preloaded_pt = nil + tbl.policy_table.module_config.preloaded_date = nil +end + +function commonDefect.DefaultStruct() + return { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + groups = { "Base-4"}, + } +end + +local function updatePTU(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonDefect.DefaultStruct() +end + +local function jsonFileToTable(file_name) + local f = io.open(file_name, "r") + local content = f:read("*all") + f:close() + return json.decode(content) +end + +local function tableToJsonFile(tbl, file_name) + local f = io.open(file_name, "w") + f:write(json.encode(tbl)) + f:close() +end + +local function ptu(self, ptu_update_func) + local function getAppsCount() + local count = 0 + for _, _ in pairs(hmiAppIds) do + count = count + 1 + end + return count + end + + local policy_file_name = "PolicyTableUpdate" + local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + local ptu_file_name = os.tmpname() + local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) + EXPECT_HMIRESPONSE(requestId) + :Do(function() + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + { requestType = "PROPRIETARY", fileName = pts_file_name }) + getPTUFromPTS(ptu_table) + updatePTU(ptu_table) + if ptu_update_func then + ptu_update_func(ptu_table) + end + tableToJsonFile(ptu_table, ptu_file_name) + + local event = events.Event() + event.matches = function(e1, e2) return e1 == e2 end + EXPECT_EVENT(event, "PTU event") + :Timeout(11000) + + for id = 1, getAppsCount() do + local mobileSession = commonDefect.getMobileSession(self, id) + mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :Do(function() + print("App ".. id .. " was used for PTU") + RAISE_EVENT(event, event, "PTU event") + local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", + { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, d3) + self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", + { policyfile = policy_file_path .. "/" .. policy_file_name }) + end) + mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + end) + :Times(AtMost(1)) + end + end) + os.remove(ptu_file_name) +end + function commonDefect.preconditions() commonFunctions:SDLForceStop() commonSteps:DeletePolicyTable() @@ -77,4 +176,83 @@ function commonDefect.restoreINIFile() commonPreconditions:RestoreFile("smartDeviceLink.ini") end +function commonDefect.rai_ptu(ptu_update_func, self) + self, ptu_update_func = commonDefect.getSelfAndParams(ptu_update_func, self) + commonDefect.rai_ptu_n(1, ptu_update_func, self) +end + +function commonDefect.rai_ptu_n(id, ptu_update_func, self) + self, id, ptu_update_func = commonDefect.getSelfAndParams(id, ptu_update_func, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC + ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :Do(function(_, d2) + self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptu_table = jsonFileToTable(d2.params.file) + ptu(self, ptu_update_func) + end) + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + end) + end) +end + +function commonDefect.activate_app(pAppId, self) + self, pAppId = commonDefect.getSelfAndParams(pAppId, self) + if not pAppId then pAppId = 1 end + local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + local mobSession = commonDefect.getMobileSession(self, pAppId) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + EXPECT_HMIRESPONSE(requestId) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + commonTestCases:DelayedExp(commonDefect.minTimeout) +end + +function commonDefect.getSelfAndParams(...) + local out = { } + local selfIdx = nil + for i,v in pairs({...}) do + if type(v) == "table" and v.isTest then + table.insert(out, v) + selfIdx = i + break + end + end + local idx = 2 + for i = 1, table.maxn({...}) do + if i ~= selfIdx then + out[idx] = ({...})[i] + idx = idx + 1 + end + end + return table.unpack(out, 1, table.maxn(out)) +end + +function commonDefect.getHMIAppId(pAppId) + if not pAppId then pAppId = 1 end + return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] +end + +function commonDefect.getMobileSession(self, pAppId) + if not pAppId then pAppId = 1 end + return self["mobileSession" .. pAppId] +end + return commonDefect From 8ad8052e120518d2e410e4a9cb699af72ac2b9ff Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 13 Dec 2017 12:48:51 +0200 Subject: [PATCH 204/681] Add DelayExp function --- test_scripts/Defects/4_5/commonDefects.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test_scripts/Defects/4_5/commonDefects.lua b/test_scripts/Defects/4_5/commonDefects.lua index b1b116244e..3dc9dd97b1 100644 --- a/test_scripts/Defects/4_5/commonDefects.lua +++ b/test_scripts/Defects/4_5/commonDefects.lua @@ -255,4 +255,9 @@ function commonDefect.getMobileSession(self, pAppId) return self["mobileSession" .. pAppId] end +function commonDefect.delayedExp(pTimeout) + if not pTimeout then pTimeout = commonDefect.timeout end + commonTestCases:DelayedExp(pTimeout) +end + return commonDefect From f9a0e447849f5f2561d659732ea5035c43fb7c93 Mon Sep 17 00:00:00 2001 From: Ira Lytvynenko Date: Mon, 11 Dec 2017 17:57:31 +0200 Subject: [PATCH 205/681] Script that verifies SUSPEND -> OnSDLAwake -> SUSPEND -> IGN_OFF sequence for resumption data saving --- .../4_5/1395_Resumption_data_IGN_OFF.lua | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua diff --git a/test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua b/test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua new file mode 100644 index 0000000000..bfd9ae6077 --- /dev/null +++ b/test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua @@ -0,0 +1,121 @@ +--------------------------------------------------------------------------------------------------- +-- Script verifies SUSPEND -> OnSDLAwake -> SUSPEND -> IGN_OFF sequence for resumption data saving +-- Precondition: +-- 1. SDL and HMI are started. +-- 2. App is registered. +-- Steps: +-- 1. Send AddCommand and check that OnHashChanged() notification is sent to mobile. +-- 2. Send BC.OnExitAllApplications(SUSPEND) and check that OnHashChanged() notification +-- is not sent to mobile when new data are added. +-- 3. Send BasicCommunication.OnAwakeSDL and check that OnHashChanged() notification is sent to mobile. +-- 4. Perform IGN_OFF - IGN_ON cycle and check resumption of persistent data and HMI Level + +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local mobile_session = require("mobile_session") +local common = require('test_scripts/Defects/4_5/commonDefects') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local SDL = require('SDL') + +--[[ Local Variables ]] + +--[[ Local Functions ]] +local function AddCommand(self) + self.mobileSession1:SendRPC("AddCommand", { cmdID = 1, vrCommands = {"VRCommand1"}}) + EXPECT_HMICALL("VR.AddCommand"):Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + self.mobileSession1:ExpectResponse("AddCommand", { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +local function AddCommandAfterSUSPEND(self) + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) + self.mobileSession1:SendRPC("AddCommand", { cmdID = 2, vrCommands = {"VRCommand2"}}) + EXPECT_HMICALL("VR.AddCommand"):Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + self.mobileSession1:ExpectResponse("AddCommand", { success = true, resultCode = "SUCCESS" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete") + self.mobileSession1:ExpectNotification("OnHashChange"):Times(0) + common.delayedExp(3000) +end + +local function OnAwakeSDL(self) + self.hmiConnection:SendNotification("BasicCommunication.OnAwakeSDL",{}) + self.mobileSession1:ExpectNotification("OnHashChange"):Do(function(_, data) + self.currentHashID = data.payload.hashID + end) +end + +local function IGNITION_OFF(self) + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", + { reason = "SUSPEND" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", + { reason = "IGNITION_OFF" }) + self.mobileSession1:ExpectNotification("OnAppInterfaceUnregistered", + { reason = "IGNITION_OFF" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + SDL:DeleteFile() + end) +end + +local function expectResumeData(self) + local on_vr_commands_added = EXPECT_HMICALL("VR.AddCommand"):Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS") + end):Times(2) + on_vr_commands_added:ValidIf(function(_, data) + if (data.params.type == "Command" and (data.params.cmdID == 1 or data.params.cmdID == 2)) then + if (data.params.appID == config.application1.registerAppInterfaceParams.hmi_app_id) then + return true + else + commonFunctions:userPrint(31, "Received the same notification or App is registered with wrong appID") + return false + end + end + end) + self.mobileSession1:ExpectNotification("OnHashChange") + end + + local function registerAppAndResumeData(self) + self.mobileSession1 = mobile_session.MobileSession(self, self.mobileConnection) + self.mobileSession1:StartService(7):Do(function() + config.application1.registerAppInterfaceParams.hashID = self.currentHashID + expectResumeData(self) + local corId = self.mobileSession1:SendRPC("RegisterAppInterface", + config.application1.registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config.application1.registerAppInterfaceParams.appName }}):Do(function(_, data) + config.application1.registerAppInterfaceParams.hmi_app_id = data.params.application.appID + end) + self.mobileSession1:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + EXPECT_HMICALL("BasicCommunication.ActivateApp", + {appID = config.application1.registerAppInterfaceParams.hmi_app_id}):Do(function(_,data) + self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) + end) + self.mobileSession1:ExpectNotification("OnHMIStatus", + {hmiLevel = "NONE", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE"}, + {hmiLevel = "FULL", systemContext = "MAIN", audioStreamingState = "AUDIBLE"}):Times(2) + end) + end + + --[[ Scenario ]] + runner.Title("Preconditions") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("RAI, PTU", common.rai_ptu) + runner.Step("Activate App", common.activate_app) + + runner.Title("Test") + runner.Step("Add Command", AddCommand) + runner.Step("Add Command After SUSPEND", AddCommandAfterSUSPEND) + runner.Step("Send OnAwakeSDL", OnAwakeSDL) + runner.Step("IGNITION_OFF", IGNITION_OFF) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Register App And Resume Data", registerAppAndResumeData) + + runner.Title("Postconditions") + runner.Step("Stop SDL", common.postconditions) From 8a10665b9c7ff7a3df643854f5dcb109710358f6 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 13 Dec 2017 12:26:59 +0200 Subject: [PATCH 206/681] Update according to review comments --- test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua b/test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua index bfd9ae6077..1ab8314771 100644 --- a/test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua +++ b/test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua @@ -1,4 +1,5 @@ --------------------------------------------------------------------------------------------------- +-- Script verifies issue https://github.com/SmartDeviceLink/sdl_core/issues/1395 -- Script verifies SUSPEND -> OnSDLAwake -> SUSPEND -> IGN_OFF sequence for resumption data saving -- Precondition: -- 1. SDL and HMI are started. @@ -15,7 +16,6 @@ local runner = require('user_modules/script_runner') local mobile_session = require("mobile_session") local common = require('test_scripts/Defects/4_5/commonDefects') -local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local SDL = require('SDL') --[[ Local Variables ]] @@ -72,8 +72,7 @@ local function expectResumeData(self) if (data.params.appID == config.application1.registerAppInterfaceParams.hmi_app_id) then return true else - commonFunctions:userPrint(31, "Received the same notification or App is registered with wrong appID") - return false + return false, "Received the same notification or App is registered with wrong appID" end end end) From f836640b28e74d3a7ecec7dfc4616cdd47206f56 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 13 Dec 2017 16:19:15 +0200 Subject: [PATCH 207/681] Add new functions --- test_scripts/Defects/4_5/commonDefects.lua | 41 ++++++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/test_scripts/Defects/4_5/commonDefects.lua b/test_scripts/Defects/4_5/commonDefects.lua index 3dc9dd97b1..a6cd26ee77 100644 --- a/test_scripts/Defects/4_5/commonDefects.lua +++ b/test_scripts/Defects/4_5/commonDefects.lua @@ -185,6 +185,9 @@ function commonDefect.rai_ptu_n(id, ptu_update_func, self) self, id, ptu_update_func = commonDefect.getSelfAndParams(id, ptu_update_func, self) if not id then id = 1 end self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) self["mobileSession" .. id]:StartService(7) :Do(function() local corId = self["mobileSession" .. id]:SendRPC @@ -193,9 +196,6 @@ function commonDefect.rai_ptu_n(id, ptu_update_func, self) { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) :Do(function(_, d1) hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) - :Times(3) EXPECT_HMICALL("BasicCommunication.PolicyUpdate") :Do(function(_, d2) self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) @@ -255,9 +255,44 @@ function commonDefect.getMobileSession(self, pAppId) return self["mobileSession" .. pAppId] end +function commonDefect.putFile(pFileName, self) + self, pFileName = commonDefect.getSelfAndParams(pFileName, self) + local cid = self.mobileSession1:SendRPC( + "PutFile", + {syncFileName = pFileName, fileType = "GRAPHIC_PNG", persistentFile = false, systemFile = false}, + "files/icon.png") + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + function commonDefect.delayedExp(pTimeout) if not pTimeout then pTimeout = commonDefect.timeout end commonTestCases:DelayedExp(pTimeout) end +function commonDefect.rai_n(id, self) + self, id = commonDefect.getSelfAndParams(id, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC("RegisterAppInterface", + config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { + application = { appName = config["application" .. id].registerAppInterfaceParams.appName } + }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", { + hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" + }) + :Times(AtLeast(1)) + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + end) + end) +end + return commonDefect From 2ac45071cc73e5c984b9eeaa145329eaf78f79fe Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 7 Dec 2017 16:26:43 +0200 Subject: [PATCH 208/681] Script for issue 1225 --- .../Defects/4_5/1225_FACTORY_DEFAULTS.lua | 232 ++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua diff --git a/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua b/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua new file mode 100644 index 0000000000..6fd1ff2dbe --- /dev/null +++ b/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua @@ -0,0 +1,232 @@ +--------------------------------------------------------------------------------------------------- +-- Preconditions: +-- SDL is built with Extended policy flag. +-- SDL and HMI are started. First ignition cycle. +-- Connect device. +-- App registered, consented on device. +-- App has consented groups. +-- Steps to reproduce: +-- Send OnExitAllApplications ("reason":"FACTORY_DEFAULTS") fron HMI. +-- Or run script ATF_Factory_reset.lua +-- Actual result: +-- SDL not clear all user consent records in "user_consent_records" section of the LocalPT after FACTORY_DEFAULTS. +-- Scenario is failed. +-- Expected result: +-- On FACTORY_DEFAULTS, Policy Manager must clear all user consent records in "user_consent_records" section +-- of the LocalPT, other content of the LocalPT must be unchanged. +-- Scenario is passed. +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.ExitOnCrash = false + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonDefects = require('test_scripts/Defects/4_5/commonDefects') +local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') +local mobile_session = require('mobile_session') +local commonSteps = require ('user_modules/shared_testcases/commonSteps') +local testCasesForPolicyTableSnapshot = require ('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') + +--[[ Local Variables ]] +local HMIid +local groups = {} + +--[[ Local Functions ]] +local function ReplacePreloadedFile() + os.execute('cp ' .. config.pathToSDL .. 'sdl_preloaded_pt.json' .. ' ' .. config.pathToSDL .. + 'backup_sdl_preloaded_pt.json') + os.execute('cp files/jsons/Policies/Related_HMI_API/OnAppPermissionConsent.json ' .. config.pathToSDL .. + 'sdl_preloaded_pt.json') + os.execute('rm ' .. config.pathToSDL .. 'policy.sqlite') +end + +local function RestorePreloadedPT() + os.execute('rm ' .. config.pathToSDL .. 'sdl_preloaded_pt.json') + os.execute('cp ' .. config.pathToSDL .. 'backup_sdl_preloaded_pt.json' .. ' ' .. config.pathToSDL .. + 'sdl_preloaded_pt.json') +end + +local function Register_App(self) + self.mobileSession1 = mobile_session.MobileSession(self, self.mobileConnection) + self.mobileSession1:StartService(7) + :Do(function() + local CorIdRAI = self.mobileSession1:SendRPC + ("RegisterAppInterface", config.application1.registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = + { appName = config.application1.registerAppInterfaceParams.appName }}) + :Do(function(_,data) HMIid = data.params.application.appID end) + self.mobileSession1:ExpectResponse(CorIdRAI, { success = true, resultCode = "SUCCESS"}) + end) +end + +local function Precondition_Activate_app_To_Trigger_PTU(self) + local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = HMIid }) + EXPECT_HMIRESPONSE(RequestId) + :Do(function(_,_) + local RequestId1 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", + {language = "EN-US", messageCodes = {"DataConsent"}}) + EXPECT_HMIRESPONSE( RequestId1, {result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) + :Do(function(_,_) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", + {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1", isSDLAllowed = true}}) + local request_id_list_of_permissions = self.hmiConnection:SendRequest("SDL.GetListOfPermissions", + { appID = HMIid }) + EXPECT_HMIRESPONSE(request_id_list_of_permissions) + :Do(function(_,data) + if #data.result.allowedFunctions > 0 then + for i = 1, #data.result.allowedFunctions do + groups[i] = data.result.allowedFunctions[i] + groups[i].allowed = true + end + end + commonFunctions:printTable(groups) + self.hmiConnection:SendNotification("SDL.OnAppPermissionConsent", + { appID = HMIid, consentedFunctions = groups, source = "GUI"}) + self.mobileSession1:ExpectNotification("OnPermissionsChange") + end) + end) + end) + self.mobileSession1:ExpectNotification("OnHMIStatus", {hmiLevel = "FULL", systemContext = "MAIN"}) +end + +local function TrigerPTUForCreationSnapshotWithConsent(self) + local RequestId1 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", + {language = "EN-US", messageCodes = {"DataConsent"}}) + EXPECT_HMIRESPONSE( RequestId1, {result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) + :Do(function(_,_) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", + {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1", isSDLAllowed = true}}) + local request_id_list_of_permissions = self.hmiConnection:SendRequest("SDL.GetListOfPermissions", + { appID = HMIid }) + EXPECT_HMIRESPONSE(request_id_list_of_permissions) + commonDefects.delayedExp(1000) -- without delayed snapshot is not created in time + end) +end + +local function Check_user_consent_records_in_PT(self) + local is_test_fail = false + if( commonSteps:file_exists("/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json") == false) then + self:FailTestCase("/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json is not created") + else + testCasesForPolicyTableSnapshot:extract_pts({HMIid}) + local app_consent_location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data." .. + config.deviceMAC .. ".user_consent_records."..config.application1.registerAppInterfaceParams.appID .. + ".consent_groups.Location-1") + local app_consent_notifications = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data." .. + config.deviceMAC .. ".user_consent_records." .. config.application1.registerAppInterfaceParams.appID .. + ".consent_groups.Notifications") + if(app_consent_location ~= true) then + commonFunctions:printError("Error: user_consent_records.consent_groups.Location is not present in LPT") + is_test_fail = true + end + if(app_consent_notifications ~= true) then + commonFunctions:printError("Error: user_consent_records.consent_groups.Notifications is not present in LPT") + is_test_fail = true + end + if( commonSteps:file_exists(config.pathToSDL.."/storage/policy.sqlite") == false) then + self:FailTestCase(config.pathToSDL .."/storage/policy.sqlite is not created") + else + local queryCG = "select device_id from consent_group" + local r_actual_CG = commonFunctions:get_data_policy_sql(config.pathToSDL.."/storage/policy.sqlite", queryCG) + if #r_actual_CG ~= 2 then + commonFunctions:printError("Error: consent_group does not contain 2 required records in LPT") + is_test_fail = true + end + local queryDCG = "select device_id from device_consent_group" + local r_actualDCG = commonFunctions:get_data_policy_sql(config.pathToSDL.."/storage/policy.sqlite", queryDCG) + if #r_actualDCG ~= 1 then + commonFunctions:printError("Error: device_consent_group does not contain 1 required record in LPT") + is_test_fail = true + end + end + end + if(is_test_fail == true) then + self:FailTestCase("Test is FAILED.") + end +end + +local function CheckLPT(self) + local is_test_fail = false + if( commonSteps:file_exists(config.pathToSDL.."/storage/policy.sqlite") == false) then + self:FailTestCase(config.pathToSDL .."/storage/policy.sqlite is not created") + else + local queryCG = "select device_id from consent_group" + local r_actual_CG = commonFunctions:get_data_policy_sql(config.pathToSDL.."/storage/policy.sqlite", queryCG) + if #r_actual_CG ~= 0 then + commonFunctions:printError("Error: consent_group contains redundant records in LPT") + is_test_fail = true + end + local queryDCG = "select device_id from device_consent_group" + local r_actualDCG = commonFunctions:get_data_policy_sql(config.pathToSDL.."/storage/policy.sqlite", queryDCG) + if #r_actualDCG ~= 0 then + commonFunctions:printError("Error: device_consent_group contains redundant record in LPT") + is_test_fail = true + end + end + if(is_test_fail == true) then + self:FailTestCase("Test is FAILED.") + end +end + +local function Check_no_user_consent_records_in_PT(self) + local is_test_fail = false + if( commonSteps:file_exists("/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json") == false) then + self:FailTestCase(config.pathToSDL .. "sdl_preloaded_pt.json " .. "is not created") + else + testCasesForPolicyTableSnapshot:extract_pts( + {self.applications[config.application1.registerAppInterfaceParams.appName]}) + local app_consent_location = testCasesForPolicyTableSnapshot:get_data_from_PTS + ("device_data." .. config.deviceMAC .. ".user_consent_records." .. + config.application1.registerAppInterfaceParams.appID .. ".consent_groups.Location-1") + local app_consent_notifications = testCasesForPolicyTableSnapshot:get_data_from_PTS + ("device_data." .. config.deviceMAC .. ".user_consent_records." .. + config.application1.registerAppInterfaceParams.appID .. ".consent_groups.Notifications") + if(app_consent_location == true) then + commonFunctions:printError("Error: user_consent_records.consent_groups.Location was not reset in LPT") + is_test_fail = true + end + if(app_consent_notifications == true) then + commonFunctions:printError("Error: user_consent_records.consent_groups.Notifications was not reset in LPT") + is_test_fail = true + end + end + if(is_test_fail == true) then + self:FailTestCase("Test is FAILED.") + end +end + +local function FACTORY_DEFAULTS(self) + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "FACTORY_DEFAULTS" }) +end + +local function Wait_SDL_stop() + os.execute("sleep 15") +end + +local function RemoveSnapshot() + os.execute('rm "/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json"') +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonDefects.preconditions) +runner.Step("ReplacePreloadedFile", ReplacePreloadedFile) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start) +runner.Step("RAI, PTU", Register_App) +runner.Step("Activate App", Precondition_Activate_app_To_Trigger_PTU) + +runner.Title("Test") +runner.Step("TrigerPTUForCreationSnapshotWithConsent", TrigerPTUForCreationSnapshotWithConsent) +runner.Step("Check_user_consent_records_in_PT", Check_user_consent_records_in_PT) +runner.Step("FACTORY_DEFAULTS", FACTORY_DEFAULTS) +runner.Step("Wait_SDL_stop", Wait_SDL_stop) +runner.Step("CheckLPT", CheckLPT) +runner.Step("RemoveSnapshot", RemoveSnapshot) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start) +runner.Step("RAI, PTU", Register_App) +runner.Step("Activate App", Precondition_Activate_app_To_Trigger_PTU) +runner.Step("Check_no_user_consent_records_in_PT", Check_no_user_consent_records_in_PT) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonDefects.postconditions) +runner.Step("RestorePreloadedPT", RestorePreloadedPT) From 27e0b1c04de208ec0667bff6a0378f57166cfe69 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 13 Dec 2017 16:21:58 +0200 Subject: [PATCH 209/681] Script refactoring --- .../Defects/4_5/1225_FACTORY_DEFAULTS.lua | 288 +++++++++--------- 1 file changed, 142 insertions(+), 146 deletions(-) diff --git a/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua b/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua index 6fd1ff2dbe..229471e3ce 100644 --- a/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua +++ b/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua @@ -1,6 +1,7 @@ --------------------------------------------------------------------------------------------------- +-- Script verifies issue https://github.com/SmartDeviceLink/sdl_core/issues/1225 +-- Flow: EXTERNAL_PROPRIETARY -- Preconditions: --- SDL is built with Extended policy flag. -- SDL and HMI are started. First ignition cycle. -- Connect device. -- App registered, consented on device. @@ -23,142 +24,158 @@ config.ExitOnCrash = false local runner = require('user_modules/script_runner') local commonDefects = require('test_scripts/Defects/4_5/commonDefects') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') -local mobile_session = require('mobile_session') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTableSnapshot = require ('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local sdl = require("SDL") +local events = require('events') --[[ Local Variables ]] -local HMIid -local groups = {} +local pathToPTS = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" + .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") +local pathToLPT = config.pathToSDL .. "/storage/policy.sqlite" --[[ Local Functions ]] -local function ReplacePreloadedFile() - os.execute('cp ' .. config.pathToSDL .. 'sdl_preloaded_pt.json' .. ' ' .. config.pathToSDL .. - 'backup_sdl_preloaded_pt.json') - os.execute('cp files/jsons/Policies/Related_HMI_API/OnAppPermissionConsent.json ' .. config.pathToSDL .. - 'sdl_preloaded_pt.json') - os.execute('rm ' .. config.pathToSDL .. 'policy.sqlite') +local function start(self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady() + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + self:connectMobile() + :Do(function() + commonFunctions:userPrint(35, "Mobile connected") + end) + end) + end) + end) end -local function RestorePreloadedPT() - os.execute('rm ' .. config.pathToSDL .. 'sdl_preloaded_pt.json') - os.execute('cp ' .. config.pathToSDL .. 'backup_sdl_preloaded_pt.json' .. ' ' .. config.pathToSDL .. - 'sdl_preloaded_pt.json') +local function allowSDL(self) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { + allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } + }) end -local function Register_App(self) - self.mobileSession1 = mobile_session.MobileSession(self, self.mobileConnection) - self.mobileSession1:StartService(7) - :Do(function() - local CorIdRAI = self.mobileSession1:SendRPC - ("RegisterAppInterface", config.application1.registerAppInterfaceParams) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = - { appName = config.application1.registerAppInterfaceParams.appName }}) - :Do(function(_,data) HMIid = data.params.application.appID end) - self.mobileSession1:ExpectResponse(CorIdRAI, { success = true, resultCode = "SUCCESS"}) - end) +local function delayedExp(pTime, self) + local event = events.Event() + event.matches = function(e1, e2) return e1 == e2 end + EXPECT_HMIEVENT(event, "Delayed event") + :Timeout(pTime + 5000) + local function toRun() + event_dispatcher:RaiseEvent(self.hmiConnection, event) + end + RUN_AFTER(toRun, pTime) end -local function Precondition_Activate_app_To_Trigger_PTU(self) - local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = HMIid }) - EXPECT_HMIRESPONSE(RequestId) - :Do(function(_,_) - local RequestId1 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", - {language = "EN-US", messageCodes = {"DataConsent"}}) - EXPECT_HMIRESPONSE( RequestId1, {result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) - :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1", isSDLAllowed = true}}) - local request_id_list_of_permissions = self.hmiConnection:SendRequest("SDL.GetListOfPermissions", - { appID = HMIid }) - EXPECT_HMIRESPONSE(request_id_list_of_permissions) - :Do(function(_,data) - if #data.result.allowedFunctions > 0 then - for i = 1, #data.result.allowedFunctions do - groups[i] = data.result.allowedFunctions[i] - groups[i].allowed = true - end - end - commonFunctions:printTable(groups) - self.hmiConnection:SendNotification("SDL.OnAppPermissionConsent", - { appID = HMIid, consentedFunctions = groups, source = "GUI"}) - self.mobileSession1:ExpectNotification("OnPermissionsChange") - end) - end) - end) - self.mobileSession1:ExpectNotification("OnHMIStatus", {hmiLevel = "FULL", systemContext = "MAIN"}) +local function ptUpdateFunc(pTbl) + local appId = config.application1.registerAppInterfaceParams.appID + table.insert(pTbl.policy_table.app_policies[appId].groups, "Location-1") +end + +local function removeSnapshotAndTriggerPTUFromHMI(self) + os.execute("rm " .. pathToPTS) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate", { file = pathToPTS }) + self.hmiConnection:SendNotification("SDL.OnPolicyUpdate", { }) end -local function TrigerPTUForCreationSnapshotWithConsent(self) - local RequestId1 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", - {language = "EN-US", messageCodes = {"DataConsent"}}) - EXPECT_HMIRESPONSE( RequestId1, {result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) - :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1", isSDLAllowed = true}}) - local request_id_list_of_permissions = self.hmiConnection:SendRequest("SDL.GetListOfPermissions", - { appID = HMIid }) - EXPECT_HMIRESPONSE(request_id_list_of_permissions) - commonDefects.delayedExp(1000) -- without delayed snapshot is not created in time +local function makeConsent(self) + local request_id = self.hmiConnection:SendRequest("SDL.GetListOfPermissions") + EXPECT_HMIRESPONSE(request_id,{ + result = { + code = 0, + method = "SDL.GetListOfPermissions", + allowedFunctions = {{name = "Location", allowed = nil}}, + externalConsentStatus = {} + } + }) + :Do(function(_,data) + local groupId + for i = 1, #data.result.allowedFunctions do + if(data.result.allowedFunctions[i].name == "Location") then + groupId = data.result.allowedFunctions[i].id + end + end + if groupId then + self.hmiConnection:SendNotification("SDL.OnAppPermissionConsent", { + appID = commonDefects.getHMIAppId(), + source = "GUI", + consentedFunctions = {{name = "Location", id = groupId, allowed = true}} + }) + else + self:FailTestCase("GroupId for Location was not found") + end end) end -local function Check_user_consent_records_in_PT(self) +local function Check_user_consent_records_in_LPT(self) local is_test_fail = false - if( commonSteps:file_exists("/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json") == false) then - self:FailTestCase("/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json is not created") + if( commonSteps:file_exists(pathToLPT) == false) then + self:FailTestCase(config.pathToSDL .. pathToLPT .. " is not created") else - testCasesForPolicyTableSnapshot:extract_pts({HMIid}) - local app_consent_location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data." .. - config.deviceMAC .. ".user_consent_records."..config.application1.registerAppInterfaceParams.appID .. - ".consent_groups.Location-1") - local app_consent_notifications = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data." .. - config.deviceMAC .. ".user_consent_records." .. config.application1.registerAppInterfaceParams.appID .. - ".consent_groups.Notifications") - if(app_consent_location ~= true) then - commonFunctions:printError("Error: user_consent_records.consent_groups.Location is not present in LPT") + local queryCG = "select device_id from consent_group" + local r_actual_CG = commonFunctions:get_data_policy_sql(pathToLPT, queryCG) + if #r_actual_CG ~= 1 then + commonFunctions:printError("Error: consent_group does not contain 1 required records in LPT") is_test_fail = true end - if(app_consent_notifications ~= true) then - commonFunctions:printError("Error: user_consent_records.consent_groups.Notifications is not present in LPT") + local queryDCG = "select device_id from device_consent_group" + local r_actualDCG = commonFunctions:get_data_policy_sql(pathToLPT, queryDCG) + if #r_actualDCG ~= 1 then + commonFunctions:printError("Error: device_consent_group does not contain 1 required record in LPT") is_test_fail = true end - if( commonSteps:file_exists(config.pathToSDL.."/storage/policy.sqlite") == false) then - self:FailTestCase(config.pathToSDL .."/storage/policy.sqlite is not created") - else - local queryCG = "select device_id from consent_group" - local r_actual_CG = commonFunctions:get_data_policy_sql(config.pathToSDL.."/storage/policy.sqlite", queryCG) - if #r_actual_CG ~= 2 then - commonFunctions:printError("Error: consent_group does not contain 2 required records in LPT") - is_test_fail = true - end - local queryDCG = "select device_id from device_consent_group" - local r_actualDCG = commonFunctions:get_data_policy_sql(config.pathToSDL.."/storage/policy.sqlite", queryDCG) - if #r_actualDCG ~= 1 then - commonFunctions:printError("Error: device_consent_group does not contain 1 required record in LPT") - is_test_fail = true - end - end end if(is_test_fail == true) then self:FailTestCase("Test is FAILED.") end end -local function CheckLPT(self) +local function Check_user_consent_records_in_Snapshot(self) local is_test_fail = false - if( commonSteps:file_exists(config.pathToSDL.."/storage/policy.sqlite") == false) then - self:FailTestCase(config.pathToSDL .."/storage/policy.sqlite is not created") + if (commonSteps:file_exists(pathToPTS) == false) then + self:FailTestCase(pathToPTS .. " is not created") else - local queryCG = "select device_id from consent_group" - local r_actual_CG = commonFunctions:get_data_policy_sql(config.pathToSDL.."/storage/policy.sqlite", queryCG) - if #r_actual_CG ~= 0 then + local app_consent_location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data." + .. config.deviceMAC .. ".user_consent_records." + .. config.application1.registerAppInterfaceParams.appID .. ".consent_groups.Location-1") + if (app_consent_location ~= true) then + commonFunctions:printError("Error: user_consent_records.consent_groups.Location is not present in LPT") + is_test_fail = true + end + end + if (is_test_fail == true) then + self:FailTestCase("Test is FAILED.") + end +end + +local function performFACTORY_DEFAULTS(self) + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "FACTORY_DEFAULTS" }) + self.mobileSession1:ExpectNotification("OnAppInterfaceUnregistered", { reason = "FACTORY_DEFAULTS" }) + :Do(function() sdl:DeleteFile() end) +end + +local function Wait_SDL_stop(self) + delayedExp(5000, self) +end + +local function Check_no_user_consent_records_in_LPT(self) + local is_test_fail = false + if (commonSteps:file_exists(pathToLPT) == false) then + self:FailTestCase(config.pathToSDL .. pathToLPT .. " is not created") + else + local queryCG = "select count(*) from consent_group" + local r_actual_CG = commonFunctions:get_data_policy_sql(pathToLPT, queryCG) + if r_actual_CG[1] ~= "0" then commonFunctions:printError("Error: consent_group contains redundant records in LPT") is_test_fail = true end - local queryDCG = "select device_id from device_consent_group" - local r_actualDCG = commonFunctions:get_data_policy_sql(config.pathToSDL.."/storage/policy.sqlite", queryDCG) - if #r_actualDCG ~= 0 then + local queryDCG = "select count(*) from device_consent_group" + local r_actualDCG = commonFunctions:get_data_policy_sql(pathToLPT, queryDCG) + if r_actualDCG[1] ~= "0" then commonFunctions:printError("Error: device_consent_group contains redundant record in LPT") is_test_fail = true end @@ -168,65 +185,44 @@ local function CheckLPT(self) end end -local function Check_no_user_consent_records_in_PT(self) +local function Check_no_user_consent_records_in_Snapshot(self) local is_test_fail = false - if( commonSteps:file_exists("/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json") == false) then - self:FailTestCase(config.pathToSDL .. "sdl_preloaded_pt.json " .. "is not created") + if (commonSteps:file_exists(pathToPTS) == false) then + self:FailTestCase(pathToPTS .. " is not created") else - testCasesForPolicyTableSnapshot:extract_pts( - {self.applications[config.application1.registerAppInterfaceParams.appName]}) - local app_consent_location = testCasesForPolicyTableSnapshot:get_data_from_PTS - ("device_data." .. config.deviceMAC .. ".user_consent_records." .. - config.application1.registerAppInterfaceParams.appID .. ".consent_groups.Location-1") - local app_consent_notifications = testCasesForPolicyTableSnapshot:get_data_from_PTS - ("device_data." .. config.deviceMAC .. ".user_consent_records." .. - config.application1.registerAppInterfaceParams.appID .. ".consent_groups.Notifications") - if(app_consent_location == true) then + local app_consent_location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data." + .. config.deviceMAC .. ".user_consent_records." + .. config.application1.registerAppInterfaceParams.appID .. ".consent_groups.Location-1") + if (app_consent_location ~= nil) then commonFunctions:printError("Error: user_consent_records.consent_groups.Location was not reset in LPT") is_test_fail = true end - if(app_consent_notifications == true) then - commonFunctions:printError("Error: user_consent_records.consent_groups.Notifications was not reset in LPT") - is_test_fail = true - end end - if(is_test_fail == true) then + if (is_test_fail == true) then self:FailTestCase("Test is FAILED.") end end -local function FACTORY_DEFAULTS(self) - self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "FACTORY_DEFAULTS" }) -end - -local function Wait_SDL_stop() - os.execute("sleep 15") -end - -local function RemoveSnapshot() - os.execute('rm "/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json"') -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonDefects.preconditions) -runner.Step("ReplacePreloadedFile", ReplacePreloadedFile) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start) -runner.Step("RAI, PTU", Register_App) -runner.Step("Activate App", Precondition_Activate_app_To_Trigger_PTU) +runner.Step("Start SDL, HMI, connect Mobile, start Session", start) +runner.Step("Allow SDL for device", allowSDL) +runner.Step("RAI, PTU", commonDefects.rai_ptu, { ptUpdateFunc}) +runner.Step("Make consent for Location group", makeConsent) runner.Title("Test") -runner.Step("TrigerPTUForCreationSnapshotWithConsent", TrigerPTUForCreationSnapshotWithConsent) -runner.Step("Check_user_consent_records_in_PT", Check_user_consent_records_in_PT) -runner.Step("FACTORY_DEFAULTS", FACTORY_DEFAULTS) +runner.Step("Remove Snapshot and Trigger PTU", removeSnapshotAndTriggerPTUFromHMI) +runner.Step("Check_presence_of_user_consent_records_in_LPT", Check_user_consent_records_in_LPT) +runner.Step("Check_presence_of_user_consent_records_in_Snapshot", Check_user_consent_records_in_Snapshot) +runner.Step("FACTORY_DEFAULTS", performFACTORY_DEFAULTS) runner.Step("Wait_SDL_stop", Wait_SDL_stop) -runner.Step("CheckLPT", CheckLPT) -runner.Step("RemoveSnapshot", RemoveSnapshot) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start) -runner.Step("RAI, PTU", Register_App) -runner.Step("Activate App", Precondition_Activate_app_To_Trigger_PTU) -runner.Step("Check_no_user_consent_records_in_PT", Check_no_user_consent_records_in_PT) +runner.Step("Start SDL, HMI, connect Mobile, start Session", start) +runner.Step("Check_absence_of_user_consent_records_in_LPT", Check_no_user_consent_records_in_LPT) +runner.Step("Allow SDL for device", allowSDL) +runner.Step("RAI", commonDefects.rai_n) +runner.Step("Remove Snapshot and Trigger PTU", removeSnapshotAndTriggerPTUFromHMI) +runner.Step("Check_absence_of_user_consent_records_in_Snapshot", Check_no_user_consent_records_in_Snapshot) runner.Title("Postconditions") runner.Step("Stop SDL", commonDefects.postconditions) -runner.Step("RestorePreloadedPT", RestorePreloadedPT) From e2de9d52e2a1ce942034f440ca5b63c37e4dfce0 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Mon, 4 Dec 2017 14:46:52 +0200 Subject: [PATCH 210/681] Script for reproducing 1880 issue --- test_scripts/Defects/4_5/.gitignore | 41 -- ...1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua | 375 ++++++++++++++++++ 2 files changed, 375 insertions(+), 41 deletions(-) delete mode 100644 test_scripts/Defects/4_5/.gitignore create mode 100644 test_scripts/Defects/4_5/1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua diff --git a/test_scripts/Defects/4_5/.gitignore b/test_scripts/Defects/4_5/.gitignore deleted file mode 100644 index 6fd0a376de..0000000000 --- a/test_scripts/Defects/4_5/.gitignore +++ /dev/null @@ -1,41 +0,0 @@ -# Compiled Lua sources -luac.out - -# luarocks build files -*.src.rock -*.zip -*.tar.gz - -# Object files -*.o -*.os -*.ko -*.obj -*.elf - -# Precompiled Headers -*.gch -*.pch - -# Libraries -*.lib -*.a -*.la -*.lo -*.def -*.exp - -# Shared objects (inc. Windows DLLs) -*.dll -*.so -*.so.* -*.dylib - -# Executables -*.exe -*.out -*.app -*.i*86 -*.x86_64 -*.hex - diff --git a/test_scripts/Defects/4_5/1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua b/test_scripts/Defects/4_5/1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua new file mode 100644 index 0000000000..9210c19643 --- /dev/null +++ b/test_scripts/Defects/4_5/1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua @@ -0,0 +1,375 @@ +--------------------------------------------------------------------------------------------- +-- In case +-- SDL transfers *RPC with own timeout from mobile app to HMI (please see list with impacted *RPCs below) +-- and HMI does NOT respond during + <*RPCs_own_timeout> (please see APPLINK-27495) +-- SDL must: +-- respond 'GENERIC_ERROR, success:false' to mobile app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonDefects = require("test_scripts/Defects/4_5/commonDefects") + +--[[ Local Variables ]] +local DefaultTimeout = 10000 + +local AlertRequestParams = { + alertText1 = "alertText1", + duration = 7000 +} + +local AlertRequestParamsWithoutDuration = { + alertText1 = "alertText1", + ttsChunks = { + { + text = "TTSChunk", + type = "TEXT", + } + }, +} + +local SliderRequetsParams = { + numTicks = 3, + position = 2, + sliderHeader ="sliderHeader", + sliderFooter = {"1", "2", "3"}, + timeout = 7000 +} + +local SliderRequetsParamsWithoutTimeout = { + numTicks = 3, + position = 2, + sliderHeader ="sliderHeader", + sliderFooter = {"1", "2", "3"}, +} + +local ScrollableMessageRequestParamsWithSoftButtons = { + scrollableMessageBody = "abc", + softButtons = + { + { + softButtonID = 1, + text = "Button1", + type = "IMAGE", + image = + { + value = "icon.png", + imageType = "DYNAMIC" + }, + isHighlighted = false, + systemAction = "DEFAULT_ACTION" + }, + { + softButtonID = 2, + text = "Button2", + type = "IMAGE", + image = + { + value = "icon.png", + imageType = "DYNAMIC" + }, + isHighlighted = false, + systemAction = "DEFAULT_ACTION" + } + }, + timeout = 7000 +} + +local ScrollableMessageRequestParamsWithoutSoftButtons = { + scrollableMessageBody = "abc", + timeout = 3000 +} + +local ScrollableMessageRequestParamsWithoutTimeout = { + scrollableMessageBody = "abc", +} + +local PerformInteractionRequestParamsBOTH = { + initialText = "StartPerformInteraction", + initialPrompt = { + { + text = "Make your choice", + type = "TEXT" + } + }, + interactionMode = "BOTH", + interactionChoiceSetIDList = {100}, + helpPrompt = { + { + text = "Help Prompt", + type = "TEXT", + } + }, + timeoutPrompt = { + { + text = " Time out ", + type = "TEXT", + } + }, + timeout = 7000, + vrHelp = { + { + text = " New VRHelp ", + position = 1, + image = { + value = "icon.png", + imageType = "STATIC", + } + } + }, + interactionLayout = "ICON_ONLY" +} + +local PerformInteractionRequestParamsMANUAL = { + initialText = "StartPerformInteraction", + interactionMode = "MANUAL_ONLY", + initialPrompt = { + { + text = "Make your choice", + type = "TEXT" + } + }, + interactionChoiceSetIDList = {100}, + timeout = 8000, + interactionLayout = "LIST_ONLY" +} + +local PerformInteractionRequestParamsVR = { + initialText = "StartPerformInteraction", + initialPrompt = { + { + text = "Make your choice", + type = "TEXT" + } + }, + interactionMode = "VR_ONLY", + interactionChoiceSetIDList = {100}, + helpPrompt = { + { + text = "Help Prompt", + type = "TEXT", + } + }, + timeoutPrompt = { + { + text = "Time out", + type = "TEXT", + } + }, + timeout = 12000, + vrHelp = { + { + text = "New VRHelp", + position = 1, + image = { + value = "icon.png", + imageType = "STATIC", + } + } + }, + interactionLayout = "ICON_ONLY" +} + +--[[ Local Functions ]] +local function Alert(params, self) + local AlertDuration + if params.duration then + AlertDuration = params.duration + else + -- deration default valur from mobile API + AlertDuration = 5000 + end + local RespTimeout = DefaultTimeout + AlertDuration + local RequestTime + local RespTime + local TimeBetweenReqRes + + if params.ttsChunks then + EXPECT_HMICALL("TTS.Speak") + :Do(function(_,data) + local function SpeakResp() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + RUN_AFTER(SpeakResp, 2000) + end) + end + + local cid = self.mobileSession1:SendRPC("Alert", params) + RequestTime = timestamp() + + EXPECT_HMICALL("UI.Alert") + + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) + :Timeout(RespTimeout + 1000) + :ValidIf(function() + RespTime = timestamp() + TimeBetweenReqRes = RespTime - RequestTime + if + TimeBetweenReqRes > RespTimeout - 1000 and + TimeBetweenReqRes < RespTimeout + 1000 then + return true + else + return false, "SDL triggers timeout earlier then expected(".. tostring(RespTimeout) .." sec), after " .. + tostring(TimeBetweenReqRes) .. + " sec.\n SDL must use Alert duration + default timeout in case of absence softButtons." + end + end) +end + +local function Slider(params, self) + local SliderDuration + if params.timeout then + SliderDuration = params.timeout + else + -- timeout default value from mobile API + SliderDuration = 10000 + end + local RespTimeout = DefaultTimeout + SliderDuration + local RequestTime + local RespTime + local TimeBetweenReqRes + local cid = self.mobileSession1:SendRPC("Slider", params) + RequestTime = timestamp() + EXPECT_HMICALL("UI.Slider") + self.mobileSession1:ExpectResponse(cid, {success = false, resultCode = "GENERIC_ERROR"}) + :Timeout(RespTimeout + 1000) + :ValidIf(function() + RespTime = timestamp() + TimeBetweenReqRes = RespTime - RequestTime + if + TimeBetweenReqRes > RespTimeout - 1000 and + TimeBetweenReqRes < RespTimeout + 1000 then + return true + else + return false, "SDL triggers timeout earlier then expected(".. tostring(RespTimeout) .." sec), after " .. + tostring(TimeBetweenReqRes) .. " sec. \n SDL must use Slider timeout + default timeout." + end + end) +end + +local function ScrollableMessage(params, self) + local ScrMesDuration + if params.timeout then + ScrMesDuration = params.timeout + else + -- timeout default value from mobile API + ScrMesDuration = 30000 + end + local RespTimeout = DefaultTimeout + ScrMesDuration + local RequestTime + local RespTime + local TimeBetweenReqRes + local cid = self.mobileSession1:SendRPC("ScrollableMessage", params) + RequestTime = timestamp() + EXPECT_HMICALL("UI.ScrollableMessage") + self.mobileSession1:ExpectResponse(cid, {success = false, resultCode = "GENERIC_ERROR"}) + :Timeout(RespTimeout + 1000) + :ValidIf(function() + RespTime = timestamp() + TimeBetweenReqRes = RespTime - RequestTime + if + TimeBetweenReqRes > RespTimeout - 1000 and + TimeBetweenReqRes < RespTimeout + 1000 then + return true + else + return false, "SDL triggers timeout earlier then expected(".. tostring(RespTimeout) .." sec), after " .. + tostring(TimeBetweenReqRes) .. " sec. \n SDL must use ScrollableMessage timeout + default timeout." + end + end) +end + +local function CreateInteractionChoiceSet(self) + local cid = self.mobileSession1:SendRPC("CreateInteractionChoiceSet", { + interactionChoiceSetID = 100, + choiceSet = { + { + choiceID = 100, + menuName ="Choice100", + vrCommands = { + "Choice100", + } + } + } + }) + EXPECT_HMICALL("VR.AddCommand") + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + self.mobileSession1:ExpectResponse(cid, {success = true, resultCode = "SUCCESS"}) +end + +local function PerformInteraction(params, self) + local PIDuration + local RequestTime + local RespTime + local TimeBetweenReqRes + local TimeToResponseForVR = 2000 + local RespTimeout + if params.interactionMode ~= "VR_ONLY" then + if params.timeout then + PIDuration = params.timeout + RespTimeout = DefaultTimeout + 2*PIDuration + else + PIDuration = 10000 + RespTimeout = DefaultTimeout + 2*PIDuration + end + else + RespTimeout = params.timeout + end + local cid = self.mobileSession1:SendRPC("PerformInteraction", params) + EXPECT_HMICALL("VR.PerformInteraction") + :Do(function(_,data) + local function RespVR() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + RequestTime = timestamp() + end + RUN_AFTER(RespVR, TimeToResponseForVR) + end) + EXPECT_HMICALL("UI.PerformInteraction") + self.mobileSession1:ExpectResponse(cid, {success = false, resultCode = "GENERIC_ERROR"}) + :Timeout(RespTimeout + 3000) + :ValidIf(function() + RespTime = timestamp() + TimeBetweenReqRes = RespTime - RequestTime + if + TimeBetweenReqRes > RespTimeout - 1000 and + TimeBetweenReqRes < RespTimeout + 1000 then + return true + else + return false, "SDL triggers timeout earlier then expected(".. tostring(RespTimeout) .." sec), after " .. + tostring(TimeBetweenReqRes) .. " sec. \n SDL must use PI timeout + default timeout." + end + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonDefects.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start) +runner.Step("RAI, PTU", commonDefects.rai_ptu) +runner.Step("Activate App", commonDefects.activate_app) +runner.Step("Upload file", commonDefects.putFile, {"icon.png"}) + +runner.Title("Test") +runner.Step("Alert_default_timeout_and_Alert_timeout", Alert, { AlertRequestParams }) +runner.Step("Alert_default_timeout", Alert, { AlertRequestParamsWithoutDuration }) + +runner.Step("Slider_default_timeout_and_Slider_timeout", Slider, { SliderRequetsParams }) +runner.Step("Slider_default_timeout", Slider, { SliderRequetsParamsWithoutTimeout }) + +runner.Step("ScrollableMessage_default_timeout_and_ScrMes_timeout_with_softButtons", ScrollableMessage, + { ScrollableMessageRequestParamsWithSoftButtons }) +runner.Step("ScrollableMessage_default_timeout_and_ScrMes_timeout_without_softButtons", ScrollableMessage, + { ScrollableMessageRequestParamsWithoutSoftButtons }) +runner.Step("ScrollableMessage_default_timeout", ScrollableMessage, + { ScrollableMessageRequestParamsWithoutTimeout }) + +runner.Step("CreateInteractionChoiceSet", CreateInteractionChoiceSet) +runner.Step("PerformInteraction_default_timeout_and_PI_timeout_BOTH", PerformInteraction, + { PerformInteractionRequestParamsBOTH }) +runner.Step("PerformInteraction_default_timeout_and_PI_timeout_MANUAL", PerformInteraction, + { PerformInteractionRequestParamsMANUAL }) +runner.Step("PerformInteraction_timeout_VR", PerformInteraction, { PerformInteractionRequestParamsVR }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonDefects.postconditions) + From 0e35f9dcd8c7707bf2df9ea5df058c0c4f52c7b6 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 7 Dec 2017 08:04:54 +0200 Subject: [PATCH 211/681] Added separated script for VR_ONLY mode --- ...1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua | 48 +++++++++++++++---- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/test_scripts/Defects/4_5/1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua b/test_scripts/Defects/4_5/1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua index 9210c19643..5dd10faab5 100644 --- a/test_scripts/Defects/4_5/1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua +++ b/test_scripts/Defects/4_5/1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua @@ -304,16 +304,12 @@ local function PerformInteraction(params, self) local TimeBetweenReqRes local TimeToResponseForVR = 2000 local RespTimeout - if params.interactionMode ~= "VR_ONLY" then - if params.timeout then - PIDuration = params.timeout - RespTimeout = DefaultTimeout + 2*PIDuration - else - PIDuration = 10000 - RespTimeout = DefaultTimeout + 2*PIDuration - end + if params.timeout then + PIDuration = params.timeout + RespTimeout = DefaultTimeout + 2*PIDuration else - RespTimeout = params.timeout + PIDuration = 10000 + RespTimeout = DefaultTimeout + 2*PIDuration end local cid = self.mobileSession1:SendRPC("PerformInteraction", params) EXPECT_HMICALL("VR.PerformInteraction") @@ -341,6 +337,38 @@ local function PerformInteraction(params, self) end) end +local function PerformInteractionVR(params, self) + local RequestTime + local RespTime + local TimeBetweenReqRes + local TimeToResponseForVR = 2000 + local RespTimeout = params.timeout + local cid = self.mobileSession1:SendRPC("PerformInteraction", params) + RequestTime = timestamp() + EXPECT_HMICALL("VR.PerformInteraction") + :Do(function(_,data) + local function RespVR() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + RUN_AFTER(RespVR, TimeToResponseForVR) + end) + EXPECT_HMICALL("UI.PerformInteraction") + self.mobileSession1:ExpectResponse(cid, {success = false, resultCode = "GENERIC_ERROR"}) + :Timeout(RespTimeout + 1000) + :ValidIf(function() + RespTime = timestamp() + TimeBetweenReqRes = RespTime - RequestTime + if + TimeBetweenReqRes > RespTimeout - 1000 and + TimeBetweenReqRes < RespTimeout + 1000 then + return true + else + return false, "SDL triggers timeout earlier then expected(".. tostring(RespTimeout) .." sec), after " .. + tostring(TimeBetweenReqRes) .. " sec. \n SDL must use PI timeout + default timeout." + end + end) +end + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonDefects.preconditions) @@ -368,7 +396,7 @@ runner.Step("PerformInteraction_default_timeout_and_PI_timeout_BOTH", PerformInt { PerformInteractionRequestParamsBOTH }) runner.Step("PerformInteraction_default_timeout_and_PI_timeout_MANUAL", PerformInteraction, { PerformInteractionRequestParamsMANUAL }) -runner.Step("PerformInteraction_timeout_VR", PerformInteraction, { PerformInteractionRequestParamsVR }) +runner.Step("PerformInteraction_timeout_VR", PerformInteractionVR, { PerformInteractionRequestParamsVR }) runner.Title("Postconditions") runner.Step("Stop SDL", commonDefects.postconditions) From 9fb9bf61ebd37cac5b7a8a4c3ba4fababce08136 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 13 Dec 2017 12:08:35 +0200 Subject: [PATCH 212/681] Fixed typos and cosmetic changes --- ...1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua | 48 +++++++------------ 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/test_scripts/Defects/4_5/1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua b/test_scripts/Defects/4_5/1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua index 5dd10faab5..af50527ed5 100644 --- a/test_scripts/Defects/4_5/1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua +++ b/test_scripts/Defects/4_5/1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua @@ -44,8 +44,7 @@ local SliderRequetsParamsWithoutTimeout = { local ScrollableMessageRequestParamsWithSoftButtons = { scrollableMessageBody = "abc", - softButtons = - { + softButtons = { { softButtonID = 1, text = "Button1", @@ -175,7 +174,7 @@ local function Alert(params, self) if params.duration then AlertDuration = params.duration else - -- deration default valur from mobile API + -- duration default value from mobile API AlertDuration = 5000 end local RespTimeout = DefaultTimeout + AlertDuration @@ -203,14 +202,12 @@ local function Alert(params, self) :ValidIf(function() RespTime = timestamp() TimeBetweenReqRes = RespTime - RequestTime - if - TimeBetweenReqRes > RespTimeout - 1000 and - TimeBetweenReqRes < RespTimeout + 1000 then + if TimeBetweenReqRes > RespTimeout - 1000 and TimeBetweenReqRes < RespTimeout + 1000 then return true else - return false, "SDL triggers timeout earlier then expected(".. tostring(RespTimeout) .." sec), after " .. - tostring(TimeBetweenReqRes) .. - " sec.\n SDL must use Alert duration + default timeout in case of absence softButtons." + return false, "SDL triggers timeout earlier then expected(" + .. tostring(RespTimeout) .." sec), after " .. tostring(TimeBetweenReqRes) + .. " sec.\n SDL must use Alert duration + default timeout in case of absence softButtons." end end) end @@ -235,13 +232,11 @@ local function Slider(params, self) :ValidIf(function() RespTime = timestamp() TimeBetweenReqRes = RespTime - RequestTime - if - TimeBetweenReqRes > RespTimeout - 1000 and - TimeBetweenReqRes < RespTimeout + 1000 then + if TimeBetweenReqRes > RespTimeout - 1000 and TimeBetweenReqRes < RespTimeout + 1000 then return true else - return false, "SDL triggers timeout earlier then expected(".. tostring(RespTimeout) .." sec), after " .. - tostring(TimeBetweenReqRes) .. " sec. \n SDL must use Slider timeout + default timeout." + return false, "SDL triggers timeout earlier then expected(".. tostring(RespTimeout) .." sec), after " + .. tostring(TimeBetweenReqRes) .. " sec. \n SDL must use Slider timeout + default timeout." end end) end @@ -266,13 +261,11 @@ local function ScrollableMessage(params, self) :ValidIf(function() RespTime = timestamp() TimeBetweenReqRes = RespTime - RequestTime - if - TimeBetweenReqRes > RespTimeout - 1000 and - TimeBetweenReqRes < RespTimeout + 1000 then + if TimeBetweenReqRes > RespTimeout - 1000 and TimeBetweenReqRes < RespTimeout + 1000 then return true else - return false, "SDL triggers timeout earlier then expected(".. tostring(RespTimeout) .." sec), after " .. - tostring(TimeBetweenReqRes) .. " sec. \n SDL must use ScrollableMessage timeout + default timeout." + return false, "SDL triggers timeout earlier then expected(".. tostring(RespTimeout) .." sec), after " + .. tostring(TimeBetweenReqRes) .. " sec. \n SDL must use ScrollableMessage timeout + default timeout." end end) end @@ -326,13 +319,11 @@ local function PerformInteraction(params, self) :ValidIf(function() RespTime = timestamp() TimeBetweenReqRes = RespTime - RequestTime - if - TimeBetweenReqRes > RespTimeout - 1000 and - TimeBetweenReqRes < RespTimeout + 1000 then + if TimeBetweenReqRes > RespTimeout - 1000 and TimeBetweenReqRes < RespTimeout + 1000 then return true else - return false, "SDL triggers timeout earlier then expected(".. tostring(RespTimeout) .." sec), after " .. - tostring(TimeBetweenReqRes) .. " sec. \n SDL must use PI timeout + default timeout." + return false, "SDL triggers timeout earlier then expected(".. tostring(RespTimeout) .." sec), after " + .. tostring(TimeBetweenReqRes) .. " sec. \n SDL must use PI timeout + default timeout." end end) end @@ -358,13 +349,11 @@ local function PerformInteractionVR(params, self) :ValidIf(function() RespTime = timestamp() TimeBetweenReqRes = RespTime - RequestTime - if - TimeBetweenReqRes > RespTimeout - 1000 and - TimeBetweenReqRes < RespTimeout + 1000 then + if TimeBetweenReqRes > RespTimeout - 1000 and TimeBetweenReqRes < RespTimeout + 1000 then return true else - return false, "SDL triggers timeout earlier then expected(".. tostring(RespTimeout) .." sec), after " .. - tostring(TimeBetweenReqRes) .. " sec. \n SDL must use PI timeout + default timeout." + return false, "SDL triggers timeout earlier then expected(".. tostring(RespTimeout) .." sec), after " + .. tostring(TimeBetweenReqRes) .. " sec. \n SDL must use PI timeout + default timeout." end end) end @@ -400,4 +389,3 @@ runner.Step("PerformInteraction_timeout_VR", PerformInteractionVR, { PerformInte runner.Title("Postconditions") runner.Step("Stop SDL", commonDefects.postconditions) - From 9fa904e32650f3d01d2449ed8fed0f7cb961d9fd Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 14 Dec 2017 13:56:24 +0200 Subject: [PATCH 213/681] Add obtaining of default values for parameters from API --- ...1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/test_scripts/Defects/4_5/1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua b/test_scripts/Defects/4_5/1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua index af50527ed5..59292cb7da 100644 --- a/test_scripts/Defects/4_5/1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua +++ b/test_scripts/Defects/4_5/1880_DefaultAndRPCTimeoutGENERIC_ERROR.lua @@ -8,6 +8,9 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonDefects = require("test_scripts/Defects/4_5/commonDefects") +local apiLoader = require("modules/api_loader") +local api = apiLoader.init("data/MOBILE_API.xml") +local schema = api.interface[next(api.interface)] --[[ Local Variables ]] local DefaultTimeout = 10000 @@ -169,13 +172,23 @@ local PerformInteractionRequestParamsVR = { } --[[ Local Functions ]] +local function getDefaultValueFromAPI(pFunctionName, pParamName) + local defvalue = schema.type["request"].functions[pFunctionName].param[pParamName].defvalue + if not defvalue then + print("Default value was not found in API for function '" .. pFunctionName + .. "' and parameter '" .. pParamName .. "'") + defvalue = 0 + end + print("Default value: " .. defvalue) + return defvalue +end + local function Alert(params, self) local AlertDuration if params.duration then AlertDuration = params.duration else - -- duration default value from mobile API - AlertDuration = 5000 + AlertDuration = getDefaultValueFromAPI("Alert", "duration") end local RespTimeout = DefaultTimeout + AlertDuration local RequestTime @@ -217,8 +230,7 @@ local function Slider(params, self) if params.timeout then SliderDuration = params.timeout else - -- timeout default value from mobile API - SliderDuration = 10000 + SliderDuration = getDefaultValueFromAPI("Slider", "timeout") end local RespTimeout = DefaultTimeout + SliderDuration local RequestTime @@ -246,8 +258,7 @@ local function ScrollableMessage(params, self) if params.timeout then ScrMesDuration = params.timeout else - -- timeout default value from mobile API - ScrMesDuration = 30000 + ScrMesDuration = getDefaultValueFromAPI("ScrollableMessage", "timeout") end local RespTimeout = DefaultTimeout + ScrMesDuration local RequestTime @@ -301,7 +312,7 @@ local function PerformInteraction(params, self) PIDuration = params.timeout RespTimeout = DefaultTimeout + 2*PIDuration else - PIDuration = 10000 + PIDuration = getDefaultValueFromAPI("PerformInteraction", "timeout") RespTimeout = DefaultTimeout + 2*PIDuration end local cid = self.mobileSession1:SendRPC("PerformInteraction", params) From f9d4f6b26d5d5cee6ba41ed4f85a5472cc11ddc3 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 15 Dec 2017 14:19:50 +0200 Subject: [PATCH 214/681] Stabilize script --- .../Defects/4_5/1225_FACTORY_DEFAULTS.lua | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua b/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua index 229471e3ce..e193512567 100644 --- a/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua +++ b/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua @@ -25,9 +25,9 @@ local runner = require('user_modules/script_runner') local commonDefects = require('test_scripts/Defects/4_5/commonDefects') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') -local testCasesForPolicyTableSnapshot = require ('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local sdl = require("SDL") local events = require('events') +local json = require("modules/json") --[[ Local Variables ]] local pathToPTS = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" @@ -71,13 +71,20 @@ local function delayedExp(pTime, self) RUN_AFTER(toRun, pTime) end +local function ptsToTable(pts_f) + local f = io.open(pts_f, "r") + local content = f:read("*all") + f:close() + return json.decode(content) +end + local function ptUpdateFunc(pTbl) local appId = config.application1.registerAppInterfaceParams.appID table.insert(pTbl.policy_table.app_policies[appId].groups, "Location-1") end local function removeSnapshotAndTriggerPTUFromHMI(self) - os.execute("rm " .. pathToPTS) + os.execute("rm -f " .. pathToPTS) EXPECT_HMICALL("BasicCommunication.PolicyUpdate", { file = pathToPTS }) self.hmiConnection:SendNotification("SDL.OnPolicyUpdate", { }) end @@ -109,11 +116,12 @@ local function makeConsent(self) self:FailTestCase("GroupId for Location was not found") end end) + delayedExp(1000, self) end local function Check_user_consent_records_in_LPT(self) local is_test_fail = false - if( commonSteps:file_exists(pathToLPT) == false) then + if (commonSteps:file_exists(pathToLPT) == false) then self:FailTestCase(config.pathToSDL .. pathToLPT .. " is not created") else local queryCG = "select device_id from consent_group" @@ -139,11 +147,10 @@ local function Check_user_consent_records_in_Snapshot(self) if (commonSteps:file_exists(pathToPTS) == false) then self:FailTestCase(pathToPTS .. " is not created") else - local app_consent_location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data." - .. config.deviceMAC .. ".user_consent_records." - .. config.application1.registerAppInterfaceParams.appID .. ".consent_groups.Location-1") - if (app_consent_location ~= true) then - commonFunctions:printError("Error: user_consent_records.consent_groups.Location is not present in LPT") + local pts = ptsToTable(pathToPTS) + local ucr = pts.policy_table.device_data[config.deviceMAC].user_consent_records + if not (ucr[config.application1.registerAppInterfaceParams.appID]) then + commonFunctions:printError("Error: user_consent_records.consent_groups.Location is not present in Snapshot") is_test_fail = true end end @@ -190,11 +197,10 @@ local function Check_no_user_consent_records_in_Snapshot(self) if (commonSteps:file_exists(pathToPTS) == false) then self:FailTestCase(pathToPTS .. " is not created") else - local app_consent_location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data." - .. config.deviceMAC .. ".user_consent_records." - .. config.application1.registerAppInterfaceParams.appID .. ".consent_groups.Location-1") - if (app_consent_location ~= nil) then - commonFunctions:printError("Error: user_consent_records.consent_groups.Location was not reset in LPT") + local pts = ptsToTable(pathToPTS) + local ucr = pts.policy_table.device_data[config.deviceMAC].user_consent_records + if (ucr[config.application1.registerAppInterfaceParams.appID]) then + commonFunctions:printError("Error: user_consent_records.consent_groups.Location was not reset in Snapshot") is_test_fail = true end end From f9660a39e827a61c707dc6e5de7fddf5957bb8e1 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 8 Dec 2017 13:02:11 +0200 Subject: [PATCH 215/681] Script for issue 1892 --- ...rom_SDL_after_receiving_HB_from_mobile.lua | 150 ++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 test_scripts/Defects/4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua diff --git a/test_scripts/Defects/4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua b/test_scripts/Defects/4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua new file mode 100644 index 0000000000..f199f753df --- /dev/null +++ b/test_scripts/Defects/4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua @@ -0,0 +1,150 @@ +--------------------------------------------------------------------------------------------------- +-- Description +-- SDL must start heartbeat only after first Heartbeat request from mobile app +-- Preconditions +-- SDL and HMI are started. +-- mobile app successfully connects to SDL over protocol v3 or higher +-- the value of "HeartBeat" param at .ini file is more than zero +-- Steps to reproduce +-- App sends first HeartBeat request by itself over control service to SDL +-- Actual result +-- SDL start HeartBeat process right after first StartService_request from mobile app +-- Expected result +-- SDL must respond HeartBeat_ACK over control service to mobile app start HeartBeat timeout (defined at .ini file) +-- SDL must NOT start HeartBeat process right after first StartService_request from mobile app(as currently implemented) +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonDefects = require('test_scripts/Defects/4_5/commonDefects') +local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local mobile_session = require('mobile_session') +local constants = require('protocol_handler/ford_protocol_constants') +local events = require('events') +local mobile = require('mobile_connection') +local tcp = require('tcp_connection') +local file_connection = require('file_connection') + +--[[ General configuration parameters ]] +config.heartbeatTimeout = 7000 + +--[[ Local Functions ]] +local function BackUpIniFileAndSetHBValue() + commonPreconditions:BackupFile("smartDeviceLink.ini") + commonFunctions:write_parameter_to_smart_device_link_ini("HeartBeatTimeout", 5000) +end + +local function RestoreIniFile() + commonPreconditions:RestoreFile("smartDeviceLink.ini") +end + +local function OpenConnectionCreateSession(self) + config.defaultProtocolVersion = 3 + local tcpConnection = tcp.Connection(config.mobileHost, config.mobilePort) + local fileConnection = file_connection.FileConnection("mobile.out", tcpConnection) + self.mobileConnection = mobile.MobileConnection(fileConnection) + self.mobileSession1= mobile_session.MobileSession( + self, + self.mobileConnection) + event_dispatcher:AddConnection(self.mobileConnection) + self.mobileSession1:ExpectEvent(events.connectedEvent, "Connection 1 started") + self.mobileConnection:Connect() + self.mobileSession1.activateHeartbeat = false + self.mobileSession1.sendHeartbeatToSDL = false + self.mobileSession1.answerHeartbeatFromSDL = false + self.mobileSession1.ignoreHeartBeatAck = false + self.mobileSession1:StartService(7) +end + +local function RegisterAppInterface(self) + local CorIdRegister = self.mobileSession1:SendRPC("RegisterAppInterface", { + syncMsgVersion ={ + majorVersion = 4, + minorVersion = 3 + }, + appName = config.application1.registerAppInterfaceParams.appName, + isMediaApplication = true, + languageDesired = 'EN-US', + hmiDisplayLanguageDesired = 'EN-US', + appHMIType = { "DEFAULT" }, + appID = config.application1.registerAppInterfaceParams.appID + }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = {appName = config.application1.registerAppInterfaceParams.appName }}) + self.mobileSession1:ExpectResponse(CorIdRegister, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE" }) +end + +local function ExpectationAfterAppRegistration(self) + local hmiAppId = commonDefects.getHMIAppId(1) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", + {unexpectedDisconnect = true, appID = hmiAppId}) + :Times(0) + commonFunctions:userPrint (33,"Log: AppSession started, HB disabled") + commonFunctions:userPrint (33, "Log: App v.3 disconnection not expected since no HB ACK and timer" .. + "should be started by SDL till the HB request from app first") + local HBEvent = events.Event() + HBEvent.matches = + function(_, data) + return data.frameType == 0 and + data.serviceType == 0 and + (data.sessionId == self.mobileSession1.sessionId) and + data.frameInfo == 0 + end + self.mobileSession1:ExpectEvent(HBEvent, "HB") + :Times(0) + commonDefects.delayedExp(10000) +end + +local function sendHBFromMobileAndReceivingFromSDL(self) + local HBEvent = events.Event() + HBEvent.matches = + function(_, data) + return data.frameType == 0 and + data.serviceType == 0 and + (data.sessionId == self.mobileSession1.sessionId) and + data.frameInfo == 0 + end + local HBACKEvent = events.Event() + HBACKEvent.matches = + function(_, data) + return data.frameType == 0 and + data.serviceType == 0 and + (data.sessionId == self.mobileSession1.sessionId) and + data.frameInfo == 255 + end + self.mobileSession1:Send({ + frameType = constants.FRAME_TYPE.CONTROL_FRAME, + serviceType = constants.SERVICE_TYPE.CONTROL, + frameInfo = constants.FRAME_INFO.HEARTBEAT + }) + self.mobileSession1:ExpectEvent(HBEvent, "HB") + self.mobileSession1:ExpectEvent(HBACKEvent, "HB") +end + +local function DisconnectDueToHeartbeat() + local hmiAppId = commonDefects.getHMIAppId(1) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = hmiAppId}) + commonDefects.delayedExp() + commonFunctions:userPrint(33, "AppSession started, HB enabled") + commonFunctions:userPrint(33, "In DisconnectDueToHeartbeat TC disconnection is expected because HB process started" .. + "by SDL after app's HB request") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonDefects.preconditions) +runner.Step("BackUpIniFileAndSetHBValue", BackUpIniFileAndSetHBValue) +runner.Step("Start SDL, HMI", commonDefects.startWithoutMobile) + +runner.Title("Test") +runner.Step("OpenConnectionCreateSession", OpenConnectionCreateSession) +runner.Step("RegisterApp", RegisterAppInterface) +runner.Step("ExpectationAfterAppRegistration", ExpectationAfterAppRegistration) +runner.Step("SendHBFromMobileAndExpectationHBFromSDL", sendHBFromMobileAndReceivingFromSDL) +runner.Step("DisconnectDueToHeartbeat", DisconnectDueToHeartbeat) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonDefects.postconditions) +runner.Step("RestoreIniFile", RestoreIniFile) From ee5d3a36355edfb76fdc796ac7c739c60247e41f Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 19 Dec 2017 14:31:30 +0200 Subject: [PATCH 216/681] Add comments --- ...PTU_Trigger_PTU_failed_previous_IGN_ON.lua | 18 ++ ...havior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua | 51 +++++ ..._does_not_send_HB_and_does_not_respond.lua | 65 ++++++ test_scripts/Defects/4_5/commonDefects.lua | 188 +++++++++++++++--- 4 files changed, 294 insertions(+), 28 deletions(-) diff --git a/test_scripts/Defects/4_5/1206_REQUEST_PTU_Trigger_PTU_failed_previous_IGN_ON.lua b/test_scripts/Defects/4_5/1206_REQUEST_PTU_Trigger_PTU_failed_previous_IGN_ON.lua index da93b612fa..098ffc8f8f 100644 --- a/test_scripts/Defects/4_5/1206_REQUEST_PTU_Trigger_PTU_failed_previous_IGN_ON.lua +++ b/test_scripts/Defects/4_5/1206_REQUEST_PTU_Trigger_PTU_failed_previous_IGN_ON.lua @@ -10,17 +10,35 @@ local common = require("test_scripts/Defects/4_5/commonDefects") local color = require("user_modules/consts").color --[[ Local Functions ]] +--[[ @registerApplicationAndWaitPTUStart: create mobile session, start RPC service, register mobile application +--! and check that 'SDL.OnStatusUpdate' notification is sent to HMI with 'UPDATE_NEEDED' status +--! @parameters: +--! self - test object which will be provided automatically by runner module +--! @return: none +--]] local function registerApplicationAndWaitPTUStart(self) + -- create mobile session self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) + -- start RPC service self.mobileSession:StartService(7) :Do(function() + -- send 'RegisterAppInterface' RPC with default parameters for mobile application + -- and return correlation identifier local corId = self.mobileSession:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) + -- register expectation of response for 'RegisterAppInterface' request with appropriate correlation id + -- on Mobile connection + -- it's expected that request is processed successfully self.mobileSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + -- register expectation of 'BC.OnAppRegistered' notification on HMI connection + -- it's expected that the value of 'application.appName' argument will be equal to default application name EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config.application1.registerAppInterfaceParams.appName } }) + -- register expectation of 'SDL.OnStatusUpdate' notification on HMI connection + -- it's expected that the value of 'status' argument will be 'UPDATE_NEEDED' EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }) :Do(function() + -- print information about received notification to console commonFunctions:userPrint(color.blue, "Received OnStatusUpdate: UPDATE_NEEDED") end) end) diff --git a/test_scripts/Defects/4_5/1211_ATF_Check_count_of_removals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua b/test_scripts/Defects/4_5/1211_ATF_Check_count_of_removals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua index 08f701bbf1..0c23f0b296 100644 --- a/test_scripts/Defects/4_5/1211_ATF_Check_count_of_removals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua +++ b/test_scripts/Defects/4_5/1211_ATF_Check_count_of_removals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua @@ -10,34 +10,67 @@ local common = require("test_scripts/Defects/4_5/commonDefects") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") --[[ General configuration parameters ]] +-- switch ATF to mode when it will continue test script execution even if SDL crashes config.ExitOnCrash = false -- [[Local variables]] +-- define number of requests that have to be sent local count_of_requests = 10 +--[[ @updateINIFile: update parameters in SDL .ini file +--! @parameters: none +--! @return: none +--]] local function updateINIFile() + -- backup .ini file common.backupINIFile() + -- change the value of 'AppHMILevelNoneTimeScaleMaxRequests' parameter commonFunctions:write_parameter_to_smart_device_link_ini("AppHMILevelNoneTimeScaleMaxRequests", count_of_requests) + -- change the value of 'AppHMILevelNoneRequestsTimeScale' parameter commonFunctions:write_parameter_to_smart_device_link_ini("AppHMILevelNoneRequestsTimeScale", 30000) end +--[[ @registerApp: create mobile session, start RPC service and register mobile application +--! @parameters: +--! self - test object which will be provided automatically by runner module +--! @return: none +--]] local function registerApp(self) + -- create mobile session self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) + -- start RPC service self.mobileSession:StartService(7) :Do(function () + -- send 'RegisterAppInterface' RPC with default parameters for mobile application + -- and return correlation identifier local cid = self.mobileSession:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) + -- register expectation of 'BC.OnAppRegistered' notification on HMI connection EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered") + -- register expectation of response for 'RegisterAppInterface' request with appropriate correlation id + -- on Mobile connection EXPECT_RESPONSE(cid, { success = true }) + -- register expectation of 'OnPermissionsChange' notification on Mobile connection EXPECT_NOTIFICATION("OnPermissionsChange") + -- register expectation of 'OnHMIStatus' notification on Mobile connection + -- it's expected that value of 'hmiLevel' parameter will be 'NONE' self.mobileSession:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) end) end +--[[ @Send_TOO_MANY_REQUESTS_WHILE_IN_NONE_HMI_LEVEL: send predefined number of requests +--! 'AddCommand' RPC will be sent (count_of_requests + 10) number of times +--! @parameters: +--! self - test object which will be provided automatically by runner module +--! @return: none +--]] local function Send_TOO_MANY_REQUESTS_WHILE_IN_NONE_HMI_LEVEL(self) + -- define number of requests that will be sent local count_of_sending_requests = count_of_requests + 10 + -- define loop where RPC will be sent several times one by one for i = 1, count_of_sending_requests do + -- send 'AddCommand' RPC with some parameters self.mobileSession:SendRPC("AddCommand", { cmdID = i, menuParams = @@ -47,19 +80,37 @@ local function Send_TOO_MANY_REQUESTS_WHILE_IN_NONE_HMI_LEVEL(self) } }) end + -- register expectation of 'OnAppInterfaceUnregistered' notification on Mobile connection + -- it's expected that value of 'reason' parameter will be 'REQUEST_WHILE_IN_NONE_HMI_LEVEL' EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", {reason = "REQUEST_WHILE_IN_NONE_HMI_LEVEL"}) end +--[[ @Wait: wait 3 sec. +--! @parameters: none +--! @return: none +--]] local function Wait() + -- invoke 'DelayedExp' function of 'commonTestCases' module with parameter of '3000' msec. commonTestCases:DelayedExp(3000) end +--[[ @Check_TOO_MANY_REQUESTS_in_DB: check value of 'count_of_removals_for_bad_behavior' in Local Policy Database +--! @parameters: +--! self - test object which will be provided automatically by runner module +--! @return: none +--]] local function Check_TOO_MANY_REQUESTS_in_DB(self) + -- define path to SQLite database file that is Local Policy Database local db_path = config.pathToSDL.."storage/policy.sqlite" + -- define query which is going to be executed local sql_query = "SELECT count_of_removals_for_bad_behavior FROM app_level WHERE application_id = '" .. config.application1.registerAppInterfaceParams.appID .. "'" + -- define expected value for the query + -- it's expected that the value of 'count_of_removals_for_bad_behavior' parameter will be increased from '0' to '1' local exp_result = {"1"} + -- compare actual value in database against the expected one if commonFunctions:is_db_contains(db_path, sql_query, exp_result) == false then + -- fail test step if the values are different self:FailTestCase("DB doesn't include expected value") end end diff --git a/test_scripts/Defects/4_5/1893_ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua b/test_scripts/Defects/4_5/1893_ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua index 19c94dab5c..aa9bb78472 100644 --- a/test_scripts/Defects/4_5/1893_ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua +++ b/test_scripts/Defects/4_5/1893_ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua @@ -9,72 +9,137 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local mobile_session = require('mobile_session') --[[ General Precondition before ATF start ]] +-- switch ATF to use 3rd version (with HeartBeat) of SDL protocol config.defaultProtocolVersion = 3 +-- define default application is Media one config.application1.registerAppInterfaceParams.isMediaApplication = true -- [[Local variables]] +-- define parameters for 1st application local default_app_params = config.application1.registerAppInterfaceParams +-- define parameters for 2nd application local default_app_params2 = config.application2.registerAppInterfaceParams --[[ Local Functions ]] + +--[[ @updateINIFile: update parameters in SDL .ini file +--! @parameters: none +--! @return: none +--]] local function updateINIFile() + -- backup .ini file common.backupINIFile() + -- change the value of 'HeartBeatTimeout' parameter commonFunctions:write_parameter_to_smart_device_link_ini("HeartBeatTimeout", 5000) end +--[[ @Start_Session_And_Register_App: create mobile session, start RPC service and register 1st mobile application +--! @parameters: none +--! self - test object which will be provided automatically by runner module +--! @return: none +--]] local function Start_Session_And_Register_App(self) + -- create 1st mobile session self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) + -- define parameters for heartbeat: 1st application shouldn't sent heartbeat neither as answer on heartbeat messages + -- from SDL self.mobileSession.sendHeartbeatToSDL = false self.mobileSession.answerHeartbeatFromSDL = false self.mobileSession.ignoreSDLHeartBeatACK = false + -- start RPC service self.mobileSession:StartRPC() :Do(function() + -- send 'RegisterAppInterface' RPC with defined parameters for mobile application + -- and return correlation identifier local correlation_id = self.mobileSession:SendRPC("RegisterAppInterface", default_app_params) + -- register expectation of 'BC.OnAppRegistered' notification on HMI connection EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = default_app_params.appName } }) :Do(function(_,data) + -- save HMI application Id into 'hmi_app_id' variable: it will be required in next steps default_app_params.hmi_app_id = data.params.application.appID end) + -- register expectation of response for 'RegisterAppInterface' request with appropriate correlation id + -- on Mobile connection self.mobileSession:ExpectResponse(correlation_id, { success = true, resultCode = "SUCCESS" }) + -- register expectation of 'OnHMIStatus' notification on Mobile connection + -- it's expected that value of 'hmiLevel' parameter will be 'NONE' self.mobileSession:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + -- register expectation of 'OnPermissionsChange' notification on Mobile connection self.mobileSession:ExpectNotification("OnPermissionsChange", {}) end) end +--[[ @Register_Second_App_With_HeartBeat: create mobile session, start RPC service and register 2nd mobile application +--! @parameters: none +--! self - test object which will be provided automatically by runner module +--! @return: none +--]] local function Register_Second_App_With_HeartBeat(self) + -- create 2nd mobile session self.mobileSession1 = mobile_session.MobileSession(self, self.mobileConnection) + -- define parameters for heartbeat: 2nd application shouldn't sent heartbeat, but should answer on heartbeat messages + -- from SDL self.mobileSession1.sendHeartbeatToSDL = false self.mobileSession1.answerHeartbeatFromSDL = true self.mobileSession1.ignoreSDLHeartBeatACK = false self.mobileSession1:StartRPC() :Do(function() + -- send 'RegisterAppInterface' RPC with defined parameters for mobile application + -- and return correlation identifier local correlation_id = self.mobileSession1:SendRPC("RegisterAppInterface", default_app_params2) + -- register expectation of 'BC.OnAppRegistered' notification on HMI connection EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = default_app_params2.appName } }) + -- register expectation of response for 'RegisterAppInterface' request with appropriate correlation id + -- on Mobile connection self.mobileSession1:ExpectResponse(correlation_id, { success = true, resultCode = "SUCCESS" }) + -- register expectation of 'OnHMIStatus' notification on Mobile connection + -- it's expected that value of 'hmiLevel' parameter will be 'NONE' self.mobileSession1:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + -- register expectation of 'OnPermissionsChange' notification on Mobile connection self.mobileSession1:ExpectNotification("OnPermissionsChange", {}) end) end +--[[ @Wait_15_seconds_And_Verify_OnAppUnregistered: wait 15 sec and check if 1st application is unregistered +--! due to heartbeat timeout +--! @parameters: none +--! self - test object which will be provided automatically by runner module +--! @return: none +--]] local function Wait_15_seconds_And_Verify_OnAppUnregistered(self) + -- register expectation of 'BC.OnAppUnregistered' notification on HMI connection + -- it's expected that 1st application is unregistered with 'unexpectedDisconnect' = true EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = default_app_params.hmi_app_id, unexpectedDisconnect = true }) + -- increase default timeout for wait from 10s to 15s + -- this is required in order to heartbeat timeout of SDL is run out + -- and SDL is able to close session for 1st application :Timeout(15000) :Do(function() + -- stop heartbeat (if it was started previously) self.mobileSession:StopHeartbeat() end) end +--[[ @Verify_That_Second_App_Still_Registered: verify that 2nd application is still registered +--! @parameters: none +--! self - test object which will be provided automatically by runner module +--! @return: none +--]] local function Verify_That_Second_App_Still_Registered(self) + -- send 'RegisterAppInterface' RCP with defined parameters local cor_id = self.mobileSession1:SendRPC("RegisterAppInterface", default_app_params2) + -- register expectation that response will be unsuccessful with appropriate resultCode + -- meaning session for 2nd application is still alive self.mobileSession1:ExpectResponse(cor_id, { success = false, resultCode = "APPLICATION_REGISTERED_ALREADY"}) end diff --git a/test_scripts/Defects/4_5/commonDefects.lua b/test_scripts/Defects/4_5/commonDefects.lua index 0eccc95ac5..0177b555ca 100644 --- a/test_scripts/Defects/4_5/commonDefects.lua +++ b/test_scripts/Defects/4_5/commonDefects.lua @@ -2,8 +2,11 @@ -- RC common module --------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] +-- define MAC address mobile device config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +-- define 2nd version of SDL protocol by default config.defaultProtocolVersion = 2 +-- switch off schema validation for output messages against APIs config.ValidateSchema = false --[[ Required Shared libraries ]] @@ -16,22 +19,27 @@ local mobile_session = require("mobile_session") local events = require("events") local json = require("modules/json") - --[[ Local Variables ]] + +-- table with data for Policy Table Update local ptu_table = {} +-- table with HMI application identifiers local hmiAppIds = {} +-- table for module local commonDefect = {} --[[ Module Constants ]] + +-- default timeout commonDefect.timeout = 2000 +-- minimal timeout commonDefect.minTimeout = 500 -local function allowSdl(self) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { - allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } - }) -end - +--[[ @getPTUFromPTS: create policy table update table (PTU) +--! @parameters: +--! tbl - table with policy table snapshot (PTS) +--! @return: table with PTU +--]] local function getPTUFromPTS(tbl) tbl.policy_table.consumer_friendly_messages.messages = nil tbl.policy_table.device_data = nil @@ -42,6 +50,10 @@ local function getPTUFromPTS(tbl) tbl.policy_table.module_config.preloaded_date = nil end +--[[ @DefaultStruct: provide default values for application required in PTU +--! @parameters: none +--! @return: table with data +--]] function commonDefect.DefaultStruct() return { keep_context = false, @@ -52,10 +64,20 @@ function commonDefect.DefaultStruct() } end +--[[ @updatePTU: update PTU with application data +--! @parameters: +--! tbl - table with data for policy table update +--! @return: none +--]] local function updatePTU(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonDefect.DefaultStruct() end +--[[ @jsonFileToTable: convert .json file to table +--! @parameters: +--! file_name - file name +--! @return: table +--]] local function jsonFileToTable(file_name) local f = io.open(file_name, "r") local content = f:read("*all") @@ -63,18 +85,24 @@ local function jsonFileToTable(file_name) return json.decode(content) end +--[[ @tableToJsonFile: convert table to .json file +--! @parameters: +--! tbl - table +--! file_name - file name +--! @return: none +--]] local function tableToJsonFile(tbl, file_name) local f = io.open(file_name, "w") f:write(json.encode(tbl)) f:close() end -local function checkIfPTSIsSentAsBinary(bin_data) - if not (bin_data ~= nil and string.len(bin_data) > 0) then - commonFunctions:userPrint(31, "PTS was not sent to Mobile in payload of OnSystemRequest") - end -end - +--[[ @ptu: perform policy table update +--! @parameters: +--! self - test object +--! ptu_update_func - additional function for update +--! @return: none +--]] local function ptu(self, ptu_update_func) local function getAppsCount() local count = 0 @@ -111,7 +139,6 @@ local function ptu(self, ptu_update_func) :Do(function(_, d2) print("App ".. id .. " was used for PTU") RAISE_EVENT(event, event, "PTU event") - checkIfPTSIsSentAsBinary(d2.binaryData) local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) EXPECT_HMICALL("BasicCommunication.SystemRequest") @@ -128,18 +155,31 @@ local function ptu(self, ptu_update_func) os.remove(ptu_file_name) end +--[[ @allow_sdl: sequence that allows SDL functionality +--! @parameters: +--! self - test object +--! @return: none +--]] local function allow_sdl(self) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) end +--[[ @preconditions: precondition steps +--! @parameters: none +--! @return: none +--]] function commonDefect.preconditions() commonFunctions:SDLForceStop() commonSteps:DeletePolicyTable() commonSteps:DeleteLogsFiles() end - +--[[ @start: starting sequence: starting of SDL, initialization of HMI, connect mobile +--! @parameters: +--! self - test object +--! @return: none +--]] function commonDefect.start(self) self:runSDL() commonFunctions:waitForSDLStart(self) @@ -160,7 +200,11 @@ function commonDefect.start(self) end) end - +--[[ @startWithoutMobile: starting sequence: starting of SDL, initialization of HMI +--! @parameters: +--! self - test object +--! @return: none +--]] function commonDefect.startWithoutMobile(pHMIParams, self) self, pHMIParams = commonDefect.getSelfAndParams(pHMIParams, self) self:runSDL() @@ -177,14 +221,27 @@ function commonDefect.startWithoutMobile(pHMIParams, self) end) end +--[[ @postconditions: postcondition steps +--! @parameters: none +--! @return: none +--]] function commonDefect.postconditions() StopSDL() end +--[[ @printSDLConfig: print information about SDL build options +--! @parameters: none +--! @return: none +--]] function commonDefect.printSDLConfig() commonFunctions:printTable(sdl.buildOptions) end +--[[ @ignitionOff: IGNITION_OFF sequence +--! @parameters: +--! self - test object +--! @return: none +--]] function commonDefect.ignitionOff(self) self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete") @@ -199,23 +256,47 @@ function commonDefect.ignitionOff(self) end) end +--[[ @backupINIFile: backup SDL .ini file +--! @parameters: none +--! @return: none +--]] function commonDefect.backupINIFile() commonPreconditions:BackupFile("smartDeviceLink.ini") end +--[[ @restoreINIFile: restore SDL .ini file to an initial state +--! @parameters: none +--! @return: none +--]] function commonDefect.restoreINIFile() commonPreconditions:RestoreFile("smartDeviceLink.ini") end +--[[ @rai_ptu: register mobile application and perform PTU sequence for 1st application +--! @parameters: +--! ptu_update_func - additional function for update +--! self - test object +--! @return: none +--]] function commonDefect.rai_ptu(ptu_update_func, self) self, ptu_update_func = commonDefect.getSelfAndParams(ptu_update_func, self) commonDefect.rai_ptu_n(1, ptu_update_func, self) end +--[[ @rai_ptu_n: register mobile application and perform PTU sequence for N application +--! @parameters: +--! id - application number (1, 2, etc.) +--! ptu_update_func - additional function for update +--! self - test object +--! @return: none +--]] function commonDefect.rai_ptu_n(id, ptu_update_func, self) self, id, ptu_update_func = commonDefect.getSelfAndParams(id, ptu_update_func, self) if not id then id = 1 end self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) self["mobileSession" .. id]:StartService(7) :Do(function() local corId = self["mobileSession" .. id]:SendRPC @@ -224,9 +305,6 @@ function commonDefect.rai_ptu_n(id, ptu_update_func, self) { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) :Do(function(_, d1) hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) - :Times(3) EXPECT_HMICALL("BasicCommunication.PolicyUpdate") :Do(function(_, d2) self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) @@ -238,12 +316,20 @@ function commonDefect.rai_ptu_n(id, ptu_update_func, self) :Do(function() self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + :Times(AtLeast(1)) self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") end) end) end +--[[ @rai_ptu_n_without_OnPermissionsChange: register mobile application and perform PTU sequence for N application +--! 'OnPermissionsChange' notification is excluded from expectations +--! @parameters: +--! id - application number (1, 2, etc.) +--! ptu_update_func - additional function for update +--! self - test object +--! @return: none +--]] function commonDefect.rai_ptu_n_without_OnPermissionsChange(id, ptu_update_func, self) self, id, ptu_update_func = commonDefect.getSelfAndParams(id, ptu_update_func, self) if not id then id = 1 end @@ -270,11 +356,17 @@ function commonDefect.rai_ptu_n_without_OnPermissionsChange(id, ptu_update_func, :Do(function() self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + :Times(AtLeast(1)) end) end) end +--[[ @UnsuccessPTU: perform PTU sequence with failed result +--! @parameters: +--! ptu_update_func - additional function for update +--! self - test object +--! @return: none +--]] function commonDefect.UnsuccessPTU(ptu_update_func, self) EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UPDATE_NEEDED" }) @@ -312,10 +404,9 @@ function commonDefect.UnsuccessPTU(ptu_update_func, self) for id = 1, getAppsCount() do local mobileSession = commonDefect.getMobileSession(self, id) mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) - :Do(function(_, d2) + :Do(function() print("App ".. id .. " was used for PTU") RAISE_EVENT(event, event, "PTU event") - checkIfPTSIsSentAsBinary(d2.binaryData) local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) EXPECT_HMICALL("BasicCommunication.SystemRequest") @@ -332,6 +423,12 @@ function commonDefect.UnsuccessPTU(ptu_update_func, self) os.remove(ptu_file_name) end +--[[ @rai_n: register N mobile application without PTU sequence +--! @parameters: +--! id - application number (1, 2, etc.) +--! self - test object +--! @return: none +--]] function commonDefect.rai_n(id, self) self, id = commonDefect.getSelfAndParams(id, self) if not id then id = 1 end @@ -349,17 +446,28 @@ function commonDefect.rai_n(id, self) :Do(function() self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + :Times(AtLeast(1)) self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") end) end) end +--[[ @delayedExp: delay test step for defined timeout +--! @parameters: +--! timeout - time of delay in milliseconds +--! @return: none +--]] function commonDefect.delayedExp(timeout) if not timeout then timeout = commonDefect.timeout end commonTestCases:DelayedExp(timeout) end +--[[ @unregisterApp: unregister application +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! self - test object +--! @return: none +--]] function commonDefect.unregisterApp(pAppId, self) local mobSession = commonDefect.getMobileSession(self, pAppId) local hmiAppId = commonDefect.getHMIAppId(pAppId) @@ -368,6 +476,12 @@ function commonDefect.unregisterApp(pAppId, self) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) end +--[[ @activate_app: activate application +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! self - test object +--! @return: none +--]] function commonDefect.activate_app(pAppId, self) self, pAppId = commonDefect.getSelfAndParams(pAppId, self) if not pAppId then pAppId = 1 end @@ -380,6 +494,12 @@ function commonDefect.activate_app(pAppId, self) commonTestCases:DelayedExp(commonDefect.minTimeout) end +--[[ @putFile: perform PutFile sequence +--! @parameters: +--! pFileName - name of the file +--! self - test object +--! @return: none +--]] function commonDefect.putFile(pFileName, self) self, pFileName = commonDefect.getSelfAndParams(pFileName, self) local cid = self.mobileSession1:SendRPC( @@ -390,10 +510,11 @@ function commonDefect.putFile(pFileName, self) self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) end -function commonDefect.postconditions() - StopSDL() -end - +--[[ @getSelfAndParams: shifting parameters in order to move self at 1st position +--! @parameters: +--! ... - various parameters and self +--! @return: test object and other parameters +--]] function commonDefect.getSelfAndParams(...) local out = { } local selfIdx = nil @@ -414,11 +535,22 @@ function commonDefect.getSelfAndParams(...) return table.unpack(out, 1, table.maxn(out)) end +--[[ @getHMIAppId: get HMI application identifier +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: application identifier +--]] function commonDefect.getHMIAppId(pAppId) if not pAppId then pAppId = 1 end return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] end +--[[ @getMobileSession: get mobile session +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! self - test object +--! @return: mobile session +--]] function commonDefect.getMobileSession(self, pAppId) if not pAppId then pAppId = 1 end return self["mobileSession" .. pAppId] From b8a6efd283a7d527e4f7cd76b93ce95d02838c5a Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 19 Dec 2017 14:32:23 +0200 Subject: [PATCH 217/681] Added comments in scripts --- .../Defects/4_5/1225_FACTORY_DEFAULTS.lua | 74 +++++++++++++--- .../Defects/4_5/1376_PTU_all_flows.lua | 85 ++++++++++++++++++- .../4_5/1395_Resumption_data_IGN_OFF.lua | 52 ++++++++++++ .../4_5/1772_update_default_section.lua | 17 ++++ 4 files changed, 217 insertions(+), 11 deletions(-) diff --git a/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua b/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua index e193512567..c56a02b83c 100644 --- a/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua +++ b/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua @@ -18,6 +18,7 @@ -- Scenario is passed. --------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] +-- config.ExitOnCrash = false means that in case of SDL stop through script execution ATF will not stop execution config.ExitOnCrash = false --[[ Required Shared libraries ]] @@ -30,11 +31,14 @@ local events = require('events') local json = require("modules/json") --[[ Local Variables ]] +-- Path to policy table snapshot local pathToPTS = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" - .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") +.. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") +-- Path to local policy table local pathToLPT = config.pathToSDL .. "/storage/policy.sqlite" --[[ Local Functions ]] +-- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP local function start(self) self:runSDL() commonFunctions:waitForSDLStart(self) @@ -54,12 +58,16 @@ local function start(self) end) end +-- Allow device from HMI local function allowSDL(self) + -- sending notification OnAllowSDLFunctionality from HMI to allow connected device self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { - allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } - }) + allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } + }) end +-- Delay without expectation +-- @tparam number pTime time to wait local function delayedExp(pTime, self) local event = events.Event() event.matches = function(e1, e2) return e1 == e2 end @@ -71,6 +79,7 @@ local function delayedExp(pTime, self) RUN_AFTER(toRun, pTime) end +-- decode snapshot from json to table local function ptsToTable(pts_f) local f = io.open(pts_f, "r") local content = f:read("*all") @@ -78,19 +87,29 @@ local function ptsToTable(pts_f) return json.decode(content) end +-- Prepare policy table for policy table update +-- @tparam table tbl table to update local function ptUpdateFunc(pTbl) local appId = config.application1.registerAppInterfaceParams.appID + -- add to table in app_policies section record for appId with group "Location-1" table.insert(pTbl.policy_table.app_policies[appId].groups, "Location-1") end +-- Remove snapshot and trigger PTU from HMI local function removeSnapshotAndTriggerPTUFromHMI(self) + -- remove Snapshot os.execute("rm -f " .. pathToPTS) + -- expect PolicyUpdate request on HMI side EXPECT_HMICALL("BasicCommunication.PolicyUpdate", { file = pathToPTS }) + -- Sending OnPolicyUpdate notification form HMI self.hmiConnection:SendNotification("SDL.OnPolicyUpdate", { }) end +-- Perform user consent of "Location" group local function makeConsent(self) + -- Send GetListOfPermissions request from HMI side local request_id = self.hmiConnection:SendRequest("SDL.GetListOfPermissions") + -- expect GetListOfPermissions response on HMI side with "Location" group EXPECT_HMIRESPONSE(request_id,{ result = { code = 0, @@ -100,6 +119,7 @@ local function makeConsent(self) } }) :Do(function(_,data) + -- after receiving GetListOfPermissions response on HMI side get id of "Location" group local groupId for i = 1, #data.result.allowedFunctions do if(data.result.allowedFunctions[i].name == "Location") then @@ -107,29 +127,35 @@ local function makeConsent(self) end end if groupId then + -- Sending OnAppPermissionConsent notification from HMI to SDL wit info about allowed group self.hmiConnection:SendNotification("SDL.OnAppPermissionConsent", { - appID = commonDefects.getHMIAppId(), - source = "GUI", - consentedFunctions = {{name = "Location", id = groupId, allowed = true}} - }) + appID = commonDefects.getHMIAppId(), + source = "GUI", + consentedFunctions = {{name = "Location", id = groupId, allowed = true}} + }) else + -- Fail test case in case GetListOfPermissions response from SDL does not contain id of group self:FailTestCase("GroupId for Location was not found") end end) + -- delay in 1 sec delayedExp(1000, self) end local function Check_user_consent_records_in_LPT(self) local is_test_fail = false + -- Check existence of local policy table if (commonSteps:file_exists(pathToLPT) == false) then self:FailTestCase(config.pathToSDL .. pathToLPT .. " is not created") else + -- check presence record of device_id in table consent_group, must be created after consent "Location" group local queryCG = "select device_id from consent_group" local r_actual_CG = commonFunctions:get_data_policy_sql(pathToLPT, queryCG) if #r_actual_CG ~= 1 then commonFunctions:printError("Error: consent_group does not contain 1 required records in LPT") is_test_fail = true end + -- check presence record of device_id in table device_consent_group, must be created after device consent local queryDCG = "select device_id from device_consent_group" local r_actualDCG = commonFunctions:get_data_policy_sql(pathToLPT, queryDCG) if #r_actualDCG ~= 1 then @@ -144,9 +170,11 @@ end local function Check_user_consent_records_in_Snapshot(self) local is_test_fail = false + -- Check existence of policy table snapshot if (commonSteps:file_exists(pathToPTS) == false) then self:FailTestCase(pathToPTS .. " is not created") else + -- Check presence of consented group for registered appID local pts = ptsToTable(pathToPTS) local ucr = pts.policy_table.device_data[config.deviceMAC].user_consent_records if not (ucr[config.application1.registerAppInterfaceParams.appID]) then @@ -160,26 +188,34 @@ local function Check_user_consent_records_in_Snapshot(self) end local function performFACTORY_DEFAULTS(self) + -- Send notification OnExitAllApplications(FACTORY_DEFAULTS) from HMI self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "FACTORY_DEFAULTS" }) + -- Expect notification OnAppInterfaceUnregistered(FACTORY_DEFAULTS) on mobile app self.mobileSession1:ExpectNotification("OnAppInterfaceUnregistered", { reason = "FACTORY_DEFAULTS" }) :Do(function() sdl:DeleteFile() end) end local function Wait_SDL_stop(self) + -- Delay for SDL stop delayedExp(5000, self) end local function Check_no_user_consent_records_in_LPT(self) local is_test_fail = false + -- Check existence of local policy table if (commonSteps:file_exists(pathToLPT) == false) then self:FailTestCase(config.pathToSDL .. pathToLPT .. " is not created") else + -- check absence of record device_id in table consent_group, + -- must be absent because of device consent is not performed local queryCG = "select count(*) from consent_group" local r_actual_CG = commonFunctions:get_data_policy_sql(pathToLPT, queryCG) if r_actual_CG[1] ~= "0" then commonFunctions:printError("Error: consent_group contains redundant records in LPT") is_test_fail = true end + -- check absence of record device_id in table device_consent_group, + -- must be absent because of group consent is not performed local queryDCG = "select count(*) from device_consent_group" local r_actualDCG = commonFunctions:get_data_policy_sql(pathToLPT, queryDCG) if r_actualDCG[1] ~= "0" then @@ -194,10 +230,12 @@ end local function Check_no_user_consent_records_in_Snapshot(self) local is_test_fail = false + -- Check existence of policy table snapshot if (commonSteps:file_exists(pathToPTS) == false) then self:FailTestCase(pathToPTS .. " is not created") else - local pts = ptsToTable(pathToPTS) + -- Check absence of consented group for registered appID + local pts = ptsToTable(pathToPTS) local ucr = pts.policy_table.device_data[config.deviceMAC].user_consent_records if (ucr[config.application1.registerAppInterfaceParams.appID]) then commonFunctions:printError("Error: user_consent_records.consent_groups.Location was not reset in Snapshot") @@ -211,23 +249,39 @@ end --[[ Scenario ]] runner.Title("Preconditions") +-- Stop SDL if process is still running, delete local policy table and log files runner.Step("Clean environment", commonDefects.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", start) +-- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP +runner.Step("Start SDL, HMI, connect Mobile", start) +-- Allow connected device on HMI runner.Step("Allow SDL for device", allowSDL) +-- create mobile session, register application, perform PTU wit PT from ptUpdateFunc +-- with "Location" group for registered application runner.Step("RAI, PTU", commonDefects.rai_ptu, { ptUpdateFunc}) +-- Consent of "Location" group runner.Step("Make consent for Location group", makeConsent) runner.Title("Test") +-- Remove snapshot to make sure that SDL creates new one during PTU, trigger PTU to initiation of snapshot creation runner.Step("Remove Snapshot and Trigger PTU", removeSnapshotAndTriggerPTUFromHMI) +-- Check records related to consent group and device in LPT runner.Step("Check_presence_of_user_consent_records_in_LPT", Check_user_consent_records_in_LPT) +-- Check records related to consent group and device in snapshot runner.Step("Check_presence_of_user_consent_records_in_Snapshot", Check_user_consent_records_in_Snapshot) +-- Perform FACTORY_DEFAULTS runner.Step("FACTORY_DEFAULTS", performFACTORY_DEFAULTS) runner.Step("Wait_SDL_stop", Wait_SDL_stop) -runner.Step("Start SDL, HMI, connect Mobile, start Session", start) +-- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP +runner.Step("Start SDL, HMI, connect Mobile", start) +-- Check absence of records related to consent group and device in LPT after FACTORY_DEFAULTS runner.Step("Check_absence_of_user_consent_records_in_LPT", Check_no_user_consent_records_in_LPT) +-- Make device consent runner.Step("Allow SDL for device", allowSDL) +-- Create session, register application runner.Step("RAI", commonDefects.rai_n) +-- Remove snapshot to make sure that SDL creates new one during PTU, trigger PTU to initiation of snapshot creation runner.Step("Remove Snapshot and Trigger PTU", removeSnapshotAndTriggerPTUFromHMI) +-- Check absence of records related to consent group in Snapshot after FACTORY_DEFAULTS runner.Step("Check_absence_of_user_consent_records_in_Snapshot", Check_no_user_consent_records_in_Snapshot) runner.Title("Postconditions") diff --git a/test_scripts/Defects/4_5/1376_PTU_all_flows.lua b/test_scripts/Defects/4_5/1376_PTU_all_flows.lua index a6cf65136e..c4fdf62ea6 100644 --- a/test_scripts/Defects/4_5/1376_PTU_all_flows.lua +++ b/test_scripts/Defects/4_5/1376_PTU_all_flows.lua @@ -24,16 +24,22 @@ local flowType = { --[[ Local Functions ]] local function preconditions() + -- Stop SDL if process is still running commonFunctions:SDLForceStop() + -- Remove Local Policy Update commonSteps:DeletePolicyTable() + -- Delete log files commonSteps:DeleteLogsFiles() end +-- Allow device from HMI local function allowSDL(self) + -- sending notification OnAllowSDLFunctionality from HMI to allow connected device self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) end +-- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP local function start(self) self:runSDL() commonFunctions:waitForSDLStart(self) @@ -54,6 +60,7 @@ local function start(self) end) end +-- Loging messages in terminal local function log(...) local str = "[" .. atf_logger.formated_time(true) .. "]" for i, p in pairs({...}) do @@ -64,6 +71,8 @@ local function log(...) commonFunctions:userPrint(35, str) end +-- Convert snapshot form json to table +-- @tparam file pts_f snapshot file local function ptsToTable(pts_f) local f = io.open(pts_f, "r") local content = f:read("*all") @@ -71,33 +80,50 @@ local function ptsToTable(pts_f) return json.decode(content) end +-- Creation policy table from snapshot +-- @tparam table ptu snapshot table local function getPTUFromPTS(ptu) + -- remove messages in consumer_friendly_messages ptu.policy_table.consumer_friendly_messages.messages = nil + -- remove device_data ptu.policy_table.device_data = nil + -- remove module_meta ptu.policy_table.module_meta = nil + -- remove usage_and_error_counts ptu.policy_table.usage_and_error_counts = nil + -- write empty struct in "DataConsent-2".rpcs ptu.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + -- remove preloaded_pt ptu.policy_table.module_config.preloaded_pt = nil + -- remove preloaded_date ptu.policy_table.module_config.preloaded_date = nil - -- + -- Create structure in app_policies related to registered application ptu.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = { keep_context = false, steal_focus = false, priority = "NONE", default_hmi = "NONE" } + -- Added permissions for registered app from "Base-4", "Base-6" groups ptu.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID]["groups"] = { "Base-4", "Base-6" } end +-- Save created PT in file +-- @tparam table ptu PT table +-- @tparam string ptu_file_name file name local function storePTUInFile(ptu, ptu_file_name) local f = io.open(ptu_file_name, "w") f:write(json.encode(ptu)) f:close() end +-- Check that PT is sent as binary data in OnSystem request +-- @tparam table bin_data binary data +-- @tparam number pFlow number of floe type from flowType local function checkIfPTSIsSentAsBinary(bin_data, pFlow) + -- decode binary data to table depending on policy flow local pt = nil if flowType[pFlow] == flowType.PROPRIETARY then pt = json.decode(bin_data).HTTPRequest.body @@ -105,63 +131,93 @@ local function checkIfPTSIsSentAsBinary(bin_data, pFlow) pt = bin_data end pt = json.decode(pt) + -- Check presence of policy_table in decoded PT if not pt.policy_table then commonFunctions:userPrint(31, "PTS was not sent to Mobile in payload of OnSystemRequest") end end +-- Policy table update with Proprietary flow +-- @tparam table ptu_table PT table +-- @tparam string pFlow policy flow local function ptuProprietary(ptu_table, self, pFlow) + -- Get path to snapshot local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + -- create ptu_file_name as tmp file local ptu_file_name = os.tmpname() + -- Send GetURLS request from HMI to SDL with service 7 local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) log("HMI->SDL: RQ: SDL.GetURLS") + -- Expect response GetURLS on HMI side EXPECT_HMIRESPONSE(requestId) :Do(function() log("SDL->HMI: RS: SDL.GetURLS") + -- After receiving GetURLS response send OnSystemRequest notification from HMI self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = pts_file_name }) log("HMI->SDL: N: BC.OnSystemRequest") + -- Prepare PT for update getPTUFromPTS(ptu_table) + -- Save created PT for update in tmp file storePTUInFile(ptu_table, ptu_file_name) + -- Expect receiving of OnSystemRequest notification with snapshot on mobile side self.mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) :Do(function(_, d) + -- After receiving OnSystemRequest notification on mobile side check that + -- data in notification was sent as binary data checkIfPTSIsSentAsBinary(d.binaryData, pFlow) log("SDL->MOB: N: OnSystemRequest") + -- Send SystemRequest request with PT for update from mobile side local corIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", { requestType = "PROPRIETARY" }, ptu_file_name) log("MOB->SDL: RQ: SystemRequest") + -- Expect SystemRequest request on HMI side EXPECT_HMICALL("BasicCommunication.SystemRequest") :Do(function(_, dd) log("SDL->HMI: RQ: BC.SystemRequest") + -- Send SystemRequest response form HMI with resultCode SUCCESS self.hmiConnection:SendResponse(dd.id, dd.method, "SUCCESS", { }) log("HMI->SDL: RS: SUCCESS: BC.SystemRequest") + -- Send OnReceivedPolicyUpdate notification from HMI self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = dd.params.fileName }) log("HMI->SDL: N: SDL.OnReceivedPolicyUpdate") end) + -- Expect SystemRequest response with resultCode SUCCESS on mobile side self.mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS"}) + -- remove tmp PT file after receiving SystemRequest response on mobile side :Do(function() os.remove(ptu_file_name) end) log("SDL->MOB: RS: SUCCESS: SystemRequest") end) end) end +-- Policy table update with HTTP flow +-- @tparam table ptu_table PT table local function ptuHttp(ptu_table, self) + -- name for PT for SystemRequest local policy_file_name = "PolicyTableUpdate" + -- tmp file name for PT file local ptu_file_name = os.tmpname() + -- Prepare PT for update getPTUFromPTS(ptu_table) + -- Save created PT for update in tmp file storePTUInFile(ptu_table, ptu_file_name) + -- Send SystemRequest form mobile app with created PT local corId = self.mobileSession:SendRPC("SystemRequest", { requestType = "HTTP", fileName = policy_file_name }, ptu_file_name) log("MOB->SDL: RQ: SystemRequest") + -- Expect successful SystemRequest response on mobile side self.mobileSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() log("SDL->MOB: RS: SUCCESS: SystemRequest") end) + -- remove tmp PT file os.remove(ptu_file_name) end +-- Expect 3 OnStatusUpdate notification on HMI side during PTU local function expOnStatusUpdate() EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, {status = "UP_TO_DATE" }) @@ -171,46 +227,61 @@ local function expOnStatusUpdate() :Times(3) end +-- Fail test cases by incorrect PTU +-- @tparam string pRequestName request name of RPC that is failed expectations local function failInCaseIncorrectPTU(pRequestName, self) self:FailTestCase(pRequestName .. " was sent more than once (PTU update was incorrect)") end +-- Registration of application with policy table update local function raiPTU(self) expOnStatusUpdate() -- temp solution due to issue in SDL: -- SDL.OnStatusUpdate(UPDATE_NEEDED) notification is sent before BC.OnAppRegistered (EXTERNAL_PROPRIETARY flow) + -- creation mobile session self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) + -- open RPC service in created session self.mobileSession:StartService(7) :Do(function() + -- Send RegisterAppInterface request from mobile application local corId = self.mobileSession:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) log("MOB->SDL: RQ: RegisterAppInterface") + -- Expect OnAppRegistered on HMI side from SDL EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config.application1.registerAppInterfaceParams.appName } }) :Do(function() log("SDL->HMI: N: BC.OnAppRegistered") if sdl.buildOptions.extendedPolicy == "PROPRIETARY" or sdl.buildOptions.extendedPolicy == "EXTERNAL_PROPRIETARY" then + -- Expect PolicyUpdate request on HMI side EXPECT_HMICALL("BasicCommunication.PolicyUpdate") :Do(function(e, d) if e.occurences == 1 then -- SDL send BC.PolicyUpdate more than once if PTU update was incorrect log("SDL->HMI: RQ: BC.PolicyUpdate") + -- Create PT form snapshot local ptu_table = ptsToTable(d.params.file) + -- Sending PolicyUpdate request from HMI with resultCode SUCCESS self.hmiConnection:SendResponse(d.id, d.method, "SUCCESS", { }) log("HMI->SDL: RS: BC.PolicyUpdate") + -- PTU proprietary flow ptuProprietary(ptu_table, self, sdl.buildOptions.extendedPolicy) else failInCaseIncorrectPTU("BC.PolicyUpdate", self) end end) elseif sdl.buildOptions.extendedPolicy == "HTTP" then + -- Expect OnSystemRequest notification on mobile side self.mobileSession:ExpectNotification("OnSystemRequest") :Do(function(e, d) log("SDL->MOB: N: OnSystemRequest", e.occurences, d.payload.requestType) if d.payload.requestType == "HTTP" then if e.occurences <= 2 then -- SDL send OnSystemRequest more than once if PTU update was incorrect + -- Check data in receives OnSystemRequest notification on mobile side checkIfPTSIsSentAsBinary(d.binaryData, sdl.buildOptions.extendedPolicy) if d.binaryData then + -- Create PT form binary data local ptu_table = json.decode(d.binaryData) + -- PTU HTTP flow ptuHttp(ptu_table, self) end else @@ -221,14 +292,17 @@ local function raiPTU(self) :Times(2) end end) + -- Expect RegisterAppInterface response on mobile side with resultCode SUCCESS self.mobileSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() log("SDL->MOB: RS: RegisterAppInterface") + -- Expect OnHMIStatus with hmiLevel NONE on mobile side form SDL self.mobileSession:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) :Do(function(_, d) log("SDL->MOB: N: OnHMIStatus", d.payload.hmiLevel) end) + -- Expect OnPermissionsChange on mobile side form SDL self.mobileSession:ExpectNotification("OnPermissionsChange") :Do(function() log("SDL->MOB: N: OnPermissionsChange") @@ -238,15 +312,19 @@ local function raiPTU(self) end) end +-- Check update status local function checkPTUStatus(self) + -- Send GetStatusUpdate form HMI to SDL local reqId = self.hmiConnection:SendRequest("SDL.GetStatusUpdate") log("HMI->SDL: RQ: SDL.GetStatusUpdate") + -- Expect GetStatusUpdate response from SDL to HMI with update status EXPECT_HMIRESPONSE(reqId, { result = { status = "UP_TO_DATE" }}) :Do(function(_, d) log("HMI->SDL: RS: SDL.GetStatusUpdate", tostring(d.result.status)) end) end +-- Pring in terminal build options(RC status and policy slow) local function printSDLConfig() commonFunctions:printTable(sdl.buildOptions) end @@ -257,12 +335,17 @@ end --[[ Scenario ]] runner.Title("Preconditions") +-- Stop SDL if process is still running, delete local policy table and log files runner.Step("Clean environment", preconditions) +-- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP runner.Step("Start SDL, HMI, connect Mobile", start) +-- Pring in terminal build options(RC status and policy slow) runner.Step("SDL Configuration", printSDLConfig) runner.Title("Test") +-- create mobile session, register application, perform PTU wit PT runner.Step("RAI, PTU", raiPTU) +-- Check that PTU is performed successful runner.Step("Check Status", checkPTUStatus) runner.Title("Postconditions") diff --git a/test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua b/test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua index 1ab8314771..7801eb1455 100644 --- a/test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua +++ b/test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua @@ -21,53 +21,83 @@ local SDL = require('SDL') --[[ Local Variables ]] --[[ Local Functions ]] +-- Successful processing AddCommand request from mobile app local function AddCommand(self) + -- Send AddCommand request from HMI self.mobileSession1:SendRPC("AddCommand", { cmdID = 1, vrCommands = {"VRCommand1"}}) + -- Expect VR.AddCommand request on HMI from SDL EXPECT_HMICALL("VR.AddCommand"):Do(function(_, data) + -- Sending VR.AddCommand response from HMI to SDL with resultCode SUCCESS self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) + -- Expect successful AddCommand response on mobile side from SDL self.mobileSession1:ExpectResponse("AddCommand", { success = true, resultCode = "SUCCESS" }) + -- Expect OnHashChange notification on mobile side from SDL self.mobileSession1:ExpectNotification("OnHashChange") end +-- Successful processing AddCommand request from mobile app after OnExitAllApplications(SUSPEND) notification from HMI local function AddCommandAfterSUSPEND(self) + -- Send OnExitAllApplications(SUSPEND) from HMI to SDL self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) + -- Send AddCommand request from mobile side to SDL self.mobileSession1:SendRPC("AddCommand", { cmdID = 2, vrCommands = {"VRCommand2"}}) + -- Expect "VR.AddCommand" request on HMI side from SDL EXPECT_HMICALL("VR.AddCommand"):Do(function(_, data) + -- Send VR.AddCommand response from HMI to SDL with resultCode SUCCESS self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) + -- Expect successful response AddCommand on mobile side from SDL self.mobileSession1:ExpectResponse("AddCommand", { success = true, resultCode = "SUCCESS" }) + -- Expect OnSDLPersistenceComplete notification on HMI side EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete") + -- Expect 0 times of receiving OnHashChange notification on mobile side self.mobileSession1:ExpectNotification("OnHashChange"):Times(0) + -- Delay in 3 sec to make sure in absence of OnHashChange notification common.delayedExp(3000) end +-- OnAwakeSDL notification from HMI local function OnAwakeSDL(self) + -- Send OnAwakeSDL notification from HMI self.hmiConnection:SendNotification("BasicCommunication.OnAwakeSDL",{}) + -- Expect OnHashChange notification on HMI side self.mobileSession1:ExpectNotification("OnHashChange"):Do(function(_, data) + -- Write hashID to self.currentHashID self.currentHashID = data.payload.hashID end) end +-- IGNITION_OFF flow local function IGNITION_OFF(self) + -- Send OnExitAllApplications(SUSPEND) notification from HMI self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) + -- Expect notification OnSDLPersistenceComplete(IGNITION_OFF) on HMI side EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() + -- Send OnExitAllApplications(IGNITION_OFF) from HMI to SDL self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) + -- Send OnAppInterfaceUnregistered(IGNITION_OFF) from HMI to SDL self.mobileSession1:ExpectNotification("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) + -- Expect OnAppUnregistered notification on HMI from SDL EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + -- Expect OnAppUnregistered notification on HMI from SDL EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") SDL:DeleteFile() end) end +-- Data resumption local function expectResumeData(self) + -- Expect 2 VR.AddCommand requests on HMI side local on_vr_commands_added = EXPECT_HMICALL("VR.AddCommand"):Do(function(_,data) + -- Send response VR.AddCommand from HMI with resultCode SUCCESS self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS") end):Times(2) on_vr_commands_added:ValidIf(function(_, data) + -- Check parameters of received HMI requests if (data.params.type == "Command" and (data.params.cmdID == 1 or data.params.cmdID == 2)) then if (data.params.appID == config.application1.registerAppInterfaceParams.hmi_app_id) then return true @@ -76,25 +106,37 @@ local function expectResumeData(self) end end end) + -- Expect OnHashChange notification on mobile side self.mobileSession1:ExpectNotification("OnHashChange") end + -- Register application with resumption data local function registerAppAndResumeData(self) + -- Create mobile session self.mobileSession1 = mobile_session.MobileSession(self, self.mobileConnection) + -- Open RPC service in created session self.mobileSession1:StartService(7):Do(function() + -- Write actual hashID value in params for app registration to perform resumption config.application1.registerAppInterfaceParams.hashID = self.currentHashID + -- resumption of AddCommand expectResumeData(self) + -- Send request RegisterAppInterface from mobile side local corId = self.mobileSession1:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) + -- expect OnAppRegistered notification on HMI from SDL EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config.application1.registerAppInterfaceParams.appName }}):Do(function(_, data) config.application1.registerAppInterfaceParams.hmi_app_id = data.params.application.appID end) + -- Expect successful RegisterAppInterface response on mobile side from SDL self.mobileSession1:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + -- Expect ActivateApp request on HMI from SDL EXPECT_HMICALL("BasicCommunication.ActivateApp", {appID = config.application1.registerAppInterfaceParams.hmi_app_id}):Do(function(_,data) + -- Send ActivateApp response from HMI to SDL self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) end) + -- Expect 2 notifications OnHMIStatus, first with hmiLevel=NONE, second one with hmiLevel=FULL self.mobileSession1:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE"}, {hmiLevel = "FULL", systemContext = "MAIN", audioStreamingState = "AUDIBLE"}):Times(2) @@ -103,17 +145,27 @@ local function expectResumeData(self) --[[ Scenario ]] runner.Title("Preconditions") + -- Stop SDL if process is still running, delete local policy table and log files runner.Step("Clean environment", common.preconditions) + -- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP + -- and create mobile session runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + -- Register application and perform PTU runner.Step("RAI, PTU", common.rai_ptu) runner.Step("Activate App", common.activate_app) runner.Title("Test") + -- Add command after application registration runner.Step("Add Command", AddCommand) + -- Successful processing AddCommand after SUSPEND runner.Step("Add Command After SUSPEND", AddCommandAfterSUSPEND) + -- OnAwakeSDL notification from HMI runner.Step("Send OnAwakeSDL", OnAwakeSDL) runner.Step("IGNITION_OFF", IGNITION_OFF) + -- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP + -- and create mobile session runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + -- Register application process resumption data runner.Step("Register App And Resume Data", registerAppAndResumeData) runner.Title("Postconditions") diff --git a/test_scripts/Defects/4_5/1772_update_default_section.lua b/test_scripts/Defects/4_5/1772_update_default_section.lua index 751d940376..124389cb8e 100644 --- a/test_scripts/Defects/4_5/1772_update_default_section.lua +++ b/test_scripts/Defects/4_5/1772_update_default_section.lua @@ -19,7 +19,10 @@ local runner = require('user_modules/script_runner') local commonDefects = require('test_scripts/Defects/4_5/commonDefects') --[[ Local Functions ]] +-- Preparation policy table for Policy table update +-- @tparam table tbl table to update local function ptuUpdateFunc(tbl) + -- creation record for PT with RPC GetVehicleData, hmi_levels and parameters local VDgroup = { rpcs = { GetVehicleData = { @@ -28,28 +31,42 @@ local function ptuUpdateFunc(tbl) } } } + -- add NewTestCaseGroup record in structure functional_groupings in PT with value VDgroup tbl.policy_table.functional_groupings["NewTestCaseGroup"] = VDgroup + -- added created group NewTestCaseGroup in structure groups of section default + -- for update default permissions with new GetVehicleData RPC tbl.policy_table.app_policies.default.groups = { "Base-4", "NewTestCaseGroup" } + -- written nil in policy_table.app_policies[appID] to make sure that PT has no record with update related to appID tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = nil end +-- Successful processing of GetVehicleData RPC local function GetVD(self) + -- Request from mobile app local cid = self.mobileSession1:SendRPC("GetVehicleData", { gps = true }) + -- expectation of VehicleInfo.GetVehicleData request from SDL on HMI side EXPECT_HMICALL("VehicleInfo.GetVehicleData") :Do(function(_, data) + -- sending VehicleInfo.GetVehicleData response from HMI with resultCode SUCCESS self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) + -- expectation of GetVehicleData response on mobile app with resultCode SUCCESS self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end --[[ Scenario ]] runner.Title("Preconditions") +-- Stop SDL if process is still running, delete local policy table and log files runner.Step("Clean environment", commonDefects.preconditions) +-- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP and create mobile session runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start) +-- Register application and perform PTU with table from local function ptuUpdateFunc runner.Step("RAI, PTU", commonDefects.rai_ptu, { ptuUpdateFunc }) +-- Activate app to FULL HMI level runner.Step("Activate App", commonDefects.activate_app) runner.Title("Test") +-- Check successful processing GetVehicleData after update default section with GetVehicleData RPC runner.Step("GetVD_requet_is_success", GetVD) runner.Title("Postconditions") From d4f38ab214a4293c30a55528bc8f797e850bf2d3 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 19 Dec 2017 18:43:59 +0200 Subject: [PATCH 218/681] Add failing test step in case of absent binary data --- .../Defects/4_5/1376_PTU_all_flows.lua | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/test_scripts/Defects/4_5/1376_PTU_all_flows.lua b/test_scripts/Defects/4_5/1376_PTU_all_flows.lua index c4fdf62ea6..d57ad1df72 100644 --- a/test_scripts/Defects/4_5/1376_PTU_all_flows.lua +++ b/test_scripts/Defects/4_5/1376_PTU_all_flows.lua @@ -122,18 +122,20 @@ end -- Check that PT is sent as binary data in OnSystem request -- @tparam table bin_data binary data -- @tparam number pFlow number of floe type from flowType -local function checkIfPTSIsSentAsBinary(bin_data, pFlow) +local function checkIfPTSIsSentAsBinary(bin_data, pFlow, self) -- decode binary data to table depending on policy flow local pt = nil - if flowType[pFlow] == flowType.PROPRIETARY then - pt = json.decode(bin_data).HTTPRequest.body - elseif flowType[pFlow] == flowType.EXTERNAL_PROPRIETARY or flowType[pFlow] == flowType.HTTP then - pt = bin_data + if bin_data ~= nil and string.len(bin_data) > 0 then + if flowType[pFlow] == flowType.PROPRIETARY then + pt = json.decode(bin_data).HTTPRequest.body + elseif flowType[pFlow] == flowType.EXTERNAL_PROPRIETARY or flowType[pFlow] == flowType.HTTP then + pt = bin_data + end + pt = json.decode(pt) end - pt = json.decode(pt) -- Check presence of policy_table in decoded PT - if not pt.policy_table then - commonFunctions:userPrint(31, "PTS was not sent to Mobile in payload of OnSystemRequest") + if pt == nil or not pt.policy_table then + self:FailTestCase("PTS was not sent to Mobile as binary data in payload of OnSystemRequest") end end @@ -166,7 +168,7 @@ local function ptuProprietary(ptu_table, self, pFlow) :Do(function(_, d) -- After receiving OnSystemRequest notification on mobile side check that -- data in notification was sent as binary data - checkIfPTSIsSentAsBinary(d.binaryData, pFlow) + checkIfPTSIsSentAsBinary(d.binaryData, pFlow, self) log("SDL->MOB: N: OnSystemRequest") -- Send SystemRequest request with PT for update from mobile side local corIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", @@ -277,7 +279,7 @@ local function raiPTU(self) if d.payload.requestType == "HTTP" then if e.occurences <= 2 then -- SDL send OnSystemRequest more than once if PTU update was incorrect -- Check data in receives OnSystemRequest notification on mobile side - checkIfPTSIsSentAsBinary(d.binaryData, sdl.buildOptions.extendedPolicy) + checkIfPTSIsSentAsBinary(d.binaryData, sdl.buildOptions.extendedPolicy, self) if d.binaryData then -- Create PT form binary data local ptu_table = json.decode(d.binaryData) From 727034f0360cfb3c768b3e88a50c0f6710a7a5c8 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 20 Dec 2017 09:28:08 +0200 Subject: [PATCH 219/681] Added comments in script --- ...tion_After_changing_HMIlevel_from_NONE.lua | 84 +++++ test_scripts/Defects/4_5/commonDefects.lua | 301 ------------------ 2 files changed, 84 insertions(+), 301 deletions(-) delete mode 100644 test_scripts/Defects/4_5/commonDefects.lua diff --git a/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua b/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua index 0583406010..7b5b9feac8 100644 --- a/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua +++ b/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua @@ -19,95 +19,179 @@ config.application2.registerAppInterfaceParams.isMediaApplication = false config.application2.registerAppInterfaceParams.appHMIType = {"DEFAULT"} --[[ Local Functions ]] +--! @OnDDinNONE: Processing OnDriverDistraction notification with expectations 0 times +--! @parameters: +--! id - id of session, +--! params - parameters for OnDriverDistraction request +--! self - test object +--! @return: none local function OnDDinNONE(id, params, self) + -- Send OnDriverDistraction request from mobile app self.hmiConnection:SendNotification("UI.OnDriverDistraction", params) + -- Expect 0 OnDriverDistraction notifications on mobile side means does not receive notification self["mobileSession" .. id]:ExpectNotification("OnDriverDistraction") :Times(0) + -- Delay in 2 sec commonDefects.delayedExp(2000) end +--! @OnDD: Successful processing OnDriverDistraction +--! @parameters: +--! id - id of session, +--! params - parameters for OnDriverDistraction request +--! self - test object +--! @return: none local function OnDD(id, params, self) + -- Send OnDriverDistraction notification from mobile side self.hmiConnection:SendNotification("UI.OnDriverDistraction", params) + -- Expect OnDriverDistraction notification on mobile app self["mobileSession" .. id]:ExpectNotification("OnDriverDistraction", params) end +--! @OnDD2Apps: Successful processing OnDriverDistraction on one session and expect 0 times on second session +--! @parameters: +--! idres - id of session for expectation notification, +--! id - id of session, +--! params - parameters for OnDriverDistraction request +--! self - test object +--! @return: none local function OnDD2Apps(idres, id, params, self) + -- Send OnDriverDistraction notification from mobile application self.hmiConnection:SendNotification("UI.OnDriverDistraction", params) + -- Expect 0 notifications on mobile app self["mobileSession" .. id]:ExpectNotification("OnDriverDistraction") :Times(0) + -- Expect notification on mobile app self["mobileSession" .. idres]:ExpectNotification("OnDriverDistraction", params) commonDefects.delayedExp(2000) end +--! @ActivationAppWithOnDD: Receiving OnDriverDistraction notification right after activation with one application +--! @parameters: +--! params - parameters for OnDriverDistraction request +--! self - test object +--! @return: none local function ActivationAppWithOnDD( params, self) + -- Get HMI id of first application local hmiAppId = commonDefects.getHMIAppId(1) + -- Sent ActivateApp request from HMI to SDL local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = hmiAppId }) + -- Expect ActivateApp response on HMI EXPECT_HMIRESPONSE(requestId) + -- Expect OnHMIStatus notification on mobile app self.mobileSession1:ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + -- Expect OnDriverDistraction notification on mobile app self.mobileSession1:ExpectNotification("OnDriverDistraction", params) end +--! @RegisterAppWithOnDDResumption: Receiving OnDriverDistraction right after resume app in Limited HMI level +--! @parameters: +--! params - parameters for OnDriverDistraction request +--! self - test object +--! @return: none local function RegisterAppWithOnDDResumption( params, self) + -- Open mobile session self.mobileSession1 = mobile_session.MobileSession(self, self.mobileConnection) + -- Open RPC service in created session self.mobileSession1:StartService(7) :Do(function() + -- Send RegisterAppInterface request from mobile app local corId = self.mobileSession1:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) + -- Expect OnAppRegistered notification on HMI side EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config.application1.registerAppInterfaceParams.appName } }) + -- Expect successful RegisterAppInterface response on mobile side from SDL self.mobileSession1:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() + -- Expect 2 OnHMIStatus notifications on mobile app, + -- first one with hmiLevel = "NONE", second one with hmiLevel = "LIMITED" self.mobileSession1:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE" }, { hmiLevel = "LIMITED" }) :Times(2) + -- Expect OnPermissionsChange notification on mobile side from SDL with applied permissions self.mobileSession1:ExpectNotification("OnPermissionsChange") + -- Expect 0 OnDriverDistraction notifications on second mobile application self.mobileSession2:ExpectNotification("OnDriverDistraction") :Times(0) + -- Expect ExpectNotification notification on first mobile app self.mobileSession1:ExpectNotification("OnDriverDistraction", params) commonDefects.delayedExp(1000) end) end) end +--! @ActivationAppWithOnDD2Apps: Receiving OnDriverDistraction notification right after activation with two applications +--! @parameters: +--! params - parameters for OnDriverDistraction request +--! self - test object +--! @return: none local function ActivationAppWithOnDD2Apps( params, self) + -- Get HMI id of second registered application local hmiAppId = commonDefects.getHMIAppId(2) + -- Send request ActivateApp from HMI for activation second app local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = hmiAppId }) + -- Expect ActivateApp response on HMI side EXPECT_HMIRESPONSE(requestId) + -- Expect OnHMIStatus notification with hmiLevel = "FULL" on second mobile application self.mobileSession2:ExpectNotification("OnHMIStatus", { hmiLevel = "FULL"}) + -- Expect OnDriverDistraction notification on second mobile application self.mobileSession2:ExpectNotification("OnDriverDistraction", params) + -- Expect 0 OnDriverDistraction notifications on first mobile application self.mobileSession1:ExpectNotification("OnDriverDistraction") :Times(0) + -- Expect OnHMIStatus on first mobile app with hmiLevel = "LIMITED" self.mobileSession1:ExpectNotification("OnHMIStatus", { hmiLevel = "LIMITED"}) commonDefects.delayedExp(1000) end +--! @CloseSession: Closing first session +--! @parameters: +--! self - test object +--! @return: none local function CloseSession(self) self.mobileSession1:Stop() end --[[ Scenario ]] runner.Title("Preconditions") +-- Stop SDL if process is still running, delete local policy table and log files runner.Step("Clean environment", commonDefects.preconditions) +-- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP and create mobile session runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start) +-- Register application, perform PTU runner.Step("RAI, PTU", commonDefects.rai_ptu) runner.Title("Test") +-- Absence of OnDriverDistraction notification on mobile app in NONE HMI level runner.Step("Absence_OnDriverDistraction_in_NONE", OnDDinNONE, {1, {state = "DD_ON"}}) +-- Receiving OnDriverDistraction notification on mobile app in FULL HMI level runner.Step("OnDriverDistraction_in_FULL", ActivationAppWithOnDD, {{state = "DD_ON"}}) runner.Step("UnregisterRegisterApp", commonDefects.unregisterApp, {1}) +-- Register first application runner.Step("RAI_first_app", commonDefects.rai_n, {1}) +-- Register second application runner.Step("RAI_second_app", commonDefects.rai_ptu_n, {2}) +-- Activate first application runner.Step("Activate_first_app", commonDefects.activate_app) +-- Receiving OnDriverDistraction notification on mobile app with FULL HMI level +-- and check absence notification on second mobile application with NONE HMI level runner.Step("OnDriverDistraction_in_FULL_ansence_in_NONE", OnDD2Apps, {1, 2, {state = "DD_ON"}}) +-- Receiving OnDriverDistraction notification on mobile app with FULL HMI level +-- and check absence notification on second mobile application with NONE HMI level by changing DriverDistraction status runner.Step("OnDriverDistraction_changed_in_FULL_ansence_in_NONE", OnDD2Apps, {1, 2, {state = "DD_OFF"}}) +-- Receiving OnDriverDistraction notification on mobile app after activation runner.Step("OnDriverDistraction_after_app_activation", ActivationAppWithOnDD2Apps, {{state = "DD_OFF"}}) +-- Close first session runner.Step("CloseSession", CloseSession) +-- Change DriverDistraction status and check receiving of OnDriverDistraction notification on mobile app in FULL level runner.Step("OnDriverDistraction_change_in_FULL", OnDD, {2,{state = "DD_ON"}}) +-- Receiving OnDriverDistraction notification on mobile app in LIMITED HMI level after changing HMI status from NONE runner.Step("OnDriverDistraction_in_LIMITED_after_resumption", RegisterAppWithOnDDResumption, {{state = "DD_ON"}}) runner.Title("Postconditions") diff --git a/test_scripts/Defects/4_5/commonDefects.lua b/test_scripts/Defects/4_5/commonDefects.lua deleted file mode 100644 index 0755febe0e..0000000000 --- a/test_scripts/Defects/4_5/commonDefects.lua +++ /dev/null @@ -1,301 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RC common module ---------------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" -config.defaultProtocolVersion = 2 -config.ValidateSchema = false - ---[[ Required Shared libraries ]] -local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local commonSteps = require("user_modules/shared_testcases/commonSteps") -local commonTestCases = require("user_modules/shared_testcases/commonTestCases") -local mobile_session = require("mobile_session") -local json = require("modules/json") -local events = require("events") - ---[[ Local Variables ]] -local ptu_table = {} -local hmiAppIds = {} - -local commonDefect = {} - -commonDefect.timeout = 2000 -commonDefect.minTimeout = 500 -commonDefect.DEFAULT = "Default" -commonDefect.buttons = { climate = "FAN_UP", radio = "VOLUME_UP" } - -local function getPTUFromPTS(tbl) - tbl.policy_table.consumer_friendly_messages.messages = nil - tbl.policy_table.device_data = nil - tbl.policy_table.module_meta = nil - tbl.policy_table.usage_and_error_counts = nil - tbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null - tbl.policy_table.module_config.preloaded_pt = nil - tbl.policy_table.module_config.preloaded_date = nil -end - -function commonDefect.DefaultStruct() - return { - keep_context = false, - steal_focus = false, - priority = "NONE", - default_hmi = "NONE", - groups = { "Base-4"}, - } -end - -local function updatePTU(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonDefect.DefaultStruct() -end - -local function jsonFileToTable(file_name) - local f = io.open(file_name, "r") - local content = f:read("*all") - f:close() - return json.decode(content) -end - -local function tableToJsonFile(tbl, file_name) - local f = io.open(file_name, "w") - f:write(json.encode(tbl)) - f:close() -end - -local function checkIfPTSIsSentAsBinary(bin_data) - if not (bin_data ~= nil and string.len(bin_data) > 0) then - commonFunctions:userPrint(31, "PTS was not sent to Mobile in payload of OnSystemRequest") - end -end - -local function ptu(self, ptu_update_func) - local function getAppsCount() - local count = 0 - for _, _ in pairs(hmiAppIds) do - count = count + 1 - end - return count - end - - local policy_file_name = "PolicyTableUpdate" - local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") - local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") - local ptu_file_name = os.tmpname() - local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(requestId) - :Do(function() - self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", - { requestType = "PROPRIETARY", fileName = pts_file_name }) - getPTUFromPTS(ptu_table) - updatePTU(ptu_table) - if ptu_update_func then - ptu_update_func(ptu_table) - end - tableToJsonFile(ptu_table, ptu_file_name) - - local event = events.Event() - event.matches = function(e1, e2) return e1 == e2 end - EXPECT_EVENT(event, "PTU event") - :Timeout(11000) - - for id = 1, getAppsCount() do - local mobileSession = commonDefect.getMobileSession(self, id) - mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) - :Do(function(_, d2) - print("App ".. id .. " was used for PTU") - RAISE_EVENT(event, event, "PTU event") - checkIfPTSIsSentAsBinary(d2.binaryData) - local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", - { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) - EXPECT_HMICALL("BasicCommunication.SystemRequest") - :Do(function(_, d3) - self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) - self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", - { policyfile = policy_file_path .. "/" .. policy_file_name }) - end) - mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) - end) - :Times(AtMost(1)) - end - end) - os.remove(ptu_file_name) -end - -local function allow_sdl(self) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) -end - -function commonDefect.preconditions() - commonFunctions:SDLForceStop() - commonSteps:DeletePolicyTable() - commonSteps:DeleteLogsFiles() -end - -function commonDefect.start(pHMIParams, self) - self, pHMIParams = commonDefect.getSelfAndParams(pHMIParams, self) - self:runSDL() - commonFunctions:waitForSDLStart(self) - :Do(function() - self:initHMI(self) - :Do(function() - commonFunctions:userPrint(35, "HMI initialized") - self:initHMI_onReady(pHMIParams) - :Do(function() - commonFunctions:userPrint(35, "HMI is ready") - self:connectMobile() - :Do(function() - commonFunctions:userPrint(35, "Mobile connected") - allow_sdl(self) - end) - end) - end) - end) -end - -function commonDefect.startWithoutMobile(pHMIParams, self) - self, pHMIParams = commonDefect.getSelfAndParams(pHMIParams, self) - self:runSDL() - commonFunctions:waitForSDLStart(self) - :Do(function() - self:initHMI(self) - :Do(function() - commonFunctions:userPrint(35, "HMI initialized") - self:initHMI_onReady(pHMIParams) - :Do(function() - commonFunctions:userPrint(35, "HMI is ready") - end) - end) - end) -end - -function commonDefect.rai_ptu(ptu_update_func, self) - self, ptu_update_func = commonDefect.getSelfAndParams(ptu_update_func, self) - commonDefect.rai_ptu_n(1, ptu_update_func, self) -end - -function commonDefect.rai_ptu_n(id, ptu_update_func, self) - self, id, ptu_update_func = commonDefect.getSelfAndParams(id, ptu_update_func, self) - if not id then id = 1 end - self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) - self["mobileSession" .. id]:StartService(7) - :Do(function() - local corId = self["mobileSession" .. id]:SendRPC - ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", - { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) - :Do(function(_, d1) - hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) - :Times(3) - EXPECT_HMICALL("BasicCommunication.PolicyUpdate") - :Do(function(_, d2) - self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) - ptu_table = jsonFileToTable(d2.params.file) - ptu(self, ptu_update_func) - end) - end) - self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) - :Do(function() - self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", - { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice - self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") - end) - end) -end - -function commonDefect.rai_n(id, self) - self, id = commonDefect.getSelfAndParams(id, self) - if not id then id = 1 end - self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) - self["mobileSession" .. id]:StartService(7) - :Do(function() - local corId = self["mobileSession" .. id]:SendRPC - ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", - { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) - :Do(function(_, d1) - hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID - end) - self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) - :Do(function() - self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", - { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice - self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") - end) - end) -end - -function commonDefect.delayedExp(timeout) - if not timeout then timeout = commonDefect.timeout end - commonTestCases:DelayedExp(timeout) -end - -function commonDefect.unregisterApp(pAppId, self) - local mobSession = commonDefect.getMobileSession(self, pAppId) - local hmiAppId = commonDefect.getHMIAppId(pAppId) - local cid = mobSession:SendRPC("UnregisterAppInterface",{}) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = hmiAppId, unexpectedDisconnect = false }) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) -end - -function commonDefect.activate_app(pAppId, self) - self, pAppId = commonDefect.getSelfAndParams(pAppId, self) - if not pAppId then pAppId = 1 end - local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] - local mobSession = commonDefect.getMobileSession(self, pAppId) - local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) - EXPECT_HMIRESPONSE(requestId) - mobSession:ExpectNotification("OnHMIStatus", - { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) - commonTestCases:DelayedExp(commonDefect.minTimeout) -end - -function commonDefect.putFile(pFileName, self) - self, pFileName = commonDefect.getSelfAndParams(pFileName, self) - local cid = self.mobileSession1:SendRPC( - "PutFile", - {syncFileName = pFileName, fileType = "GRAPHIC_PNG", persistentFile = false, systemFile = false}, - "files/icon.png") - - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) -end - -function commonDefect.postconditions() - StopSDL() -end - -function commonDefect.getSelfAndParams(...) - local out = { } - local selfIdx = nil - for i,v in pairs({...}) do - if type(v) == "table" and v.isTest then - table.insert(out, v) - selfIdx = i - break - end - end - local idx = 2 - for i = 1, table.maxn({...}) do - if i ~= selfIdx then - out[idx] = ({...})[i] - idx = idx + 1 - end - end - return table.unpack(out, 1, table.maxn(out)) -end - -function commonDefect.getHMIAppId(pAppId) - if not pAppId then pAppId = 1 end - return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] -end - -function commonDefect.getMobileSession(self, pAppId) - if not pAppId then pAppId = 1 end - return self["mobileSession" .. pAppId] -end - -return commonDefect From 1a6518ed779e1e663fab60ea8216bed6434111bf Mon Sep 17 00:00:00 2001 From: "Getmanets Irina (GitHub)" Date: Wed, 20 Dec 2017 09:50:22 +0200 Subject: [PATCH 220/681] Update 1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua --- ...81_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua b/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua index 7b5b9feac8..caff7b9586 100644 --- a/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua +++ b/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua @@ -190,7 +190,7 @@ runner.Step("OnDriverDistraction_after_app_activation", ActivationAppWithOnDD2Ap -- Close first session runner.Step("CloseSession", CloseSession) -- Change DriverDistraction status and check receiving of OnDriverDistraction notification on mobile app in FULL level -runner.Step("OnDriverDistraction_change_in_FULL", OnDD, {2,{state = "DD_ON"}}) +runner.Step("OnDriverDistraction_change_in_FULL", OnDD, {2, {state = "DD_ON"}}) -- Receiving OnDriverDistraction notification on mobile app in LIMITED HMI level after changing HMI status from NONE runner.Step("OnDriverDistraction_in_LIMITED_after_resumption", RegisterAppWithOnDDResumption, {{state = "DD_ON"}}) From 751320903755c5e4a5408a4e76c208b3bc8595b2 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 20 Dec 2017 11:43:48 +0200 Subject: [PATCH 221/681] Add additional verification for last mobile session --- ..._does_not_send_HB_and_does_not_respond.lua | 151 ++++++++++-------- 1 file changed, 84 insertions(+), 67 deletions(-) diff --git a/test_scripts/Defects/4_5/1893_ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua b/test_scripts/Defects/4_5/1893_ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua index aa9bb78472..05547dc3b9 100644 --- a/test_scripts/Defects/4_5/1893_ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua +++ b/test_scripts/Defects/4_5/1893_ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua @@ -7,6 +7,7 @@ local runner = require("user_modules/script_runner") local common = require("test_scripts/Defects/4_5/commonDefects") local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local mobile_session = require('mobile_session') +local events = require("events") --[[ General Precondition before ATF start ]] -- switch ATF to use 3rd version (with HeartBeat) of SDL protocol @@ -15,10 +16,15 @@ config.defaultProtocolVersion = 3 config.application1.registerAppInterfaceParams.isMediaApplication = true -- [[Local variables]] --- define parameters for 1st application -local default_app_params = config.application1.registerAppInterfaceParams --- define parameters for 2nd application -local default_app_params2 = config.application2.registerAppInterfaceParams +-- array with default parameters for mobile applications +local appParams = { + [1] = config.application1.registerAppInterfaceParams, + [2] = config.application2.registerAppInterfaceParams +} +-- array to store HMI application identifiers +local hmiAppId = {} +-- array to store mobile sessions +local mobileSession = {} --[[ Local Functions ]] @@ -33,128 +39,139 @@ local function updateINIFile() commonFunctions:write_parameter_to_smart_device_link_ini("HeartBeatTimeout", 5000) end ---[[ @Start_Session_And_Register_App: create mobile session, start RPC service and register 1st mobile application ---! @parameters: none +--[[ @connectMobile: create mobile connection +--! @parameters: --! self - test object which will be provided automatically by runner module --! @return: none --]] -local function Start_Session_And_Register_App(self) - -- create 1st mobile session - self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) - -- define parameters for heartbeat: 1st application shouldn't sent heartbeat neither as answer on heartbeat messages - -- from SDL - self.mobileSession.sendHeartbeatToSDL = false - self.mobileSession.answerHeartbeatFromSDL = false - self.mobileSession.ignoreSDLHeartBeatACK = false - -- start RPC service - self.mobileSession:StartRPC() - :Do(function() - -- send 'RegisterAppInterface' RPC with defined parameters for mobile application - -- and return correlation identifier - local correlation_id = self.mobileSession:SendRPC("RegisterAppInterface", default_app_params) - -- register expectation of 'BC.OnAppRegistered' notification on HMI connection - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { - application = { appName = default_app_params.appName } - }) - :Do(function(_,data) - -- save HMI application Id into 'hmi_app_id' variable: it will be required in next steps - default_app_params.hmi_app_id = data.params.application.appID - end) - -- register expectation of response for 'RegisterAppInterface' request with appropriate correlation id - -- on Mobile connection - self.mobileSession:ExpectResponse(correlation_id, { success = true, resultCode = "SUCCESS" }) - -- register expectation of 'OnHMIStatus' notification on Mobile connection - -- it's expected that value of 'hmiLevel' parameter will be 'NONE' - self.mobileSession:ExpectNotification("OnHMIStatus", { - hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" - }) - -- register expectation of 'OnPermissionsChange' notification on Mobile connection - self.mobileSession:ExpectNotification("OnPermissionsChange", {}) - end) +local function connectMobile(self) + -- connect mobile device + self.mobileConnection:Connect() + -- register "Connected" expectation + EXPECT_EVENT(events.connectedEvent, "Connected") end ---[[ @Register_Second_App_With_HeartBeat: create mobile session, start RPC service and register 2nd mobile application +--[[ @Register_App: create mobile session, start RPC service and register mobile application --! @parameters: none +--! appId - application number (1, 2, etc.) +--! answerHeartbeatFromSDL - if 'true' ATF will answer on heartbeat messages from SDL --! self - test object which will be provided automatically by runner module --! @return: none --]] -local function Register_Second_App_With_HeartBeat(self) - -- create 2nd mobile session - self.mobileSession1 = mobile_session.MobileSession(self, self.mobileConnection) - -- define parameters for heartbeat: 2nd application shouldn't sent heartbeat, but should answer on heartbeat messages - -- from SDL - self.mobileSession1.sendHeartbeatToSDL = false - self.mobileSession1.answerHeartbeatFromSDL = true - self.mobileSession1.ignoreSDLHeartBeatACK = false - self.mobileSession1:StartRPC() +local function Register_App(appId, answerHeartbeatFromSDL, self) + -- create mobile session + mobileSession[appId] = mobile_session.MobileSession(self, self.mobileConnection) + -- set parameters for heartbeat + mobileSession[appId].activateHeartbeat = false + mobileSession[appId].sendHeartbeatToSDL = false + mobileSession[appId].answerHeartbeatFromSDL = answerHeartbeatFromSDL + mobileSession[appId].ignoreSDLHeartBeatACK = false + -- start RPC service + mobileSession[appId]:StartRPC() :Do(function() -- send 'RegisterAppInterface' RPC with defined parameters for mobile application -- and return correlation identifier - local correlation_id = self.mobileSession1:SendRPC("RegisterAppInterface", default_app_params2) + local correlation_id = mobileSession[appId]:SendRPC("RegisterAppInterface", appParams[appId]) -- register expectation of 'BC.OnAppRegistered' notification on HMI connection EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { - application = { appName = default_app_params2.appName } + application = { appName = appParams[appId].appName } }) + :Do(function(_,data) + -- save HMI application Id: it will be required in next steps + hmiAppId[appId] = data.params.application.appID + end) -- register expectation of response for 'RegisterAppInterface' request with appropriate correlation id -- on Mobile connection - self.mobileSession1:ExpectResponse(correlation_id, { success = true, resultCode = "SUCCESS" }) + mobileSession[appId]:ExpectResponse(correlation_id, { success = true, resultCode = "SUCCESS" }) -- register expectation of 'OnHMIStatus' notification on Mobile connection -- it's expected that value of 'hmiLevel' parameter will be 'NONE' - self.mobileSession1:ExpectNotification("OnHMIStatus", { + mobileSession[appId]:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) -- register expectation of 'OnPermissionsChange' notification on Mobile connection - self.mobileSession1:ExpectNotification("OnPermissionsChange", {}) + mobileSession[appId]:ExpectNotification("OnPermissionsChange", {}) end) end --[[ @Wait_15_seconds_And_Verify_OnAppUnregistered: wait 15 sec and check if 1st application is unregistered --! due to heartbeat timeout --! @parameters: none ---! self - test object which will be provided automatically by runner module --! @return: none --]] -local function Wait_15_seconds_And_Verify_OnAppUnregistered(self) +local function Wait_15_seconds_And_Verify_OnAppUnregistered() -- register expectation of 'BC.OnAppUnregistered' notification on HMI connection -- it's expected that 1st application is unregistered with 'unexpectedDisconnect' = true - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { - appID = default_app_params.hmi_app_id, unexpectedDisconnect = true - }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = hmiAppId[1], unexpectedDisconnect = true }) -- increase default timeout for wait from 10s to 15s -- this is required in order to heartbeat timeout of SDL is run out -- and SDL is able to close session for 1st application :Timeout(15000) :Do(function() -- stop heartbeat (if it was started previously) - self.mobileSession:StopHeartbeat() + mobileSession[1]:StopHeartbeat() end) end --[[ @Verify_That_Second_App_Still_Registered: verify that 2nd application is still registered --! @parameters: none ---! self - test object which will be provided automatically by runner module --! @return: none --]] -local function Verify_That_Second_App_Still_Registered(self) +local function Verify_That_Second_App_Still_Registered() -- send 'RegisterAppInterface' RCP with defined parameters - local cor_id = self.mobileSession1:SendRPC("RegisterAppInterface", default_app_params2) + local cor_id = mobileSession[2]:SendRPC("RegisterAppInterface", appParams[2]) -- register expectation that response will be unsuccessful with appropriate resultCode -- meaning session for 2nd application is still alive - self.mobileSession1:ExpectResponse(cor_id, { success = false, resultCode = "APPLICATION_REGISTERED_ALREADY"}) + mobileSession[2]:ExpectResponse(cor_id, { success = false, resultCode = "APPLICATION_REGISTERED_ALREADY"}) +end + +--[[ @Stop_HB_2nd_App: stop heartbeat for 2nd app, wait 15 sec and check that 2nd application is unregistered +--! due to heartbeat timeout, also verify that mobile connection is not closed +--! @parameters: none +--! @return: none +--]] +local function Stop_HB_2nd_App() + -- switch off heartbeat for 2nd application + mobileSession[2].answerHeartbeatFromSDL = false + mobileSession[2]:StopHeartbeat() + -- register expectation of 'BC.OnAppUnregistered' notification on HMI connection + -- it's expected that the application is unregistered with 'unexpectedDisconnect' = true + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = hmiAppId[2], unexpectedDisconnect = true }) + -- increase default timeout for wait from 10s to 15s + -- this is required in order to heartbeat timeout of SDL is run out + -- and SDL is able to close session for application + :Timeout(15000) + -- register expectation that mobile connection won't be closed + EXPECT_EVENT(events.disconnectedEvent, "Disconnected") + :Times(0) +end + +--[[ @Verify_That_New_Session_can_be_created: verify that new mobile session can be created on existing connection +--! @parameters: +--! self - test object which will be provided automatically by runner module +--! @return: none +--]] +local function Verify_That_New_Session_can_be_created(self) + -- create mobile session + mobileSession[3] = mobile_session.MobileSession(self, self.mobileConnection) + -- start RPC service + mobileSession[3]:StartRPC() end -- [[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Update INI file", updateINIFile) -runner.Step("Start SDL, HMI, connect Mobile", common.start) runner.Step("SDL Configuration", common.printSDLConfig) +runner.Step("Start SDL and HMI", common.startWithoutMobile) +runner.Step("Connect Mobile", connectMobile) runner.Title("Test") -runner.Step("Start_Session_And_Register_App", Start_Session_And_Register_App) -runner.Step("Register_Second_App_With_HeartBeat", Register_Second_App_With_HeartBeat) +runner.Step("Register_1st_App_without_HeartBeat", Register_App, { 1, false }) +runner.Step("Register_2nd_App_with_HeartBeat", Register_App, { 2, true }) runner.Step("Wait_15_seconds_And_Verify_OnAppUnregistered", Wait_15_seconds_And_Verify_OnAppUnregistered) runner.Step("Verify_That_Second_App_Still_Registered", Verify_That_Second_App_Still_Registered) +runner.Step("Stop_HeartBeat_for_2nd_App_and_verify_that_connection_is_alive", Stop_HB_2nd_App) +runner.Step("Verify_That_New_Session_can_be_created", Verify_That_New_Session_can_be_created) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) From f3aeba8a10d407a688eb649c43c2710bea30d7c7 Mon Sep 17 00:00:00 2001 From: "Getmanets Irina (GitHub)" Date: Wed, 20 Dec 2017 11:50:45 +0200 Subject: [PATCH 222/681] Update 1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua --- ...nDriverDistraction_After_changing_HMIlevel_from_NONE.lua | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua b/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua index caff7b9586..9535a3ba2f 100644 --- a/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua +++ b/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua @@ -1,11 +1,5 @@ --------------------------------------------------------------------------------------------- -- GitHub issue: https://github.com/SmartDeviceLink/sdl_core/issues/1881 --- In case --- mobile app registers and gets NONE HMILevel --- and SDL receives OnDriverDistraction () fom HMI --- SDL must: --- transfer the last known (actual) OnDriverDistraction () to this mobile app right after this mobile app --- changes HMILevel to any other than NONE --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') From be2a9d2f91775321500a499eed68a27afe2936ca Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 20 Dec 2017 13:00:29 +0200 Subject: [PATCH 223/681] Added comments in script 1892 --- ...rom_SDL_after_receiving_HB_from_mobile.lua | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/test_scripts/Defects/4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua b/test_scripts/Defects/4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua index f199f753df..327e1b8ad3 100644 --- a/test_scripts/Defects/4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua +++ b/test_scripts/Defects/4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua @@ -29,15 +29,27 @@ local file_connection = require('file_connection') config.heartbeatTimeout = 7000 --[[ Local Functions ]] +--! @BackUpIniFileAndSetHBValue: Backup .ini file and set HB value +--! @parameters:none +--! @return: none local function BackUpIniFileAndSetHBValue() commonPreconditions:BackupFile("smartDeviceLink.ini") commonFunctions:write_parameter_to_smart_device_link_ini("HeartBeatTimeout", 5000) end +--[[ Local Functions ]] +--! @RestoreIniFile: Restore .ini file to original +--! @parameters:none +--! @return: none local function RestoreIniFile() commonPreconditions:RestoreFile("smartDeviceLink.ini") end +--[[ Local Functions ]] +--! @OpenConnectionCreateSession: Creation new session via 3 protocol without heart beat +--! @parameters: +--! self - test object +--! @return: none local function OpenConnectionCreateSession(self) config.defaultProtocolVersion = 3 local tcpConnection = tcp.Connection(config.mobileHost, config.mobilePort) @@ -56,7 +68,13 @@ local function OpenConnectionCreateSession(self) self.mobileSession1:StartService(7) end +--[[ Local Functions ]] +--! @RegisterAppInterface: Register application +--! @parameters: +--! self - test object +--! @return: none local function RegisterAppInterface(self) + -- Send RegisterAppInterface request from mobile app local CorIdRegister = self.mobileSession1:SendRPC("RegisterAppInterface", { syncMsgVersion ={ majorVersion = 4, @@ -69,21 +87,32 @@ local function RegisterAppInterface(self) appHMIType = { "DEFAULT" }, appID = config.application1.registerAppInterfaceParams.appID }) + -- Expect OnAppRegistered notification on HMI side EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = {appName = config.application1.registerAppInterfaceParams.appName }}) + -- Expect successful RegisterAppInterface response on mobile app self.mobileSession1:ExpectResponse(CorIdRegister, { success = true, resultCode = "SUCCESS" }) + -- Expect OnHMIStatus notification on mobile side self.mobileSession1:ExpectNotification("OnHMIStatus", { systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE" }) end +--[[ Local Functions ]] +--! @ExpectationAfterAppRegistration: Expect absence of HB from SDL +--! @parameters: +--! self - test object +--! @return: none local function ExpectationAfterAppRegistration(self) + -- Get HMI id of first application local hmiAppId = commonDefects.getHMIAppId(1) + -- Does not expect OnAppUnregistered notification on HMI side, times 0 EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = hmiAppId}) :Times(0) commonFunctions:userPrint (33,"Log: AppSession started, HB disabled") commonFunctions:userPrint (33, "Log: App v.3 disconnection not expected since no HB ACK and timer" .. "should be started by SDL till the HB request from app first") + -- Does not expect HB from SDL, times 0 local HBEvent = events.Event() HBEvent.matches = function(_, data) @@ -97,6 +126,11 @@ local function ExpectationAfterAppRegistration(self) commonDefects.delayedExp(10000) end +--[[ Local Functions ]] +--! @sendHBFromMobileAndReceivingFromSDL: Send HB from mobile and expect HB from SDL +--! @parameters: +--! self - test object +--! @return: none local function sendHBFromMobileAndReceivingFromSDL(self) local HBEvent = events.Event() HBEvent.matches = @@ -114,17 +148,26 @@ local function sendHBFromMobileAndReceivingFromSDL(self) (data.sessionId == self.mobileSession1.sessionId) and data.frameInfo == 255 end + -- Send HB from mobile app to SDL self.mobileSession1:Send({ frameType = constants.FRAME_TYPE.CONTROL_FRAME, serviceType = constants.SERVICE_TYPE.CONTROL, frameInfo = constants.FRAME_INFO.HEARTBEAT }) + -- Expect HB on mobile app from SDL self.mobileSession1:ExpectEvent(HBEvent, "HB") + -- Expect HB ACK from SDL on mobile app self.mobileSession1:ExpectEvent(HBACKEvent, "HB") end +--[[ Local Functions ]] +--! @DisconnectDueToHeartbeat: Disconnect app due to HB timeout +--! @parameters: none +--! @return: none local function DisconnectDueToHeartbeat() + -- Get HMI id for registered app local hmiAppId = commonDefects.getHMIAppId(1) + -- Expect OnAppUnregistered notification on HMI side from SDL EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = hmiAppId}) commonDefects.delayedExp() commonFunctions:userPrint(33, "AppSession started, HB enabled") From 789d770b38b919691099d8e0e41bdc6086007b35 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Sat, 9 Dec 2017 10:26:29 +0200 Subject: [PATCH 224/681] Script for issue 1912 Update according to review comments Added comments for script 1912 --- ...912_Video_service_start_via_2_protocol.lua | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 test_scripts/Defects/4_5/1912_Video_service_start_via_2_protocol.lua diff --git a/test_scripts/Defects/4_5/1912_Video_service_start_via_2_protocol.lua b/test_scripts/Defects/4_5/1912_Video_service_start_via_2_protocol.lua new file mode 100644 index 0000000000..6485b340bc --- /dev/null +++ b/test_scripts/Defects/4_5/1912_Video_service_start_via_2_protocol.lua @@ -0,0 +1,69 @@ +--------------------------------------------------------------------------------------------- +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1912 +-- Description +-- SDL must respond NACK in case navigation app connected over protocol v2 sends StartService for audio service +-- Preconditions +-- SDL and HMI are started. +-- Steps to reproduce +-- navigation app connects over protocol v2 and this app sends StartService for audio service +-- Actual result +-- N/A +-- Expected result +-- SDL must respond StartService_NACK to this app +--------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require("user_modules/script_runner") +local constants = require('protocol_handler/ford_protocol_constants') +local commonDefects = require('test_scripts/Defects/4_5/commonDefects') +local events = require('events') + +--[[ General configuration parameters ]] +config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 +config.application1.registerAppInterfaceParams.appHMIType = {"NAVIGATION"} + +--[[ Local Functions ]] +--! @StartAudioServiceVia2Protocol: Start audio service via 2 protocol +--! @parameters: +--! self - test object +--! @return: none +local function StartAudioServiceVia2Protocol(self) + local StartServiceResponseEvent = events.Event() + StartServiceResponseEvent.matches = + function(_, data) + return data.frameType == constants.FRAME_TYPE.CONTROL_FRAME and + data.serviceType == constants.SERVICE_TYPE.PCM and + data.sessionId == self.mobileSession1.sessionId and + (data.frameInfo == constants.FRAME_INFO.START_SERVICE_NACK or + data.frameInfo == constants.FRAME_INFO.START_SERVICE_ACK) + end + -- Send Audio service start from mobile app to SDL + self.mobileSession1:Send({ + frameType = constants.FRAME_TYPE.CONTROL_FRAME, + serviceType = constants.SERVICE_TYPE.PCM, + frameInfo = constants.FRAME_INFO.START_SERVICE + }) + -- Expect StartServiceNACK on mobile app from SDL, it means service is not started + self.mobileSession1:ExpectEvent(StartServiceResponseEvent, "Expect StartServiceNACK") + :ValidIf(function(_, data) + if data.frameInfo == constants.FRAME_INFO.START_SERVICE_NACK then + return true + else + return false, "StartService ACK received" + end + end) + commonDefects.delayedExp() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonDefects.preconditions) +runner.Step("Start SDL, HMI", commonDefects.start) +runner.Step("RAI, PTU", commonDefects.rai_ptu) +runner.Step("Activate App", commonDefects.activate_app) + +runner.Title("Test") +runner.Step("Start audio service via 2 protocol with expectation of StartServiceNACK", StartAudioServiceVia2Protocol) + +runner.Title("Postconditions") +runner.Step("Stop SDL", StopSDL) From 2c5b691ddfc0e81b30fb9fe2477ee91f79a4764f Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 20 Dec 2017 18:34:04 +0200 Subject: [PATCH 225/681] Minor fix of ignition off function --- ...206_REQUEST_PTU_Trigger_PTU_failed_previous_IGN_ON.lua | 8 ++++---- test_scripts/Defects/4_5/commonDefects.lua | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test_scripts/Defects/4_5/1206_REQUEST_PTU_Trigger_PTU_failed_previous_IGN_ON.lua b/test_scripts/Defects/4_5/1206_REQUEST_PTU_Trigger_PTU_failed_previous_IGN_ON.lua index 098ffc8f8f..f950383ce4 100644 --- a/test_scripts/Defects/4_5/1206_REQUEST_PTU_Trigger_PTU_failed_previous_IGN_ON.lua +++ b/test_scripts/Defects/4_5/1206_REQUEST_PTU_Trigger_PTU_failed_previous_IGN_ON.lua @@ -18,17 +18,17 @@ local color = require("user_modules/consts").color --]] local function registerApplicationAndWaitPTUStart(self) -- create mobile session - self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) + self.mobileSession1 = mobile_session.MobileSession(self, self.mobileConnection) -- start RPC service - self.mobileSession:StartService(7) + self.mobileSession1:StartService(7) :Do(function() -- send 'RegisterAppInterface' RPC with default parameters for mobile application -- and return correlation identifier - local corId = self.mobileSession:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) + local corId = self.mobileSession1:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) -- register expectation of response for 'RegisterAppInterface' request with appropriate correlation id -- on Mobile connection -- it's expected that request is processed successfully - self.mobileSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) -- register expectation of 'BC.OnAppRegistered' notification on HMI connection -- it's expected that the value of 'application.appName' argument will be equal to default application name EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { diff --git a/test_scripts/Defects/4_5/commonDefects.lua b/test_scripts/Defects/4_5/commonDefects.lua index 0177b555ca..b5b7ab0d6e 100644 --- a/test_scripts/Defects/4_5/commonDefects.lua +++ b/test_scripts/Defects/4_5/commonDefects.lua @@ -247,7 +247,7 @@ function commonDefect.ignitionOff(self) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete") :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) - self.mobileSession:ExpectNotification("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) + self.mobileSession1:ExpectNotification("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") :Do(function() From 8a56105b83272d07f286e64a1b36649be0384d6c Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 7 Dec 2017 17:36:26 +0200 Subject: [PATCH 226/681] Scripts for issue 1873 Removed SendLocation check from script because SendLocation functionality is not merged to develop branch. Updated according to review result and added comments --- .../1873_Parameters_empty_in_policy_table.lua | 81 ++++++++++++ ..._OnVD_Parameters_empty_in_policy_table.lua | 125 ++++++++++++++++++ 2 files changed, 206 insertions(+) create mode 100644 test_scripts/Defects/4_5/1873_Parameters_empty_in_policy_table.lua create mode 100644 test_scripts/Defects/4_5/1873_UnsubscribeVD_OnVD_Parameters_empty_in_policy_table.lua diff --git a/test_scripts/Defects/4_5/1873_Parameters_empty_in_policy_table.lua b/test_scripts/Defects/4_5/1873_Parameters_empty_in_policy_table.lua new file mode 100644 index 0000000000..468333cc96 --- /dev/null +++ b/test_scripts/Defects/4_5/1873_Parameters_empty_in_policy_table.lua @@ -0,0 +1,81 @@ +--------------------------------------------------------------------------------------------- +-- GitHub issue https://github.com/SmartDeviceLink/sdl_core/issues/1873 +--------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonDefects = require('test_scripts/Defects/4_5/commonDefects') +local json = require("json") + +--[[ Local Functions ]] +--! @ptuUpdateFuncDisallowedRPC: Update PT with empty parameters +--! @parameters: +--! tbl - policy table +--! @return: none +local function ptuUpdateFuncDisallowedRPC(tbl) + local VDgroup = { + rpcs = { + GetVehicleData = { + hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, + parameters = json.EMPTY_ARRAY + }, + SubscribeVehicleData = { + hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, + parameters = json.EMPTY_ARRAY + } + } + } + tbl.policy_table.functional_groupings.NewTestCaseGroup = VDgroup + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = + {"Base-4", "NewTestCaseGroup"} +end + +--[[ Local Functions ]] +--! @GetVD: Processing GetVehicleData RPC with resultCode DISALLOWED +--! @parameters: +--! self - test object +--! @return: none +local function GetVD(self) + -- Send GetVehicleData request from mobile app + local cid = self.mobileSession1:SendRPC("GetVehicleData", {gps = true}) + -- Does not expect GetVehicleData request on HMI side, times 0. + EXPECT_HMICALL("VehicleInfo.GetVehicleData") + :Times(0) + commonDefects.delayedExp() + -- Expect GetVehicleData response on mobile side from SDL with resultCode DISALLOWED + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +--[[ Local Functions ]] +--! @SubscribeVD: Processing SubscribeVehicleData RPC with resultCode DISALLOWED +--! @parameters: +--! self - test object +--! @return: none +local function SubscribeVD(self) + -- Send SubscribeVehicleData request from mobile app + local cid = self.mobileSession1:SendRPC("SubscribeVehicleData", {gps = true}) + -- Does not expect GetVehicleData request on HMI side, times 0. + EXPECT_HMICALL("VehicleInfo.SubscribeVehicleData") + :Times(0) + commonDefects.delayedExp() + -- Expect GetVehicleData response on mobile side from SDL with resultCode DISALLOWED + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +-- Stop SDL if process is still running, delete local policy table and log files +runner.Step("Clean environment", commonDefects.preconditions) +-- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP and create mobile session +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start) +-- Register application, perform PTU with policy table from ptuUpdateFuncDisallowedRPC +runner.Step("RAI, PTU", commonDefects.rai_ptu, { ptuUpdateFuncDisallowedRPC }) +runner.Step("Activate App", commonDefects.activate_app) + +runner.Title("Test") +-- Processing GetVehicleData RPC with resultCode DISALLOWED +runner.Step("GEtVD_parameters_empty_in_policy_table", GetVD) +-- Processing SubscribeVehicleData RPC with resultCode DISALLOWED +runner.Step("SubscribeVD_parameters_empty_in_policy_table", SubscribeVD) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonDefects.postconditions) diff --git a/test_scripts/Defects/4_5/1873_UnsubscribeVD_OnVD_Parameters_empty_in_policy_table.lua b/test_scripts/Defects/4_5/1873_UnsubscribeVD_OnVD_Parameters_empty_in_policy_table.lua new file mode 100644 index 0000000000..c57fefbd67 --- /dev/null +++ b/test_scripts/Defects/4_5/1873_UnsubscribeVD_OnVD_Parameters_empty_in_policy_table.lua @@ -0,0 +1,125 @@ +--------------------------------------------------------------------------------------------- +-- GitHub issue: https://github.com/SmartDeviceLink/sdl_core/issues/1873 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonDefects = require('test_scripts/Defects/4_5/commonDefects') +local json = require("json") + +--[[ Local Variables ]] +local gpsDataResponse = { + longitudeDegrees = 100, + latitudeDegrees = 20, + utcYear = 2050, + utcMonth = 10, + utcDay = 30, + utcHours = 20, + utcMinutes = 50, + utcSeconds = 50, + compassDirection = "NORTH", + pdop = 5, + hdop = 5, + vdop = 5, + actual = false, + satellites = 30, + dimension = "2D", + altitude = 9500, + heading = 350, + speed = 450 +} + +--[[ Local Functions ]] +--! @ptuUpdateFuncDisallowedRPC: Update PT with empty parameters +--! @parameters: +--! tbl - policy table +--! @return: none +local function ptuUpdateFuncDisallowedRPC(tbl) + local VDgroup = { + rpcs = { + SubscribeVehicleData = { + hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, + parameters = {"gps"} + }, + OnVehicleData = { + hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, + parameters = json.EMPTY_ARRAY + }, + UnsubscribeVehicleData = { + hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, + parameters = json.EMPTY_ARRAY + } + } + } + tbl.policy_table.functional_groupings.NewTestCaseGroup = VDgroup + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = + {"Base-4", "NewTestCaseGroup"} +end + +--[[ Local Functions ]] +--! @SubscribeVD: Successful processing SubscribeVehicleData RPC +--! @parameters: +--! self - test object +--! @return: none +local function SubscribeVD(self) + -- Send request SubscribeVehicleData from mobile app + local cid = self.mobileSession1:SendRPC("SubscribeVehicleData", {gps = true}) + -- Expect SubscribeVehicleData request on HMI side form SDL + EXPECT_HMICALL("VehicleInfo.SubscribeVehicleData") + :Do(function(_,data) + -- Send SubscribeVehicleData response from HMI to SDL with resultCode SUCCESS + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + -- Expect successful SubscribeVehicleData response on mobile app + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Local Functions ]] +--! @UnsubscribeVD: Processing UnsubscribeVehicleData RPC with resultCode DISALLOWED +--! @parameters: +--! self - test object +--! @return: none +local function UnsubscribeVD(self) + local cid = self.mobileSession1:SendRPC("UnsubscribeVehicleData", {gps = true}) + -- Send UnsubscribeVehicleData request from mobile app + EXPECT_HMICALL("VehicleInfo.UnsubscribeVehicleData") + -- Does not expect UnsubscribeVehicleData request on HMI side, times 0. + :Times(0) + commonDefects.delayedExp() + -- Expect UnsubscribeVehicleData response on mobile side from SDL with resultCode DISALLOWED + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +--[[ Local Functions ]] +--! @OnVD: Processing OnVehicleData RPC with resultCode DISALLOWED +--! @parameters: +--! self - test object +--! @return: none +local function OnVD(self) + -- Send OnVehicleData request notification from HMI to SDL + self.hmiConnection:SendNotification("VehicleInfo.OnVehicleData", {gps = gpsDataResponse} ) + -- Does not expect OnVehicleData notification on mobile side, times 0. + self.mobileSession1:ExpectNotification("OnVehicleData") + :Times(0) + commonDefects.delayedExp(500) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +-- Stop SDL if process is still running, delete local policy table and log files +runner.Step("Clean environment", commonDefects.preconditions) +-- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP and create mobile session +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start) +-- Register application, perform PTU with policy table from ptuUpdateFuncDisallowedRPC +runner.Step("RAI, PTU", commonDefects.rai_ptu, { ptuUpdateFuncDisallowedRPC }) +runner.Step("Activate App", commonDefects.activate_app) +-- Subscribe to gps as precondition for UnsubscribeVehicleData +runner.Step("SubscribeVD", SubscribeVD) + +runner.Title("Test") +-- Processing OnVehicleData notification as not allowed by policies +runner.Step("OnVD_parameters_empty_in_policy_table", OnVD) +-- Processing GetVehicleData RPC with resultCode DISALLOWED +runner.Step("UnsubscribeVD_parameters_empty_in_policy_table", UnsubscribeVD) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonDefects.postconditions) From c1bdfb7f5e37f0cfaca16fc9334bfaa42bb5bef1 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 20 Dec 2017 18:37:06 +0200 Subject: [PATCH 227/681] Add additional check after ignition off --- .../Defects/4_5/1873_Parameters_empty_in_policy_table.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test_scripts/Defects/4_5/1873_Parameters_empty_in_policy_table.lua b/test_scripts/Defects/4_5/1873_Parameters_empty_in_policy_table.lua index 468333cc96..c84cc78ad8 100644 --- a/test_scripts/Defects/4_5/1873_Parameters_empty_in_policy_table.lua +++ b/test_scripts/Defects/4_5/1873_Parameters_empty_in_policy_table.lua @@ -77,5 +77,13 @@ runner.Step("GEtVD_parameters_empty_in_policy_table", GetVD) -- Processing SubscribeVehicleData RPC with resultCode DISALLOWED runner.Step("SubscribeVD_parameters_empty_in_policy_table", SubscribeVD) +-- Perform Ignition Off / On +runner.Step("Ignition Off", commonDefects.ignitionOff) +runner.Step("Start SDL, HMI, connect Mobile", commonDefects.start) +runner.Step("RAI", commonDefects.rai_n) +runner.Step("Activate App", commonDefects.activate_app) +-- Processing GetVehicleData RPC with resultCode DISALLOWED +runner.Step("GEtVD_parameters_empty_in_policy_table", GetVD) + runner.Title("Postconditions") runner.Step("Stop SDL", commonDefects.postconditions) From 9a420b010656921ea24e59a997d7d4c0952210b1 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 21 Dec 2017 12:54:48 +0200 Subject: [PATCH 228/681] Stabilize script for 1892 issue --- ...rom_SDL_after_receiving_HB_from_mobile.lua | 125 ++++++++---------- 1 file changed, 54 insertions(+), 71 deletions(-) diff --git a/test_scripts/Defects/4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua b/test_scripts/Defects/4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua index 327e1b8ad3..641042605b 100644 --- a/test_scripts/Defects/4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua +++ b/test_scripts/Defects/4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua @@ -45,6 +45,36 @@ local function RestoreIniFile() commonPreconditions:RestoreFile("smartDeviceLink.ini") end +--! @HBFromSDLEvent: Expectation of HB message from SDL +--! @parameters:none +--! @return: expecation +local function HBFromSDLMsg(self) + local event = events.Event() + event.matches = + function(_, data) + return data.frameType == 0 and + data.serviceType == 0 and + data.sessionId == self.mobileSession1.sessionId and + data.frameInfo == 0 + end + return self.mobileSession1:ExpectEvent(event, "HB") +end + +--! @HBFromSDLEvent: Expectation of HB ACK message from SDL +--! @parameters:none +--! @return: expecation +local function HBACKFromSDLMsg(self) + local event = events.Event() + event.matches = + function(_, data) + return data.frameType == 0 and + data.serviceType == 0 and + data.sessionId == self.mobileSession1.sessionId and + data.frameInfo == 255 + end + return self.mobileSession1:ExpectEvent(event, "HBACK") +end + --[[ Local Functions ]] --! @OpenConnectionCreateSession: Creation new session via 3 protocol without heart beat --! @parameters: @@ -55,9 +85,7 @@ local function OpenConnectionCreateSession(self) local tcpConnection = tcp.Connection(config.mobileHost, config.mobilePort) local fileConnection = file_connection.FileConnection("mobile.out", tcpConnection) self.mobileConnection = mobile.MobileConnection(fileConnection) - self.mobileSession1= mobile_session.MobileSession( - self, - self.mobileConnection) + self.mobileSession1= mobile_session.MobileSession(self, self.mobileConnection) event_dispatcher:AddConnection(self.mobileConnection) self.mobileSession1:ExpectEvent(events.connectedEvent, "Connection 1 started") self.mobileConnection:Connect() @@ -66,64 +94,36 @@ local function OpenConnectionCreateSession(self) self.mobileSession1.answerHeartbeatFromSDL = false self.mobileSession1.ignoreHeartBeatAck = false self.mobileSession1:StartService(7) + HBFromSDLMsg(self):Times(0) + commonDefects.delayedExp(10000) end --[[ Local Functions ]] ---! @RegisterAppInterface: Register application +--! @RegisterAppInterface: Register application, do not expect app unregister due to heartbeat time out +--! do not expect HB from SDL --! @parameters: --! self - test object --! @return: none local function RegisterAppInterface(self) + -- define default application parameters + local appParams = config.application1.registerAppInterfaceParams -- Send RegisterAppInterface request from mobile app - local CorIdRegister = self.mobileSession1:SendRPC("RegisterAppInterface", { - syncMsgVersion ={ - majorVersion = 4, - minorVersion = 3 - }, - appName = config.application1.registerAppInterfaceParams.appName, - isMediaApplication = true, - languageDesired = 'EN-US', - hmiDisplayLanguageDesired = 'EN-US', - appHMIType = { "DEFAULT" }, - appID = config.application1.registerAppInterfaceParams.appID - }) + local CorIdRegister = self.mobileSession1:SendRPC("RegisterAppInterface", appParams) -- Expect OnAppRegistered notification on HMI side - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", - { application = {appName = config.application1.registerAppInterfaceParams.appName }}) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = appParams.appName }}) -- Expect successful RegisterAppInterface response on mobile app self.mobileSession1:ExpectResponse(CorIdRegister, { success = true, resultCode = "SUCCESS" }) -- Expect OnHMIStatus notification on mobile side self.mobileSession1:ExpectNotification("OnHMIStatus", { systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE" }) -end - ---[[ Local Functions ]] ---! @ExpectationAfterAppRegistration: Expect absence of HB from SDL ---! @parameters: ---! self - test object ---! @return: none -local function ExpectationAfterAppRegistration(self) - -- Get HMI id of first application - local hmiAppId = commonDefects.getHMIAppId(1) -- Does not expect OnAppUnregistered notification on HMI side, times 0 - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", - {unexpectedDisconnect = true, appID = hmiAppId}) - :Times(0) - commonFunctions:userPrint (33,"Log: AppSession started, HB disabled") - commonFunctions:userPrint (33, "Log: App v.3 disconnection not expected since no HB ACK and timer" .. - "should be started by SDL till the HB request from app first") + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered"):Times(0) + commonFunctions:userPrint(33,"AppSession started, HB disabled") + commonFunctions:userPrint(33, "App v.3 disconnection not expected since no HB ACK and timer" + .. "should be started by SDL till the HB request from app first") -- Does not expect HB from SDL, times 0 - local HBEvent = events.Event() - HBEvent.matches = - function(_, data) - return data.frameType == 0 and - data.serviceType == 0 and - (data.sessionId == self.mobileSession1.sessionId) and - data.frameInfo == 0 - end - self.mobileSession1:ExpectEvent(HBEvent, "HB") - :Times(0) - commonDefects.delayedExp(10000) + HBFromSDLMsg(self):Times(0) + commonDefects.delayedExp(15000) end --[[ Local Functions ]] @@ -132,32 +132,16 @@ end --! self - test object --! @return: none local function sendHBFromMobileAndReceivingFromSDL(self) - local HBEvent = events.Event() - HBEvent.matches = - function(_, data) - return data.frameType == 0 and - data.serviceType == 0 and - (data.sessionId == self.mobileSession1.sessionId) and - data.frameInfo == 0 - end - local HBACKEvent = events.Event() - HBACKEvent.matches = - function(_, data) - return data.frameType == 0 and - data.serviceType == 0 and - (data.sessionId == self.mobileSession1.sessionId) and - data.frameInfo == 255 - end -- Send HB from mobile app to SDL self.mobileSession1:Send({ frameType = constants.FRAME_TYPE.CONTROL_FRAME, serviceType = constants.SERVICE_TYPE.CONTROL, frameInfo = constants.FRAME_INFO.HEARTBEAT }) - -- Expect HB on mobile app from SDL - self.mobileSession1:ExpectEvent(HBEvent, "HB") + -- Expect HB from SDL on mobile app + HBFromSDLMsg(self) -- Expect HB ACK from SDL on mobile app - self.mobileSession1:ExpectEvent(HBACKEvent, "HB") + HBACKFromSDLMsg(self) end --[[ Local Functions ]] @@ -165,14 +149,14 @@ end --! @parameters: none --! @return: none local function DisconnectDueToHeartbeat() - -- Get HMI id for registered app - local hmiAppId = commonDefects.getHMIAppId(1) -- Expect OnAppUnregistered notification on HMI side from SDL - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {unexpectedDisconnect = true, appID = hmiAppId}) - commonDefects.delayedExp() + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { + unexpectedDisconnect = true, appID = commonDefects.getHMIAppId(1) + }) commonFunctions:userPrint(33, "AppSession started, HB enabled") - commonFunctions:userPrint(33, "In DisconnectDueToHeartbeat TC disconnection is expected because HB process started" .. - "by SDL after app's HB request") + commonFunctions:userPrint(33, "In DisconnectDueToHeartbeat TC disconnection is expected because HB process started" + .. "by SDL after app's HB request") + commonDefects.delayedExp(10000) end --[[ Scenario ]] @@ -184,7 +168,6 @@ runner.Step("Start SDL, HMI", commonDefects.startWithoutMobile) runner.Title("Test") runner.Step("OpenConnectionCreateSession", OpenConnectionCreateSession) runner.Step("RegisterApp", RegisterAppInterface) -runner.Step("ExpectationAfterAppRegistration", ExpectationAfterAppRegistration) runner.Step("SendHBFromMobileAndExpectationHBFromSDL", sendHBFromMobileAndReceivingFromSDL) runner.Step("DisconnectDueToHeartbeat", DisconnectDueToHeartbeat) From 08cfe60d9d5693f2631f97a71ef2b2f81a4a2eca Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 21 Dec 2017 12:59:55 +0200 Subject: [PATCH 229/681] Add some comments to script --- .../4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test_scripts/Defects/4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua b/test_scripts/Defects/4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua index 641042605b..520aa7c5ac 100644 --- a/test_scripts/Defects/4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua +++ b/test_scripts/Defects/4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua @@ -1,4 +1,5 @@ --------------------------------------------------------------------------------------------------- +-- Script verifies issue https://github.com/smartdevicelink/sdl_core/issues/1892 -- Description -- SDL must start heartbeat only after first Heartbeat request from mobile app -- Preconditions @@ -94,6 +95,7 @@ local function OpenConnectionCreateSession(self) self.mobileSession1.answerHeartbeatFromSDL = false self.mobileSession1.ignoreHeartBeatAck = false self.mobileSession1:StartService(7) + -- Does not expect HB from SDL, times 0 HBFromSDLMsg(self):Times(0) commonDefects.delayedExp(10000) end From 543170ba069bdf7f08f290b69dc9bb4b92fa85d1 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 21 Dec 2017 14:58:13 +0200 Subject: [PATCH 230/681] Add Heartbeat settings --- ...F_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test_scripts/Defects/4_5/1893_ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua b/test_scripts/Defects/4_5/1893_ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua index 05547dc3b9..ff30650935 100644 --- a/test_scripts/Defects/4_5/1893_ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua +++ b/test_scripts/Defects/4_5/1893_ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua @@ -153,6 +153,11 @@ end local function Verify_That_New_Session_can_be_created(self) -- create mobile session mobileSession[3] = mobile_session.MobileSession(self, self.mobileConnection) + -- set heartbeat options + mobileSession[3].activateHeartbeat = false + mobileSession[3].sendHeartbeatToSDL = false + mobileSession[3].answerHeartbeatFromSDL = false + mobileSession[3].ignoreSDLHeartBeatACK = false -- start RPC service mobileSession[3]:StartRPC() end From 2076d2376632a9c8ec8382e916992e2af08a86b6 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 21 Dec 2017 16:47:45 +0200 Subject: [PATCH 231/681] Fix test scripts related to Heartbeat due to corresponding changes in ATF --- ...F_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua | 4 +++- .../ATF_HeartBeat_App_does_not_send_HB_but_respond.lua | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua index 6ba37d729d..341370e38a 100644 --- a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua +++ b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua @@ -67,6 +67,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:Start_Session_And_Register_App() self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) + self.mobileSession.activateHeartbeat = false self.mobileSession.sendHeartbeatToSDL = false self.mobileSession.answerHeartbeatFromSDL = false self.mobileSession.ignoreSDLHeartBeatACK = false @@ -84,6 +85,7 @@ end function Test:Register_Second_App_With_HeartBeat() self.mobileSession1 = mobile_session.MobileSession(self, self.mobileConnection) + self.mobileSession1.activateHeartbeat = true self.mobileSession1.sendHeartbeatToSDL = true self.mobileSession1.answerHeartbeatFromSDL = true self.mobileSession1.ignoreSDLHeartBeatACK = false @@ -115,4 +117,4 @@ function Test.Stop_SDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_but_respond.lua b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_but_respond.lua index 5223012591..ade96f4b4c 100644 --- a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_but_respond.lua +++ b/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_but_respond.lua @@ -66,9 +66,10 @@ commonFunctions:newTestCasesGroup("Test") function Test:Start_Session_And_Register_App() self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) + self.mobileSession.activateHeartbeat = true self.mobileSession.sendHeartbeatToSDL = false self.mobileSession.answerHeartbeatFromSDL = true - self.mobileSession.ignoreSDLHeartBeatACK = false + self.mobileSession.ignoreSDLHeartBeatACK = true self.mobileSession:StartRPC():Do(function() local correlation_id = self.mobileSession:SendRPC("RegisterAppInterface", default_app_params) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", @@ -98,4 +99,4 @@ function Test.Stop_SDL() StopSDL() end -return Test \ No newline at end of file +return Test From 4e29570511da781651ee20a33ccf0176f20e0210 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 21 Dec 2017 16:51:59 +0200 Subject: [PATCH 232/681] Fix test script due to issue 1893 --- .../ATF_Resumption_heartbeat_disconnect.lua | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua index b3784329a2..daf4855677 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua @@ -42,6 +42,17 @@ local function connectMobile(self) return EXPECT_EVENT(events.connectedEvent, "Connected") end +local function delayedExp(pTime, self) + local event = events.Event() + event.matches = function(e1, e2) return e1 == e2 end + EXPECT_HMIEVENT(event, "Delayed event") + :Timeout(pTime + 5000) + local function toRun() + event_dispatcher:RaiseEvent(self.hmiConnection, event) + end + RUN_AFTER(toRun, pTime) +end + --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") commonSteps:DeletePolicyTable() @@ -88,14 +99,8 @@ function Test:Wait_20_sec() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {appID = self.applications[default_app_params], unexpectedDisconnect = true }) :Timeout(20000) EXPECT_EVENT(events.disconnectedEvent, "Disconnected") - :Do(function() - print("Disconnected!!!") - end) - :Timeout(20000) -end - -function Test:Connect_Mobile() - connectMobile(self) + :Times(0) + delayedExp(20000, self) end function Test:Register_And_Resume_App_And_Data() @@ -114,4 +119,4 @@ function Test.Stop_SDL() StopSDL() end -return Test \ No newline at end of file +return Test From b33cd1ca7b989108c952bfbc9a612de0b7809544 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 22 Dec 2017 10:53:22 +0200 Subject: [PATCH 233/681] Revert of 'Remove turnText item' fix since it's applicable for Send Location only --- test_scripts/smoke_api.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test_scripts/smoke_api.lua b/test_scripts/smoke_api.lua index c6af915f6a..a03e98210b 100644 --- a/test_scripts/smoke_api.lua +++ b/test_scripts/smoke_api.lua @@ -2771,6 +2771,12 @@ local function displayCap_textFields_Value() rows = 1, width = 500 }, + { + characterSet = "TYPE2SET", + name = "turnText", + rows = 1, + width = 500 + }, { characterSet = "TYPE2SET", name = "menuTitle", @@ -3446,7 +3452,7 @@ local function setExTurnList(size) navigationText = { fieldText = "Text", - fieldName = "navigationText" + fieldName = "turnText" }, turnIcon = { @@ -3463,7 +3469,7 @@ local function setExTurnList(size) navigationText = { fieldText = "Text"..i, - fieldName = "navigationText" + fieldName = "turnText" }, turnIcon = { From 3a9a9a3bb7a462b34ace67bfba04e9878db65fe9 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 5 Dec 2017 17:11:15 +0200 Subject: [PATCH 234/681] Initial version of the scripts --- files/Security/client_credential.pem | 95 ++++ .../Trigger_PTU_NO_Certificate/001.lua | 87 ++++ .../Trigger_PTU_NO_Certificate/common.lua | 448 ++++++++++++++++++ user_modules/script_runner.lua | 2 +- .../shared_testcases/commonFunctions.lua | 2 + .../shared_testcases/commonTestCases.lua | 4 +- 6 files changed, 635 insertions(+), 3 deletions(-) create mode 100644 files/Security/client_credential.pem create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/001.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua diff --git a/files/Security/client_credential.pem b/files/Security/client_credential.pem new file mode 100644 index 0000000000..fa9f61e1ed --- /dev/null +++ b/files/Security/client_credential.pem @@ -0,0 +1,95 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAuUkj2daWe5+y6awVQ/xmM6TYvS/a41Nx1QS8UHnzrO1TO4Zy +e+9tvf+UNf6Py9v+dBPJHcxPo8aa9i1XleSp46//0L+x3r2r1GeNUXC2w8nx00np +gFZugOx1J3rEbwu1LmNjg9ejL/FUiW/SgpNcec8kT1qWVqe8BQIV5n6ECglnHeCI +vKG217fczzPRtuHmKS+zEZohI0rIp15mznm2mOnZzwoGJvU1WVahwiP7WCgISpU7 +1azOilahNuosQ3f0MJYo3UhYXWOGxkxkjr5qg3O3Ln+DUm+9RxV5Bj8vS+WG04fF +sI14z+xZnHOxBv4/gOLFDU3Elsb5Vsot/Ef2FQIDAQABAoIBACSr6C+WPCRtoDCF +gZP6IZQ5HTicfxsdCduaW1cmO+dO9XlDi+chpTvEmOXy4yz69qqsu9Js/JoylbsB +kGM3ZbSNwfjj5+Vo7thUQnEK+PFZR8aEy3U+JhLYOfu9XaGI1KxAuZJ/nGnBvvSQ +sD5twhDNwab/C+BMxHbNSd5bzfBaQ9reN/RyQIqYRzhFYFl4Jy0k4S4Cr7ssCEpR +SyhXYOuIj++6lcQh30PEso+/seYBTZfujP+YVSsRd7zEzBJV/KOBtaLlDQqsSzlr +KWv8yGwd4rMrJK0CTQsbWP10/fEfCjzBY4Apvv3LnK0pD5JPpMhRvawh3R4ngFeq +EmDKJwECgYEA2zl17/73XSojMP0v4YWZgV1gDmXaLibq9B674+4SUrwTIGN9fFqo +HB83vJle5yT6bekzPtt0vvO7CE/f55Ac1ruLcnLMzZTmki5Ttj9jfHHnh/l8QlkT +lqqxC+75GlKCuWQhCjc7bdr2DqA7YCPqsrd89muab4tISa+KhEKQEEECgYEA2F4w +KS2Q/UaKeJ0NEF2j4O6Lw3tCoOe8G7IwITp4TIk5494CaePVghzub5nQg2FvphRU +SuTCUY8YbvVHeVCnQiMmH55Q/ekgGRd//xFwMphXNzgOIbBgHeYtwSvrFu0C+bo/ +tWJcvKHmUSCyqrMh75ZojPiq/6AtGydjdr/OcNUCgYEAho0d9c9nw6a5MrgzSxfU +v7Gv4yZgYzM/wdWbPKpCVMVad+aYflqmE5yVeQwpU3U+v3cCHPJVFV5CzTc5Fcc9 +7A3v6K7NROC/I7mLZ7BAP4EpuitGOPKzMyZQxCJIgf9ifKcYIE0GDMb3fsKZrshc +pJQ5/oTMpOm31IIJYmP4SAECgYBC2D56ykgL53oqLyL1FmjluezV9MOt4En+KHu0 +GFNIGfEXk+QdALVaoEONmPCRVk3e+lLcXHYoKlQ7G238bc1uoltJ02hkOVygQ+FY +VPPbvbLcLWY4RDw9oHosPrw/dfPAYSkDiaLq5/22vKpWEEeAtHASdVSm6r5ksDOL +YVCPDQKBgQC2hsExoYn6JPQIIN+2ZR6NE2OvomEYzozEAaC0VbY3hpS2+SY4+Nqy +uarADTr86karSA4OcffcIsA95heeo3NH1Fk9g7UtuHW/7kf2d6Ppj6E3+qBqRpy3 +RS2ltpna6N79NYTtRzgEtCCboMwom8JLr55PwOUoPBovlrY5/WVymA== +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDsjCCApoCCQCFzhX0lBkicDANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMC +VVMxETAPBgNVBAgMCE1pY2hpZ2FuMRAwDgYDVQQHDAdEZXRyb2l0MRQwEgYDVQQK +DAtGT1JEX0NMSUVOVDEYMBYGA1UECwwPRk9SRF9TRExfQ0xJRU5UMRQwEgYDVQQD +DAtGT1JEX0NMSUVOVDEeMBwGCSqGSIb3DQEJARYPc2FtcGxlQGZvcmQuY29tMB4X +DTE3MTIwMTEzNDYzNloXDTQ1MDQxODEzNDYzNlowgZwxCzAJBgNVBAYTAlJVMQ8w +DQYDVQQIDAZSdXNzaWExFzAVBgNVBAcMDlN0LiBQZXRlcnNidXJnMQ8wDQYDVQQK +DAZMdXhvZnQxETAPBgNVBAsMCEhlYWRVbml0MQ8wDQYDVQQDDAZjbGllbnQxIDAe +BgkqhkiG9w0BCQEWEXNhbXBsZUBsdXhvZnQuY29tMQwwCgYDVQQFEwNTUFQwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5SSPZ1pZ7n7LprBVD/GYzpNi9 +L9rjU3HVBLxQefOs7VM7hnJ77229/5Q1/o/L2/50E8kdzE+jxpr2LVeV5Knjr//Q +v7HevavUZ41RcLbDyfHTSemAVm6A7HUnesRvC7UuY2OD16Mv8VSJb9KCk1x5zyRP +WpZWp7wFAhXmfoQKCWcd4Ii8obbXt9zPM9G24eYpL7MRmiEjSsinXmbOebaY6dnP +CgYm9TVZVqHCI/tYKAhKlTvVrM6KVqE26ixDd/QwlijdSFhdY4bGTGSOvmqDc7cu +f4NSb71HFXkGPy9L5YbTh8WwjXjP7Fmcc7EG/j+A4sUNTcSWxvlWyi38R/YVAgMB +AAEwDQYJKoZIhvcNAQELBQADggEBAHinD+7dbcMf41W5gwxn45x9RbWkkwuF0JBc +DYcfQ1uRQkYRfohcsoouvfYfB+cDBVuaj8+o7UeLiUixcsthPl/PhG//qbTqvQpL +E09pRyveiQSdvuKRv6wifFfZ2COAL/hXksfJJJTzxWU/8lk8/T2DMWmroeixGxCu +t/v/kgNtOrD74NNlkJkN+bQB23I3vU2rXTVVoNl4b01qkcux4VuV6ypGKDJXhFPy +4EIdZJ44MoHHFaJHJhmq1I6oFNKMghRpvyjhSHuZyE05AV0IkuUPeLHiyfOWRMHT +y9sJVx5iAoL145dCiT07h4j2n+JZS5kTlZqggov+iemTI+Xnp/8= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIJAITI5lAQ6iOFMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEXMBUGA1UEBwwOU2lsaWNvbiBW +YWxsZXkxEzARBgNVBAoMCkNBY2VydC5vcmcxDzANBgNVBAsMBkNBY2VydDEUMBIG +A1UEAwwLc2VydmVyX3Jvb3QxIDAeBgkqhkiG9w0BCQEWEXNhbXBsZUBjYWNlcnQu +b3JnMB4XDTE3MTIwMTEzNDYzNloXDTQ1MDQxODEzNDYzNlowgZkxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRcwFQYDVQQHDA5TaWxpY29uIFZhbGxl +eTETMBEGA1UECgwKQ0FjZXJ0Lm9yZzEPMA0GA1UECwwGQ0FjZXJ0MRQwEgYDVQQD +DAtzZXJ2ZXJfcm9vdDEgMB4GCSqGSIb3DQEJARYRc2FtcGxlQGNhY2VydC5vcmcw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAmyE96hjM8RbFpV3ISy6K +ACXcq3CSS4JjiBMlIbwNydE2rd6aznEdSo1Usi44dhl47tw6H3YetD1d3BbQiIZV +brH8RyAPWNlFhpv6LiVSbsigXp4aGnS876zE3urDz0ov/SqWpBSNNcflqaak+TH1 +VWJnkZyWcEv27laI2HSFvhcxsXOw+BKbkBu7WpnTybHMQGBHQNLhP3sKdcJUPzZa +9Fc3UbITMpq3p92J155BEVtuEGVti3osKe4Rr2UB8D8hQLUQ4tYH4yx1dZHdfSRJ +fUY6l42rupCW/VRGtY7fF/ZH6AlBZbA5dYFVC2y0PUIAgPnGJ6/wprpeJtZDXyUD +AgMBAAGjUDBOMB0GA1UdDgQWBBQz72vddo+HSnyy/vAW5b6O4x3PyjAfBgNVHSME +GDAWgBQz72vddo+HSnyy/vAW5b6O4x3PyjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQA3nZjVmizW85OPK9PoAMQYb6t8PFmTY+UTl4G20AKvMIkxv4rk +5CF4JOqCYvv7bzsLKOsHI/rbYTTmJFQuUXNjPBysPX/lT+mBK2o6k7TanCw7IgIb +1mV3LzCV1vY3K8DpaeTabK/HcCbgLIqVvULyo1HsWzpdOtcCaWt5Ssz4/ZqP3eaR +N6j3V4YeTvKZPx9oxcgIaNY6eLCt0c0mlx5XHAHoeaF1MXLgjIkITPOUSZNUB04G +OD9UhOZVMpHWTSpsVZryWiUpZiLz301RXGti7FbrC/9yHF5UycJ3SfCheBxy4Pqa +Zt0ck3RykZ+v3GwSY+39Oo3mBbLNiB+9668W +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDqDCCApACCQC/Ty1f/qRtejANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMC +VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFzAVBgNVBAcMDlNpbGljb24gVmFsbGV5 +MRMwEQYDVQQKDApDQWNlcnQub3JnMQ8wDQYDVQQLDAZDQWNlcnQxFDASBgNVBAMM +C3NlcnZlcl9yb290MSAwHgYJKoZIhvcNAQkBFhFzYW1wbGVAY2FjZXJ0Lm9yZzAe +Fw0xNzEyMDExMzQ2MzZaFw00NTA0MTgxMzQ2MzZaMIGRMQswCQYDVQQGEwJVUzER +MA8GA1UECAwITWljaGlnYW4xEDAOBgNVBAcMB0RldHJvaXQxFDASBgNVBAoMC0ZP +UkRfU0VSVkVSMRgwFgYDVQQLDA9GT1JEX1NETF9TRVJWRVIxDTALBgNVBAMMBEZP +UkQxHjAcBgkqhkiG9w0BCQEWD3NhbXBsZUBmb3JkLmNvbTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAMcLS+D5+pJ9dM9K3gifVsUXwSC3YT3kj4M26rqk +8IRJNB/zBbwjOVhG5f0wrm+JFn3TETB8QTet4seKWCHBGy3lXeKHPNZeXee/RLUf +BDWtytEaYvAuS0VQkktYlR2GDd28TmwK8ALyeZ8qyk6+MyddSYrkwNfISIcxIjwB +0sNPNskYXQXwjOB1rkaWTUM+0Y8RDyVjNmef9X8ZfQpP0o9K+feEoE+GL8Gw0dTr +D3S8exfB9STLuNNxn2KNKXT7G+YAqTrRwNZATfwII6EZv3GQVNS9DVGM3UyG9Gyg +tAYIEZJpll+HPqAaZ0Sm1mTC4uDYrSgLy+HdkiYyj1HaJCkCAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEAk9L6Njo8nNt9rSgqUyD1fcT7w+BRQ48Kjk20nl/865uLlI16 +eLV9v/Fy2ojyewhhGwesL6oQOzVn4uQ8w2Yn6F7YGM8KOzI4fkCm9uJHIS0DaSY9 +BwwIg75rUtFhifTFCyD+onuBbFN1JHG7hMC1KHEoWNYfIL2J5JudvwnyODnLqbLF +Ox0GBk0lsYMMaiDmEReZLayzGGMoF4zNAmKXHQTuAbseNhlaKuzK3KkttX9S5Dge +qHpnAvu8dt0Y9Qnc3cRBVpOeifyyVVJd5YBX4MHl7SWOgR7AVdQw8DBqvIbSXrAd ++B7gbCcDklgOacyCfNcQuNvcxbEjU20ATt38bg== +-----END CERTIFICATE----- diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/001.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/001.lua new file mode 100644 index 0000000000..81b95aa0ef --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/001.lua @@ -0,0 +1,87 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/9 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/button_press_emulation.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Button press event emulation +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) and sends valid ButtonPress RPC with valid parameters +-- SDL must: +-- 1) Transfer this request to HMI +-- 2) Respond with received from HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') +-- local commonFunctions = require("user_modules/shared_testcases/commonFunctions") + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { "NAVIGATION" } + +--[[ Local Variables ]] +local serviceId = 7 + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt +end + +local function startServiceSecured(pData) + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, pData) + + local handshakeOccurences = 0 + if pData.encryption == true then handshakeOccurences = 1 end + common.getMobileSession():ExpectHandshakeMessage() + :Times(handshakeOccurences) + + common.delayedExp() +end + +local function addCommandSecured() + local params = { + cmdID = 1, + menuParams = { + position = 1, + menuName = "Command_1" + } + } + local cid = common.getMobileSession():SendEncryptedRPC("AddCommand", params) + common.getHMIConnection():ExpectRequest("UI.AddCommand", params) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { }) + end) + common.getMobileSession():ExpectEncryptedResponse(cid, { success = true, resultCode = "SUCCESS" }) + common.getMobileSession():ExpectEncryptedNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) + +runner.Step("StartService Secured NACK", startServiceSecured, { { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false } }) + +runner.Step("PolicyTableUpdate with certificate", common.PolicyTableUpdate, { ptUpdate }) + +runner.Step("StartService Secured ACK", startServiceSecured, { { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true } }) + +runner.Step("AddCommand Secured", addCommandSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua new file mode 100644 index 0000000000..f1be8d1cc6 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua @@ -0,0 +1,448 @@ +--------------------------------------------------------------------------------------------------- +-- Navigation common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 +config.application1.registerAppInterfaceParams.appName = "server" +config.application1.registerAppInterfaceParams.appID = "SPT" + +--[[ Required Shared libraries ]] +local mobile_session = require("mobile_session") +local json = require("modules/json") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +local events = require("events") +local test = require("user_modules/dummy_connecttest") +local expectations = require('expectations') +local Expectation = expectations.Expectation +local constants = require('protocol_handler/ford_protocol_constants') +-- local util = require("atf.util") + +local m = {} + +--[[ Constants ]] +m.timeout = 2000 +m.minTimeout = 500 +m.appId1 = 1 +m.appId2 = 2 +m.frameInfo = constants.FRAME_INFO + +--[[ Variables ]] +local ptuTable = {} +local hmiAppIds = {} + +--[[ Functions ]] + +--[[ @getPTUFromPTS: create policy table update table (PTU) +--! @parameters: +--! pTbl - table with policy table snapshot (PTS) +--! @return: table with PTU +--]] +local function getPTUFromPTS(pTbl) + pTbl.policy_table.consumer_friendly_messages.messages = nil + pTbl.policy_table.device_data = nil + pTbl.policy_table.module_meta = nil + pTbl.policy_table.usage_and_error_counts = nil + pTbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + pTbl.policy_table.module_config.preloaded_pt = nil + pTbl.policy_table.module_config.preloaded_date = nil +end + +--[[ @jsonFileToTable: convert .json file to table +--! @parameters: +--! pFileName - file name +--! @return: table +--]] +local function jsonFileToTable(pFileName) + local f = io.open(pFileName, "r") + local content = f:read("*all") + f:close() + return json.decode(content) +end + +--[[ @tableToJsonFile: convert table to .json file +--! @parameters: +--! pTbl - table +--! pFileName - file name +--]] +local function tableToJsonFile(pTbl, pFileName) + local f = io.open(pFileName, "w") + f:write(json.encode(pTbl)) + f:close() +end + +--[[ @updatePTU: update PTU table with additional functional group for Navigation RPCs +--! @parameters: +--! pTbl - PTU table +--! pAppId - application number (1, 2, etc.) +--]] +local function updatePTU(pTbl, pAppId) + local appID = config["application" .. pAppId].registerAppInterfaceParams.appID + pTbl.policy_table.app_policies[appID] = { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + AppHMIType = { "NAVIGATION" }, + groups = { "Base-4", "Location-1" } + } +end + +--[[ @ptu: perform policy table update +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! pPTUpdateFunc - additional function for update +--]] +local function ptu(pPTUpdateFunc, pAppId) + if not pAppId then pAppId = 1 end + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" + .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + local ptu_file_name = os.tmpname() + local requestId = test.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) + EXPECT_HMIRESPONSE(requestId) + :Do(function() + test.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + { requestType = "PROPRIETARY", fileName = pts_file_name }) + getPTUFromPTS(ptuTable) + + updatePTU(ptuTable, pAppId) + + if pPTUpdateFunc then + pPTUpdateFunc(ptuTable) + end + + tableToJsonFile(ptuTable, ptu_file_name) + + local event = events.Event() + event.matches = function(e1, e2) return e1 == e2 end + EXPECT_EVENT(event, "PTU event") + + local function getAppsCount() + local count = 0 + for _ in pairs(hmiAppIds) do + count = count + 1 + end + return count + end + for id = 1, getAppsCount() do + local mobileSession = m.getMobileSession(id) + mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :Do(function() + print("App ".. id .. " was used for PTU") + RAISE_EVENT(event, event, "PTU event") + local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", + { requestType = "PROPRIETARY" }, ptu_file_name) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, d3) + test.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + test.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = d3.params.fileName }) + end) + mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + :Do(function() os.remove(ptu_file_name) end) + end) + :Times(AtMost(1)) + end + end) +end + +--[[ @allowSDL: sequence that allows SDL functionality +--! @parameters: +--]] +local function allowSDL() + test.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", + { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) +end + +local function registerStartSecureServiceFunc(pMobSession) + function pMobSession.mobile_session_impl.control_services:StartSecureService(pServiceId) + local msg = { + serviceType = pServiceId, + frameInfo = constants.FRAME_INFO.START_SERVICE, + sessionId = self.session.sessionId.get(), + encryption = true + } + self:Send(msg) + end + function pMobSession.mobile_session_impl:StartSecureService(pServiceId) + if not self.isSecuredSession then + self.security:registerSessionSecurity() + self.security:prepareToHandshake() + end + return self.control_services:StartSecureService(pServiceId) + end +end + +local function registerExpectServiceEventFunc(pMobSession) + function pMobSession.mobile_session_impl.control_services:ExpectControlMessage(pServiceId, pData) + local event = events.Event() + event.matches = function(_, data) + return data.frameType == constants.FRAME_TYPE.CONTROL_FRAME and + data.serviceType == pServiceId and + (pServiceId == constants.SERVICE_TYPE.RPC or data.sessionId == self.session.sessionId.get()) and + (data.frameInfo == constants.FRAME_INFO.START_SERVICE_ACK or + data.frameInfo == constants.FRAME_INFO.START_SERVICE_NACK) + end + local ret = self.session:ExpectEvent(event, "StartService") + :ValidIf(function(_, data) + if data.encryption ~= pData.encryption then + return false, "Expected 'encryption' flag is '" .. tostring(pData.encryption) + .. "', actual is '" .. tostring(data.encryption) .. "'" + end + return true + end) + :ValidIf(function(_, data) + if data.frameInfo ~= pData.frameInfo then + return false, "Expected 'frameInfo' is '" .. tostring(pData.frameInfo) + .. "', actual is '" .. tostring(data.frameInfo) .. "'" + end + return true + end) + return ret + end + function pMobSession.mobile_session_impl:ExpectControlMessage(pServiceId, pData) + local ret = self.control_services:ExpectControlMessage(pServiceId, pData) + :Do(function(exp) + if exp.status == expectations.FAILED then return end + self.security:registerSecureService(pServiceId) + end) + return ret + end + function pMobSession:ExpectControlMessage(pServiceId, pData) + return self.mobile_session_impl:ExpectControlMessage(pServiceId, pData) + end + function pMobSession.mobile_session_impl.control_services:ExpectHandshakeMessage() + -- if not self.session.isSecuredSession then + local handshakeEvent = events.Event() + local handShakeExp + handshakeEvent.matches = function(_,data) + return data.frameType ~= constants.FRAME_TYPE.CONTROL_FRAME + and data.serviceType == constants.SERVICE_TYPE.CONTROL + and data.sessionId == self.session.sessionId.get() + and data.rpcType == constants.BINARY_RPC_TYPE.NOTIFICATION + and data.rpcFunctionId == constants.BINARY_RPC_FUNCTION_ID.HANDSHAKE + end + handShakeExp = self.session:ExpectEvent(handshakeEvent, "Handshake internal") + :Do(function(_, data) + local binData = data.binaryData + local dataToSend = self.session.security:performHandshake(binData) + if dataToSend then + local handshakeMessage = { + frameInfo = 0, + serviceType = constants.SERVICE_TYPE.CONTROL, + encryption = false, + rpcType = constants.BINARY_RPC_TYPE.NOTIFICATION, + rpcFunctionId = constants.BINARY_RPC_FUNCTION_ID.HANDSHAKE, + rpcCorrelationId = data.rpcCorrelationId, + binaryData = dataToSend + } + self.session:Send(handshakeMessage) + end + -- if self.session.security:isHandshakeFinished() then + -- self.session.test:RemoveExpectation(handShakeExp) + -- end + end) + -- end + return handShakeExp + end + function pMobSession:ExpectHandshakeMessage(service) + local event = events.Event() + event.matches = function(e1, e2) return e1 == e2 end + local ret = pMobSession:ExpectEvent(event, "Handshake") + self.mobile_session_impl.control_services:ExpectHandshakeMessage(service) + :Do(function(e) + local isHandshakeFinished = self.mobile_session_impl.control_services.session.security:isHandshakeFinished() + -- print(e.occurences, isHandshakeFinished) + if isHandshakeFinished then + event_dispatcher:RaiseEvent(test.mobileConnection, event) + end + end) + :Times(AnyNumber()) + return ret + end +end + +--[[ @preconditions: precondition steps +--! @parameters: none +--]] +function m.preconditions() + commonFunctions:SDLForceStop() + commonSteps:DeletePolicyTable() + commonSteps:DeleteLogsFiles() +end + +--[[ @postconditions: postcondition steps +--! @parameters: none +--]] +function m.postconditions() + StopSDL() +end + +--[[ @activateApp: activate application +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--]] +function m.activateApp(pAppId) + if not pAppId then pAppId = 1 end + local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + local mobSession = m.getMobileSession(pAppId) + local requestId = test.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + EXPECT_HMIRESPONSE(requestId) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + commonTestCases:DelayedExp(m.minTimeout) +end + +--[[ @getHMIAppId: get HMI application identifier +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: application identifier +--]] +function m.getHMIAppId(pAppId) + if not pAppId then pAppId = 1 end + return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] +end + +--[[ @getMobileSession: get mobile session +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: mobile session +--]] +function m.getMobileSession(pAppId) + if not pAppId then pAppId = 1 end + local session + if not test["mobileSession" .. pAppId] then + session = mobile_session.MobileSession(test, test.mobileConnection) + test["mobileSession" .. pAppId] = session + registerStartSecureServiceFunc(session) + registerExpectServiceEventFunc(session) + else + session = test["mobileSession" .. pAppId] + end + return session +end + +--[[ @registerAppWithPTU: register mobile application and perform PTU +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--]] +function m.registerApp(pAppId) + if not pAppId then pAppId = 1 end + local mobSession = m.getMobileSession(pAppId) + mobSession:StartService(7) + :Do(function() + local corId = mobSession:SendRPC("RegisterAppInterface", + config["application" .. pAppId].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = d1.params.application.appID + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(2) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :Do(function(_, d2) + test.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptuTable = jsonFileToTable(d2.params.file) + end) + end) + mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + mobSession:ExpectNotification("OnPermissionsChange") + end) + end) +end + +function m.PolicyTableUpdate(pPTUpdateFunc, pAppId) + if not pAppId then pAppId = 1 end + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UP_TO_DATE" }) + -- m.getMobileSession(pAppId):ExpectNotification("OnPermissionsChange") -- SDL issue + ptu(pPTUpdateFunc, pAppId) +end + +--[[ @start: starting sequence: starting of SDL, initialization of HMI, connect mobile +--! @parameters: +--! pHMIParams - table with parameters for HMI initialization +--]] +function m.start(pHMIParams) + test:runSDL() + commonFunctions:waitForSDLStart(test) + :Do(function() + test:initHMI() + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + test:initHMI_onReady(pHMIParams) + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + test:connectMobile() + :Do(function() + commonFunctions:userPrint(35, "Mobile connected") + allowSDL(test) + end) + end) + end) + end) +end + +--[[ @DelayedExp: delay test step for default timeout +--! @parameters: none +--]] +function m.delayedExp() + commonTestCases:DelayedExp(m.timeout) +end + +function m.readFile(pPath) + local open = io.open + local file = open(pPath, "rb") + if not file then return nil end + local content = file:read "*a" + file:close() + return content +end + +function test.hmiConnection:ExpectRequest(methodName, ...) + local event = events.Event() + event.matches = function(_, data) + return data.method == methodName + end + local args = table.pack(...) + local ret = Expectation("HMI call " .. methodName, self) + if #args > 0 then + ret:ValidIf(function(e, data) + local arguments + if e.occurences > #args then + arguments = args[#args] + else + arguments = args[e.occurences] + end + return compareValues(arguments, data.params, "params") + end) + end + ret.event = event + event_dispatcher:AddEvent(self, event, ret) + test:AddExpectation(ret) + return ret +end + +function m.getHMIConnection() + return test.hmiConnection +end + +--[[ @protect: make table immutable +--! @parameters: +--! pTbl - mutable table +--! @return: immutable table +--]] +local function protect(pTbl) + local mt = { + __index = pTbl, + __newindex = function(_, k, v) + error("Attempting to change item " .. tostring(k) .. " to " .. tostring(v), 2) + end + } + return setmetatable({}, mt) +end + +return protect(m) diff --git a/user_modules/script_runner.lua b/user_modules/script_runner.lua index 19edd783ac..de09f61864 100644 --- a/user_modules/script_runner.lua +++ b/user_modules/script_runner.lua @@ -86,7 +86,7 @@ local function extendedAddTestStep(testStepName, testStepImplFunction, paramsTab table.insert(implFunctionsListWithParams, {implFunc = testStepImplFunction, params = paramsTable}) local newTestStepImplFunction = function(self) for _, func in pairs(implFunctionsListWithParams) do - table.insert(func.params, self) + -- table.insert(func.params, self) func.implFunc(unpack(func.params, 1, table.maxn(func.params))) end end diff --git a/user_modules/shared_testcases/commonFunctions.lua b/user_modules/shared_testcases/commonFunctions.lua index 5fa75964f6..c5262caff8 100644 --- a/user_modules/shared_testcases/commonFunctions.lua +++ b/user_modules/shared_testcases/commonFunctions.lua @@ -7,6 +7,8 @@ local commonFunctions = {} local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') require('atf.util') local json = require('json4lua/json/json') +local expectations = require('expectations') +local events = require('events') require('modules/config') local NewTestSuiteNumber = 0 -- use as subfix of test case "NewTestSuite" to make different test case name. diff --git a/user_modules/shared_testcases/commonTestCases.lua b/user_modules/shared_testcases/commonTestCases.lua index cac75f875c..20c61d34ab 100644 --- a/user_modules/shared_testcases/commonTestCases.lua +++ b/user_modules/shared_testcases/commonTestCases.lua @@ -9,7 +9,7 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local policyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local mobile_session = require('mobile_session') - +local events = require('events') @@ -278,4 +278,4 @@ function commonTestCases:verifyResultCode_TOO_MANY_PENDING_REQUESTS(numberOfRequ end -return commonTestCases \ No newline at end of file +return commonTestCases From 03b712be960b847bbb02704bf2bac75fca7dc831 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 7 Dec 2017 15:55:32 +0200 Subject: [PATCH 235/681] Add new scripts --- .../{001.lua => 1888_1_navi.lua} | 31 +++---- .../1888_2_non-navi.lua | 87 +++++++++++++++++++ .../1891_1_navi.lua | 51 +++++++++++ .../1891_2_non-navi.lua | 57 ++++++++++++ .../1894_1_navi.lua | 43 +++++++++ .../1894_2_non-navi.lua | 51 +++++++++++ .../1924_1_non-navi.lua | 45 ++++++++++ .../1924_2_navi.lua | 48 ++++++++++ .../1925_1_navi_no_cert_new_app.lua | 42 +++++++++ .../1925_2_navi_no_cert_existing_app.lua | 44 ++++++++++ .../1925_3_navi_cert_new_app.lua | 45 ++++++++++ .../1925_4_navi_cert_existing_app.lua | 49 +++++++++++ .../1925_5_non-navi_no_cert_existing_app.lua | 42 +++++++++ .../1925_6_non-navi_cert_existing_app.lua | 46 ++++++++++ .../1925_7_non-navi_cert_new_app.lua | 45 ++++++++++ .../1925_8_non-navi_cert_existing_app.lua | 49 +++++++++++ .../Trigger_PTU_NO_Certificate/common.lua | 84 ++++++++++++++---- 17 files changed, 821 insertions(+), 38 deletions(-) rename test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/{001.lua => 1888_1_navi.lua} (74%) create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_existing_app.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_cert_existing_app.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/001.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua similarity index 74% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/001.lua rename to test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua index 81b95aa0ef..b8a8d4ae05 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/001.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua @@ -1,35 +1,25 @@ --------------------------------------------------------------------------------------------------- --- User story: https://github.com/smartdevicelink/sdl_requirements/issues/9 --- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/button_press_emulation.md --- Item: Use Case 1: Main Flow --- --- Requirement summary: --- [SDL_RC] Button press event emulation --- --- Description: --- In case: --- 1) Application is registered with REMOTE_CONTROL appHMIType --- 2) and sends valid ButtonPress RPC with valid parameters --- SDL must: --- 1) Transfer this request to HMI --- 2) Respond with received from HMI +-- TBA --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --- local commonFunctions = require("user_modules/shared_testcases/commonFunctions") - ---[[ General configuration parameters ]] -config.application1.registerAppInterfaceParams.appHMIType = { "NAVIGATION" } --[[ Local Variables ]] local serviceId = 7 +local appHMIType = "NAVIGATION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appName = "server" +config.application1.registerAppInterfaceParams.appID = "SPT" +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) local filePath = "./files/Security/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end local function startServiceSecured(pData) @@ -44,7 +34,7 @@ local function startServiceSecured(pData) common.delayedExp() end -local function addCommandSecured() +local function sendRPCAddCommandSecured() local params = { cmdID = 1, menuParams = { @@ -64,6 +54,7 @@ end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") @@ -81,7 +72,7 @@ runner.Step("StartService Secured ACK", startServiceSecured, { { frameInfo = common.frameInfo.START_SERVICE_ACK, encryption = true } }) -runner.Step("AddCommand Secured", addCommandSecured) +runner.Step("AddCommand Secured", sendRPCAddCommandSecured) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua new file mode 100644 index 0000000000..655be805f4 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua @@ -0,0 +1,87 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 7 +local appHMIType = "DEFAULT" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appName = "server" +config.application1.registerAppInterfaceParams.appID = "SPT" +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function startServiceSecured(pData) + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, pData) + + local handshakeOccurences = 0 + local crt = nil + if pData.encryption == true then + handshakeOccurences = 1 + crt = common.readFile("./files/Security/client_credential.pem") + end + common.getMobileSession():ExpectHandshakeMessage() + :Times(handshakeOccurences) + + local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } + end + + local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + end + + common.PolicyTableUpdate(ptUpdate, expNotificationFunc) + common.delayedExp() +end + +local function sendRPCAddCommandSecured() + local params = { + cmdID = 1, + menuParams = { + position = 1, + menuName = "Command_1" + } + } + local cid = common.getMobileSession():SendEncryptedRPC("AddCommand", params) + common.getHMIConnection():ExpectRequest("UI.AddCommand", params) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { }) + end) + common.getMobileSession():ExpectEncryptedResponse(cid, { success = true, resultCode = "SUCCESS" }) + common.getMobileSession():ExpectEncryptedNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) + +runner.Step("StartService Secured, PTU wo cert, NACK, no Handshake", startServiceSecured, { { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }}) + +runner.Step("StartService Secured, PTU with cert, ACK, Handshake", startServiceSecured, { { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true + }}) + +runner.Step("AddCommand Secured", sendRPCAddCommandSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua new file mode 100644 index 0000000000..297b69f9a7 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua @@ -0,0 +1,51 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 7 +local appHMIType = "NAVIGATION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } + pTbl.policy_table.module_config.seconds_between_retries = nil +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + common.delayedExp() +end + +local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(4) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate fails", common.PolicyTableUpdate, { ptUpdate, expNotificationFunc }) +runner.Step("StartService Secured NACK, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua new file mode 100644 index 0000000000..ebc274f80d --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 7 +local appHMIType = "DEFAULT" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdateSuccess(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function ptUpdateUnssucess(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } + pTbl.policy_table.module_config.seconds_between_retries = nil +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + + local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(4) + end + + common.PolicyTableUpdate(ptUpdateUnssucess, expNotificationFunc) + common.delayedExp() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdateSuccess }) +runner.Step("StartService Secured, PTU started and fails, NACK, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua new file mode 100644 index 0000000000..f8dd63d8bb --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 7 +local appHMIType = "NAVIGATION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + common.delayedExp() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate without certificate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("StartService Secured NACK, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua new file mode 100644 index 0000000000..aab82b28cc --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua @@ -0,0 +1,51 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 7 +local appHMIType = "DEFAULT" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + + local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + end + + common.PolicyTableUpdate(ptUpdate, expNotificationFunc) + common.delayedExp() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate without certificate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("StartService Secured, PTU started, NACK, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua new file mode 100644 index 0000000000..fcc1f3d5c8 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 7 +local appHMIType = "DEFAULT" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { }) + :Times(0) + + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(2) + common.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") + + common.delayedExp() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate without certificate", common.PolicyTableUpdate, { ptUpdate }) + +runner.Title("Test") + +runner.Step("StartService Secured, PTU started, No ACK/NACK", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua new file mode 100644 index 0000000000..7f385be197 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 7 +local appHMIType = "NAVIGATION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(0) + common.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") + :Times(0) + + common.delayedExp() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate without certificate", common.PolicyTableUpdate, { ptUpdate }) + +runner.Title("Test") + +runner.Step("StartService Secured, PTU not started, NACK", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua new file mode 100644 index 0000000000..21c3d1ffa9 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua @@ -0,0 +1,42 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local appHMIType = { + [1] = "DEFAULT", + [2] = "NAVIGATION" +} + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType[1] } +config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } +end + +local function registerApp(pAppId) + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(2) + common.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") + common.registerAppWOPTU(pAppId) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register " .. appHMIType[1] .. " App", common.registerApp, { 1 }) +runner.Step("PTU 1 finished", common.PolicyTableUpdate, { ptUpdate }) + +runner.Title("Test") +runner.Step("Register " .. appHMIType[2] .. " App, PTU started", registerApp, { 2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua new file mode 100644 index 0000000000..7c4dfc78f0 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local appHMIType = { + [1] = "DEFAULT", + [2] = "NAVIGATION" +} + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType[1] } +config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } + common.updatePTU(pTbl, 2) + pTbl.policy_table.app_policies[common.getAppID(2)].AppHMIType = { appHMIType[2] } +end + +local function registerApp(pAppId) + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(2) + common.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") + common.registerAppWOPTU(pAppId) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register " .. appHMIType[1] .. " App", common.registerApp, { 1 }) +runner.Step("PTU 1 finished", common.PolicyTableUpdate, { ptUpdate }) + +runner.Title("Test") +runner.Step("Register " .. appHMIType[2] .. " App, PTU started", registerApp, { 2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua new file mode 100644 index 0000000000..fc4c3b519e --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local appHMIType = { + [1] = "DEFAULT", + [2] = "NAVIGATION" +} + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType[1] } +config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } + local filePath = "./files/Security/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt +end + +local function registerApp(pAppId) + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(2) + common.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") + common.registerAppWOPTU(pAppId) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register " .. appHMIType[1] .. " App", common.registerApp, { 1 }) +runner.Step("PTU 1 finished", common.PolicyTableUpdate, { ptUpdate }) + +runner.Title("Test") +runner.Step("Register " .. appHMIType[2] .. " App, PTU started", registerApp, { 2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua new file mode 100644 index 0000000000..a7d4edeb38 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local appHMIType = { + [1] = "DEFAULT", + [2] = "NAVIGATION" +} + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType[1] } +config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } + local filePath = "./files/Security/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + common.updatePTU(pTbl, 2) + pTbl.policy_table.app_policies[common.getAppID(2)].AppHMIType = { appHMIType[2] } +end + +local function registerApp(pAppId) + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(0) + common.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") + :Times(0) + common.registerAppWOPTU(pAppId) + common.delayedExp() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register " .. appHMIType[1] .. " App", common.registerApp, { 1 }) +runner.Step("PTU 1 finished", common.PolicyTableUpdate, { ptUpdate }) + +runner.Title("Test") +runner.Step("Register " .. appHMIType[2] .. " App, PTU not started", registerApp, { 2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_existing_app.lua new file mode 100644 index 0000000000..69ad2a25db --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_existing_app.lua @@ -0,0 +1,42 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local appHMIType = { + [1] = "DEFAULT", + [2] = "DEFAULT" +} + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType[1] } +config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } +end + +local function registerApp(pAppId) + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(2) + common.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") + common.registerAppWOPTU(pAppId) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register " .. appHMIType[1] .. " App", common.registerApp, { 1 }) +runner.Step("PTU 1 finished", common.PolicyTableUpdate, { ptUpdate }) + +runner.Title("Test") +runner.Step("Register " .. appHMIType[2] .. " App, PTU started", registerApp, { 2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_cert_existing_app.lua new file mode 100644 index 0000000000..3bb00a537f --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_cert_existing_app.lua @@ -0,0 +1,46 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local appHMIType = { + [1] = "DEFAULT", + [2] = "DEFAULT" +} + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType[1] } +config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } + common.updatePTU(pTbl, 2) + pTbl.policy_table.app_policies[common.getAppID(2)].AppHMIType = { appHMIType[2] } +end + +local function registerApp(pAppId) + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(0) + common.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") + :Times(0) + common.registerAppWOPTU(pAppId) + common.delayedExp() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register " .. appHMIType[1] .. " App", common.registerApp, { 1 }) +runner.Step("PTU 1 finished", common.PolicyTableUpdate, { ptUpdate }) + +runner.Title("Test") +runner.Step("Register " .. appHMIType[2] .. " App, PTU not started", registerApp, { 2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua new file mode 100644 index 0000000000..a0f68b2214 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local appHMIType = { + [1] = "DEFAULT", + [2] = "DEFAULT" +} + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType[1] } +config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } + local filePath = "./files/Security/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt +end + +local function registerApp(pAppId) + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(2) + common.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") + common.registerAppWOPTU(pAppId) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register " .. appHMIType[1] .. " App", common.registerApp, { 1 }) +runner.Step("PTU 1 finished", common.PolicyTableUpdate, { ptUpdate }) + +runner.Title("Test") +runner.Step("Register " .. appHMIType[2] .. " App, PTU started", registerApp, { 2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua new file mode 100644 index 0000000000..89c67c8709 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local appHMIType = { + [1] = "DEFAULT", + [2] = "DEFAULT" +} + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType[1] } +config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } + local filePath = "./files/Security/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + common.updatePTU(pTbl, 2) + pTbl.policy_table.app_policies[common.getAppID(2)].AppHMIType = { appHMIType[2] } +end + +local function registerApp(pAppId) + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(0) + common.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") + :Times(0) + common.registerAppWOPTU(pAppId) + common.delayedExp() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register " .. appHMIType[1] .. " App", common.registerApp, { 1 }) +runner.Step("PTU 1 finished", common.PolicyTableUpdate, { ptUpdate }) + +runner.Title("Test") +runner.Step("Register " .. appHMIType[2] .. " App, PTU not started", registerApp, { 2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua index f1be8d1cc6..716b836ffb 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua @@ -4,8 +4,6 @@ --[[ General configuration parameters ]] config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 -config.application1.registerAppInterfaceParams.appName = "server" -config.application1.registerAppInterfaceParams.appID = "SPT" --[[ Required Shared libraries ]] local mobile_session = require("mobile_session") @@ -78,14 +76,12 @@ end --! pTbl - PTU table --! pAppId - application number (1, 2, etc.) --]] -local function updatePTU(pTbl, pAppId) - local appID = config["application" .. pAppId].registerAppInterfaceParams.appID - pTbl.policy_table.app_policies[appID] = { +function m.updatePTU(pTbl, pAppId) + pTbl.policy_table.app_policies[m.getAppID(pAppId)] = { keep_context = false, steal_focus = false, priority = "NONE", default_hmi = "NONE", - AppHMIType = { "NAVIGATION" }, groups = { "Base-4", "Location-1" } } end @@ -107,7 +103,7 @@ local function ptu(pPTUpdateFunc, pAppId) { requestType = "PROPRIETARY", fileName = pts_file_name }) getPTUFromPTS(ptuTable) - updatePTU(ptuTable, pAppId) + m.updatePTU(ptuTable, pAppId) if pPTUpdateFunc then pPTUpdateFunc(ptuTable) @@ -263,6 +259,11 @@ local function registerExpectServiceEventFunc(pMobSession) end end +function m.getAppID(pAppId) + if not pAppId then pAppId = 1 end + return config["application" .. pAppId].registerAppInterfaceParams.appID +end + --[[ @preconditions: precondition steps --! @parameters: none --]] @@ -334,13 +335,13 @@ function m.registerApp(pAppId) :Do(function() local corId = mobSession:SendRPC("RegisterAppInterface", config["application" .. pAppId].registerAppInterfaceParams) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) :Do(function(_, d1) hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = d1.params.application.appID - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + test.hmiConnection:ExpectNotification("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) :Times(2) - EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + test.hmiConnection:ExpectRequest("BasicCommunication.PolicyUpdate") :Do(function(_, d2) test.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) ptuTable = jsonFileToTable(d2.params.file) @@ -355,9 +356,29 @@ function m.registerApp(pAppId) end) end -function m.PolicyTableUpdate(pPTUpdateFunc, pAppId) +function m.registerAppWOPTU(pAppId) + if not pAppId then pAppId = 1 end + local mobSession = m.getMobileSession(pAppId) + mobSession:StartService(7) + :Do(function() + local corId = mobSession:SendRPC("RegisterAppInterface", + config["application" .. pAppId].registerAppInterfaceParams) + test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) + mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + mobSession:ExpectNotification("OnPermissionsChange") + end) + end) +end + +function m.PolicyTableUpdate(pPTUpdateFunc, pExpNotificationFunc, pAppId) if not pAppId then pAppId = 1 end - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UP_TO_DATE" }) + if not pExpNotificationFunc then + test.hmiConnection:ExpectNotification("SDL.OnStatusUpdate", { status = "UP_TO_DATE" }) + end -- m.getMobileSession(pAppId):ExpectNotification("OnPermissionsChange") -- SDL issue ptu(pPTUpdateFunc, pAppId) end @@ -389,8 +410,9 @@ end --[[ @DelayedExp: delay test step for default timeout --! @parameters: none --]] -function m.delayedExp() - commonTestCases:DelayedExp(m.timeout) +function m.delayedExp(pTimeOut) + if not pTimeOut then pTimeOut = m.timeout end + commonTestCases:DelayedExp(pTimeOut) end function m.readFile(pPath) @@ -402,13 +424,33 @@ function m.readFile(pPath) return content end -function test.hmiConnection:ExpectRequest(methodName, ...) +function test.hmiConnection:ExpectRequest(name, ...) local event = events.Event() - event.matches = function(_, data) - return data.method == methodName + event.matches = function(_, data) return data.method == name end + local args = table.pack(...) + local ret = Expectation("HMI call " .. name, self) + if #args > 0 then + ret:ValidIf(function(e, data) + local arguments + if e.occurences > #args then + arguments = args[#args] + else + arguments = args[e.occurences] + end + return compareValues(arguments, data.params, "params") + end) end + ret.event = event + event_dispatcher:AddEvent(self, event, ret) + test:AddExpectation(ret) + return ret +end + +function test.hmiConnection:ExpectNotification(name, ...) + local event = events.Event() + event.matches = function(_, data) return data.method == name end local args = table.pack(...) - local ret = Expectation("HMI call " .. methodName, self) + local ret = Expectation("HMI notification " .. name, self) if #args > 0 then ret:ValidIf(function(e, data) local arguments @@ -417,6 +459,7 @@ function test.hmiConnection:ExpectRequest(methodName, ...) else arguments = args[e.occurences] end + test.notification_counter = test.notification_counter + 1 return compareValues(arguments, data.params, "params") end) end @@ -430,6 +473,11 @@ function m.getHMIConnection() return test.hmiConnection end +function m.setForceProtectedServiceParam(pParamValue) + local paramName = "ForceProtectedService" + commonFunctions:SetValuesInIniFile(paramName .. "%s-=%s-[%d,A-Z,a-z]-%s-\n", paramName, pParamValue) +end + --[[ @protect: make table immutable --! @parameters: --! pTbl - mutable table From 5ac5d3959d69897a4bd478dc4a78b00f0044898e Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 15 Dec 2017 13:46:12 +0200 Subject: [PATCH 236/681] Add parametrization for self in runner --- .../Trigger_PTU_NO_Certificate/1888_1_navi.lua | 1 + .../Trigger_PTU_NO_Certificate/1888_2_non-navi.lua | 1 + .../Trigger_PTU_NO_Certificate/1891_1_navi.lua | 1 + .../Trigger_PTU_NO_Certificate/1891_2_non-navi.lua | 1 + .../Trigger_PTU_NO_Certificate/1894_1_navi.lua | 1 + .../Trigger_PTU_NO_Certificate/1894_2_non-navi.lua | 1 + .../Trigger_PTU_NO_Certificate/1924_1_non-navi.lua | 1 + .../Trigger_PTU_NO_Certificate/1924_2_navi.lua | 1 + .../1925_1_navi_no_cert_new_app.lua | 1 + .../1925_2_navi_no_cert_existing_app.lua | 1 + .../1925_3_navi_cert_new_app.lua | 1 + .../1925_4_navi_cert_existing_app.lua | 1 + .../1925_5_non-navi_no_cert_existing_app.lua | 1 + .../1925_6_non-navi_cert_existing_app.lua | 1 + .../1925_7_non-navi_cert_new_app.lua | 1 + .../1925_8_non-navi_cert_existing_app.lua | 1 + .../Trigger_PTU_NO_Certificate/common.lua | 9 +++++++++ user_modules/script_runner.lua | 13 ++++++++++++- 18 files changed, 37 insertions(+), 1 deletion(-) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua index b8a8d4ae05..684740df8c 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua @@ -52,6 +52,7 @@ local function sendRPCAddCommandSecured() end --[[ Scenario ]] +runner.IncludeSelf(false) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua index 655be805f4..350bb911b9 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua @@ -61,6 +61,7 @@ local function sendRPCAddCommandSecured() end --[[ Scenario ]] +runner.IncludeSelf(false) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua index 297b69f9a7..24375905f1 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua @@ -37,6 +37,7 @@ local function expNotificationFunc() end --[[ Scenario ]] +runner.IncludeSelf(false) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua index ebc274f80d..0493af7890 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua @@ -43,6 +43,7 @@ local function startServiceSecured() end --[[ Scenario ]] +runner.IncludeSelf(false) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua index f8dd63d8bb..541d5fd3f5 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua @@ -29,6 +29,7 @@ local function startServiceSecured() end --[[ Scenario ]] +runner.IncludeSelf(false) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua index aab82b28cc..bf3c14a495 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua @@ -37,6 +37,7 @@ local function startServiceSecured() end --[[ Scenario ]] +runner.IncludeSelf(false) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua index fcc1f3d5c8..f1e8e2d10c 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua @@ -31,6 +31,7 @@ local function startServiceSecured() end --[[ Scenario ]] +runner.IncludeSelf(false) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua index 7f385be197..1e167c6c4c 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua @@ -34,6 +34,7 @@ local function startServiceSecured() end --[[ Scenario ]] +runner.IncludeSelf(false) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua index 21c3d1ffa9..ff2cd1a060 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua @@ -29,6 +29,7 @@ local function registerApp(pAppId) end --[[ Scenario ]] +runner.IncludeSelf(false) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua index 7c4dfc78f0..552964eeb2 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua @@ -31,6 +31,7 @@ local function registerApp(pAppId) end --[[ Scenario ]] +runner.IncludeSelf(false) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua index fc4c3b519e..c732ae905e 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua @@ -32,6 +32,7 @@ local function registerApp(pAppId) end --[[ Scenario ]] +runner.IncludeSelf(false) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua index a7d4edeb38..e440268d2e 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua @@ -36,6 +36,7 @@ local function registerApp(pAppId) end --[[ Scenario ]] +runner.IncludeSelf(false) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_existing_app.lua index 69ad2a25db..307567845c 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_existing_app.lua @@ -29,6 +29,7 @@ local function registerApp(pAppId) end --[[ Scenario ]] +runner.IncludeSelf(false) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_cert_existing_app.lua index 3bb00a537f..23efab5d4c 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_cert_existing_app.lua @@ -33,6 +33,7 @@ local function registerApp(pAppId) end --[[ Scenario ]] +runner.IncludeSelf(false) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua index a0f68b2214..d252ddc75d 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua @@ -32,6 +32,7 @@ local function registerApp(pAppId) end --[[ Scenario ]] +runner.IncludeSelf(false) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua index 89c67c8709..7b7e2e4a79 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua @@ -36,6 +36,7 @@ local function registerApp(pAppId) end --[[ Scenario ]] +runner.IncludeSelf(false) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua index 716b836ffb..6f378cbe5c 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua @@ -318,6 +318,12 @@ function m.getMobileSession(pAppId) test["mobileSession" .. pAppId] = session registerStartSecureServiceFunc(session) registerExpectServiceEventFunc(session) + if config.defaultProtocolVersion > 2 then + session.activateHeartbeat = true + session.sendHeartbeatToSDL = true + session.answerHeartbeatFromSDL = true + session.ignoreSDLHeartBeatACK = true + end else session = test["mobileSession" .. pAppId] end @@ -365,6 +371,9 @@ function m.registerAppWOPTU(pAppId) config["application" .. pAppId].registerAppInterfaceParams) test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = d1.params.application.appID + end) mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() mobSession:ExpectNotification("OnHMIStatus", diff --git a/user_modules/script_runner.lua b/user_modules/script_runner.lua index de09f61864..589bfa40cc 100644 --- a/user_modules/script_runner.lua +++ b/user_modules/script_runner.lua @@ -5,9 +5,11 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local isInitialStep = true local isPrintTitle = false +local isSelfIncluded = true local title local runner = {} + runner.testSettings = testSettings Test.isTest = true @@ -86,7 +88,9 @@ local function extendedAddTestStep(testStepName, testStepImplFunction, paramsTab table.insert(implFunctionsListWithParams, {implFunc = testStepImplFunction, params = paramsTable}) local newTestStepImplFunction = function(self) for _, func in pairs(implFunctionsListWithParams) do - -- table.insert(func.params, self) + if isSelfIncluded == true then + table.insert(func.params, self) + end func.implFunc(unpack(func.params, 1, table.maxn(func.params))) end end @@ -182,4 +186,11 @@ function runner.Step(testStepName, testStepImplFunction, paramsTable) end end +function runner.IncludeSelf(isIncluded) + if isIncluded == nil then return + elseif isIncluded == true then isSelfIncluded = true + elseif isIncluded == false then isSelfIncluded = false + end +end + return runner From dcd1b8b018b953faee2b6930e83d9675a70dc223 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 15 Dec 2017 16:42:24 +0200 Subject: [PATCH 237/681] Add new scripts --- .../1888_1_navi.lua | 2 +- .../1888_2_non-navi.lua | 2 +- .../1888_3_navi_audio_force_off.lua | 56 +++++++++++++++++ .../1888_4_navi_video_force_off.lua | 56 +++++++++++++++++ .../1888_5_navi_audio_force_on.lua | 56 +++++++++++++++++ .../1888_6_navi_video_force_on.lua | 56 +++++++++++++++++ .../1891_1_navi.lua | 2 +- .../1891_2_non-navi.lua | 2 +- .../1891_3_navi_audio.lua | 55 +++++++++++++++++ .../1891_4_navi_video.lua | 55 +++++++++++++++++ .../1891_5_non-navi_audio.lua | 60 +++++++++++++++++++ .../1891_6_non-navi_video.lua | 60 +++++++++++++++++++ .../1894_1_navi.lua | 3 +- .../1894_2_non-navi.lua | 3 +- .../1894_3_navi_audio.lua | 47 +++++++++++++++ .../1894_4_navi_video.lua | 47 +++++++++++++++ .../1894_5_non-navi_audio.lua | 54 +++++++++++++++++ .../1894_6_non-navi_video.lua | 54 +++++++++++++++++ .../1922_1_navi_audio.lua | 54 +++++++++++++++++ .../1922_2_navi_video.lua | 54 +++++++++++++++++ .../1922_3_non-navi_audio.lua | 56 +++++++++++++++++ .../1922_4_non-navi_video.lua | 56 +++++++++++++++++ .../1923_1_navi_audio.lua | 54 +++++++++++++++++ .../1923_2_navi_video.lua | 54 +++++++++++++++++ .../1923_3_non-navi_audio.lua | 60 +++++++++++++++++++ .../1923_4_non-navi_video.lua | 60 +++++++++++++++++++ .../1924_1_non-navi.lua | 2 +- .../1924_2_navi.lua | 2 +- .../1925_1_navi_no_cert_new_app.lua | 2 +- .../1925_2_navi_no_cert_existing_app.lua | 2 +- .../1925_3_navi_cert_new_app.lua | 2 +- .../1925_4_navi_cert_existing_app.lua | 2 +- .../1925_5_non-navi_no_cert_existing_app.lua | 2 +- .../1925_6_non-navi_cert_existing_app.lua | 2 +- .../1925_7_non-navi_cert_new_app.lua | 2 +- .../1925_8_non-navi_cert_existing_app.lua | 2 +- user_modules/script_runner.lua | 10 ++-- 37 files changed, 1128 insertions(+), 20 deletions(-) create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_5_non-navi_audio.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_6_non-navi_video.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_5_non-navi_audio.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_6_non-navi_video.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_3_non-navi_audio.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_4_non-navi_video.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_3_non-navi_audio.lua create mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_4_non-navi_video.lua diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua index 684740df8c..981479fde5 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua @@ -52,7 +52,7 @@ local function sendRPCAddCommandSecured() end --[[ Scenario ]] -runner.IncludeSelf(false) +runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua index 350bb911b9..f3c09e9cdb 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua @@ -61,7 +61,7 @@ local function sendRPCAddCommandSecured() end --[[ Scenario ]] -runner.IncludeSelf(false) +runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua new file mode 100644 index 0000000000..23b69c56cc --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 10 +local appHMIType = "NAVIGATION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appName = "server" +config.application1.registerAppInterfaceParams.appID = "SPT" +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured(pData) + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, pData) + + local handshakeOccurences = 0 + if pData.encryption == true then handshakeOccurences = 1 end + common.getMobileSession():ExpectHandshakeMessage() + :Times(handshakeOccurences) + + common.delayedExp() +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) + +runner.Step("PolicyTableUpdate with certificate", common.PolicyTableUpdate, { ptUpdate }) + +runner.Step("StartService Secured ACK", startServiceSecured, { { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true } }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua new file mode 100644 index 0000000000..56811f0294 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 11 +local appHMIType = "NAVIGATION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appName = "server" +config.application1.registerAppInterfaceParams.appID = "SPT" +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured(pData) + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, pData) + + local handshakeOccurences = 0 + if pData.encryption == true then handshakeOccurences = 1 end + common.getMobileSession():ExpectHandshakeMessage() + :Times(handshakeOccurences) + + common.delayedExp() +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) + +runner.Step("PolicyTableUpdate with certificate", common.PolicyTableUpdate, { ptUpdate }) + +runner.Step("StartService Secured ACK", startServiceSecured, { { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true } }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua new file mode 100644 index 0000000000..c603bb2205 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 10 +local appHMIType = "NAVIGATION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appName = "server" +config.application1.registerAppInterfaceParams.appID = "SPT" +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured(pData) + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, pData) + + local handshakeOccurences = 0 + if pData.encryption == true then handshakeOccurences = 1 end + common.getMobileSession():ExpectHandshakeMessage() + :Times(handshakeOccurences) + + common.delayedExp() +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0A" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) + +runner.Step("PolicyTableUpdate with certificate", common.PolicyTableUpdate, { ptUpdate }) + +runner.Step("StartService Secured ACK", startServiceSecured, { { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true } }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua new file mode 100644 index 0000000000..378aaae77d --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 11 +local appHMIType = "NAVIGATION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appName = "server" +config.application1.registerAppInterfaceParams.appID = "SPT" +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured(pData) + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, pData) + + local handshakeOccurences = 0 + if pData.encryption == true then handshakeOccurences = 1 end + common.getMobileSession():ExpectHandshakeMessage() + :Times(handshakeOccurences) + + common.delayedExp() +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0B" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) + +runner.Step("PolicyTableUpdate with certificate", common.PolicyTableUpdate, { ptUpdate }) + +runner.Step("StartService Secured ACK", startServiceSecured, { { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true } }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua index 24375905f1..c54cc5b100 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua @@ -37,7 +37,7 @@ local function expNotificationFunc() end --[[ Scenario ]] -runner.IncludeSelf(false) +runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua index 0493af7890..b2e6a9ee18 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua @@ -43,7 +43,7 @@ local function startServiceSecured() end --[[ Scenario ]] -runner.IncludeSelf(false) +runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua new file mode 100644 index 0000000000..4e7c2621ed --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 10 +local appHMIType = "NAVIGATION" + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } + pTbl.policy_table.module_config.seconds_between_retries = nil +end + +local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(4) +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = false + }) + + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + common.delayedExp() +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate fails", common.PolicyTableUpdate, { ptUpdate, expNotificationFunc }) +runner.Step("Activate App", common.activateApp) +runner.Step("StartService Secured ACK, no encryption, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua new file mode 100644 index 0000000000..4bed09b816 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 11 +local appHMIType = "NAVIGATION" + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } + pTbl.policy_table.module_config.seconds_between_retries = nil +end + +local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(4) +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = false + }) + + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + common.delayedExp() +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate fails", common.PolicyTableUpdate, { ptUpdate, expNotificationFunc }) +runner.Step("Activate App", common.activateApp) +runner.Step("StartService Secured ACK, no encryption, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_5_non-navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_5_non-navi_audio.lua new file mode 100644 index 0000000000..1a63788e7b --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_5_non-navi_audio.lua @@ -0,0 +1,60 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 10 +local appHMIType = "DEFAULT" + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdateSuccess(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + + local function ptUpdateUnssucess(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } + pTbl.policy_table.module_config.seconds_between_retries = nil + end + + local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(4) + end + + common.PolicyTableUpdate(ptUpdateUnssucess, expNotificationFunc) + common.delayedExp() +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdateSuccess }) +runner.Step("Activate App", common.activateApp) +runner.Step("StartService Secured, PTU started and fails, ACK, no encryption, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_6_non-navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_6_non-navi_video.lua new file mode 100644 index 0000000000..67d05fdd76 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_6_non-navi_video.lua @@ -0,0 +1,60 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 11 +local appHMIType = "DEFAULT" + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdateSuccess(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + + local function ptUpdateUnssucess(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } + pTbl.policy_table.module_config.seconds_between_retries = nil + end + + local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(4) + end + + common.PolicyTableUpdate(ptUpdateUnssucess, expNotificationFunc) + common.delayedExp() +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdateSuccess }) +runner.Step("Activate App", common.activateApp) +runner.Step("StartService Secured, PTU started and fails, ACK, no encryption, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua index 541d5fd3f5..fbd6ce3be9 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua @@ -14,6 +14,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end @@ -29,7 +30,7 @@ local function startServiceSecured() end --[[ Scenario ]] -runner.IncludeSelf(false) +runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua index bf3c14a495..b94faba30d 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua @@ -14,6 +14,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end @@ -37,7 +38,7 @@ local function startServiceSecured() end --[[ Scenario ]] -runner.IncludeSelf(false) +runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua new file mode 100644 index 0000000000..e968533c1a --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua @@ -0,0 +1,47 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 10 +local appHMIType = "NAVIGATION" + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + common.delayedExp() +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate without certificate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) +runner.Step("StartService Secured ACK, no encryption, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua new file mode 100644 index 0000000000..fc3df8f613 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua @@ -0,0 +1,47 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 11 +local appHMIType = "NAVIGATION" + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + common.delayedExp() +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate without certificate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) +runner.Step("StartService Secured ACK, no encryption, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_5_non-navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_5_non-navi_audio.lua new file mode 100644 index 0000000000..62b84e90c1 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_5_non-navi_audio.lua @@ -0,0 +1,54 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 10 +local appHMIType = "DEFAULT" + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + + local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + end + + common.PolicyTableUpdate(ptUpdate, expNotificationFunc) + common.delayedExp() +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) +runner.Step("StartService Secured ACK, no encryption, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_6_non-navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_6_non-navi_video.lua new file mode 100644 index 0000000000..0598286c89 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_6_non-navi_video.lua @@ -0,0 +1,54 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 11 +local appHMIType = "DEFAULT" + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + + local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + end + + common.PolicyTableUpdate(ptUpdate, expNotificationFunc) + common.delayedExp() +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) +runner.Step("StartService Secured ACK, no encryption, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua new file mode 100644 index 0000000000..d6756301b8 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua @@ -0,0 +1,54 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 10 +local appHMIType = "NAVIGATION" + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + common.delayedExp() +end + +local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(4) +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0A" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate fails", common.PolicyTableUpdate, { ptUpdate, expNotificationFunc }) +runner.Step("Activate App", common.activateApp) +runner.Step("StartService Secured NACK, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua new file mode 100644 index 0000000000..2e3c9c4a45 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua @@ -0,0 +1,54 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 11 +local appHMIType = "NAVIGATION" + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + common.delayedExp() +end + +local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(4) +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0B" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate fails", common.PolicyTableUpdate, { ptUpdate, expNotificationFunc }) +runner.Step("Activate App", common.activateApp) +runner.Step("StartService Secured NACK, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_3_non-navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_3_non-navi_audio.lua new file mode 100644 index 0000000000..4c5a4dce3a --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_3_non-navi_audio.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 10 +local appHMIType = "DEFAULT" + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + + local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(4) + end + + common.PolicyTableUpdate(ptUpdate, expNotificationFunc) + common.delayedExp() +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0A" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) +runner.Step("StartService Secured, PTU started and fails, NACK, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_4_non-navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_4_non-navi_video.lua new file mode 100644 index 0000000000..4634dc7cec --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_4_non-navi_video.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 11 +local appHMIType = "DEFAULT" + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + + local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(4) + end + + common.PolicyTableUpdate(ptUpdate, expNotificationFunc) + common.delayedExp() +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0B" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) +runner.Step("StartService Secured, PTU started and fails, NACK, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua new file mode 100644 index 0000000000..c9f6d4b477 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua @@ -0,0 +1,54 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 10 +local appHMIType = "NAVIGATION" + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } + pTbl.policy_table.module_config.seconds_between_retries = nil +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + common.delayedExp() +end + +local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(4) +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0A" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate fails", common.PolicyTableUpdate, { ptUpdate, expNotificationFunc }) +runner.Step("Activate App", common.activateApp) +runner.Step("StartService Secured NACK, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua new file mode 100644 index 0000000000..6c4078b4d4 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua @@ -0,0 +1,54 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 11 +local appHMIType = "NAVIGATION" + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } + pTbl.policy_table.module_config.seconds_between_retries = nil +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + common.delayedExp() +end + +local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(4) +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0B" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate fails", common.PolicyTableUpdate, { ptUpdate, expNotificationFunc }) +runner.Step("Activate App", common.activateApp) +runner.Step("StartService Secured NACK, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_3_non-navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_3_non-navi_audio.lua new file mode 100644 index 0000000000..4175321240 --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_3_non-navi_audio.lua @@ -0,0 +1,60 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 10 +local appHMIType = "DEFAULT" + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdateSuccess(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + + local function ptUpdateUnssucess(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } + pTbl.policy_table.module_config.seconds_between_retries = nil + end + + local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(4) + end + + common.PolicyTableUpdate(ptUpdateUnssucess, expNotificationFunc) + common.delayedExp() +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0A" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdateSuccess }) +runner.Step("Activate App", common.activateApp) +runner.Step("StartService Secured, PTU started and fails, NACK, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_4_non-navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_4_non-navi_video.lua new file mode 100644 index 0000000000..6dbdee7b8f --- /dev/null +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_4_non-navi_video.lua @@ -0,0 +1,60 @@ +--------------------------------------------------------------------------------------------------- +-- TBA +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local runner = require('user_modules/script_runner') + +--[[ Local Variables ]] +local serviceId = 11 +local appHMIType = "DEFAULT" + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdateSuccess(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + +local function startServiceSecured() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + + local function ptUpdateUnssucess(pTbl) + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } + pTbl.policy_table.module_config.seconds_between_retries = nil + end + + local function expNotificationFunc() + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(4) + end + + common.PolicyTableUpdate(ptUpdateUnssucess, expNotificationFunc) + common.delayedExp() +end + +--[[ Scenario ]] +runner.SetParameters({ isSelfIncluded = false }) +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0B" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdateSuccess }) +runner.Step("Activate App", common.activateApp) +runner.Step("StartService Secured, PTU started and fails, NACK, no Handshake", startServiceSecured) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua index f1e8e2d10c..201c594d75 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua @@ -31,7 +31,7 @@ local function startServiceSecured() end --[[ Scenario ]] -runner.IncludeSelf(false) +runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua index 1e167c6c4c..b809055070 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua @@ -34,7 +34,7 @@ local function startServiceSecured() end --[[ Scenario ]] -runner.IncludeSelf(false) +runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua index ff2cd1a060..2a37caaa79 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua @@ -29,7 +29,7 @@ local function registerApp(pAppId) end --[[ Scenario ]] -runner.IncludeSelf(false) +runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua index 552964eeb2..037456ea9b 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua @@ -31,7 +31,7 @@ local function registerApp(pAppId) end --[[ Scenario ]] -runner.IncludeSelf(false) +runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua index c732ae905e..e4e9d13cd2 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua @@ -32,7 +32,7 @@ local function registerApp(pAppId) end --[[ Scenario ]] -runner.IncludeSelf(false) +runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua index e440268d2e..12744244dc 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua @@ -36,7 +36,7 @@ local function registerApp(pAppId) end --[[ Scenario ]] -runner.IncludeSelf(false) +runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_existing_app.lua index 307567845c..cac19e1aa2 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_existing_app.lua @@ -29,7 +29,7 @@ local function registerApp(pAppId) end --[[ Scenario ]] -runner.IncludeSelf(false) +runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_cert_existing_app.lua index 23efab5d4c..e815b88465 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_cert_existing_app.lua @@ -33,7 +33,7 @@ local function registerApp(pAppId) end --[[ Scenario ]] -runner.IncludeSelf(false) +runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua index d252ddc75d..c5c4b80505 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua @@ -32,7 +32,7 @@ local function registerApp(pAppId) end --[[ Scenario ]] -runner.IncludeSelf(false) +runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua index 7b7e2e4a79..080c632a61 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua @@ -36,7 +36,7 @@ local function registerApp(pAppId) end --[[ Scenario ]] -runner.IncludeSelf(false) +runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/user_modules/script_runner.lua b/user_modules/script_runner.lua index 589bfa40cc..43f3e7fc24 100644 --- a/user_modules/script_runner.lua +++ b/user_modules/script_runner.lua @@ -186,10 +186,12 @@ function runner.Step(testStepName, testStepImplFunction, paramsTable) end end -function runner.IncludeSelf(isIncluded) - if isIncluded == nil then return - elseif isIncluded == true then isSelfIncluded = true - elseif isIncluded == false then isSelfIncluded = false +function runner.SetParameters(paramsTable) + if paramsTable == nil or type(paramsTable) ~= "table" then return end + for k, v in pairs(paramsTable) do + if k == "isSelfIncluded" then + isSelfIncluded = v + end end end From c023e2c5d2a95d92f29489ed952db9881186a8b1 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 22 Dec 2017 16:02:53 +0200 Subject: [PATCH 238/681] Remove test scripts since AV services are forbidden for non-navi applications --- .../1891_5_non-navi_audio.lua | 60 ------------------- .../1891_6_non-navi_video.lua | 60 ------------------- .../1894_5_non-navi_audio.lua | 54 ----------------- .../1894_6_non-navi_video.lua | 54 ----------------- .../1922_3_non-navi_audio.lua | 56 ----------------- .../1922_4_non-navi_video.lua | 56 ----------------- .../1923_3_non-navi_audio.lua | 60 ------------------- .../1923_4_non-navi_video.lua | 60 ------------------- 8 files changed, 460 deletions(-) delete mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_5_non-navi_audio.lua delete mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_6_non-navi_video.lua delete mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_5_non-navi_audio.lua delete mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_6_non-navi_video.lua delete mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_3_non-navi_audio.lua delete mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_4_non-navi_video.lua delete mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_3_non-navi_audio.lua delete mode 100644 test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_4_non-navi_video.lua diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_5_non-navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_5_non-navi_audio.lua deleted file mode 100644 index 1a63788e7b..0000000000 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_5_non-navi_audio.lua +++ /dev/null @@ -1,60 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- TBA ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') -local runner = require('user_modules/script_runner') - ---[[ Local Variables ]] -local serviceId = 10 -local appHMIType = "DEFAULT" - ---[[ General configuration parameters ]] -config.defaultProtocolVersion = 3 -config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } - ---[[ Local Functions ]] -local function ptUpdateSuccess(pTbl) - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } -end - -local function startServiceSecured() - common.getMobileSession():StartSecureService(serviceId) - common.getMobileSession():ExpectControlMessage(serviceId, { - frameInfo = common.frameInfo.START_SERVICE_ACK, - encryption = false - }) - common.getMobileSession():ExpectHandshakeMessage() - :Times(0) - - local function ptUpdateUnssucess(pTbl) - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } - pTbl.policy_table.module_config.seconds_between_retries = nil - end - - local function expNotificationFunc() - common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) - :Times(4) - end - - common.PolicyTableUpdate(ptUpdateUnssucess, expNotificationFunc) - common.delayedExp() -end - ---[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) - -runner.Title("Test") -runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdateSuccess }) -runner.Step("Activate App", common.activateApp) -runner.Step("StartService Secured, PTU started and fails, ACK, no encryption, no Handshake", startServiceSecured) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_6_non-navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_6_non-navi_video.lua deleted file mode 100644 index 67d05fdd76..0000000000 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_6_non-navi_video.lua +++ /dev/null @@ -1,60 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- TBA ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') -local runner = require('user_modules/script_runner') - ---[[ Local Variables ]] -local serviceId = 11 -local appHMIType = "DEFAULT" - ---[[ General configuration parameters ]] -config.defaultProtocolVersion = 3 -config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } - ---[[ Local Functions ]] -local function ptUpdateSuccess(pTbl) - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } -end - -local function startServiceSecured() - common.getMobileSession():StartSecureService(serviceId) - common.getMobileSession():ExpectControlMessage(serviceId, { - frameInfo = common.frameInfo.START_SERVICE_ACK, - encryption = false - }) - common.getMobileSession():ExpectHandshakeMessage() - :Times(0) - - local function ptUpdateUnssucess(pTbl) - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } - pTbl.policy_table.module_config.seconds_between_retries = nil - end - - local function expNotificationFunc() - common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) - :Times(4) - end - - common.PolicyTableUpdate(ptUpdateUnssucess, expNotificationFunc) - common.delayedExp() -end - ---[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) - -runner.Title("Test") -runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdateSuccess }) -runner.Step("Activate App", common.activateApp) -runner.Step("StartService Secured, PTU started and fails, ACK, no encryption, no Handshake", startServiceSecured) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_5_non-navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_5_non-navi_audio.lua deleted file mode 100644 index 62b84e90c1..0000000000 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_5_non-navi_audio.lua +++ /dev/null @@ -1,54 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- TBA ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') -local runner = require('user_modules/script_runner') - ---[[ Local Variables ]] -local serviceId = 10 -local appHMIType = "DEFAULT" - ---[[ General configuration parameters ]] -config.defaultProtocolVersion = 3 -config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } - ---[[ Local Functions ]] -local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } -end - -local function startServiceSecured() - common.getMobileSession():StartSecureService(serviceId) - common.getMobileSession():ExpectControlMessage(serviceId, { - frameInfo = common.frameInfo.START_SERVICE_ACK, - encryption = false - }) - common.getMobileSession():ExpectHandshakeMessage() - :Times(0) - - local function expNotificationFunc() - common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) - :Times(3) - end - - common.PolicyTableUpdate(ptUpdate, expNotificationFunc) - common.delayedExp() -end - ---[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) - -runner.Title("Test") -runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdate }) -runner.Step("Activate App", common.activateApp) -runner.Step("StartService Secured ACK, no encryption, no Handshake", startServiceSecured) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_6_non-navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_6_non-navi_video.lua deleted file mode 100644 index 0598286c89..0000000000 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_6_non-navi_video.lua +++ /dev/null @@ -1,54 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- TBA ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') -local runner = require('user_modules/script_runner') - ---[[ Local Variables ]] -local serviceId = 11 -local appHMIType = "DEFAULT" - ---[[ General configuration parameters ]] -config.defaultProtocolVersion = 3 -config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } - ---[[ Local Functions ]] -local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } -end - -local function startServiceSecured() - common.getMobileSession():StartSecureService(serviceId) - common.getMobileSession():ExpectControlMessage(serviceId, { - frameInfo = common.frameInfo.START_SERVICE_ACK, - encryption = false - }) - common.getMobileSession():ExpectHandshakeMessage() - :Times(0) - - local function expNotificationFunc() - common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) - :Times(3) - end - - common.PolicyTableUpdate(ptUpdate, expNotificationFunc) - common.delayedExp() -end - ---[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) - -runner.Title("Test") -runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdate }) -runner.Step("Activate App", common.activateApp) -runner.Step("StartService Secured ACK, no encryption, no Handshake", startServiceSecured) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_3_non-navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_3_non-navi_audio.lua deleted file mode 100644 index 4c5a4dce3a..0000000000 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_3_non-navi_audio.lua +++ /dev/null @@ -1,56 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- TBA ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') -local runner = require('user_modules/script_runner') - ---[[ Local Variables ]] -local serviceId = 10 -local appHMIType = "DEFAULT" - ---[[ General configuration parameters ]] -config.defaultProtocolVersion = 3 -config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } - ---[[ Local Functions ]] -local function ptUpdate(pTbl) - pTbl.policy_table.module_config.certificate = nil - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } -end - -local function startServiceSecured() - common.getMobileSession():StartSecureService(serviceId) - common.getMobileSession():ExpectControlMessage(serviceId, { - frameInfo = common.frameInfo.START_SERVICE_NACK, - encryption = false - }) - common.getMobileSession():ExpectHandshakeMessage() - :Times(0) - - local function expNotificationFunc() - common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) - :Times(4) - end - - common.PolicyTableUpdate(ptUpdate, expNotificationFunc) - common.delayedExp() -end - ---[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0A" }) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) - -runner.Title("Test") -runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdate }) -runner.Step("Activate App", common.activateApp) -runner.Step("StartService Secured, PTU started and fails, NACK, no Handshake", startServiceSecured) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_4_non-navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_4_non-navi_video.lua deleted file mode 100644 index 4634dc7cec..0000000000 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_4_non-navi_video.lua +++ /dev/null @@ -1,56 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- TBA ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') -local runner = require('user_modules/script_runner') - ---[[ Local Variables ]] -local serviceId = 11 -local appHMIType = "DEFAULT" - ---[[ General configuration parameters ]] -config.defaultProtocolVersion = 3 -config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } - ---[[ Local Functions ]] -local function ptUpdate(pTbl) - pTbl.policy_table.module_config.certificate = nil - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } -end - -local function startServiceSecured() - common.getMobileSession():StartSecureService(serviceId) - common.getMobileSession():ExpectControlMessage(serviceId, { - frameInfo = common.frameInfo.START_SERVICE_NACK, - encryption = false - }) - common.getMobileSession():ExpectHandshakeMessage() - :Times(0) - - local function expNotificationFunc() - common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) - :Times(4) - end - - common.PolicyTableUpdate(ptUpdate, expNotificationFunc) - common.delayedExp() -end - ---[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0B" }) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) - -runner.Title("Test") -runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdate }) -runner.Step("Activate App", common.activateApp) -runner.Step("StartService Secured, PTU started and fails, NACK, no Handshake", startServiceSecured) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_3_non-navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_3_non-navi_audio.lua deleted file mode 100644 index 4175321240..0000000000 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_3_non-navi_audio.lua +++ /dev/null @@ -1,60 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- TBA ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') -local runner = require('user_modules/script_runner') - ---[[ Local Variables ]] -local serviceId = 10 -local appHMIType = "DEFAULT" - ---[[ General configuration parameters ]] -config.defaultProtocolVersion = 3 -config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } - ---[[ Local Functions ]] -local function ptUpdateSuccess(pTbl) - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } -end - -local function startServiceSecured() - common.getMobileSession():StartSecureService(serviceId) - common.getMobileSession():ExpectControlMessage(serviceId, { - frameInfo = common.frameInfo.START_SERVICE_NACK, - encryption = false - }) - common.getMobileSession():ExpectHandshakeMessage() - :Times(0) - - local function ptUpdateUnssucess(pTbl) - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } - pTbl.policy_table.module_config.seconds_between_retries = nil - end - - local function expNotificationFunc() - common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) - :Times(4) - end - - common.PolicyTableUpdate(ptUpdateUnssucess, expNotificationFunc) - common.delayedExp() -end - ---[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0A" }) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) - -runner.Title("Test") -runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdateSuccess }) -runner.Step("Activate App", common.activateApp) -runner.Step("StartService Secured, PTU started and fails, NACK, no Handshake", startServiceSecured) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_4_non-navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_4_non-navi_video.lua deleted file mode 100644 index 6dbdee7b8f..0000000000 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_4_non-navi_video.lua +++ /dev/null @@ -1,60 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- TBA ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') -local runner = require('user_modules/script_runner') - ---[[ Local Variables ]] -local serviceId = 11 -local appHMIType = "DEFAULT" - ---[[ General configuration parameters ]] -config.defaultProtocolVersion = 3 -config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } - ---[[ Local Functions ]] -local function ptUpdateSuccess(pTbl) - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } -end - -local function startServiceSecured() - common.getMobileSession():StartSecureService(serviceId) - common.getMobileSession():ExpectControlMessage(serviceId, { - frameInfo = common.frameInfo.START_SERVICE_NACK, - encryption = false - }) - common.getMobileSession():ExpectHandshakeMessage() - :Times(0) - - local function ptUpdateUnssucess(pTbl) - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } - pTbl.policy_table.module_config.seconds_between_retries = nil - end - - local function expNotificationFunc() - common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) - :Times(4) - end - - common.PolicyTableUpdate(ptUpdateUnssucess, expNotificationFunc) - common.delayedExp() -end - ---[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0B" }) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) - -runner.Title("Test") -runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdateSuccess }) -runner.Step("Activate App", common.activateApp) -runner.Step("StartService Secured, PTU started and fails, NACK, no Handshake", startServiceSecured) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) From 4be786f629efd3a91d8062bf522afa995b92db58 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 22 Dec 2017 16:20:43 +0200 Subject: [PATCH 239/681] Rename scripts --- ..._cert_existing_app.lua => 1925_5_non-navi_no_cert_new_app.lua} | 0 ..._existing_app.lua => 1925_6_non-navi_no_cert_existing_app.lua} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/{1925_5_non-navi_no_cert_existing_app.lua => 1925_5_non-navi_no_cert_new_app.lua} (100%) rename test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/{1925_6_non-navi_cert_existing_app.lua => 1925_6_non-navi_no_cert_existing_app.lua} (100%) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua similarity index 100% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_existing_app.lua rename to test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua similarity index 100% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_cert_existing_app.lua rename to test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua From 70e4e5be6b1499024dea43b32ab0df86f1b5f74c Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 22 Dec 2017 18:06:37 +0200 Subject: [PATCH 240/681] Fix issue with secure session --- .../Trigger_PTU_NO_Certificate/common.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua index 6f378cbe5c..a04d1c6d98 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua @@ -199,9 +199,10 @@ local function registerExpectServiceEventFunc(pMobSession) end function pMobSession.mobile_session_impl:ExpectControlMessage(pServiceId, pData) local ret = self.control_services:ExpectControlMessage(pServiceId, pData) - :Do(function(exp) - if exp.status == expectations.FAILED then return end - self.security:registerSecureService(pServiceId) + :Do(function(exp, data) + if exp.status ~= expectations.FAILED and data.encryption == true then + self.security:registerSecureService(pServiceId) + end end) return ret end From 1c69b45f32966611ed38e071576bea94885fde3f Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 25 Dec 2017 09:22:03 +0200 Subject: [PATCH 241/681] Add SPT (server) certificate --- files/Security/spt_credential.pem | 140 +++++++++--------- .../Trigger_PTU_NO_Certificate/common.lua | 5 +- 2 files changed, 74 insertions(+), 71 deletions(-) diff --git a/files/Security/spt_credential.pem b/files/Security/spt_credential.pem index f820556d8a..6e10ce50b4 100644 --- a/files/Security/spt_credential.pem +++ b/files/Security/spt_credential.pem @@ -1,95 +1,95 @@ -----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- -MIIDqTCCApECCQDU4esYMmc0HDANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UEBhMC +MIIDqTCCApECCQDF1v7gJp0C1jANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UEBhMC VVMxETAPBgNVBAgMCE1pY2hpZ2FuMRAwDgYDVQQHDAdEZXRyb2l0MRQwEgYDVQQK DAtGT1JEX1NFUlZFUjEYMBYGA1UECwwPRk9SRF9TRExfU0VSVkVSMQ0wCwYDVQQD -DARGT1JEMR4wHAYJKoZIhvcNAQkBFg9zYW1wbGVAZm9yZC5jb20wHhcNMTYwMzAy -MDgxNTQxWhcNNDMwNzE5MDgxNTQxWjCBmjELMAkGA1UEBhMCUlUxDzANBgNVBAgM +DARGT1JEMR4wHAYJKoZIhvcNAQkBFg9zYW1wbGVAZm9yZC5jb20wHhcNMTcxMjAx +MTM0NjM2WhcNNDUwNDE4MTM0NjM2WjCBmjELMAkGA1UEBhMCUlUxDzANBgNVBAgM BlJ1c3NpYTEXMBUGA1UEBwwOU3QuIFBldGVyc2J1cmcxDzANBgNVBAoMBkx1eG9m dDEPMA0GA1UECwwGTW9iaWxlMQ8wDQYDVQQDDAZzZXJ2ZXIxIDAeBgkqhkiG9w0B CQEWEXNhbXBsZUBsdXhvZnQuY29tMQwwCgYDVQQFEwNTUFQwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQC8SlK4zMhpY17/yJNPJdZV5HY7AATzNszz+XpE -j6lpG9LCpgKMOeHqQOqJ64pvh8hZsXFbFZs64TnEEsE2fpFHYZEpEa0zruznvZkT -lPP/LyvTMpLhbDroENDIW0NMKVDQHchym3o4AYZR/9FLLWNF03w0mH/yOHbiBVBO -3qhfftXv9xjTOCY+LCLb8MWGd4zigjvyvSatzjqG0Fsv0+Ef8M2mbO8ig0XgiKm6 -eQmYkNUpPYJFaeK+QToE4JUo9csA0O0bVr3bDRsQMvwtdDdgiUryDahYd07MLcAI -Si53Z0LVFpPL30Q8GwSB712aGVAC4FeKl6SD+QWcw9IOrr1fAgMBAAEwDQYJKoZI -hvcNAQELBQADggEBAJCagXIZzLRWAK0u1Kipd6WQpOilkPWXkdFhUSEXxBnAF0Df -88ii+d+jNTsdTWpHnviaGuEUENiuvtcdhwtX/wDxe/W/lj1g/wy/kqrBy6zslD09 -IK8MvCYcoOlsmo5CofRg8KmZNXjCcPQ2fLi9W8+g90cKt4zXrbLDNlEd6mbpIwH+ -JSHRptnekFpEeOgqGMEeRtUiUt4Eumnle+np7O0xHc9OdVqzMmrG7/aD/r4qqir7 -B3a5Hj8/pLoZMjVo/mynB7Pfr3YQc9eCuXlcpg0W4AG8eT8iSGjVFMpAaYZAShMp -RqWmSS3fTIbTCa8OQ076Nu5EpEG4OM7MX1V/NLw= +DQEBAQUAA4IBDwAwggEKAoIBAQDDqHx1cpxCmy0dmxV9wkO+7H7DCcNhGxCfLATl +XvhzpBWTWeoCYPveIkXIjP0nYJKsdFllhmzCxC/CYXsSZKXi224TGhVCb194R0LY +BwxZNKCQqiE+6yTKOgZlf8ARcoRP/24mkyw6QFVXOSNIw09xZEqlY7tBL39alDiG +bnyAwxOoX31Nz18N8x3j3xwSnU211OeqhtvzH0KLGFeH6+OYVRw/PCqCsvFIpJiq +ZY57PmDrsMqkYQewZggs1htYzkU/hTuGvQi+hWM2fG6snkYktevqgw23KcM0CT8L +QRwfNWrdbQZOHeIVUl4gJXqOO7upZiSkznEYqTlPu/PwsopfAgMBAAEwDQYJKoZI +hvcNAQELBQADggEBABO1QYExP8TCmse0wWon5SubcW+7IY6QIixN1CbxZEfbsiAT +W6vIIUxdH4CFe46W4V8dKJqtPVH12tAITLKTQ4SxN7C09q2370aoAfoepq6tVtcw +v4BdUmhxZUtdwk5y79jwj41FCeoj2Fx0JVuNFyd2enrVT+o1T0wZqFrwMLhyqXNY +YEQ9FMoZn4OIo4pLYT1c+1A0C+cU3lj4NfBHZI6IdJBwpXPPydeoVDNf9lLTRAlx +Y+SWwGqrj1AYkfwZ0yXYHe7XPCSJm4Q9NuBzzEVUL5JQuyIiHKc7xfQWttPh4XRa +aruma5FMPfM33usutpCRcx0xrcr9G6hhwbyRL3U= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIEBzCCAu+gAwIBAgIJAPLNT6jOaFGEMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYD +MIIEBzCCAu+gAwIBAgIJAMVpgNqGnorkMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYD VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEXMBUGA1UEBwwOU2lsaWNvbiBW YWxsZXkxEzARBgNVBAoMCkNBY2VydC5vcmcxDzANBgNVBAsMBkNBY2VydDEUMBIG A1UEAwwLY2xpZW50X3Jvb3QxIDAeBgkqhkiG9w0BCQEWEXNhbXBsZUBjYWNlcnQu -b3JnMB4XDTE2MDMwMjA4MTU0MFoXDTQzMDcxOTA4MTU0MFowgZkxCzAJBgNVBAYT +b3JnMB4XDTE3MTIwMTEzNDYzNloXDTQ1MDQxODEzNDYzNlowgZkxCzAJBgNVBAYT AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRcwFQYDVQQHDA5TaWxpY29uIFZhbGxl eTETMBEGA1UECgwKQ0FjZXJ0Lm9yZzEPMA0GA1UECwwGQ0FjZXJ0MRQwEgYDVQQD DAtjbGllbnRfcm9vdDEgMB4GCSqGSIb3DQEJARYRc2FtcGxlQGNhY2VydC5vcmcw -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCxLgK5kZndg4h+7iwPzy0E -rEYNloqAWfIpEIvZA0QqO3XHXZd7u5BFz+wNHXvO0uweZ1Pu5zYYiKpcwS4xbgzD -0urgIh431PbZcSqBDbj7azfNYgS5CfRTa4KLBWNvHwHxX9WacX/NztEUcAgHRDJl -nm70J+Vw/mGZggXDxpJtAF78JafD3BD1kyGMj4V36qzjBu3IHhi7DSDeb5xq48jr -FH+YbmXxdVaiHRuBVs8tdcWhHHNj0R0OEVzfUCRo1jfifSvr/5QfrsGqyJFQhwPA -pqNnFS3AvogwcjGI2p3xKwLhVorWoFlQLaQ3vKlwhw/H6O4GK+2AuInDUcX+IECv -AgMBAAGjUDBOMB0GA1UdDgQWBBSsNluNus9/Eeuq4lSvWw2lY2u4jzAfBgNVHSME -GDAWgBSsNluNus9/Eeuq4lSvWw2lY2u4jzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 -DQEBCwUAA4IBAQBThUyb6hhXfkOLRWkKczllA20InRcT1BDCu4P8amn+U+wZSLs+ -ef72T3l8xXJb62oqIuLijyCf9s81z3Fsha9kTN23Vb6/u+MTdbI1hOV2Ki93JGdj -K+EXE1/ckMPzc98uf7nj82HmlmPZBln+ufpzyMiGmm0BwxDQDUwsBmNyo6NGE2P9 -NbyXGL0wmi5fEjB6FYYNlR2zkxEz1FiuzUdaVzENPLN0NrESC/MQDGHNQXTJuSye -e1zwHvpIN9F0K+l6PrjZlou7X4L679KE1aQFq/haLtJ4bxBul/pFEXf2UsosVqxz -Oi0wui9msi3pcFT78OjuFG1H05SmB5imbRyC +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPKCCEwo9W90uUyLEyRC0w +pr5v9nOWOhw7IsmGt/kUnCx7e4BuD/Ml/azVTR8J6MSKvWlB2z72hvzsxCs4noYI +xgaaMUqNy3vMN3eALSCbqcOUoRZGMp+JffbcUruAs1Fob8SlA8gMwSwRcZGwlYKp +XQsdzDTNGDXWGg51Qu7PcfAWoQu0ldCFolKTxekA9YPpKFY2YBhgFvPK1nQFE+Yu +rl7UuqEdz3GQOzAsom1UGD7wRtyzu2YfwvoMaKvU+tmaMjMPXNasJePofaw7H7lG +U1qeNIReYgseNBBpT8R09d40ZiPMc0U5FvEBwdSETlTcoO2phR6YZBylYT0vjzfr +AgMBAAGjUDBOMB0GA1UdDgQWBBTdpuiA1yACL20ghEka1t1rKDAfZTAfBgNVHSME +GDAWgBTdpuiA1yACL20ghEka1t1rKDAfZTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQA90UiRy9/HsZaUMHI7j8ZOs+rwe1vvEl58j3+Z1JaOUuqNEaSr +AbJ26iGMKWL4/h0OKn+r3IN2rPw2LvyrPrC9Z07LMoK81FHySJRrAf3e3uVjuf7o +T3hbBRlUXPA2j01pB5GR5OQ/IHZFrEdD9dVJWALnMoeV9Gf6C2m0lEnJUudm1VqG +YsN0S7fbDu3MyzUAISCsJ6Thcv/1vW+xwkfOO8Boo0T+RvODeqVMVB91FS2jwswc +BM3whDm6aATNOKy1vmEb3Q5yq9jnFSvAASNN7Me37UR3CJuHfmJ8KFl9qyTWrhkv +Ju5KMgJbzJJltD2e8y6p0G7XU1w89mOaw6UH -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIDrzCCApcCCQCMhdgazsvQhDANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMC +MIIDrzCCApcCCQCjt+vFJ2iaozANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMC VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFzAVBgNVBAcMDlNpbGljb24gVmFsbGV5 MRMwEQYDVQQKDApDQWNlcnQub3JnMQ8wDQYDVQQLDAZDQWNlcnQxFDASBgNVBAMM C2NsaWVudF9yb290MSAwHgYJKoZIhvcNAQkBFhFzYW1wbGVAY2FjZXJ0Lm9yZzAe -Fw0xNjAzMDIwODE1NDBaFw00MzA3MTkwODE1NDBaMIGYMQswCQYDVQQGEwJVUzER +Fw0xNzEyMDExMzQ2MzZaFw00NTA0MTgxMzQ2MzZaMIGYMQswCQYDVQQGEwJVUzER MA8GA1UECAwITWljaGlnYW4xEDAOBgNVBAcMB0RldHJvaXQxFDASBgNVBAoMC0ZP UkRfQ0xJRU5UMRgwFgYDVQQLDA9GT1JEX1NETF9DTElFTlQxFDASBgNVBAMMC0ZP UkRfQ0xJRU5UMR4wHAYJKoZIhvcNAQkBFg9zYW1wbGVAZm9yZC5jb20wggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDar3ozo8jjyHOt6QG0HQehDAKqDhFy -yS8wgOqEIfOM5XfxrkjZoKK9lBAxzIGJjuKum5vA+/RYTm1gOnm/6tgF2/b9Ss5A -p1bxeKH7LcBX7Q0+aVv6HZL59gqFosfHeecwxEZC/PIf6vuexo4H4k6RWG2Cjsky -Eq+mrM1e745bptzh88SafnSaE4OfhokM/VAAJw77OmjwM5s5xIOjWeETbBd+4r91 -CyybGHzlzaV60rkza0NdgmYdXCqKq/fBDrraMN6U8Fnf6K2OLiOtCiqq98RP5oCw -ZNCq+JRXPzqMPd/wuGtbodjffBYuf6kWVyT53YXEQHPp86sOBHyQXQ9PAgMBAAEw -DQYJKoZIhvcNAQELBQADggEBAJ5Qj9Ior28Io/HfTtDPbE754+o/2hTRX16ElYIo -Gpg28xJcXm34GAYF3wPQbrLHG/A4cNTSDLU3zG1BWHvA0qGOGkFDqJK8NrgE/TFB -vTrBO0SjOCGUm0CKvWEbazJKkkkFPfPe80fGEtfw4s1po6Bb1Z9mXcx0zXdq/9zp -q+w8bnepuaa1B7NpPEfXL1grPxzpf1WI82O9B1xYcquAVJeayznjdwm49XZtGJEf -UFLu3ezzX1OgsnWlcoYHA9zyUjlbOkXi8+p2UiuDOEtIijf4BXsvNaB+TO1FcquV -c/sOZAkO9QM8Bd8YPVE8cjRy6SkgklhN+5zcThkH8eHHIh0= +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtm+wvvaDyoDzXB1zoKK5eI5Mfghvo +mvJ6Kcyx+jO9fZFs7v5oltb1q6wwOWKEU9AS2LG7gQzH7jjorWGUg2t++E912f/g +MURGJsdFpHlqx9XR4GGQcoEP95B+OJKYSdyExCkyBsKePGrsdKVQ40TYZUK+MjyZ +iVsrecQGn+iIc0sVXZ0NUTUtHw2xudVIwwYaC0eo8EYu08OKc9nEYkCQXiQmfsBp +8oIQba9o6PjMUQlqtuV7ZhizDCZld/BWvcYhv1X68Bbr3gfCRzHZ/tWpTWx/GXAh +OrqGl0ZtV+ia/UpsRgReu/qeBWoSzn8eQNvtQ/Sv7QLgs4g+sk5zhC/HAgMBAAEw +DQYJKoZIhvcNAQELBQADggEBAHdTV8mDZBe706j2E7FxX4NefdKgdIsMU5gOLCgX +1pm0KVdoO5T3y+dXjZTJh7Pn8O7xtw5yz8Pd5PxIbvj+IFvCOkzJS4WAipGGQJO1 +2rNpPXj+eZashufA/YOG2KRqfvHByyI4wwhwRDqPy3sy8pCaLfCShKqUPIHb0w2J +tQIPPYfYwS7dzAXSgXndnhAk71mE7UbAfcNh5YkgTFA/iffnnYFxILNircdj6fUi +xuySIziBeUlmUZcOrQnNepsE34KreMb0+DemwCn0okOXltcOY10ovNM0VBJBEaRB +pf5lldAZl7rD2pIYs1b3vT5UpRjg7x2DAM3N+xBlpPz7VWg= -----END CERTIFICATE----- diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua index a04d1c6d98..d505381006 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua @@ -5,6 +5,10 @@ config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 +config.serverCertificatePath = "./files/Security/spt_credential.pem" +config.serverPrivateKeyPath = "./files/Security/spt_credential.pem" +config.serverCAChainCertPath = "./files/Security/spt_credential.pem" + --[[ Required Shared libraries ]] local mobile_session = require("mobile_session") local json = require("modules/json") @@ -16,7 +20,6 @@ local test = require("user_modules/dummy_connecttest") local expectations = require('expectations') local Expectation = expectations.Expectation local constants = require('protocol_handler/ford_protocol_constants') --- local util = require("atf.util") local m = {} From df8f154eaa196bbf16d4584dd11809474db4dd59 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 25 Dec 2017 10:07:16 +0200 Subject: [PATCH 242/681] Minor fixes --- .../1888_1_navi.lua | 2 +- .../1888_2_non-navi.lua | 2 +- .../1888_3_navi_audio_force_off.lua | 2 +- .../1888_4_navi_video_force_off.lua | 2 +- .../1888_5_navi_audio_force_on.lua | 2 +- .../1888_6_navi_video_force_on.lua | 2 +- .../1891_1_navi.lua | 2 +- .../1891_2_non-navi.lua | 4 +- .../1891_3_navi_audio.lua | 2 +- .../1891_4_navi_video.lua | 2 +- .../1894_1_navi.lua | 2 +- .../1894_2_non-navi.lua | 4 +- .../1894_3_navi_audio.lua | 2 +- .../1894_4_navi_video.lua | 2 +- .../1922_1_navi_audio.lua | 2 +- .../1922_2_navi_video.lua | 2 +- .../1923_1_navi_audio.lua | 2 +- .../1923_2_navi_video.lua | 2 +- .../1924_1_non-navi.lua | 2 +- .../1924_2_navi.lua | 2 +- .../1925_1_navi_no_cert_new_app.lua | 2 +- .../1925_2_navi_no_cert_existing_app.lua | 2 +- .../1925_3_navi_cert_new_app.lua | 2 +- .../1925_4_navi_cert_existing_app.lua | 2 +- .../1925_5_non-navi_no_cert_new_app.lua | 2 +- .../1925_6_non-navi_no_cert_existing_app.lua | 2 +- .../1925_7_non-navi_cert_new_app.lua | 2 +- .../1925_8_non-navi_cert_existing_app.lua | 2 +- .../Trigger_PTU_NO_Certificate/common.lua | 70 +++++++++++++++---- 29 files changed, 88 insertions(+), 42 deletions(-) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua index 981479fde5..3910aad4c4 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua @@ -67,7 +67,7 @@ runner.Step("StartService Secured NACK", startServiceSecured, { { frameInfo = common.frameInfo.START_SERVICE_NACK, encryption = false } }) -runner.Step("PolicyTableUpdate with certificate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate with certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("StartService Secured ACK", startServiceSecured, { { frameInfo = common.frameInfo.START_SERVICE_ACK, diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua index f3c09e9cdb..a20db1b6f5 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua @@ -39,7 +39,7 @@ local function startServiceSecured(pData) :Times(3) end - common.PolicyTableUpdate(ptUpdate, expNotificationFunc) + common.policyTableUpdate(ptUpdate, expNotificationFunc) common.delayedExp() end diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua index 23b69c56cc..e148c0f93b 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua @@ -46,7 +46,7 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with certificate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate with certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("StartService Secured ACK", startServiceSecured, { { frameInfo = common.frameInfo.START_SERVICE_ACK, diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua index 56811f0294..71d7c843b4 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua @@ -46,7 +46,7 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with certificate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate with certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("StartService Secured ACK", startServiceSecured, { { frameInfo = common.frameInfo.START_SERVICE_ACK, diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua index c603bb2205..86eea5ed32 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua @@ -46,7 +46,7 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with certificate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate with certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("StartService Secured ACK", startServiceSecured, { { frameInfo = common.frameInfo.START_SERVICE_ACK, diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua index 378aaae77d..c168057117 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua @@ -46,7 +46,7 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with certificate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate with certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("StartService Secured ACK", startServiceSecured, { { frameInfo = common.frameInfo.START_SERVICE_ACK, diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua index c54cc5b100..984ecadae9 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua @@ -45,7 +45,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate fails", common.PolicyTableUpdate, { ptUpdate, expNotificationFunc }) +runner.Step("PolicyTableUpdate fails", common.policyTableUpdate, { ptUpdate, expNotificationFunc }) runner.Step("StartService Secured NACK, no Handshake", startServiceSecured) runner.Title("Postconditions") diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua index b2e6a9ee18..ced4ec2878 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua @@ -38,7 +38,7 @@ local function startServiceSecured() :Times(4) end - common.PolicyTableUpdate(ptUpdateUnssucess, expNotificationFunc) + common.policyTableUpdate(ptUpdateUnssucess, expNotificationFunc) common.delayedExp() end @@ -51,7 +51,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate", common.PolicyTableUpdate, { ptUpdateSuccess }) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { ptUpdateSuccess }) runner.Step("StartService Secured, PTU started and fails, NACK, no Handshake", startServiceSecured) runner.Title("Postconditions") diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua index 4e7c2621ed..51f2dd676c 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua @@ -47,7 +47,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate fails", common.PolicyTableUpdate, { ptUpdate, expNotificationFunc }) +runner.Step("PolicyTableUpdate fails", common.policyTableUpdate, { ptUpdate, expNotificationFunc }) runner.Step("Activate App", common.activateApp) runner.Step("StartService Secured ACK, no encryption, no Handshake", startServiceSecured) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua index 4bed09b816..f7269e3e10 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua @@ -47,7 +47,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate fails", common.PolicyTableUpdate, { ptUpdate, expNotificationFunc }) +runner.Step("PolicyTableUpdate fails", common.policyTableUpdate, { ptUpdate, expNotificationFunc }) runner.Step("Activate App", common.activateApp) runner.Step("StartService Secured ACK, no encryption, no Handshake", startServiceSecured) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua index fbd6ce3be9..48280651a8 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua @@ -38,7 +38,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate without certificate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate without certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("StartService Secured NACK, no Handshake", startServiceSecured) runner.Title("Postconditions") diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua index b94faba30d..bb39c8b568 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua @@ -33,7 +33,7 @@ local function startServiceSecured() :Times(3) end - common.PolicyTableUpdate(ptUpdate, expNotificationFunc) + common.policyTableUpdate(ptUpdate, expNotificationFunc) common.delayedExp() end @@ -46,7 +46,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate without certificate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate without certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("StartService Secured, PTU started, NACK, no Handshake", startServiceSecured) runner.Title("Postconditions") diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua index e968533c1a..66606c25c3 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua @@ -39,7 +39,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate without certificate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate without certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Activate App", common.activateApp) runner.Step("StartService Secured ACK, no encryption, no Handshake", startServiceSecured) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua index fc3df8f613..71f85ff6ea 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua @@ -39,7 +39,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate without certificate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate without certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Activate App", common.activateApp) runner.Step("StartService Secured ACK, no encryption, no Handshake", startServiceSecured) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua index d6756301b8..a03432d76d 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua @@ -46,7 +46,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate fails", common.PolicyTableUpdate, { ptUpdate, expNotificationFunc }) +runner.Step("PolicyTableUpdate fails", common.policyTableUpdate, { ptUpdate, expNotificationFunc }) runner.Step("Activate App", common.activateApp) runner.Step("StartService Secured NACK, no Handshake", startServiceSecured) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua index 2e3c9c4a45..131310e526 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua @@ -46,7 +46,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate fails", common.PolicyTableUpdate, { ptUpdate, expNotificationFunc }) +runner.Step("PolicyTableUpdate fails", common.policyTableUpdate, { ptUpdate, expNotificationFunc }) runner.Step("Activate App", common.activateApp) runner.Step("StartService Secured NACK, no Handshake", startServiceSecured) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua index c9f6d4b477..e74008ec1c 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua @@ -46,7 +46,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate fails", common.PolicyTableUpdate, { ptUpdate, expNotificationFunc }) +runner.Step("PolicyTableUpdate fails", common.policyTableUpdate, { ptUpdate, expNotificationFunc }) runner.Step("Activate App", common.activateApp) runner.Step("StartService Secured NACK, no Handshake", startServiceSecured) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua index 6c4078b4d4..7d41a62e1d 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua @@ -46,7 +46,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate fails", common.PolicyTableUpdate, { ptUpdate, expNotificationFunc }) +runner.Step("PolicyTableUpdate fails", common.policyTableUpdate, { ptUpdate, expNotificationFunc }) runner.Step("Activate App", common.activateApp) runner.Step("StartService Secured NACK, no Handshake", startServiceSecured) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua index 201c594d75..ad97ab7fdc 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua @@ -36,7 +36,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate without certificate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate without certificate", common.policyTableUpdate, { ptUpdate }) runner.Title("Test") diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua index b809055070..133bf5da89 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua @@ -39,7 +39,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate without certificate", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate without certificate", common.policyTableUpdate, { ptUpdate }) runner.Title("Test") diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua index 2a37caaa79..ecd9fb3530 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua @@ -34,7 +34,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register " .. appHMIType[1] .. " App", common.registerApp, { 1 }) -runner.Step("PTU 1 finished", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PTU 1 finished", common.policyTableUpdate, { ptUpdate }) runner.Title("Test") runner.Step("Register " .. appHMIType[2] .. " App, PTU started", registerApp, { 2 }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua index 037456ea9b..174d6eddac 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua @@ -36,7 +36,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register " .. appHMIType[1] .. " App", common.registerApp, { 1 }) -runner.Step("PTU 1 finished", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PTU 1 finished", common.policyTableUpdate, { ptUpdate }) runner.Title("Test") runner.Step("Register " .. appHMIType[2] .. " App, PTU started", registerApp, { 2 }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua index e4e9d13cd2..4baf1970ac 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua @@ -37,7 +37,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register " .. appHMIType[1] .. " App", common.registerApp, { 1 }) -runner.Step("PTU 1 finished", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PTU 1 finished", common.policyTableUpdate, { ptUpdate }) runner.Title("Test") runner.Step("Register " .. appHMIType[2] .. " App, PTU started", registerApp, { 2 }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua index 12744244dc..cae8a18f2c 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua @@ -41,7 +41,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register " .. appHMIType[1] .. " App", common.registerApp, { 1 }) -runner.Step("PTU 1 finished", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PTU 1 finished", common.policyTableUpdate, { ptUpdate }) runner.Title("Test") runner.Step("Register " .. appHMIType[2] .. " App, PTU not started", registerApp, { 2 }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua index cac19e1aa2..0dcb5a7549 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua @@ -34,7 +34,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register " .. appHMIType[1] .. " App", common.registerApp, { 1 }) -runner.Step("PTU 1 finished", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PTU 1 finished", common.policyTableUpdate, { ptUpdate }) runner.Title("Test") runner.Step("Register " .. appHMIType[2] .. " App, PTU started", registerApp, { 2 }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua index e815b88465..005e64f8a1 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua @@ -38,7 +38,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register " .. appHMIType[1] .. " App", common.registerApp, { 1 }) -runner.Step("PTU 1 finished", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PTU 1 finished", common.policyTableUpdate, { ptUpdate }) runner.Title("Test") runner.Step("Register " .. appHMIType[2] .. " App, PTU not started", registerApp, { 2 }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua index c5c4b80505..0f5841e0ae 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua @@ -37,7 +37,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register " .. appHMIType[1] .. " App", common.registerApp, { 1 }) -runner.Step("PTU 1 finished", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PTU 1 finished", common.policyTableUpdate, { ptUpdate }) runner.Title("Test") runner.Step("Register " .. appHMIType[2] .. " App, PTU started", registerApp, { 2 }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua index 080c632a61..78b71c48af 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua @@ -41,7 +41,7 @@ runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register " .. appHMIType[1] .. " App", common.registerApp, { 1 }) -runner.Step("PTU 1 finished", common.PolicyTableUpdate, { ptUpdate }) +runner.Step("PTU 1 finished", common.policyTableUpdate, { ptUpdate }) runner.Title("Test") runner.Step("Register " .. appHMIType[2] .. " App, PTU not started", registerApp, { 2 }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua index d505381006..917e9b4ba9 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua @@ -91,8 +91,8 @@ end --[[ @ptu: perform policy table update --! @parameters: ---! pAppId - application number (1, 2, etc.) --! pPTUpdateFunc - additional function for update +--! pAppId - application number (1, 2, etc.) --]] local function ptu(pPTUpdateFunc, pAppId) if not pAppId then pAppId = 1 end @@ -147,13 +147,17 @@ local function ptu(pPTUpdateFunc, pAppId) end --[[ @allowSDL: sequence that allows SDL functionality ---! @parameters: +--! @parameters: none --]] local function allowSDL() test.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) end +--[[ @registerStartSecureServiceFunc: register function to start secure service +--! @parameters: +--! pMobSession - mobile session +--]] local function registerStartSecureServiceFunc(pMobSession) function pMobSession.mobile_session_impl.control_services:StartSecureService(pServiceId) local msg = { @@ -173,6 +177,11 @@ local function registerStartSecureServiceFunc(pMobSession) end end +--[[ @registerExpectServiceEventFunc: register functions for expectations of control messages: +--! Service Start ACK/NACK and Handshake +--! @parameters: +--! pMobSession - mobile session +--]] local function registerExpectServiceEventFunc(pMobSession) function pMobSession.mobile_session_impl.control_services:ExpectControlMessage(pServiceId, pData) local event = events.Event() @@ -263,6 +272,11 @@ local function registerExpectServiceEventFunc(pMobSession) end end +--[[ @getAppID: return 'appID' from configuration file +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: application identifier from configuration file +--]] function m.getAppID(pAppId) if not pAppId then pAppId = 1 end return config["application" .. pAppId].registerAppInterfaceParams.appID @@ -334,7 +348,7 @@ function m.getMobileSession(pAppId) return session end ---[[ @registerAppWithPTU: register mobile application and perform PTU +--[[ @registerApp: register mobile application --! @parameters: --! pAppId - application number (1, 2, etc.) --]] @@ -366,6 +380,10 @@ function m.registerApp(pAppId) end) end +--[[ @registerAppWOPTU: register mobile application and do not perform PTU +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--]] function m.registerAppWOPTU(pAppId) if not pAppId then pAppId = 1 end local mobSession = m.getMobileSession(pAppId) @@ -387,12 +405,17 @@ function m.registerAppWOPTU(pAppId) end) end -function m.PolicyTableUpdate(pPTUpdateFunc, pExpNotificationFunc, pAppId) +--[[ @policyTableUpdate: perform PTU +--! @parameters: +--! pPTUpdateFunc - function with additional updates +--! pExpNotificationFunc - function with specific expectations which needs to be done during PTU +--! pAppId - application number (1, 2, etc.) +--]] +function m.policyTableUpdate(pPTUpdateFunc, pExpNotificationFunc, pAppId) if not pAppId then pAppId = 1 end if not pExpNotificationFunc then test.hmiConnection:ExpectNotification("SDL.OnStatusUpdate", { status = "UP_TO_DATE" }) end - -- m.getMobileSession(pAppId):ExpectNotification("OnPermissionsChange") -- SDL issue ptu(pPTUpdateFunc, pAppId) end @@ -420,7 +443,7 @@ function m.start(pHMIParams) end) end ---[[ @DelayedExp: delay test step for default timeout +--[[ @delayedExp: delay test step for specific timeout --! @parameters: none --]] function m.delayedExp(pTimeOut) @@ -428,6 +451,11 @@ function m.delayedExp(pTimeOut) commonTestCases:DelayedExp(pTimeOut) end +--[[ @readFile: read data from file +--! @parameters: +--! pPath - path to file +-- @return: content of the file +--]] function m.readFile(pPath) local open = io.open local file = open(pPath, "rb") @@ -437,11 +465,16 @@ function m.readFile(pPath) return content end -function test.hmiConnection:ExpectRequest(name, ...) +--[[ @ExpectRequest: register expectation for request on HMI connection +--! @parameters: +--! pName - name of the request +--! ... - expected data +--]] +function test.hmiConnection:ExpectRequest(pName, ...) local event = events.Event() - event.matches = function(_, data) return data.method == name end + event.matches = function(_, data) return data.method == pName end local args = table.pack(...) - local ret = Expectation("HMI call " .. name, self) + local ret = Expectation("HMI call " .. pName, self) if #args > 0 then ret:ValidIf(function(e, data) local arguments @@ -459,11 +492,16 @@ function test.hmiConnection:ExpectRequest(name, ...) return ret end -function test.hmiConnection:ExpectNotification(name, ...) +--[[ @ExpectNotification: register expectation for notification on HMI connection +--! @parameters: +--! pName - name of the notification +--! ... - expected data +--]] +function test.hmiConnection:ExpectNotification(pName, ...) local event = events.Event() - event.matches = function(_, data) return data.method == name end + event.matches = function(_, data) return data.method == pName end local args = table.pack(...) - local ret = Expectation("HMI notification " .. name, self) + local ret = Expectation("HMI notification " .. pName, self) if #args > 0 then ret:ValidIf(function(e, data) local arguments @@ -482,10 +520,18 @@ function test.hmiConnection:ExpectNotification(name, ...) return ret end +--[[ @getHMIConnection: return HMI connection object +--! @parameters: none +--! @return: HMI connection object +--]] function m.getHMIConnection() return test.hmiConnection end +--[[ @setForceProtectedServiceParam: set value of 'ForceProtectedService' parameter in SDL .ini file +--! @parameters: +--! pParamValue - value of the paramter +--]] function m.setForceProtectedServiceParam(pParamValue) local paramName = "ForceProtectedService" commonFunctions:SetValuesInIniFile(paramName .. "%s-=%s-[%d,A-Z,a-z]-%s-\n", paramName, pParamValue) From 4992f526e11c9d916d866aab6443fe9035468bcd Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 25 Dec 2017 10:30:32 +0200 Subject: [PATCH 243/681] Add links to issues --- .../Trigger_PTU_NO_Certificate/1888_1_navi.lua | 2 +- .../Trigger_PTU_NO_Certificate/1888_2_non-navi.lua | 2 +- .../Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua | 2 +- .../Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua | 2 +- .../Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua | 2 +- .../Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua | 2 +- .../Trigger_PTU_NO_Certificate/1891_1_navi.lua | 2 +- .../Trigger_PTU_NO_Certificate/1891_2_non-navi.lua | 2 +- .../Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua | 2 +- .../Trigger_PTU_NO_Certificate/1891_4_navi_video.lua | 2 +- .../Trigger_PTU_NO_Certificate/1894_1_navi.lua | 2 +- .../Trigger_PTU_NO_Certificate/1894_2_non-navi.lua | 2 +- .../Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua | 2 +- .../Trigger_PTU_NO_Certificate/1894_4_navi_video.lua | 2 +- .../Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua | 2 +- .../Trigger_PTU_NO_Certificate/1922_2_navi_video.lua | 2 +- .../Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua | 2 +- .../Trigger_PTU_NO_Certificate/1923_2_navi_video.lua | 2 +- .../Trigger_PTU_NO_Certificate/1924_1_non-navi.lua | 2 +- .../Trigger_PTU_NO_Certificate/1924_2_navi.lua | 2 +- .../Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua | 2 +- .../1925_2_navi_no_cert_existing_app.lua | 2 +- .../Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua | 2 +- .../1925_4_navi_cert_existing_app.lua | 2 +- .../1925_5_non-navi_no_cert_new_app.lua | 2 +- .../1925_6_non-navi_no_cert_existing_app.lua | 2 +- .../Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua | 2 +- .../1925_8_non-navi_cert_existing_app.lua | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua index 3910aad4c4..67c40333a4 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1888 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua index a20db1b6f5..3f9ba97b52 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1888 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua index e148c0f93b..2d73a3aa9b 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1888 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua index 71d7c843b4..bfd086424c 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1888 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua index 86eea5ed32..d572d47279 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1888 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua index c168057117..dbbb3f3c83 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1888 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua index 984ecadae9..626f06efdb 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1891 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua index ced4ec2878..a5c3e091b2 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1891 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua index 51f2dd676c..2b99d2fb7d 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1891 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua index f7269e3e10..aae2032327 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1891 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua index 48280651a8..5cdc1a7b6c 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1894 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua index bb39c8b568..c434793301 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1894 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua index 66606c25c3..053eb10462 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1894 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua index 71f85ff6ea..8f117912a9 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1894 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua index a03432d76d..bc9cf86030 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1922 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua index 131310e526..df3b06d4eb 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1922 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua index e74008ec1c..f56e764971 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1923 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua index 7d41a62e1d..4722aa4120 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1923 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua index ad97ab7fdc..7e507df77a 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1924 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua index 133bf5da89..9fff6caf34 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1924 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua index ecd9fb3530..c4cbe782a4 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1925 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua index 174d6eddac..e5cc1a8726 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1925 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua index 4baf1970ac..ec574bb074 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1925 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua index cae8a18f2c..dd0f02c0b8 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1925 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua index 0dcb5a7549..bba6c14561 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1925 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua index 005e64f8a1..8880ace1f2 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1925 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua index 0f5841e0ae..73ad4df281 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1925 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua index 78b71c48af..34664d1008 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- TBA +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1925 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') From 34ee06250c9b1eff94abccff6240732352e46f83 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 26 Dec 2017 17:06:52 +0200 Subject: [PATCH 244/681] Fix issues --- .../1888_2_non-navi.lua | 10 +- .../1891_1_navi.lua | 3 +- .../1891_2_non-navi.lua | 2 +- .../1891_3_navi_audio.lua | 3 +- .../1891_4_navi_video.lua | 3 +- .../1922_1_navi_audio.lua | 9 +- .../1922_2_navi_video.lua | 9 +- .../1923_1_navi_audio.lua | 3 +- .../1923_2_navi_video.lua | 3 +- .../Trigger_PTU_NO_Certificate/common.lua | 106 +++++++++--------- 10 files changed, 67 insertions(+), 84 deletions(-) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua index 3f9ba97b52..63e338c9b5 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua @@ -15,6 +15,11 @@ config.application1.registerAppInterfaceParams.appID = "SPT" config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } +end + local function startServiceSecured(pData) common.getMobileSession():StartSecureService(serviceId) common.getMobileSession():ExpectControlMessage(serviceId, pData) @@ -28,7 +33,7 @@ local function startServiceSecured(pData) common.getMobileSession():ExpectHandshakeMessage() :Times(handshakeOccurences) - local function ptUpdate(pTbl) + local function ptUpdateCertificate(pTbl) pTbl.policy_table.module_config.certificate = crt pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end @@ -39,7 +44,7 @@ local function startServiceSecured(pData) :Times(3) end - common.policyTableUpdate(ptUpdate, expNotificationFunc) + common.policyTableUpdate(ptUpdateCertificate, expNotificationFunc) common.delayedExp() end @@ -70,6 +75,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate wo cert", common.policyTableUpdate, { ptUpdate }) runner.Step("Activate App", common.activateApp) runner.Step("StartService Secured, PTU wo cert, NACK, no Handshake", startServiceSecured, { { diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua index 626f06efdb..2dea8793de 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua @@ -31,9 +31,8 @@ end local function expNotificationFunc() common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) - :Times(4) + :Times(2) end --[[ Scenario ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua index a5c3e091b2..795871dc36 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua @@ -51,7 +51,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate", common.policyTableUpdate, { ptUpdateSuccess }) +runner.Step("PolicyTableUpdate fails", common.policyTableUpdate, { ptUpdateSuccess }) runner.Step("StartService Secured, PTU started and fails, NACK, no Handshake", startServiceSecured) runner.Title("Postconditions") diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua index 2b99d2fb7d..1322f666ae 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua @@ -21,9 +21,8 @@ end local function expNotificationFunc() common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) - :Times(4) + :Times(2) end local function startServiceSecured() diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua index aae2032327..0085fc5582 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua @@ -21,9 +21,8 @@ end local function expNotificationFunc() common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) - :Times(4) + :Times(2) end local function startServiceSecured() diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua index bc9cf86030..9e0f4f5c69 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua @@ -30,13 +30,6 @@ local function startServiceSecured() common.delayedExp() end -local function expNotificationFunc() - common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) - :Times(4) -end - --[[ Scenario ]] runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") @@ -46,7 +39,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate fails", common.policyTableUpdate, { ptUpdate, expNotificationFunc }) +runner.Step("PolicyTableUpdate without certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Activate App", common.activateApp) runner.Step("StartService Secured NACK, no Handshake", startServiceSecured) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua index df3b06d4eb..9bc988b6e6 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua @@ -30,13 +30,6 @@ local function startServiceSecured() common.delayedExp() end -local function expNotificationFunc() - common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) - :Times(4) -end - --[[ Scenario ]] runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") @@ -46,7 +39,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("Register App", common.registerApp) -runner.Step("PolicyTableUpdate fails", common.policyTableUpdate, { ptUpdate, expNotificationFunc }) +runner.Step("PolicyTableUpdate without certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Activate App", common.activateApp) runner.Step("StartService Secured NACK, no Handshake", startServiceSecured) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua index f56e764971..a7cd7c0392 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua @@ -32,9 +32,8 @@ end local function expNotificationFunc() common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) - :Times(4) + :Times(2) end --[[ Scenario ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua index 4722aa4120..72217ca8a4 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua @@ -32,9 +32,8 @@ end local function expNotificationFunc() common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) - :Times(4) + :Times(2) end --[[ Scenario ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua index 917e9b4ba9..3d5ca7ee8a 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua @@ -20,6 +20,7 @@ local test = require("user_modules/dummy_connecttest") local expectations = require('expectations') local Expectation = expectations.Expectation local constants = require('protocol_handler/ford_protocol_constants') +local reporter = require("reporter") local m = {} @@ -183,16 +184,22 @@ end --! pMobSession - mobile session --]] local function registerExpectServiceEventFunc(pMobSession) - function pMobSession.mobile_session_impl.control_services:ExpectControlMessage(pServiceId, pData) + function pMobSession:ExpectControlMessage(pServiceId, pData) + local session = self.mobile_session_impl.control_services.session local event = events.Event() event.matches = function(_, data) return data.frameType == constants.FRAME_TYPE.CONTROL_FRAME and data.serviceType == pServiceId and - (pServiceId == constants.SERVICE_TYPE.RPC or data.sessionId == self.session.sessionId.get()) and + (pServiceId == constants.SERVICE_TYPE.RPC or data.sessionId == session.sessionId.get()) and (data.frameInfo == constants.FRAME_INFO.START_SERVICE_ACK or data.frameInfo == constants.FRAME_INFO.START_SERVICE_NACK) end - local ret = self.session:ExpectEvent(event, "StartService") + local ret = session:ExpectEvent(event, "StartService") + :Do(function(_, data) + if data.encryption == true and data.frameInfo == constants.FRAME_INFO.START_SERVICE_ACK then + session.security:registerSecureService(pServiceId) + end + end) :ValidIf(function(_, data) if data.encryption ~= pData.encryption then return false, "Expected 'encryption' flag is '" .. tostring(pData.encryption) @@ -209,61 +216,39 @@ local function registerExpectServiceEventFunc(pMobSession) end) return ret end - function pMobSession.mobile_session_impl:ExpectControlMessage(pServiceId, pData) - local ret = self.control_services:ExpectControlMessage(pServiceId, pData) - :Do(function(exp, data) - if exp.status ~= expectations.FAILED and data.encryption == true then - self.security:registerSecureService(pServiceId) - end - end) - return ret - end - function pMobSession:ExpectControlMessage(pServiceId, pData) - return self.mobile_session_impl:ExpectControlMessage(pServiceId, pData) - end - function pMobSession.mobile_session_impl.control_services:ExpectHandshakeMessage() - -- if not self.session.isSecuredSession then - local handshakeEvent = events.Event() - local handShakeExp - handshakeEvent.matches = function(_,data) - return data.frameType ~= constants.FRAME_TYPE.CONTROL_FRAME - and data.serviceType == constants.SERVICE_TYPE.CONTROL - and data.sessionId == self.session.sessionId.get() - and data.rpcType == constants.BINARY_RPC_TYPE.NOTIFICATION - and data.rpcFunctionId == constants.BINARY_RPC_FUNCTION_ID.HANDSHAKE - end - handShakeExp = self.session:ExpectEvent(handshakeEvent, "Handshake internal") - :Do(function(_, data) - local binData = data.binaryData - local dataToSend = self.session.security:performHandshake(binData) - if dataToSend then - local handshakeMessage = { - frameInfo = 0, - serviceType = constants.SERVICE_TYPE.CONTROL, - encryption = false, - rpcType = constants.BINARY_RPC_TYPE.NOTIFICATION, - rpcFunctionId = constants.BINARY_RPC_FUNCTION_ID.HANDSHAKE, - rpcCorrelationId = data.rpcCorrelationId, - binaryData = dataToSend - } - self.session:Send(handshakeMessage) - end - -- if self.session.security:isHandshakeFinished() then - -- self.session.test:RemoveExpectation(handShakeExp) - -- end - end) - -- end - return handShakeExp - end - function pMobSession:ExpectHandshakeMessage(service) + + function pMobSession:ExpectHandshakeMessage() + local session = self.mobile_session_impl.control_services.session local event = events.Event() event.matches = function(e1, e2) return e1 == e2 end local ret = pMobSession:ExpectEvent(event, "Handshake") - self.mobile_session_impl.control_services:ExpectHandshakeMessage(service) - :Do(function(e) - local isHandshakeFinished = self.mobile_session_impl.control_services.session.security:isHandshakeFinished() - -- print(e.occurences, isHandshakeFinished) - if isHandshakeFinished then + local handshakeEvent = events.Event() + handshakeEvent.matches = function(_, data) + return data.frameType ~= constants.FRAME_TYPE.CONTROL_FRAME + and data.serviceType == constants.SERVICE_TYPE.CONTROL + and data.sessionId == session.sessionId.get() + and data.rpcType == constants.BINARY_RPC_TYPE.NOTIFICATION + and data.rpcFunctionId == constants.BINARY_RPC_FUNCTION_ID.HANDSHAKE + end + session:ExpectEvent(handshakeEvent, "Handshake internal") + :Do(function(_, data) + local binData = data.binaryData + local dataToSend = session.security:performHandshake(binData) + if dataToSend then + local handshakeMessage = { + frameInfo = 0, + serviceType = constants.SERVICE_TYPE.CONTROL, + encryption = false, + rpcType = constants.BINARY_RPC_TYPE.NOTIFICATION, + rpcFunctionId = constants.BINARY_RPC_FUNCTION_ID.HANDSHAKE, + rpcCorrelationId = data.rpcCorrelationId, + binaryData = dataToSend + } + session:Send(handshakeMessage) + end + end) + :Do(function() + if session.security:isHandshakeFinished() then event_dispatcher:RaiseEvent(test.mobileConnection, event) end end) @@ -415,6 +400,8 @@ function m.policyTableUpdate(pPTUpdateFunc, pExpNotificationFunc, pAppId) if not pAppId then pAppId = 1 end if not pExpNotificationFunc then test.hmiConnection:ExpectNotification("SDL.OnStatusUpdate", { status = "UP_TO_DATE" }) + else + pExpNotificationFunc() end ptu(pPTUpdateFunc, pAppId) end @@ -483,6 +470,10 @@ function test.hmiConnection:ExpectRequest(pName, ...) else arguments = args[e.occurences] end + reporter.AddMessage("EXPECT_HMICALL", + { ["Id"] = data.id, ["name"] = tostring(pName),["Type"] = "EXPECTED_RESULT" }, arguments) + reporter.AddMessage("EXPECT_HMICALL", + { ["Id"] = data.id, ["name"] = tostring(pName),["Type"] = "AVAILABLE_RESULT" }, data.params) return compareValues(arguments, data.params, "params") end) end @@ -510,7 +501,12 @@ function test.hmiConnection:ExpectNotification(pName, ...) else arguments = args[e.occurences] end + local cid = test.notification_counter test.notification_counter = test.notification_counter + 1 + reporter.AddMessage("EXPECT_HMINOTIFICATION", + { ["Id"] = cid, ["name"] = tostring(pName), ["Type"] = "EXPECTED_RESULT" }, arguments) + reporter.AddMessage("EXPECT_HMINOTIFICATION", + { ["Id"] = cid, ["name"] = tostring(pName), ["Type"] = "AVAILABLE_RESULT" }, data.params) return compareValues(arguments, data.params, "params") end) end From 587a223179b159b2d3bbef85d5ddc4d2a4cee5a0 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 26 Dec 2017 17:46:43 +0200 Subject: [PATCH 245/681] Fix issue regarding long executuion of Postconditions --- .../Resumption/ATF_Resumption_3rd_ignition_cycle.lua | 12 +++++++++--- .../Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua | 7 +++++-- .../ATF_Resumption_LIMITED_IGNITION_OFF.lua | 7 +++++-- ...egistered_in_more_than_30sec_after_BC.OnReady.lua | 7 +++++-- ...ption_disconnect_more_than_30s_before_SUSPEND.lua | 7 +++++-- .../Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua | 5 ++++- .../Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua | 5 ++++- 7 files changed, 37 insertions(+), 13 deletions(-) diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua index d47ffc9a3e..786672fd52 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua @@ -99,7 +99,10 @@ function Test:IGNITION_OFF() EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") - SDL:DeleteFile() + :Do(function() + SDL:DeleteFile() + SDL:StopSDL() + end) end) end @@ -114,7 +117,10 @@ function Test:IGNITION_OFF() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") - SDL:DeleteFile() + :Do(function() + SDL:DeleteFile() + SDL:StopSDL() + end) end) end @@ -138,4 +144,4 @@ function Test.Stop_SDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua index 9b698c027e..b8647f0857 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua @@ -79,7 +79,10 @@ function Test:IGNITION_OFF() end) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") - SDL:DeleteFile() + :Do(function() + SDL:DeleteFile() + SDL:StopSDL() + end) end function Test:Restart_SDL_And_Add_Mobile_Connection() @@ -112,4 +115,4 @@ function Test.Stop_SDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua index ca6efe9b35..10345dd1c0 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua @@ -75,7 +75,10 @@ function Test:IGNITION_OFF() end) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") - SDL:DeleteFile() + :Do(function() + SDL:DeleteFile() + SDL:StopSDL() + end) end function Test:Restart_SDL_And_Add_Mobile_Connection() @@ -108,4 +111,4 @@ function Test.Stop_SDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua index 5d7f0e7f1c..777e763224 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua @@ -75,7 +75,10 @@ function Test:IGNITION_OFF() end) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") - SDL:DeleteFile() + :Do(function() + SDL:DeleteFile() + SDL:StopSDL() + end) end function Test:Restart_SDL_And_Add_Mobile_Connection() @@ -111,4 +114,4 @@ function Test.Stop_SDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua index 61e9463b51..07de63e7b7 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua @@ -84,7 +84,10 @@ function Test:IGNITION_OFF() { reason = "IGNITION_OFF" }) end) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") - SDL:DeleteFile() + :Do(function() + SDL:DeleteFile() + SDL:StopSDL() + end) end function Test:Restart_SDL_And_Add_Mobile_Connection() @@ -116,4 +119,4 @@ function Test.Stop_SDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua b/test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua index ecf80a0462..029d198d36 100644 --- a/test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua +++ b/test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua @@ -68,7 +68,10 @@ function Test:ShutDown_IGNITION_OFF() EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") - SDL:DeleteFile() + :Do(function() + SDL:DeleteFile() + SDL:StopSDL() + end) end) end diff --git a/test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua b/test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua index c05d9664a4..493fcfeb1b 100644 --- a/test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua +++ b/test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua @@ -98,7 +98,10 @@ function Test:ShutDown_MASTER_RESET() EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "MASTER_RESET" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") - SDL:DeleteFile() + :Do(function() + SDL:DeleteFile() + SDL:StopSDL() + end) end --- Start SDL again then add mobile connection From ea0f87c061931210594f32e4b62b3f424269e0d8 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 27 Dec 2017 00:53:31 +0200 Subject: [PATCH 246/681] Switch protocol version to 3 --- .../Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua | 1 - .../Trigger_PTU_NO_Certificate/1891_4_navi_video.lua | 1 - .../Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua | 1 - .../Trigger_PTU_NO_Certificate/1894_4_navi_video.lua | 1 - .../Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua | 1 - .../Trigger_PTU_NO_Certificate/1922_2_navi_video.lua | 1 - .../Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua | 1 - .../Trigger_PTU_NO_Certificate/1923_2_navi_video.lua | 1 - .../Policies_Security/Trigger_PTU_NO_Certificate/common.lua | 2 +- 9 files changed, 1 insertion(+), 9 deletions(-) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua index 1322f666ae..8b3d83d71a 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua @@ -10,7 +10,6 @@ local serviceId = 10 local appHMIType = "NAVIGATION" --[[ General configuration parameters ]] -config.defaultProtocolVersion = 3 config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua index 0085fc5582..b6e1288e21 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua @@ -10,7 +10,6 @@ local serviceId = 11 local appHMIType = "NAVIGATION" --[[ General configuration parameters ]] -config.defaultProtocolVersion = 3 config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua index 053eb10462..cd509f06f7 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua @@ -10,7 +10,6 @@ local serviceId = 10 local appHMIType = "NAVIGATION" --[[ General configuration parameters ]] -config.defaultProtocolVersion = 3 config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua index 8f117912a9..6d94ec8ffc 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua @@ -10,7 +10,6 @@ local serviceId = 11 local appHMIType = "NAVIGATION" --[[ General configuration parameters ]] -config.defaultProtocolVersion = 3 config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua index 9e0f4f5c69..dc1d08cd0c 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua @@ -10,7 +10,6 @@ local serviceId = 10 local appHMIType = "NAVIGATION" --[[ General configuration parameters ]] -config.defaultProtocolVersion = 3 config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua index 9bc988b6e6..860446a2df 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua @@ -10,7 +10,6 @@ local serviceId = 11 local appHMIType = "NAVIGATION" --[[ General configuration parameters ]] -config.defaultProtocolVersion = 3 config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua index a7cd7c0392..b78df62536 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua @@ -10,7 +10,6 @@ local serviceId = 10 local appHMIType = "NAVIGATION" --[[ General configuration parameters ]] -config.defaultProtocolVersion = 3 config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua index 72217ca8a4..46abe87634 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua @@ -10,7 +10,6 @@ local serviceId = 11 local appHMIType = "NAVIGATION" --[[ General configuration parameters ]] -config.defaultProtocolVersion = 3 config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua index 3d5ca7ee8a..8931c93b45 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua @@ -3,7 +3,7 @@ --------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" -config.defaultProtocolVersion = 2 +config.defaultProtocolVersion = 3 config.serverCertificatePath = "./files/Security/spt_credential.pem" config.serverPrivateKeyPath = "./files/Security/spt_credential.pem" From 7c037ebfeca8fb3c490259ea44de9331426732a1 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 27 Dec 2017 15:13:17 +0200 Subject: [PATCH 247/681] Fix issues according to comments in review --- .../Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua | 2 +- .../Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua | 2 +- .../Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua | 2 +- .../Trigger_PTU_NO_Certificate/1922_2_navi_video.lua | 2 +- .../Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua | 2 +- .../Trigger_PTU_NO_Certificate/1923_2_navi_video.lua | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua index d572d47279..be77198293 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua @@ -38,7 +38,7 @@ end runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0A" }) +runner.Step("Set ForceProtectedService ON", common.setForceProtectedServiceParam, { "0x0A" }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua index dbbb3f3c83..0f0f420c46 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua @@ -38,7 +38,7 @@ end runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0B" }) +runner.Step("Set ForceProtectedService ON", common.setForceProtectedServiceParam, { "0x0B" }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua index dc1d08cd0c..993ab149ab 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua @@ -33,7 +33,7 @@ end runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0A" }) +runner.Step("Set ForceProtectedService ON", common.setForceProtectedServiceParam, { "0x0A" }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua index 860446a2df..b425bb3e61 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua @@ -33,7 +33,7 @@ end runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0B" }) +runner.Step("Set ForceProtectedService ON", common.setForceProtectedServiceParam, { "0x0B" }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua index b78df62536..3fd4ca53c1 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua @@ -39,7 +39,7 @@ end runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0A" }) +runner.Step("Set ForceProtectedService ON", common.setForceProtectedServiceParam, { "0x0A" }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua index 46abe87634..ddf73bcb6f 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua @@ -39,7 +39,7 @@ end runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "0x0B" }) +runner.Step("Set ForceProtectedService ON", common.setForceProtectedServiceParam, { "0x0B" }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") From 391ab594ce5023ce73df9134c3933eda6f8448ef Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Wed, 27 Dec 2017 18:54:50 +0200 Subject: [PATCH 248/681] Move isSelfIncluded option of runner to test settings --- .../Trigger_PTU_NO_Certificate/1888_1_navi.lua | 4 +++- .../Trigger_PTU_NO_Certificate/1888_2_non-navi.lua | 4 +++- .../1888_3_navi_audio_force_off.lua | 4 +++- .../1888_4_navi_video_force_off.lua | 4 +++- .../1888_5_navi_audio_force_on.lua | 4 +++- .../1888_6_navi_video_force_on.lua | 4 +++- .../Trigger_PTU_NO_Certificate/1891_1_navi.lua | 4 +++- .../Trigger_PTU_NO_Certificate/1891_2_non-navi.lua | 4 +++- .../1891_3_navi_audio.lua | 4 +++- .../1891_4_navi_video.lua | 4 +++- .../Trigger_PTU_NO_Certificate/1894_1_navi.lua | 4 +++- .../Trigger_PTU_NO_Certificate/1894_2_non-navi.lua | 4 +++- .../1894_3_navi_audio.lua | 4 +++- .../1894_4_navi_video.lua | 4 +++- .../1922_1_navi_audio.lua | 4 +++- .../1922_2_navi_video.lua | 4 +++- .../1923_1_navi_audio.lua | 4 +++- .../1923_2_navi_video.lua | 4 +++- .../Trigger_PTU_NO_Certificate/1924_1_non-navi.lua | 4 +++- .../Trigger_PTU_NO_Certificate/1924_2_navi.lua | 4 +++- .../1925_1_navi_no_cert_new_app.lua | 4 +++- .../1925_2_navi_no_cert_existing_app.lua | 4 +++- .../1925_3_navi_cert_new_app.lua | 4 +++- .../1925_4_navi_cert_existing_app.lua | 4 +++- .../1925_5_non-navi_no_cert_new_app.lua | 4 +++- .../1925_6_non-navi_no_cert_existing_app.lua | 4 +++- .../1925_7_non-navi_cert_new_app.lua | 4 +++- .../1925_8_non-navi_cert_existing_app.lua | 4 +++- user_modules/script_runner.lua | 13 +------------ user_modules/test_settings.lua | 3 ++- 30 files changed, 87 insertions(+), 41 deletions(-) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua index 67c40333a4..1db2e4bf56 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 7 local appHMIType = "NAVIGATION" @@ -52,7 +55,6 @@ local function sendRPCAddCommandSecured() end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua index 63e338c9b5..fa5fb3a6c9 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 7 local appHMIType = "DEFAULT" @@ -66,7 +69,6 @@ local function sendRPCAddCommandSecured() end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua index 2d73a3aa9b..967684814b 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 10 local appHMIType = "NAVIGATION" @@ -35,7 +38,6 @@ local function startServiceSecured(pData) end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua index bfd086424c..c4b70bb299 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 11 local appHMIType = "NAVIGATION" @@ -35,7 +38,6 @@ local function startServiceSecured(pData) end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua index be77198293..af2e6bb516 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 10 local appHMIType = "NAVIGATION" @@ -35,7 +38,6 @@ local function startServiceSecured(pData) end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService ON", common.setForceProtectedServiceParam, { "0x0A" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua index 0f0f420c46..aa721314f5 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 11 local appHMIType = "NAVIGATION" @@ -35,7 +38,6 @@ local function startServiceSecured(pData) end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService ON", common.setForceProtectedServiceParam, { "0x0B" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua index 2dea8793de..dd0e47caba 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 7 local appHMIType = "NAVIGATION" @@ -36,7 +39,6 @@ local function expNotificationFunc() end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua index 795871dc36..f6de164cde 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 7 local appHMIType = "DEFAULT" @@ -43,7 +46,6 @@ local function startServiceSecured() end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua index 8b3d83d71a..555b85a265 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 10 local appHMIType = "NAVIGATION" @@ -37,7 +40,6 @@ local function startServiceSecured() end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua index b6e1288e21..7915ba22f4 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 11 local appHMIType = "NAVIGATION" @@ -37,7 +40,6 @@ local function startServiceSecured() end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua index 5cdc1a7b6c..53eff9b445 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 7 local appHMIType = "NAVIGATION" @@ -30,7 +33,6 @@ local function startServiceSecured() end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua index c434793301..2fa333ff3f 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 7 local appHMIType = "DEFAULT" @@ -38,7 +41,6 @@ local function startServiceSecured() end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua index cd509f06f7..c57c3b5046 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 10 local appHMIType = "NAVIGATION" @@ -30,7 +33,6 @@ local function startServiceSecured() end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua index 6d94ec8ffc..ae45211da2 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 11 local appHMIType = "NAVIGATION" @@ -30,7 +33,6 @@ local function startServiceSecured() end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService OFF", common.setForceProtectedServiceParam, { "Non" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua index 993ab149ab..bcd58ba17d 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 10 local appHMIType = "NAVIGATION" @@ -30,7 +33,6 @@ local function startServiceSecured() end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService ON", common.setForceProtectedServiceParam, { "0x0A" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua index b425bb3e61..b62884c322 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 11 local appHMIType = "NAVIGATION" @@ -30,7 +33,6 @@ local function startServiceSecured() end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService ON", common.setForceProtectedServiceParam, { "0x0B" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua index 3fd4ca53c1..d913b5b9d8 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 10 local appHMIType = "NAVIGATION" @@ -36,7 +39,6 @@ local function expNotificationFunc() end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService ON", common.setForceProtectedServiceParam, { "0x0A" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua index ddf73bcb6f..0c71513630 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 11 local appHMIType = "NAVIGATION" @@ -36,7 +39,6 @@ local function expNotificationFunc() end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Set ForceProtectedService ON", common.setForceProtectedServiceParam, { "0x0B" }) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua index 7e507df77a..74ee21d462 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 7 local appHMIType = "DEFAULT" @@ -31,7 +34,6 @@ local function startServiceSecured() end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua index 9fff6caf34..7b5903bb2a 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local serviceId = 7 local appHMIType = "NAVIGATION" @@ -34,7 +37,6 @@ local function startServiceSecured() end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua index c4cbe782a4..d86f8d52d0 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local appHMIType = { [1] = "DEFAULT", @@ -29,7 +32,6 @@ local function registerApp(pAppId) end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua index e5cc1a8726..d6e158ef61 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local appHMIType = { [1] = "DEFAULT", @@ -31,7 +34,6 @@ local function registerApp(pAppId) end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua index ec574bb074..b56b023f33 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local appHMIType = { [1] = "DEFAULT", @@ -32,7 +35,6 @@ local function registerApp(pAppId) end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua index dd0f02c0b8..301d417951 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local appHMIType = { [1] = "DEFAULT", @@ -36,7 +39,6 @@ local function registerApp(pAppId) end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua index bba6c14561..8ed92f0b01 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local appHMIType = { [1] = "DEFAULT", @@ -29,7 +32,6 @@ local function registerApp(pAppId) end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua index 8880ace1f2..1278d77ec0 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local appHMIType = { [1] = "DEFAULT", @@ -33,7 +36,6 @@ local function registerApp(pAppId) end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua index 73ad4df281..f104d3e264 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local appHMIType = { [1] = "DEFAULT", @@ -32,7 +35,6 @@ local function registerApp(pAppId) end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua index 34664d1008..8b030b5753 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua @@ -5,6 +5,9 @@ local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local appHMIType = { [1] = "DEFAULT", @@ -36,7 +39,6 @@ local function registerApp(pAppId) end --[[ Scenario ]] -runner.SetParameters({ isSelfIncluded = false }) runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/user_modules/script_runner.lua b/user_modules/script_runner.lua index 43f3e7fc24..e1b9edd26a 100644 --- a/user_modules/script_runner.lua +++ b/user_modules/script_runner.lua @@ -5,11 +5,9 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local isInitialStep = true local isPrintTitle = false -local isSelfIncluded = true local title local runner = {} - runner.testSettings = testSettings Test.isTest = true @@ -88,7 +86,7 @@ local function extendedAddTestStep(testStepName, testStepImplFunction, paramsTab table.insert(implFunctionsListWithParams, {implFunc = testStepImplFunction, params = paramsTable}) local newTestStepImplFunction = function(self) for _, func in pairs(implFunctionsListWithParams) do - if isSelfIncluded == true then + if runner.testSettings.isSelfIncluded == true then table.insert(func.params, self) end func.implFunc(unpack(func.params, 1, table.maxn(func.params))) @@ -186,13 +184,4 @@ function runner.Step(testStepName, testStepImplFunction, paramsTable) end end -function runner.SetParameters(paramsTable) - if paramsTable == nil or type(paramsTable) ~= "table" then return end - for k, v in pairs(paramsTable) do - if k == "isSelfIncluded" then - isSelfIncluded = v - end - end -end - return runner diff --git a/user_modules/test_settings.lua b/user_modules/test_settings.lua index 7c9e4550b1..9ef87a0c4e 100644 --- a/user_modules/test_settings.lua +++ b/user_modules/test_settings.lua @@ -4,7 +4,8 @@ local testSettings = { restrictions = { sdlBuildOptions = {} -- no restrictions on SDL configuration }, - defaultTimeout = 10000 + defaultTimeout = 10000, + isSelfIncluded = true } return testSettings From 7ad36258ce5732579fd51ca25f38946eb9f3d03a Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 28 Dec 2017 10:55:14 +0200 Subject: [PATCH 249/681] Add explicit removal of certificate from Policy DB --- .../Trigger_PTU_NO_Certificate/1891_2_non-navi.lua | 1 + .../Trigger_PTU_NO_Certificate/1924_1_non-navi.lua | 1 + .../Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua | 1 + .../Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua | 1 + .../1925_2_navi_no_cert_existing_app.lua | 1 + .../1925_5_non-navi_no_cert_new_app.lua | 1 + .../1925_6_non-navi_no_cert_existing_app.lua | 1 + 7 files changed, 7 insertions(+) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua index f6de164cde..dab7ecd82a 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua @@ -17,6 +17,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdateSuccess(pTbl) + pTbl.policy_table.module_config.certificate = nil pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua index 74ee21d462..033cf23aec 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua @@ -17,6 +17,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua index 7b5903bb2a..ffe5626686 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua @@ -17,6 +17,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua index d86f8d52d0..1ba56e9923 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua @@ -20,6 +20,7 @@ config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } --[[ Local Functions ]] local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } end diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua index d6e158ef61..7aaabb80d1 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua @@ -20,6 +20,7 @@ config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } --[[ Local Functions ]] local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } common.updatePTU(pTbl, 2) pTbl.policy_table.app_policies[common.getAppID(2)].AppHMIType = { appHMIType[2] } diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua index 8ed92f0b01..f2da6966d2 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua @@ -20,6 +20,7 @@ config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } --[[ Local Functions ]] local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } end diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua index 1278d77ec0..ecee551524 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua +++ b/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua @@ -20,6 +20,7 @@ config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } --[[ Local Functions ]] local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } common.updatePTU(pTbl, 2) pTbl.policy_table.app_policies[common.getAppID(2)].AppHMIType = { appHMIType[2] } From 29a323cb7809e3c4e2258a587eb0e1577cf19399 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 28 Dec 2017 12:15:57 +0200 Subject: [PATCH 250/681] Move test scripts to another folder --- .../4_5}/Trigger_PTU_NO_Certificate/1888_1_navi.lua | 2 +- .../4_5}/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua | 2 +- .../Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua | 2 +- .../Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua | 2 +- .../Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua | 2 +- .../Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua | 2 +- .../4_5}/Trigger_PTU_NO_Certificate/1891_1_navi.lua | 2 +- .../4_5}/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua | 2 +- .../4_5}/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua | 2 +- .../4_5}/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua | 2 +- .../4_5}/Trigger_PTU_NO_Certificate/1894_1_navi.lua | 2 +- .../4_5}/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua | 2 +- .../4_5}/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua | 2 +- .../4_5}/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua | 2 +- .../4_5}/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua | 2 +- .../4_5}/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua | 2 +- .../4_5}/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua | 2 +- .../4_5}/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua | 2 +- .../4_5}/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua | 2 +- .../4_5}/Trigger_PTU_NO_Certificate/1924_2_navi.lua | 2 +- .../Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua | 2 +- .../1925_2_navi_no_cert_existing_app.lua | 2 +- .../Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua | 2 +- .../1925_4_navi_cert_existing_app.lua | 2 +- .../1925_5_non-navi_no_cert_new_app.lua | 2 +- .../1925_6_non-navi_no_cert_existing_app.lua | 2 +- .../Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua | 2 +- .../1925_8_non-navi_cert_existing_app.lua | 2 +- .../4_5}/Trigger_PTU_NO_Certificate/common.lua | 0 29 files changed, 28 insertions(+), 28 deletions(-) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1888_1_navi.lua (96%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua (97%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua (95%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua (95%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua (95%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua (95%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1891_1_navi.lua (95%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua (95%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua (95%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua (95%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1894_1_navi.lua (94%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua (95%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua (94%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua (94%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua (94%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua (94%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua (95%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua (95%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua (94%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1924_2_navi.lua (94%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua (94%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua (94%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua (94%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua (95%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua (94%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua (94%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua (94%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua (95%) rename test_scripts/{Policies/Policies_Security => Defects/4_5}/Trigger_PTU_NO_Certificate/common.lua (100%) diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_1_navi.lua similarity index 96% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_1_navi.lua index 1db2e4bf56..98eac05c46 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_1_navi.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_1_navi.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1888 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua similarity index 97% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua index fa5fb3a6c9..34ff3608bd 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1888 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua similarity index 95% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua index 967684814b..41c726f208 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1888 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua similarity index 95% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua index c4b70bb299..d715b8ac5f 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1888 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua similarity index 95% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua index af2e6bb516..6f259f1b16 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1888 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua similarity index 95% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua index aa721314f5..1eef37afbf 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1888 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_1_navi.lua similarity index 95% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_1_navi.lua index dd0e47caba..adf0a6f0b2 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_1_navi.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_1_navi.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1891 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua similarity index 95% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua index dab7ecd82a..7abe903165 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1891 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua similarity index 95% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua index 555b85a265..37af0eec96 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1891 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua similarity index 95% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua index 7915ba22f4..8e1bd82230 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1891 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_1_navi.lua similarity index 94% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_1_navi.lua index 53eff9b445..1c47142849 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_1_navi.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_1_navi.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1894 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua similarity index 95% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua index 2fa333ff3f..c29e64a6b7 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1894 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua similarity index 94% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua index c57c3b5046..a857a7d08a 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1894 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua similarity index 94% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua index ae45211da2..cdb233ccd9 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1894 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua similarity index 94% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua index bcd58ba17d..93425e08bd 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1922 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua similarity index 94% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua index b62884c322..ef8631d651 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1922 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua similarity index 95% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua index d913b5b9d8..92d37bade3 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1923 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua similarity index 95% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua index 0c71513630..99ee1a1829 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1923 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua similarity index 94% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua index 033cf23aec..65c08ae593 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1924 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1924_2_navi.lua similarity index 94% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1924_2_navi.lua index ffe5626686..112cdb1d4b 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1924_2_navi.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1924_2_navi.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1924 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua similarity index 94% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua index 1ba56e9923..62b367fc45 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1925 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua similarity index 94% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua index 7aaabb80d1..8293893881 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1925 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua similarity index 94% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua index b56b023f33..2ba5a572e5 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1925 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua similarity index 95% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua index 301d417951..7f8a80d78e 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1925 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua similarity index 94% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua index f2da6966d2..554d02ec7a 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1925 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua similarity index 94% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua index ecee551524..84da86156a 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1925 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua similarity index 94% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua index f104d3e264..1e002fbcf8 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1925 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua similarity index 95% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua index 8b030b5753..45967a1e87 100644 --- a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua @@ -2,7 +2,7 @@ -- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1925 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common') +local common = require('test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua similarity index 100% rename from test_scripts/Policies/Policies_Security/Trigger_PTU_NO_Certificate/common.lua rename to test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua From 8a081f94d518811469920f0e8f622813b02937db Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 27 Dec 2017 13:51:29 +0200 Subject: [PATCH 251/681] Updated script --- ...Invalid_PT_after_cutting_unknow_values.lua | 108 +++++++++++++++--- test_scripts/Defects/4_5/commonDefects.lua | 4 +- 2 files changed, 92 insertions(+), 20 deletions(-) diff --git a/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua b/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua index de2d88672d..426702cfa0 100644 --- a/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua +++ b/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua @@ -13,23 +13,43 @@ local runner = require('user_modules/script_runner') local commonDefects = require('test_scripts/Defects/4_5/commonDefects') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local commonSteps = require ('user_modules/shared_testcases/commonSteps') +local json = require("modules/json") --[[ Local Functions ]] -local isCuttingUnknownError = false local isError local ErrorMessage +-- Path to policy table snapshot +local pathToPTS = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" +.. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") --[[ Local Functions ]] +--[[ @ptsToTable: decode snapshot from json to table +--! @parameters: +--! pts_f - file for decode +--! @return: created table from file +--]] +local function ptsToTable(pts_f) + local f = io.open(pts_f, "r") + local content = f:read("*all") + f:close() + return json.decode(content) +end + +--[[ @ptuUpdateFunc: update table for PTU +--! @parameters: +--! tbl - table for update +--! @return: none +--]] local function ptuUpdateFunc(tbl) local VDgroup = { rpcs = { GetVehicleData = { hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, - parameters = {"gps"} + parameters = {"gps", "newParameter"} }, SubscribeVehicleData = { hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, - newParameter = {"value"} }, UnknownAPI = { hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, @@ -45,16 +65,20 @@ local function ptuUpdateFunc(tbl) {"Base-4", "NewTestCaseGroup"} end +--[[ @NotValidPtuUpdateFunc: update table for PTU with invalid content +--! @parameters: +--! tbl - table for update +--! @return: none +--]] local function NotValidPtuUpdateFunc(tbl) local VDgroup = { rpcs = { GetVehicleData = { hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, - parameters = {"gps"} + parameters = {"gps", "newParameter"} }, SubscribeVehicleData = { hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, - newParameter = {"value"} }, UnknownAPI = { hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, @@ -70,11 +94,22 @@ local function NotValidPtuUpdateFunc(tbl) {"Base-4", "NewTestCaseGroup"} end +--[[ @ErrorOccurred: set error status and write Error message +--! @parameters: +--! Message - Error message +--! @return: none +--]] local function ErrorOccurred(Message) isError = true ErrorMessage = ErrorMessage .. Message end +--[[ @CheckCuttingUnknowValues: Perform app registration, PTU and check absence of unknown values in +--! OnPermissionsChange notification +--! @parameters: +--! self - test object +--! @return: none +--]] local function CheckCuttingUnknowValues(self) commonDefects.rai_ptu_n_without_OnPermissionsChange(1, ptuUpdateFunc,self) self.mobileSession1:ExpectNotification("OnPermissionsChange") @@ -85,11 +120,10 @@ local function CheckCuttingUnknowValues(self) if #data.payload.permissionItem ~= 0 then for i=1, #data.payload.permissionItem do if data.payload.permissionItem[i].rpcName == "UnknownAPI" then - isCuttingUnknownError = true ErrorOccurred(" OnPermissionsChange contains unknown_RPC value.\n") end - if data.payload.permissionItem[i].newParameter then - isCuttingUnknownError = true + if data.payload.permissionItem[i].parameterPermissions.allowed["newParameter"] or + data.payload.permissionItem[i].parameterPermissions.userDisallowed["newParameter"] then ErrorOccurred(" OnPermissionsChange contains unknown_parameter value.\n") end end @@ -102,18 +136,56 @@ local function CheckCuttingUnknowValues(self) return true end end) - commonFunctions:userPrint(33, "Check PTU content of PTU attempt in SDL log by message 'PTU content is'.\n" - .. "'policy_table' must not contain 'newParameter' and 'UnknownAPI' values.") end +--[[ @removeSnapshotAndTriggerPTUFromHMI: Remove snapshot and trigger PTU from HMI for creation new snapshot, +--! check absence of unknown parameters in snapshot +--! @parameters: +--! self - test object +--! @return: none +--]] +local function removeSnapshotAndTriggerPTUFromHMI(self) + -- remove Snapshot + os.execute("rm -f " .. pathToPTS) + -- expect PolicyUpdate request on HMI side + EXPECT_HMICALL("BasicCommunication.PolicyUpdate", { file = pathToPTS }) + :Do(function() + if (commonSteps:file_exists(pathToPTS) == false) then + self:FailTestCase(pathToPTS .. " is not created") + else + local isErrorInvalidPT = false + local ErrorMessageInvalidPT = "" + local pts = ptsToTable(pathToPTS) + local isUnknownAPI = pts.policy_table.functional_groupings.NewTestCaseGroup.rpcs["UnknownAPI"] + local isnewParameter = pts.policy_table.functional_groupings.NewTestCaseGroup.rpcs.GetVehicleData.parameters["newParameter"] + if isUnknownAPI then + isErrorInvalidPT = true + ErrorMessageInvalidPT = ErrorMessageInvalidPT .. "Snapshot contains UnknownAPI\n" + end + if isnewParameter then + isErrorInvalidPT = true + ErrorMessageInvalidPT = ErrorMessageInvalidPT .. "Snapshot contains newParameter for GetVehicleData RPC\n" + end + if isErrorInvalidPT == true then + self:FailTestCase(ErrorMessageInvalidPT) + end + end + end) + -- Sending OnPolicyUpdate notification form HMI + self.hmiConnection:SendNotification("SDL.OnPolicyUpdate", { }) + -- Expect OnStatusUpdate notifications on HMI side + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(2) +end + +--[[ @InvalidPTAfterCutingUnknownValues: Unsuccessful policy table update +--! @parameters: +--! self - test object +--! @return: none +--]] local function InvalidPTAfterCutingUnknownValues(self) - if isCuttingUnknownError == true then - self:FailTestCase("Unknown values are not cut from PT, so test case is not executed.") - else - commonDefects.UnsuccessPTU(NotValidPtuUpdateFunc,self) - commonFunctions:userPrint(33, "Check PTU content of second PTU attempt in SDL log by message" .. - " 'PTU content is'.\n'policy_table' must not contain 'newParameter' and 'UnknownAPI' values.") - end + commonDefects.UnsuccessPTU(NotValidPtuUpdateFunc,self) end --[[ Scenario ]] @@ -123,8 +195,8 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start runner.Title("Test") runner.Step("Check_cutting_unknown_values_from_PT", CheckCuttingUnknowValues) +runner.Step("Remove Snapshot and trigger PTU, check new created PTS", removeSnapshotAndTriggerPTUFromHMI) runner.Step("Invalid_PTU_after_cuting_unknown_values", InvalidPTAfterCutingUnknownValues) runner.Title("Postconditions") runner.Step("Stop SDL", commonDefects.postconditions) - diff --git a/test_scripts/Defects/4_5/commonDefects.lua b/test_scripts/Defects/4_5/commonDefects.lua index b5b7ab0d6e..ab8d77df78 100644 --- a/test_scripts/Defects/4_5/commonDefects.lua +++ b/test_scripts/Defects/4_5/commonDefects.lua @@ -306,7 +306,7 @@ function commonDefect.rai_ptu_n(id, ptu_update_func, self) :Do(function(_, d1) hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID EXPECT_HMICALL("BasicCommunication.PolicyUpdate") - :Do(function(_, d2) + :DoOnce(function(_, d2) self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) ptu_table = jsonFileToTable(d2.params.file) ptu(self, ptu_update_func) @@ -346,7 +346,7 @@ function commonDefect.rai_ptu_n_without_OnPermissionsChange(id, ptu_update_func, { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) :Times(3) EXPECT_HMICALL("BasicCommunication.PolicyUpdate") - :Do(function(_, d2) + :DoOnce(function(_, d2) self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) ptu_table = jsonFileToTable(d2.params.file) ptu(self, ptu_update_func) From 6287053ca9388381f7b17a1986af6940f03806ae Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 28 Dec 2017 09:30:20 +0200 Subject: [PATCH 252/681] Separated cases for unknown RPC and parameters --- ...Invalid_PT_after_cutting_unknow_values.lua | 88 +++++++++++++++---- 1 file changed, 73 insertions(+), 15 deletions(-) diff --git a/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua b/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua index 426702cfa0..9d3e2c0ca1 100644 --- a/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua +++ b/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua @@ -16,12 +16,16 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local json = require("modules/json") ---[[ Local Functions ]] +--[[ Local variables ]] local isError local ErrorMessage -- Path to policy table snapshot local pathToPTS = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") +local SendLocationParams = { + longitudeDegrees = 1.1, + latitudeDegrees = 1.1, +} --[[ Local Functions ]] --[[ @ptsToTable: decode snapshot from json to table @@ -36,33 +40,49 @@ local function ptsToTable(pts_f) return json.decode(content) end ---[[ @ptuUpdateFunc: update table for PTU +--[[ @ptuUpdateFuncParams: update table with unknown parameters for PTU --! @parameters: --! tbl - table for update --! @return: none --]] -local function ptuUpdateFunc(tbl) +local function ptuUpdateFuncParams(tbl) local VDgroup = { rpcs = { GetVehicleData = { - hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, + hmi_levels = {"NONE", "BACKGROUND", "FULL", "LIMITED"}, parameters = {"gps", "newParameter"} }, SubscribeVehicleData = { - hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, - }, + hmi_levels = {"NONE", "BACKGROUND", "FULL", "LIMITED"}, + parameters = {"newParameter"} + } + } + } + tbl.policy_table.functional_groupings["NewTestCaseGroup1"] = VDgroup + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = + {"Base-4", "NewTestCaseGroup1"} +end + +--[[ @ptuUpdateFuncRPC: update table with unknown RPC for PTU +--! @parameters: +--! tbl - table for update +--! @return: none +--]] +local function ptuUpdateFuncRPC(tbl) + local VDgroup = { + rpcs = { UnknownAPI = { - hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, + hmi_levels = {"NONE", "BACKGROUND", "FULL", "LIMITED"}, parameters = {"gps"} }, SendLocation = { - hmi_levels = {"BACKGROUND", "FULL", "LIMITED"} + hmi_levels = {"NONE", "BACKGROUND", "FULL", "LIMITED"} } } } - tbl.policy_table.functional_groupings["NewTestCaseGroup"] = VDgroup + tbl.policy_table.functional_groupings["NewTestCaseGroup2"] = VDgroup tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = - {"Base-4", "NewTestCaseGroup"} + {"Base-4", "NewTestCaseGroup2"} end --[[ @NotValidPtuUpdateFunc: update table for PTU with invalid content @@ -110,7 +130,7 @@ end --! self - test object --! @return: none --]] -local function CheckCuttingUnknowValues(self) +local function CheckCuttingUnknowValues(ptuUpdateFunc, self) commonDefects.rai_ptu_n_without_OnPermissionsChange(1, ptuUpdateFunc,self) self.mobileSession1:ExpectNotification("OnPermissionsChange") :Times(2) @@ -120,7 +140,7 @@ local function CheckCuttingUnknowValues(self) if #data.payload.permissionItem ~= 0 then for i=1, #data.payload.permissionItem do if data.payload.permissionItem[i].rpcName == "UnknownAPI" then - ErrorOccurred(" OnPermissionsChange contains unknown_RPC value.\n") + commonFunctions:userPrint(33, " OnPermissionsChange contains unknown_RPC value.\n") end if data.payload.permissionItem[i].parameterPermissions.allowed["newParameter"] or data.payload.permissionItem[i].parameterPermissions.userDisallowed["newParameter"] then @@ -159,8 +179,7 @@ local function removeSnapshotAndTriggerPTUFromHMI(self) local isUnknownAPI = pts.policy_table.functional_groupings.NewTestCaseGroup.rpcs["UnknownAPI"] local isnewParameter = pts.policy_table.functional_groupings.NewTestCaseGroup.rpcs.GetVehicleData.parameters["newParameter"] if isUnknownAPI then - isErrorInvalidPT = true - ErrorMessageInvalidPT = ErrorMessageInvalidPT .. "Snapshot contains UnknownAPI\n" + commonFunctions:userPrint(33, " Snapshot contains UnknownAPI\n") end if isnewParameter then isErrorInvalidPT = true @@ -188,14 +207,53 @@ local function InvalidPTAfterCutingUnknownValues(self) commonDefects.UnsuccessPTU(NotValidPtuUpdateFunc,self) end +--[[ @SuccessfulProcessingRPC: Successful processing API +--! @parameters: +--! RPC - RPC name +--! params - RPC params for mobile request +--! interface - interface of RPC on HMI +--! self - test object +--! @return: none +--]] +local function SuccessfulProcessingRPC(RPC, params, interface, self) + local cid = self.mobileSession1:SendRPC(RPC, params) + EXPECT_HMICALL(interface .. "." .. RPC, params) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + self.mobileSession1:ExpectResponse(cid,{ success = true, resultCode = "SUCCESS" }) +end + +--[[ @DissalowedRPC: Unsuccessful processing SubscribeVehicleData +--! @parameters: +--! self - test object +--! @return: none +--]] +local function DissalowedRPC(self) + local cid = self.mobileSession1:SendRPC("SubscribeVehicleData", {gps = true}) + EXPECT_HMICALL("VehicleInfo.SubscribeVehicleData") + :Times(0) + self.mobileSession1:ExpectResponse(cid,{ success = false, resultCode = "DISALLOWED" }) + commonDefects.delayedExp() +end + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonDefects.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start) runner.Title("Test") -runner.Step("Check_cutting_unknown_values_from_PT", CheckCuttingUnknowValues) +runner.Step("App registration, PTU with unknown API", CheckCuttingUnknowValues, {ptuUpdateFuncRPC}) +runner.Step("Check applying of PT by processing SendLocation", SuccessfulProcessingRPC, + {"SendLocation", SendLocationParams, "Navigation"}) +runner.Step("Unregister application", commonDefects.unregisterApp, {1}) + +runner.Step("App registration, PTU with unknown parameters", CheckCuttingUnknowValues, {ptuUpdateFuncParams}) runner.Step("Remove Snapshot and trigger PTU, check new created PTS", removeSnapshotAndTriggerPTUFromHMI) +runner.Step("Check applying of PT by processing GetVehicleData", SuccessfulProcessingRPC, + {"GetVehicleData", {gps = true}, "VehicleInfo"}) +runner.Step("Check applying of PT by processing SubscribeVehicleData", DissalowedRPC) + runner.Step("Invalid_PTU_after_cuting_unknown_values", InvalidPTAfterCutingUnknownValues) runner.Title("Postconditions") From bb6522cea8ec03d99fabf2dd170937593611b9bf Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 28 Dec 2017 17:19:36 +0200 Subject: [PATCH 253/681] Fix issues and refactoring --- ...Invalid_PT_after_cutting_unknow_values.lua | 201 +++++++++--------- test_scripts/Defects/4_5/commonDefects.lua | 68 +----- 2 files changed, 108 insertions(+), 161 deletions(-) diff --git a/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua b/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua index 9d3e2c0ca1..05a792feb1 100644 --- a/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua +++ b/test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua @@ -17,17 +17,19 @@ local commonSteps = require ('user_modules/shared_testcases/commonSteps') local json = require("modules/json") --[[ Local variables ]] -local isError -local ErrorMessage --- Path to policy table snapshot +-- define path to policy table snapshot local pathToPTS = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" -.. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") +-- set default parameters for 'SendLocation' RPC local SendLocationParams = { longitudeDegrees = 1.1, latitudeDegrees = 1.1, } +local unknownAPI = "UnknownAPI" +local unknownParameter = "unknownParameter" --[[ Local Functions ]] + --[[ @ptsToTable: decode snapshot from json to table --! @parameters: --! pts_f - file for decode @@ -40,49 +42,45 @@ local function ptsToTable(pts_f) return json.decode(content) end ---[[ @ptuUpdateFuncParams: update table with unknown parameters for PTU +--[[ @ptuUpdateFuncRPC: update table with unknown RPC for PTU --! @parameters: --! tbl - table for update --! @return: none --]] -local function ptuUpdateFuncParams(tbl) +local function ptuUpdateFuncRPC(tbl) local VDgroup = { rpcs = { - GetVehicleData = { - hmi_levels = {"NONE", "BACKGROUND", "FULL", "LIMITED"}, - parameters = {"gps", "newParameter"} + [unknownAPI] = { + hmi_levels = { "NONE", "BACKGROUND", "FULL", "LIMITED" }, + parameters = { "gps" } }, - SubscribeVehicleData = { - hmi_levels = {"NONE", "BACKGROUND", "FULL", "LIMITED"}, - parameters = {"newParameter"} + SendLocation = { + hmi_levels = { "NONE", "BACKGROUND", "FULL", "LIMITED" } } } } tbl.policy_table.functional_groupings["NewTestCaseGroup1"] = VDgroup tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = - {"Base-4", "NewTestCaseGroup1"} + { "Base-4", "NewTestCaseGroup1" } end ---[[ @ptuUpdateFuncRPC: update table with unknown RPC for PTU +--[[ @ptuUpdateFuncParams: update table with unknown parameters for PTU --! @parameters: --! tbl - table for update --! @return: none --]] -local function ptuUpdateFuncRPC(tbl) +local function ptuUpdateFuncParams(tbl) local VDgroup = { rpcs = { - UnknownAPI = { - hmi_levels = {"NONE", "BACKGROUND", "FULL", "LIMITED"}, - parameters = {"gps"} - }, - SendLocation = { - hmi_levels = {"NONE", "BACKGROUND", "FULL", "LIMITED"} + GetVehicleData = { + hmi_levels = { "NONE", "BACKGROUND", "FULL", "LIMITED" }, + parameters = { "gps", unknownParameter } } } } tbl.policy_table.functional_groupings["NewTestCaseGroup2"] = VDgroup tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = - {"Base-4", "NewTestCaseGroup2"} + { "Base-4", "NewTestCaseGroup1", "NewTestCaseGroup2" } end --[[ @NotValidPtuUpdateFunc: update table for PTU with invalid content @@ -90,38 +88,41 @@ end --! tbl - table for update --! @return: none --]] -local function NotValidPtuUpdateFunc(tbl) +local function ptuUpdateFuncNotValid(tbl) local VDgroup = { rpcs = { GetVehicleData = { - hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, - parameters = {"gps", "newParameter"} + hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, + parameters = { "gps", unknownParameter } }, SubscribeVehicleData = { - hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, + hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, }, - UnknownAPI = { - hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, - parameters = {"gps"} + [unknownAPI] = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, + parameters = { "gps" } }, SendLocation = { -- missed mandatory hmi_levels parameter } } } - tbl.policy_table.functional_groupings["NewTestCaseGroup"] = VDgroup + tbl.policy_table.functional_groupings["NewTestCaseGroup3"] = VDgroup tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = - {"Base-4", "NewTestCaseGroup"} + { "Base-4", "NewTestCaseGroup1", "NewTestCaseGroup2", "NewTestCaseGroup3" } end ---[[ @ErrorOccurred: set error status and write Error message +--[[ @contains: verify if defined value is present in table --! @parameters: ---! Message - Error message ---! @return: none +--! pTbl - table for update +--! pValue - value +--! @return: true - in case value is present in table, otherwise - false --]] -local function ErrorOccurred(Message) - isError = true - ErrorMessage = ErrorMessage .. Message +local function contains(pTbl, pValue) + for _, v in pairs(pTbl) do + if v == pValue then return true end + end + return false end --[[ @CheckCuttingUnknowValues: Perform app registration, PTU and check absence of unknown values in @@ -131,33 +132,56 @@ end --! @return: none --]] local function CheckCuttingUnknowValues(ptuUpdateFunc, self) - commonDefects.rai_ptu_n_without_OnPermissionsChange(1, ptuUpdateFunc,self) + commonDefects.rai_ptu_n_without_OnPermissionsChange(1, ptuUpdateFunc, self) self.mobileSession1:ExpectNotification("OnPermissionsChange") :Times(2) - :ValidIf(function(_,data) - isError = false - ErrorMessage = "" - if #data.payload.permissionItem ~= 0 then - for i=1, #data.payload.permissionItem do - if data.payload.permissionItem[i].rpcName == "UnknownAPI" then - commonFunctions:userPrint(33, " OnPermissionsChange contains unknown_RPC value.\n") - end - if data.payload.permissionItem[i].parameterPermissions.allowed["newParameter"] or - data.payload.permissionItem[i].parameterPermissions.userDisallowed["newParameter"] then - ErrorOccurred(" OnPermissionsChange contains unknown_parameter value.\n") + :ValidIf(function(exp, data) + if exp.occurences == 2 then + local isError = false + local ErrorMessage = "" + if #data.payload.permissionItem ~= 0 then + for i = 1, #data.payload.permissionItem do + if data.payload.permissionItem[i].rpcName == unknownAPI then + commonFunctions:userPrint(33, " OnPermissionsChange contains '" .. unknownAPI .. "' value") + end + local pp = data.payload.permissionItem[i].parameterPermissions + if contains(pp.allowed, unknownParameter) or contains(pp.userDisallowed, unknownParameter) then + isError = true + ErrorMessage = ErrorMessage .. "\nOnPermissionsChange contains '" .. unknownParameter .. "' value" + end end + else + isError = true + ErrorMessage = ErrorMessage .. "\nOnPermissionsChange is not contain 'permissionItem' elements" + end + if isError == true then + return false, ErrorMessage + else + return true end - else - ErrorOccurred("OnPermissionsChange is not contain permissionItem elements") - end - if isError == true then - return false, ErrorMessage else return true end end) end +--[[ @SuccessfulProcessingRPC: Successful processing API +--! @parameters: +--! RPC - RPC name +--! params - RPC params for mobile request +--! interface - interface of RPC on HMI +--! self - test object +--! @return: none +--]] +local function SuccessfulProcessingRPC(RPC, params, interface, self) + local cid = self.mobileSession1:SendRPC(RPC, params) + EXPECT_HMICALL(interface .. "." .. RPC, params) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + self.mobileSession1:ExpectResponse(cid,{ success = true, resultCode = "SUCCESS" }) +end + --[[ @removeSnapshotAndTriggerPTUFromHMI: Remove snapshot and trigger PTU from HMI for creation new snapshot, --! check absence of unknown parameters in snapshot --! @parameters: @@ -173,41 +197,25 @@ local function removeSnapshotAndTriggerPTUFromHMI(self) if (commonSteps:file_exists(pathToPTS) == false) then self:FailTestCase(pathToPTS .. " is not created") else - local isErrorInvalidPT = false - local ErrorMessageInvalidPT = "" local pts = ptsToTable(pathToPTS) - local isUnknownAPI = pts.policy_table.functional_groupings.NewTestCaseGroup.rpcs["UnknownAPI"] - local isnewParameter = pts.policy_table.functional_groupings.NewTestCaseGroup.rpcs.GetVehicleData.parameters["newParameter"] - if isUnknownAPI then - commonFunctions:userPrint(33, " Snapshot contains UnknownAPI\n") - end - if isnewParameter then - isErrorInvalidPT = true - ErrorMessageInvalidPT = ErrorMessageInvalidPT .. "Snapshot contains newParameter for GetVehicleData RPC\n" + local rpcs = pts.policy_table.functional_groupings.NewTestCaseGroup1.rpcs + if rpcs[unknownAPI] then + commonFunctions:userPrint(33, " Snapshot contains '" .. unknownAPI .. "'") end - if isErrorInvalidPT == true then - self:FailTestCase(ErrorMessageInvalidPT) + local parameters = pts.policy_table.functional_groupings.NewTestCaseGroup2.rpcs.GetVehicleData.parameters + if contains(parameters, unknownParameter) then + self:FailTestCase("Snapshot contains '" .. unknownParameter .. "' for GetVehicleData RPC") end end end) -- Sending OnPolicyUpdate notification form HMI self.hmiConnection:SendNotification("SDL.OnPolicyUpdate", { }) -- Expect OnStatusUpdate notifications on HMI side - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) :Times(2) end ---[[ @InvalidPTAfterCutingUnknownValues: Unsuccessful policy table update ---! @parameters: ---! self - test object ---! @return: none ---]] -local function InvalidPTAfterCutingUnknownValues(self) - commonDefects.UnsuccessPTU(NotValidPtuUpdateFunc,self) -end - ---[[ @SuccessfulProcessingRPC: Successful processing API +--[[ @DisallowedRPC: Unsuccessful processing of API with Disallowed status --! @parameters: --! RPC - RPC name --! params - RPC params for mobile request @@ -215,25 +223,11 @@ end --! self - test object --! @return: none --]] -local function SuccessfulProcessingRPC(RPC, params, interface, self) +local function DisallowedRPC(RPC, params, interface, self) local cid = self.mobileSession1:SendRPC(RPC, params) - EXPECT_HMICALL(interface .. "." .. RPC, params) - :Do(function(_,data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - self.mobileSession1:ExpectResponse(cid,{ success = true, resultCode = "SUCCESS" }) -end - ---[[ @DissalowedRPC: Unsuccessful processing SubscribeVehicleData ---! @parameters: ---! self - test object ---! @return: none ---]] -local function DissalowedRPC(self) - local cid = self.mobileSession1:SendRPC("SubscribeVehicleData", {gps = true}) - EXPECT_HMICALL("VehicleInfo.SubscribeVehicleData") + EXPECT_HMICALL(interface .. "." .. RPC) :Times(0) - self.mobileSession1:ExpectResponse(cid,{ success = false, resultCode = "DISALLOWED" }) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) commonDefects.delayedExp() end @@ -243,18 +237,19 @@ runner.Step("Clean environment", commonDefects.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start) runner.Title("Test") -runner.Step("App registration, PTU with unknown API", CheckCuttingUnknowValues, {ptuUpdateFuncRPC}) +runner.Step("App registration, PTU with unknown API", CheckCuttingUnknowValues, { ptuUpdateFuncRPC }) runner.Step("Check applying of PT by processing SendLocation", SuccessfulProcessingRPC, - {"SendLocation", SendLocationParams, "Navigation"}) -runner.Step("Unregister application", commonDefects.unregisterApp, {1}) + { "SendLocation", SendLocationParams, "Navigation" }) +runner.Step("Unregister application", commonDefects.unregisterApp) -runner.Step("App registration, PTU with unknown parameters", CheckCuttingUnknowValues, {ptuUpdateFuncParams}) -runner.Step("Remove Snapshot and trigger PTU, check new created PTS", removeSnapshotAndTriggerPTUFromHMI) +runner.Step("App registration, PTU with unknown parameters", CheckCuttingUnknowValues, { ptuUpdateFuncParams }) runner.Step("Check applying of PT by processing GetVehicleData", SuccessfulProcessingRPC, - {"GetVehicleData", {gps = true}, "VehicleInfo"}) -runner.Step("Check applying of PT by processing SubscribeVehicleData", DissalowedRPC) + { "GetVehicleData", { gps = true }, "VehicleInfo" }) +runner.Step("Check applying of PT by processing SubscribeVehicleData", DisallowedRPC, + { "SubscribeVehicleData", { gps = true }, "VehicleInfo" }) -runner.Step("Invalid_PTU_after_cuting_unknown_values", InvalidPTAfterCutingUnknownValues) +runner.Step("Remove Snapshot and trigger PTU, check new created PTS", removeSnapshotAndTriggerPTUFromHMI) +runner.Step("Invalid_PTU_after_cutting_of_unknown_values", commonDefects.unsuccessfulPTU, { ptuUpdateFuncNotValid }) runner.Title("Postconditions") runner.Step("Stop SDL", commonDefects.postconditions) diff --git a/test_scripts/Defects/4_5/commonDefects.lua b/test_scripts/Defects/4_5/commonDefects.lua index ab8d77df78..3a7e1178a0 100644 --- a/test_scripts/Defects/4_5/commonDefects.lua +++ b/test_scripts/Defects/4_5/commonDefects.lua @@ -148,11 +148,11 @@ local function ptu(self, ptu_update_func) { policyfile = policy_file_path .. "/" .. policy_file_name }) end) mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + :Do(function() os.remove(ptu_file_name) end) end) :Times(AtMost(1)) end end) - os.remove(ptu_file_name) end --[[ @allow_sdl: sequence that allows SDL functionality @@ -334,6 +334,9 @@ function commonDefect.rai_ptu_n_without_OnPermissionsChange(id, ptu_update_func, self, id, ptu_update_func = commonDefect.getSelfAndParams(id, ptu_update_func, self) if not id then id = 1 end self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) self["mobileSession" .. id]:StartService(7) :Do(function() local corId = self["mobileSession" .. id]:SendRPC @@ -342,9 +345,6 @@ function commonDefect.rai_ptu_n_without_OnPermissionsChange(id, ptu_update_func, { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) :Do(function(_, d1) hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) - :Times(3) EXPECT_HMICALL("BasicCommunication.PolicyUpdate") :DoOnce(function(_, d2) self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) @@ -367,60 +367,10 @@ end --! self - test object --! @return: none --]] -function commonDefect.UnsuccessPTU(ptu_update_func, self) - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UPDATE_NEEDED" }) - :Times(AtLeast(1)) - - local function getAppsCount() - local count = 0 - for _, _ in pairs(hmiAppIds) do - count = count + 1 - end - return count - end - - local policy_file_name = "PolicyTableUpdate" - local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") - local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") - local ptu_file_name = os.tmpname() - local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(requestId) - :Do(function() - self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", - { requestType = "PROPRIETARY", fileName = pts_file_name }) - getPTUFromPTS(ptu_table) - updatePTU(ptu_table) - if ptu_update_func then - ptu_update_func(ptu_table) - end - tableToJsonFile(ptu_table, ptu_file_name) - - local event = events.Event() - event.matches = function(e1, e2) return e1 == e2 end - EXPECT_EVENT(event, "PTU event") - :Timeout(11000) - - for id = 1, getAppsCount() do - local mobileSession = commonDefect.getMobileSession(self, id) - mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) - :Do(function() - print("App ".. id .. " was used for PTU") - RAISE_EVENT(event, event, "PTU event") - local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", - { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) - EXPECT_HMICALL("BasicCommunication.SystemRequest") - :Do(function(_, d3) - self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) - self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", - { policyfile = policy_file_path .. "/" .. policy_file_name }) - end) - mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) - end) - :Times(AtMost(1)) - end - end) - os.remove(ptu_file_name) +function commonDefect.unsuccessfulPTU(ptu_update_func, self) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(2) + ptu(self, ptu_update_func) end --[[ @rai_n: register N mobile application without PTU sequence @@ -469,6 +419,8 @@ end --! @return: none --]] function commonDefect.unregisterApp(pAppId, self) + self, pAppId = commonDefect.getSelfAndParams(pAppId, self) + if not pAppId then pAppId = 1 end local mobSession = commonDefect.getMobileSession(self, pAppId) local hmiAppId = commonDefect.getHMIAppId(pAppId) local cid = mobSession:SendRPC("UnregisterAppInterface",{}) From e2a2b805541eb4888ebf475381d59eb9dac12621 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 28 Dec 2017 17:54:33 +0200 Subject: [PATCH 254/681] Fix issue related to StopSDL function --- .../Defects/4_5/1225_FACTORY_DEFAULTS.lua | 6 ++++- .../4_5/1395_Resumption_data_IGN_OFF.lua | 25 ++----------------- test_scripts/Defects/4_5/commonDefects.lua | 1 + 3 files changed, 8 insertions(+), 24 deletions(-) diff --git a/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua b/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua index c56a02b83c..85ad93828a 100644 --- a/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua +++ b/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua @@ -192,7 +192,11 @@ local function performFACTORY_DEFAULTS(self) self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "FACTORY_DEFAULTS" }) -- Expect notification OnAppInterfaceUnregistered(FACTORY_DEFAULTS) on mobile app self.mobileSession1:ExpectNotification("OnAppInterfaceUnregistered", { reason = "FACTORY_DEFAULTS" }) - :Do(function() sdl:DeleteFile() end) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + :Do(function() + sdl:DeleteFile() + sdl:StopSDL() + end) end local function Wait_SDL_stop(self) diff --git a/test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua b/test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua index 7801eb1455..34368d0936 100644 --- a/test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua +++ b/test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua @@ -16,7 +16,7 @@ local runner = require('user_modules/script_runner') local mobile_session = require("mobile_session") local common = require('test_scripts/Defects/4_5/commonDefects') -local SDL = require('SDL') +local sdl = require('SDL') --[[ Local Variables ]] @@ -68,27 +68,6 @@ local function OnAwakeSDL(self) end) end --- IGNITION_OFF flow -local function IGNITION_OFF(self) - -- Send OnExitAllApplications(SUSPEND) notification from HMI - self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", - { reason = "SUSPEND" }) - -- Expect notification OnSDLPersistenceComplete(IGNITION_OFF) on HMI side - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() - -- Send OnExitAllApplications(IGNITION_OFF) from HMI to SDL - self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", - { reason = "IGNITION_OFF" }) - -- Send OnAppInterfaceUnregistered(IGNITION_OFF) from HMI to SDL - self.mobileSession1:ExpectNotification("OnAppInterfaceUnregistered", - { reason = "IGNITION_OFF" }) - -- Expect OnAppUnregistered notification on HMI from SDL - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) - -- Expect OnAppUnregistered notification on HMI from SDL - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") - SDL:DeleteFile() - end) -end - -- Data resumption local function expectResumeData(self) -- Expect 2 VR.AddCommand requests on HMI side @@ -161,7 +140,7 @@ local function expectResumeData(self) runner.Step("Add Command After SUSPEND", AddCommandAfterSUSPEND) -- OnAwakeSDL notification from HMI runner.Step("Send OnAwakeSDL", OnAwakeSDL) - runner.Step("IGNITION_OFF", IGNITION_OFF) + runner.Step("IGNITION_OFF", common.ignitionOff) -- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP -- and create mobile session runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Defects/4_5/commonDefects.lua b/test_scripts/Defects/4_5/commonDefects.lua index 3a7e1178a0..32c069d1e2 100644 --- a/test_scripts/Defects/4_5/commonDefects.lua +++ b/test_scripts/Defects/4_5/commonDefects.lua @@ -252,6 +252,7 @@ function commonDefect.ignitionOff(self) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") :Do(function() sdl:DeleteFile() + sdl:StopSDL() end) end) end From 14cca9420ef9313ba951c6d499c74f7b1998a9a4 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 4 Jan 2018 15:00:54 +0200 Subject: [PATCH 255/681] Updated policy script --- ...Policies_To_Application_Which_Appid_Exists_In_LPT.lua | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua b/test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua index 5e9e355ce1..04c9bb9685 100644 --- a/test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua +++ b/test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua @@ -137,14 +137,11 @@ function Test:TestStep4_RegisterNewApp() end function Test:TestStep5_ValidateResult() - self.mobileSession:ExpectAny() - :ValidIf(function(_, _) + commonFunctions:printTable(r_actual) if not is_table_equal(r_expected, r_actual) then - return false, "\nExpected RPCs:\n" .. commonFunctions:convertTableToString(r_expected, 1) .. "\nActual RPCs:\n" .. commonFunctions:convertTableToString(r_actual, 1) + self:FailTestCase("\nExpected RPCs:\n" .. commonFunctions:convertTableToString(r_expected, 1) + .. "\nActual RPCs:\n" .. commonFunctions:convertTableToString(r_actual, 1)) end - return true - end) - :Times(1) end --[[ Postconditions ]] From a64ae7b5c151acc2775dbe9b52229b13e603a7a9 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 4 Jan 2018 15:07:34 +0200 Subject: [PATCH 256/681] Removed debug print --- ...xisting_Policies_To_Application_Which_Appid_Exists_In_LPT.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua b/test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua index 04c9bb9685..2fc5f5e483 100644 --- a/test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua +++ b/test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua @@ -137,7 +137,6 @@ function Test:TestStep4_RegisterNewApp() end function Test:TestStep5_ValidateResult() - commonFunctions:printTable(r_actual) if not is_table_equal(r_expected, r_actual) then self:FailTestCase("\nExpected RPCs:\n" .. commonFunctions:convertTableToString(r_expected, 1) .. "\nActual RPCs:\n" .. commonFunctions:convertTableToString(r_actual, 1)) From b56c80a0f9e15d216cfcd3c6e0473392254c2186 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 5 Jan 2018 13:04:50 +0200 Subject: [PATCH 257/681] Stabilize scripts --- .../Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua | 4 ++-- .../Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua | 2 +- .../Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua | 2 +- ...ion_app_registered_in_more_than_30sec_after_BC.OnReady.lua | 2 +- ...ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua | 2 +- test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua | 2 +- test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua | 4 +++- 7 files changed, 10 insertions(+), 8 deletions(-) diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua index 786672fd52..015a239b77 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua @@ -94,13 +94,13 @@ function Test:IGNITION_OFF() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() + SDL:DeleteFile() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") :Do(function() - SDL:DeleteFile() SDL:StopSDL() end) end) @@ -114,11 +114,11 @@ function Test:IGNITION_OFF() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() + SDL:DeleteFile() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") :Do(function() - SDL:DeleteFile() SDL:StopSDL() end) end) diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua index b8647f0857..45e513f2d5 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua @@ -73,6 +73,7 @@ function Test:IGNITION_OFF() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() + SDL:DeleteFile() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) @@ -80,7 +81,6 @@ function Test:IGNITION_OFF() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") :Do(function() - SDL:DeleteFile() SDL:StopSDL() end) end diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua index 10345dd1c0..bc44f893cb 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua @@ -69,6 +69,7 @@ commonSteps:ChangeHMIToLimited() function Test:IGNITION_OFF() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", {reason = "SUSPEND" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() + SDL:DeleteFile() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) @@ -76,7 +77,6 @@ function Test:IGNITION_OFF() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") :Do(function() - SDL:DeleteFile() SDL:StopSDL() end) end diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua index 777e763224..fde537a56a 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua @@ -69,6 +69,7 @@ function Test:IGNITION_OFF() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() + SDL:DeleteFile() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) @@ -76,7 +77,6 @@ function Test:IGNITION_OFF() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") :Do(function() - SDL:DeleteFile() SDL:StopSDL() end) end diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua b/test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua index 07de63e7b7..5eaf8f3773 100644 --- a/test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua +++ b/test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua @@ -80,12 +80,12 @@ function Test:IGNITION_OFF() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() + SDL:DeleteFile() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) end) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") :Do(function() - SDL:DeleteFile() SDL:StopSDL() end) end diff --git a/test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua b/test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua index 029d198d36..9fd9c09853 100644 --- a/test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua +++ b/test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua @@ -63,13 +63,13 @@ function Test:ShutDown_IGNITION_OFF() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete"):Do(function() + SDL:DeleteFile() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") :Do(function() - SDL:DeleteFile() SDL:StopSDL() end) end) diff --git a/test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua b/test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua index 493fcfeb1b..3a15f705c4 100644 --- a/test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua +++ b/test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua @@ -97,9 +97,11 @@ function Test:ShutDown_MASTER_RESET() { reason = "MASTER_RESET" }) EXPECT_NOTIFICATION("OnAppInterfaceUnregistered", { reason = "MASTER_RESET" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") :Do(function() SDL:DeleteFile() + end) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + :Do(function() SDL:StopSDL() end) end From 7edd5591101ef770711ae0e4f52fd6a938f574e9 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 9 Jan 2018 13:35:58 +0200 Subject: [PATCH 258/681] Initial version of script for SetDisplayLayout RPC --- ..._SetDisplayLayout_PositiveCase_SUCCESS.lua | 230 ++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..a4a62ececc --- /dev/null +++ b/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua @@ -0,0 +1,230 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: SetDisplayLayout +-- Item: Happy path +-- +-- Requirement summary: +-- [SetDisplayLayout] SUCCESS on UI.SetDisplayLayout +-- +-- Description: +-- Mobile application sends SetDisplayLayout request with valid parameters to SDL +-- +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- +-- Steps: +-- Application sends SetDisplayLayout request with valid parameters to SDL +-- +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if SetDispLay is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the UI part of request with allowed parameters to HMI +-- SDL receives UI part of response from HMI with "SUCCESS" result code +-- SDL transfers response to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Functions ]] +local function getSoftButCapValues() + return { + { + shortPressAvailable = true, + longPressAvailable = true, + upDownAvailable = true, + imageSupported = true + } + } +end + +local function getPresetBankCapValues() + return { onScreenPresetsAvailable = true } +end + +local function getButCapValues() + local names = { + "PRESET_0", + "PRESET_1", + "PRESET_2", + "PRESET_3", + "PRESET_4", + "PRESET_5", + "PRESET_6", + "PRESET_7", + "PRESET_8", + "PRESET_9", + "OK", + "SEEKLEFT", + "SEEKRIGHT", + "TUNEUP", + "TUNEDOWN" + } + local values = { } + for _, v in pairs(names) do + local item = { + name = v, + shortPressAvailable = true, + longPressAvailable = true, + upDownAvailable = true + } + table.insert(values, item) + end + return values +end + +local function getDisplayCapImageFieldsValues() + local names = { + "softButtonImage", + "choiceImage", + "choiceSecondaryImage", + "vrHelpItem", + "turnIcon", + "menuIcon", + "cmdIcon", + "graphic", + "showConstantTBTIcon", + "showConstantTBTNextTurnIcon" + } + local values = { } + for _, v in pairs(names) do + local item = { + imageResolution = { + resolutionHeight = 64, + resolutionWidth = 64 + }, + imageTypeSupported = { + "GRAPHIC_BMP", + "GRAPHIC_JPEG", + "GRAPHIC_PNG" + }, + name = v + } + table.insert(values, item) + end + return values +end + +local function getDisplayCapTextFieldsValues() + local names = { + "mainField1", + "mainField2", + "mainField3", + "mainField4", + "statusBar", + "mediaClock", + "mediaTrack", + "alertText1", + "alertText2", + "alertText3", + "scrollableMessageBody", + "initialInteractionText", + "navigationText1", + "navigationText2", + "ETA", + "totalDistance", + "navigationText", + "audioPassThruDisplayText1", + "audioPassThruDisplayText2", + "sliderHeader", + "sliderFooter", + "notificationText", + "menuName", + "secondaryText", + "tertiaryText", + "timeToDestination", + "turnText", + "menuTitle", + "locationName", + "locationDescription", + "addressLines", + "phoneNumber" + } + local values = { } + for _, v in pairs(names) do + local item = { + characterSet = "TYPE2SET", + name = v, + rows = 1, + width = 500 + } + table.insert(values, item) + end + return values +end + +local function getDisplayCapValues() + return { + displayType = "GEN2_8_DMA", + graphicSupported = true, + imageCapabilities = { + "DYNAMIC", + "STATIC" + }, + imageFields = getDisplayCapImageFieldsValues(), + mediaClockFormats = { + "CLOCK1", + "CLOCK2", + "CLOCK3", + "CLOCKTEXT1", + "CLOCKTEXT2", + "CLOCKTEXT3", + "CLOCKTEXT4" + }, + numCustomPresetsAvailable = 10, + screenParams = { + resolution = { + resolutionHeight = 480, + resolutionWidth = 800 + }, + touchEventAvailable = { + doublePressAvailable = false, + multiTouchAvailable = true, + pressAvailable = true + } + }, + templatesAvailable = { + "ONSCREEN_PRESETS" + }, + textFields = getDisplayCapTextFieldsValues() + } +end + +local function getRequestParams() + return { displayLayout = "ONSCREEN_PRESETS" } +end + +local function getResponseParams() + return { + displayCapabilities = getDisplayCapValues(), + buttonCapabilities = getButCapValues(), + softButtonCapabilities = getSoftButCapValues(), + presetBankCapabilities = getPresetBankCapValues() + } +end + +local function setDisplaySuccess(self) + local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams()) + EXPECT_HMICALL("UI.SetDisplayLayout", getRequestParams()) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", getResponseParams()) + end) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("SetDisplay Positive Case", setDisplaySuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From 6f4d5ad6b3f1a62fb0b0ee942f184ceac9e4afa4 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 9 Jan 2018 18:11:26 +0200 Subject: [PATCH 259/681] Initial version of script for Speak RPC --- test_scripts/Smoke/API/021_Speak_SUCCESS.lua | 85 ++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 test_scripts/Smoke/API/021_Speak_SUCCESS.lua diff --git a/test_scripts/Smoke/API/021_Speak_SUCCESS.lua b/test_scripts/Smoke/API/021_Speak_SUCCESS.lua new file mode 100644 index 0000000000..6474d38d96 --- /dev/null +++ b/test_scripts/Smoke/API/021_Speak_SUCCESS.lua @@ -0,0 +1,85 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: Speak +-- Item: Happy path +-- +-- Requirement summary: +-- [Speak] SUCCESS on TTS.Speak +-- +-- Description: +-- Mobile application sends Speak request with valid parameters to SDL +-- +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- +-- Steps: +-- Application sends Speak request with valid parameters to SDL +-- +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if TTS interface is available on HMI +-- SDL checks if Speak is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the TTS part of request with allowed parameters to HMI +-- SDL receives TTS part of response from HMI with "SUCCESS" result code +-- SDL transfers response to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Functions ]] +local function getRequestParams() + return { + ttsChunks = { + { + text ="a", + type ="TEXT" + } + } + } +end + +local function speakSuccess(self) + local cid = self.mobileSession1:SendRPC("Speak", getRequestParams()) + EXPECT_HMICALL("TTS.Speak", getRequestParams()) + :Do(function(_, data) + self.hmiConnection:SendNotification("TTS.Started") + local function sendSpeakResponse() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + self.hmiConnection:SendNotification("TTS.Stopped") + end + local function sendOnResetTimeout() + self.hmiConnection:SendNotification("TTS.OnResetTimeout", + { appID = commonSmoke.getHMIAppId(), methodName = "TTS.Speak" }) + end + RUN_AFTER(sendOnResetTimeout, 9000) + RUN_AFTER(sendOnResetTimeout, 18000) + RUN_AFTER(sendOnResetTimeout, 24000) + RUN_AFTER(sendSpeakResponse, 33000) + end) + + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "ATTENUATED" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }) + :Times(2) + :Timeout(35000) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + :Timeout(35000) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("Speak Positive Case", speakSuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From b991c51bfe5c66c46482b43c5d6b4ee221056eb0 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 5 Jan 2018 14:41:01 +0200 Subject: [PATCH 260/681] Separated scripts for smoke API PI and ScrMsg --- .../012_PerfomInteraction_PositiveCase.lua | 426 ++++++++++++++++++ .../013_ScrollableMessage_PositiveCase.lua | 122 +++++ test_scripts/Smoke/commonSmoke.lua | 182 ++++---- 3 files changed, 652 insertions(+), 78 deletions(-) create mode 100644 test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase.lua create mode 100644 test_scripts/Smoke/API/013_ScrollableMessage_PositiveCase.lua diff --git a/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase.lua b/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase.lua new file mode 100644 index 0000000000..4d62cde730 --- /dev/null +++ b/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase.lua @@ -0,0 +1,426 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: PerformInteraction +-- Item: Happy path +-- +-- Requirement summary: +-- [PerformInteraction]: +-- SUCCESS result code +-- TIMED_OUT result code +-- +-- Description: +-- Mobile application sends PerformInteraction request with valid parameters to SDL + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level +-- d. ChoiceSets are already added + +-- Steps: +-- appID requests PerformInteraction with valid parameters to SDL + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if PerformInteraction is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL provides ability to perform choice on HMI manually or by voice +-- After user provide the choice SDL responds with (resultCode: SUCCESS, success:true) to mobile application +-- After user does not provide the choice SDL responds with (resultCode: TIMED_OUT, success:false) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Variables ]] +local isMediaApplication = commonSmoke.GetAppMediaStatus() +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local storagePath = commonPreconditions:GetPathToSDL() .. "storage/" .. +config.application1.registerAppInterfaceParams.appID .. "_" .. config.deviceMAC .. "/" + +local ImageValue = { + value = storagePath .. "icon.png", + imageType = "DYNAMIC", +} + +local function PromptValue(text) + local tmp = { + { + text = text, + type = "TEXT" + } + } + return tmp +end + +local initialPromptValue = PromptValue(" Make your choice ") + +local helpPromptValue = PromptValue(" Help Prompt ") + +local timeoutPromptValue = PromptValue(" Time out ") + +local vrHelpvalue = { + { + text = " New VRHelp ", + position = 1, + image = ImageValue + } +} + +local requestParams = { + initialText = "StartPerformInteraction", + initialPrompt = initialPromptValue, + interactionMode = "BOTH", + interactionChoiceSetIDList = { + 100, 200, 300 + }, + helpPrompt = helpPromptValue, + timeoutPrompt = timeoutPromptValue, + timeout = 5000, + vrHelp = vrHelpvalue, + interactionLayout = "ICON_ONLY" +} + +--[[ Local Functions ]] + +--! @setChoiseSet: Creates Choice structure +--! @parameters: +--! choiceIDValue - Id for created choice +--! @return: table of created choice structure +local function setChoiseSet(choiceIDValue) + local temp = { + { + choiceID = choiceIDValue, + menuName ="Choice" .. tostring(choiceIDValue), + vrCommands = { + "VrChoice" .. tostring(choiceIDValue), + }, + image = { + value ="icon.png", + imageType ="STATIC", + } + } + } + return temp +end + +--! @SendOnSystemContext: OnSystemContext notification +--! @parameters: +--! self - test object, +--! ctx - systemContext value +--! @return: none +local function SendOnSystemContext(self, ctx) + self.hmiConnection:SendNotification("UI.OnSystemContext", + { appID = self.applications["Test Application"], systemContext = ctx }) +end + +--! @setExChoiseSet: ChoiceSet structure for UI.PerformInteraction request +--! @parameters: +--! choiceIDValues - value of choice id +--! @return: none +local function setExChoiseSet(choiceIDValues) + local exChoiceSet = { } + for i = 1, #choiceIDValues do + exChoiceSet[i] = { + choiceID = choiceIDValues[i], + image = { + value = "icon.png", + imageType = "STATIC", + }, + menuName = "Choice" .. choiceIDValues[i] + } + end + return exChoiceSet +end + +--! @ExpectOnHMIStatusWithAudioStateChanged_PI: Expectations of OnHMIStatus notification depending on the application +--! type, HMI level and interaction mode +--! @parameters: +--! self - test object, +--! request - interaction mode, +--! timeout - timeout value for expectation OnHMIStatus, +--! level - HMI level value, +--! @return: none +local function ExpectOnHMIStatusWithAudioStateChanged_PI(self, request, timeout, level) + if nil == request then request = "BOTH" end + if nil == level then level = "FULL" end + if nil == timeout then timeout = 10000 end + commonSmoke.SetAppType(config.application1.registerAppInterfaceParams.appHMIType) + if "FULL" == level then + if true == isMediaApplication or + true == commonSmoke.HMITypeStatus.NAVIGATION then + if "BOTH" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = level, audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, + { hmiLevel = level, audioStreamingState = "NOT_AUDIBLE", systemContext = "VRSESSION" }, + { hmiLevel = level, audioStreamingState = "ATTENUATED", systemContext = "VRSESSION" }, + { hmiLevel = level, audioStreamingState = "ATTENUATED", systemContext = "HMI_OBSCURED" }, + { hmiLevel = level, audioStreamingState = "AUDIBLE", systemContext = "HMI_OBSCURED" }, + { hmiLevel = level, audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + :Times(6) + elseif "VR" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "ATTENUATED" }, + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }, + { systemContext = "VRSESSION", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }, + { systemContext = "VRSESSION", hmiLevel = level, audioStreamingState = "AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "AUDIBLE" }) + :Times(5) + :Timeout(timeout) + elseif "MANUAL" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "ATTENUATED" }, + { systemContext = "HMI_OBSCURED", hmiLevel = level, audioStreamingState = "ATTENUATED" }, + { systemContext = "HMI_OBSCURED", hmiLevel = level, audioStreamingState = "AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "AUDIBLE" }) + :Times(4) + :Timeout(timeout) + end + elseif false == isMediaApplication then + if "BOTH" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = level, audioStreamingState = "NOT_AUDIBLE", systemContext = "VRSESSION" }, + { hmiLevel = level, audioStreamingState = "NOT_AUDIBLE", systemContext = "HMI_OBSCURED" }, + { hmiLevel = level, audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(3) + :Timeout(timeout) + elseif "VR" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "VRSESSION", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }) + :Times(2) + :Timeout(timeout) + elseif "MANUAL" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = level, audioStreamingState = "NOT_AUDIBLE", systemContext = "HMI_OBSCURED" }, + { hmiLevel = level, audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(2) + end + end + elseif "LIMITED" == level then + if true == isMediaApplication or + true == commonSmoke.HMITypeStatus.NAVIGATION then + if "BOTH" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = level, audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, + { hmiLevel = level, audioStreamingState = "ATTENUATED", systemContext = "MAIN" }, + { hmiLevel = level, audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + :Times(3) + elseif "VR" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "ATTENUATED" }, + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "AUDIBLE" }) + :Times(3) + :Timeout(timeout) + elseif "MANUAL" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "ATTENUATED" }, + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "AUDIBLE" }) + :Times(2) + :Timeout(timeout) + end + elseif false == isMediaApplication then + self.mobileSession1:ExpectNotification("OnHMIStatus") + :Times(0) + commonTestCases:DelayedExp(1000) + end + elseif "BACKGROUND" == level then + self.mobileSession1:ExpectNotification("OnHMIStatus") + :Times(0) + commonTestCases:DelayedExp(1000) + end +end + +--! @CreateInteractionChoiceSet: Creation of Choice Set +--! @parameters: +--! choiceSetID - id for choice set +--! self - test object +--! @return: none +local function CreateInteractionChoiceSet(choiceSetID, self) + local choiceID = choiceSetID + local cid = self.mobileSession1:SendRPC("CreateInteractionChoiceSet", { + interactionChoiceSetID = choiceSetID, + choiceSet = setChoiseSet(choiceID), + }) + EXPECT_HMICALL("VR.AddCommand", { + cmdID = choiceID, + type = "Choice", + vrCommands = { "VrChoice" .. tostring(choiceID) } + }) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + self.mobileSession1:ExpectResponse(cid, { resultCode = "SUCCESS", success = true }) +end + +--! @PI_PerformViaVR_ONLY: Processing PI with interaction mode VR_ONLY with performing selection +--! @parameters: +--! paramsSend - parameters for PI request +--! self - test object +--! @return: none +local function PI_PerformViaVR_ONLY(paramsSend, self) + local level = "FULL" + paramsSend.interactionMode = "VR_ONLY" + local cid = self.mobileSession1:SendRPC("PerformInteraction",paramsSend) + EXPECT_HMICALL("VR.PerformInteraction", { + helpPrompt = paramsSend.helpPrompt, + initialPrompt = paramsSend.initialPrompt, + timeout = paramsSend.timeout, + timeoutPrompt = paramsSend.timeoutPrompt + }) + :Do(function(_,data) + local function vrResponse() + self.hmiConnection:SendNotification("TTS.Started") + self.hmiConnection:SendNotification("VR.Started") + SendOnSystemContext(self, "VRSESSION") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + { choiceID = paramsSend.interactionChoiceSetIDList[1] }) + self.hmiConnection:SendNotification("TTS.Stopped") + self.hmiConnection:SendNotification("VR.Stopped") + SendOnSystemContext(self, "MAIN") + end + RUN_AFTER(vrResponse, 1000) + end) + + EXPECT_HMICALL("UI.PerformInteraction", { + timeout = paramsSend.timeout, + vrHelp = paramsSend.vrHelp, + vrHelpTitle = paramsSend.initialText, + }) + :Do(function(_,data) + self.hmiConnection:SendResponse( data.id, data.method, "SUCCESS", { } ) + end) + ExpectOnHMIStatusWithAudioStateChanged_PI(self, "VR", nil, level) + self.mobileSession1:ExpectResponse(cid, + { success = true, resultCode = "SUCCESS", choiceID = paramsSend.interactionChoiceSetIDList[1] }) +end + +--! @PI_PerformViaMANUAL_ONLY: Processing PI with interaction mode MANUAL_ONLY with performing selection +--! @parameters: +--! paramsSend - parameters for PI request +--! self - test object +--! @return: none +local function PI_PerformViaMANUAL_ONLY(paramsSend, self) + local level = "FULL" + paramsSend.interactionMode = "MANUAL_ONLY" + local cid = self.mobileSession1:SendRPC("PerformInteraction", paramsSend) + EXPECT_HMICALL("VR.PerformInteraction", { + helpPrompt = paramsSend.helpPrompt, + initialPrompt = paramsSend.initialPrompt, + timeout = paramsSend.timeout, + timeoutPrompt = paramsSend.timeoutPrompt + }) + :Do(function(_,data) + self.hmiConnection:SendNotification("TTS.Started") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + EXPECT_HMICALL("UI.PerformInteraction", { + timeout = paramsSend.timeout, + choiceSet = setExChoiseSet(paramsSend.interactionChoiceSetIDList), + initialText = { + fieldName = "initialInteractionText", + fieldText = paramsSend.initialText + } + }) + :Do(function(_,data) + SendOnSystemContext(self,"HMI_OBSCURED") + local function uiResponse() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + { choiceID = paramsSend.interactionChoiceSetIDList[1] }) + self.hmiConnection:SendNotification("TTS.Stopped") + SendOnSystemContext(self,"MAIN") + end + RUN_AFTER(uiResponse, 1000) + end) + ExpectOnHMIStatusWithAudioStateChanged_PI(self, "MANUAL", nil, level) + self.mobileSession1:ExpectResponse(cid, + { success = true, resultCode = "SUCCESS", choiceID = paramsSend.interactionChoiceSetIDList[1] }) +end + +--! @PI_PerformViaBOTH: Processing PI with interaction mode BOTH with timeout on VR and IU +--! @parameters: +--! paramsSend - parameters for PI request +--! self - test object +--! @return: none +local function PI_PerformViaBOTH(paramsSend, self) + local level = "FULL" + paramsSend.interactionMode = "BOTH" + local cid = self.mobileSession1:SendRPC("PerformInteraction",paramsSend) + EXPECT_HMICALL("VR.PerformInteraction", { + helpPrompt = paramsSend.helpPrompt, + initialPrompt = paramsSend.initialPrompt, + timeout = paramsSend.timeout, + timeoutPrompt = paramsSend.timeoutPrompt + }) + :Do(function(_,data) + self.hmiConnection:SendNotification("VR.Started") + self.hmiConnection:SendNotification("TTS.Started") + SendOnSystemContext(self,"VRSESSION") + local function firstSpeakTimeOut() + self.hmiConnection:SendNotification("TTS.Stopped") + self.hmiConnection:SendNotification("TTS.Started") + end + RUN_AFTER(firstSpeakTimeOut, 5) + local function vrResponse() + self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", "Perform Interaction error response.") + self.hmiConnection:SendNotification("VR.Stopped") + end + RUN_AFTER(vrResponse, 20) + end) + EXPECT_HMICALL("UI.PerformInteraction", { + timeout = paramsSend.timeout, + choiceSet = setExChoiseSet(paramsSend.interactionChoiceSetIDList), + initialText = { + fieldName = "initialInteractionText", + fieldText = paramsSend.initialText + }, + vrHelp = paramsSend.vrHelp, + vrHelpTitle = paramsSend.initialText + }) + :Do(function(_,data) + local function choiceIconDisplayed() + SendOnSystemContext(self,"HMI_OBSCURED") + end + RUN_AFTER(choiceIconDisplayed, 25) + local function uiResponse() + self.hmiConnection:SendNotification("TTS.Stopped") + self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", "Perform Interaction error response.") + SendOnSystemContext(self,"MAIN") + end + RUN_AFTER(uiResponse, 30) + end) + ExpectOnHMIStatusWithAudioStateChanged_PI(self, nil, nil, level) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "TIMED_OUT" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) +runner.Step("CreateInteractionChoiceSet with id 100", CreateInteractionChoiceSet, {100}) +runner.Step("CreateInteractionChoiceSet with id 200", CreateInteractionChoiceSet, {200}) +runner.Step("CreateInteractionChoiceSet with id 300", CreateInteractionChoiceSet, {300}) + +runner.Title("Test") +runner.Step("PerformInteraction with VR_ONLY interaction mode", PI_PerformViaVR_ONLY, {requestParams}) +runner.Step("PerformInteraction with MANUAL_ONLY interaction mode", PI_PerformViaMANUAL_ONLY, {requestParams}) +runner.Step("PerformInteraction with BOTH interaction mode", PI_PerformViaBOTH, {requestParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/013_ScrollableMessage_PositiveCase.lua b/test_scripts/Smoke/API/013_ScrollableMessage_PositiveCase.lua new file mode 100644 index 0000000000..71fbc2d375 --- /dev/null +++ b/test_scripts/Smoke/API/013_ScrollableMessage_PositiveCase.lua @@ -0,0 +1,122 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: ScrollableMessage +-- Item: Happy path +-- +-- Requirement summary: +-- [AddCommand] SUCCESS: getting SUCCESS on UI.ScrollableMessage() +-- +-- Description: +-- Mobile application sends valid ScrollableMessage request + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests ScrollableMessage with valid values of parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if ScrollableMessage is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the UI request with allowed parameters to HMI +-- SDL receives UI response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local requestParams = { + scrollableMessageBody = "abc", + softButtons = { + { + softButtonID = 1, + text = "Button1", + type = "BOTH", + image = { + value = "icon.png", + imageType = "DYNAMIC" + }, + isHighlighted = false, + systemAction = "DEFAULT_ACTION" + }, + { + softButtonID = 2, + text = "Button2", + type = "TEXT", + isHighlighted = false, + systemAction = "DEFAULT_ACTION" + } + }, + timeout = 5000 +} + +local responseUiParams = { + messageText = { + fieldName = "scrollableMessageBody", + fieldText = requestParams.scrollableMessageBody + }, + softButtons = requestParams.softButtons +} + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams, +} + +--[[ Local Functions ]] +local function ScrollableMessage(params, self) + local cid = self.mobileSession1:SendRPC("ScrollableMessage", params.requestParams) + params.responseUiParams.appID = commonSmoke.getHMIAppId() + for _, v in pairs(params.responseUiParams.softButtons) do + if v.image then + v.image.value = commonSmoke.getPathToFileInStorage("icon.png") + end + end + EXPECT_HMICALL("UI.ScrollableMessage", params.responseUiParams) + :Do(function(_,data) + self.hmiConnection:SendNotification("UI.OnSystemContext", + { appID = self.applications["Test Application"], systemContext = "HMI_OBSCURED" }) + local function uiResponse() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + self.hmiConnection:SendNotification("UI.OnSystemContext", + { appID = self.applications["Test Application"], systemContext = "MAIN" }) + end + RUN_AFTER(uiResponse, 1000) + end) + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "HMI_OBSCURED", hmiLevel = "FULL", audioStreamingState = commonSmoke.GetAudibleState() }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = commonSmoke.GetAudibleState() }) + :Times(2) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) + +runner.Title("Test") +runner.Step("ScrollableMessage Positive Case", ScrollableMessage, {allParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/commonSmoke.lua b/test_scripts/Smoke/commonSmoke.lua index 0705dfbf54..7d40b8b523 100644 --- a/test_scripts/Smoke/commonSmoke.lua +++ b/test_scripts/Smoke/commonSmoke.lua @@ -14,15 +14,7 @@ local consts = require("user_modules/consts") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") -local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') - --- local mobile_api_loader = require("modules/api_loader") --- local mobile_api = mobile_api_loader.init("data/MOBILE_API.xml") --- local mobile_api_schema = mobile_api.interface["Ford Sync RAPI"] - --- local hmi_api_loader = require("modules/api_loader") --- local hmi_api = hmi_api_loader.init("data/HMI_API.xml") --- local hmi_api_schema = hmi_api.interface["Common"] +local events = require("events") --[[ Local Variables ]] local ptu_table = {} @@ -30,6 +22,10 @@ local hmiAppIds = {} local commonSmoke = {} +commonSmoke.HMITypeStatus = { + NAVIGATION = false, + COMMUNICATION = false +} commonSmoke.timeout = 5000 commonSmoke.minTimeout = 500 @@ -48,7 +44,7 @@ end local function checkIfPTSIsSentAsBinary(bin_data) if not (bin_data ~= nil and string.len(bin_data) > 0) then commonFunctions:userPrint(consts.color.red, - "PTS was not sent to Mobile in payload of OnSystemRequest") + "PTS was not sent to Mobile in payload of OnSystemRequest") end end @@ -104,19 +100,20 @@ local function ptu(self, id, pUpdateFunction) local mobileSession = commonSmoke.getMobileSession(id, self) mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) :Do(function(_, data) - print("App ".. id .. " was used for PTU") - RAISE_EVENT(event, event, "PTU event") - checkIfPTSIsSentAsBinary(data.binaryData) - local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) - EXPECT_HMICALL("BasicCommunication.SystemRequest") - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) - self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", - { policyfile = policy_file_path .. "/" .. policy_file_name }) - end) - mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) - :Do(function() os.remove(ptu_file_name) end) + print("App ".. id .. " was used for PTU") + RAISE_EVENT(event, event, "PTU event") + checkIfPTSIsSentAsBinary(data.binaryData) + local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", + { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", + { policyfile = policy_file_path .. "/" .. policy_file_name }) end) + mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + :Do(function() os.remove(ptu_file_name) end) + end) :Times(AtMost(1)) end end) @@ -170,8 +167,8 @@ end function commonSmoke.getPathToFileInStorage(fileName) return commonSmoke.getPathToSDL() .. "storage/" - .. commonSmoke.getMobileAppId() .. "_" - .. commonSmoke.getDeviceMAC() .. "/" .. fileName + .. commonSmoke.getMobileAppId() .. "_" + .. commonSmoke.getDeviceMAC() .. "/" .. fileName end function commonSmoke.getMobileSession(pAppId, self) @@ -191,21 +188,21 @@ function commonSmoke.getSmokeAppPoliciesConfig() end function commonSmoke.splitString(inputStr, sep) - if sep == nil then - sep = "%s" - end - local splitted, i = {}, 1 - for str in string.gmatch(inputStr, "([^"..sep.."]+)") do - splitted[i] = str - i = i + 1 - end - return splitted + if sep == nil then + sep = "%s" + end + local splitted, i = {}, 1 + for str in string.gmatch(inputStr, "([^"..sep.."]+)") do + splitted[i] = str + i = i + 1 + end + return splitted end function commonSmoke.expectOnHMIStatusWithAudioStateChanged(self, pAppId, request, level) if pAppId == nil then pAppId = 1 end - if request == nil then request = "BOTH" end - if level == nil then level = "FULL" end + if request == nil then request = "BOTH" end + if level == nil then level = "FULL" end local mobSession = commonSmoke.getMobileSession(pAppId, self) local appParams = config["application" .. pAppId].registerAppInterfaceParams @@ -213,27 +210,27 @@ function commonSmoke.expectOnHMIStatusWithAudioStateChanged(self, pAppId, reques if appParams.isMediaApplication == true then if request == "BOTH" then mobSession:ExpectNotification("OnHMIStatus", - { systemContext = "ALERT", hmiLevel = level, audioStreamingState = "AUDIBLE" }, + { systemContext = "ALERT", hmiLevel = level, audioStreamingState = "AUDIBLE" }, { systemContext = "ALERT", hmiLevel = level, audioStreamingState = "ATTENUATED" }, - { systemContext = "ALERT", hmiLevel = level, audioStreamingState = "AUDIBLE" }, - { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "AUDIBLE" }) + { systemContext = "ALERT", hmiLevel = level, audioStreamingState = "AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "AUDIBLE" }) :Times(4) elseif request == "speak" then mobSession:ExpectNotification("OnHMIStatus", - { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "ATTENUATED" }, - { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "AUDIBLE" }) + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "ATTENUATED" }, + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "AUDIBLE" }) :Times(2) elseif request == "alert" then mobSession:ExpectNotification("OnHMIStatus", { systemContext = "ALERT", hmiLevel = level, audioStreamingState = "AUDIBLE" }, - { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "AUDIBLE" }) + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "AUDIBLE" }) :Times(2) end elseif appParams.isMediaApplication == false then if request == "BOTH" then mobSession:ExpectNotification("OnHMIStatus", { systemContext = "ALERT", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }, - { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }) + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }) :Times(2) elseif request == "speak" then mobSession:ExpectNotification("OnHMIStatus") @@ -241,7 +238,7 @@ function commonSmoke.expectOnHMIStatusWithAudioStateChanged(self, pAppId, reques elseif request == "alert" then mobSession:ExpectNotification("OnHMIStatus", { systemContext = "ALERT", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }, - { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }) + { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }) :Times(2) end end @@ -256,7 +253,7 @@ function commonSmoke.activateApp(pAppId, self) local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) EXPECT_HMIRESPONSE(requestId) mobSession:ExpectNotification("OnHMIStatus", - {hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN"}) + {hmiLevel = "FULL", audioStreamingState = commonSmoke.GetAudibleState(pAppId), systemContext = "MAIN"}) commonTestCases:DelayedExp(commonSmoke.minTimeout) end @@ -265,20 +262,20 @@ function commonSmoke.start(pHMIParams, self) self:runSDL() commonFunctions:waitForSDLStart(self) :Do(function() - self:initHMI(self) + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(consts.color.magenta, "HMI initialized") + self:initHMI_onReady(pHMIParams) :Do(function() - commonFunctions:userPrint(consts.color.magenta, "HMI initialized") - self:initHMI_onReady(pHMIParams) - :Do(function() - commonFunctions:userPrint(consts.color.magenta, "HMI is ready") - self:connectMobile() - :Do(function() - commonFunctions:userPrint(consts.color.magenta, "Mobile connected") - allowSDL(self) - end) - end) + commonFunctions:userPrint(consts.color.magenta, "HMI is ready") + self:connectMobile() + :Do(function() + commonFunctions:userPrint(consts.color.magenta, "Mobile connected") + allowSDL(self) end) + end) end) + end) end function commonSmoke.registerApplicationWithPTU(pAppId, pUpdateFunction, self) @@ -287,31 +284,31 @@ function commonSmoke.registerApplicationWithPTU(pAppId, pUpdateFunction, self) self["mobileSession" .. pAppId] = mobile_session.MobileSession(self, self.mobileConnection) self["mobileSession" .. pAppId]:StartService(7) :Do(function() - local corId = self["mobileSession" .. pAppId]:SendRPC("RegisterAppInterface", - config["application" .. pAppId].registerAppInterfaceParams) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", - { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) + local corId = self["mobileSession" .. pAppId]:SendRPC("RegisterAppInterface", + config["application" .. pAppId].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) + :Do(function(_, data) + hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = data.params.application.appID + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + {status = "UPDATE_NEEDED"}, {status = "UPDATING"}, {status = "UP_TO_DATE" }) + :Times(3) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") :Do(function(_, data) - hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = data.params.application.appID - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", - {status = "UPDATE_NEEDED"}, {status = "UPDATING"}, {status = "UP_TO_DATE" }) - :Times(3) - EXPECT_HMICALL("BasicCommunication.PolicyUpdate") - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) - ptu_table = jsonFileToTable(data.params.file) - ptu(self, pAppId, pUpdateFunction) - end) - end) - self["mobileSession" .. pAppId]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) - :Do(function() - self["mobileSession" .. pAppId]:ExpectNotification("OnHMIStatus", - {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) - :Times(1) - self["mobileSession" .. pAppId]:ExpectNotification("OnPermissionsChange") - :Times(AtLeast(1)) -- todo: issue with SDL --> notification is sent twice - end) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + ptu_table = jsonFileToTable(data.params.file) + ptu(self, pAppId, pUpdateFunction) + end) + end) + self["mobileSession" .. pAppId]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. pAppId]:ExpectNotification("OnHMIStatus", + {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) + :Times(1) + self["mobileSession" .. pAppId]:ExpectNotification("OnPermissionsChange") + :Times(AtLeast(1)) -- todo: issue with SDL --> notification is sent twice end) + end) end function commonSmoke.putFile(params, pAppId, self) @@ -322,6 +319,35 @@ function commonSmoke.putFile(params, pAppId, self) mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) end +function commonSmoke.SetAppType(HMIType) + for _,v in pairs(HMIType) do + if v == "NAVIGATION" then + commonSmoke.HMITypeStatus["NAVIGATION"] = true + elseif v == "COMMUNICATION" then + commonSmoke.HMITypeStatus["COMMUNICATION"] = true + end + end +end + +function commonSmoke.GetAudibleState(pAppId) + if not pAppId then pAppId = 1 end + commonSmoke.SetAppType(config["application" .. pAppId].registerAppInterfaceParams.appHMIType) + if config["application" .. pAppId].registerAppInterfaceParams.isMediaApplication == true or + commonSmoke.HMITypeStatus.COMMUNICATION == true or + commonSmoke.HMITypeStatus.NAVIGATION == true then + return "AUDIBLE" + elseif + config["application" .. pAppId].registerAppInterfaceParams.isMediaApplication == false then + return "NOT_AUDIBLE" + end +end + +function commonSmoke.GetAppMediaStatus(pAppId) + if not pAppId then pAppId = 1 end + local isMediaApplication = config["application" .. pAppId].registerAppInterfaceParams.isMediaApplication + return isMediaApplication +end + function commonSmoke.readParameterFromSmartDeviceLinkIni(paramName) return commonFunctions:read_parameter_from_smart_device_link_ini(paramName) end From cd917bef106e6b478405546b65d63d454be2dba4 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 9 Jan 2018 09:54:26 +0200 Subject: [PATCH 261/681] Separated scripts for SetTimer and Show --- .../014_SetMediaClockTimer_PositiveCase.lua | 82 +++++++++++ .../Smoke/API/015_Show_PositiveCase.lua | 134 ++++++++++++++++++ 2 files changed, 216 insertions(+) create mode 100644 test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase.lua create mode 100644 test_scripts/Smoke/API/015_Show_PositiveCase.lua diff --git a/test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase.lua b/test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase.lua new file mode 100644 index 0000000000..62d03ea658 --- /dev/null +++ b/test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase.lua @@ -0,0 +1,82 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: SetMediaClockTimer +-- Item: Happy path +-- +-- Requirement summary: +-- [SetMediaClockTimer] SUCCESS: getting SUCCESS:UI.SetMediaClockTimer() +-- +-- Description: +-- Mobile application sends valid SetMediaClockTimer request and gets UI.SetMediaClockTimer "SUCCESS" response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests SetMediaClockTimer with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if SetMediaClockTimer is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the UI part of request with allowed parameters to HMI +-- SDL receives UI part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local updateMode = {"COUNTUP", "COUNTDOWN", "PAUSE", "RESUME", "CLEAR"} + +local requestParams = { + startTime = { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = { + hours = 0, + minutes = 1 , + seconds = 35 + } +} + +--[[ Local Functions ]] +local function SetMediaClockTimer(pParams, pMode, self) + local countDown = 0 + if pMode == "COUNTDOWN" then + countDown = -1 + end + local Parameters = commonFunctions:cloneTable(pParams) + Parameters.updateMode = pMode + Parameters.endTime.minutes = 1 + countDown + local cid = self.mobileSession1:SendRPC("SetMediaClockTimer", Parameters) + Parameters.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("UI.SetMediaClockTimer", Parameters) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +for _, value in pairs (updateMode) do + runner.Step("SetMediaClockTimer Positive Case with udate mode " .. value, SetMediaClockTimer, { requestParams,value }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/015_Show_PositiveCase.lua b/test_scripts/Smoke/API/015_Show_PositiveCase.lua new file mode 100644 index 0000000000..7d4d4a1bab --- /dev/null +++ b/test_scripts/Smoke/API/015_Show_PositiveCase.lua @@ -0,0 +1,134 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: Show +-- Item: Happy path +-- +-- Requirement summary: +-- [Show] SUCCESS: getting SUCCESS:UI.Show() +-- +-- Description: +-- Mobile application sends valid Show request and gets UI.Show "SUCCESS" response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests Show with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if Show is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the UI part of request with allowed parameters to HMI +-- SDL receives UI part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local requestParams = { + mainField1 = "a", + mainField2 = "a", + mainField3 = "a", + mainField4 = "a", + statusBar = "a", + mediaClock = "a", + mediaTrack = "a", + alignment = "CENTERED", + graphic = { + imageType = "DYNAMIC", + value = "icon.png" + }, + secondaryGraphic = { + imageType = "DYNAMIC", + value = "icon.png" + }, +} + +local responseUiParams = { + showStrings = { + { + fieldName = "mainField1", + fieldText = requestParams.mainField1 + }, + { + fieldName = "mainField2", + fieldText = requestParams.mainField2 + }, + { + fieldName = "mainField3", + fieldText = requestParams.mainField3 + }, + { + fieldName = "mainField4", + fieldText = requestParams.mainField4 + }, + { + fieldName = "mediaClock", + fieldText = requestParams.mediaClock + }, + { + fieldName = "mediaTrack", + fieldText = requestParams.mediaTrack + }, + { + fieldName = "statusBar", + fieldText = requestParams.statusBar + } + }, + alignment = requestParams.alignment, + graphic = { + imageType = requestParams.graphic.imageType, + value = commonSmoke.getPathToFileInStorage(requestParams.graphic.value) + }, + secondaryGraphic = { + imageType = requestParams.secondaryGraphic.imageType, + value = commonSmoke.getPathToFileInStorage(requestParams.secondaryGraphic.value) + } +} + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams, +} + +--[[ Local Functions ]] +local function Show(pParams, self) + local cid = self.mobileSession1:SendRPC("Show", pParams.requestParams) + pParams.responseUiParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("UI.Show", pParams.responseUiParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, { putFileParams }) + +runner.Title("Test") +runner.Step("Show Positive Case", Show, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From d916e49f412a0e108062e0438478ce1d58cbe9cb Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 10 Jan 2018 09:17:10 +0200 Subject: [PATCH 262/681] Update according to review comments --- .../Smoke/API/014_SetMediaClockTimer_PositiveCase.lua | 8 +++----- test_scripts/Smoke/commonSmoke.lua | 3 ++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase.lua b/test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase.lua index 62d03ea658..7b73e25953 100644 --- a/test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase.lua +++ b/test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase.lua @@ -50,13 +50,11 @@ local requestParams = { --[[ Local Functions ]] local function SetMediaClockTimer(pParams, pMode, self) - local countDown = 0 - if pMode == "COUNTDOWN" then - countDown = -1 - end local Parameters = commonFunctions:cloneTable(pParams) Parameters.updateMode = pMode - Parameters.endTime.minutes = 1 + countDown + if pMode == "COUNTDOWN" then + Parameters.endTime.minutes = Parameters.startTime.minutes - 1 + end local cid = self.mobileSession1:SendRPC("SetMediaClockTimer", Parameters) Parameters.appID = commonSmoke.getHMIAppId() EXPECT_HMICALL("UI.SetMediaClockTimer", Parameters) diff --git a/test_scripts/Smoke/commonSmoke.lua b/test_scripts/Smoke/commonSmoke.lua index 7d40b8b523..6c22690eda 100644 --- a/test_scripts/Smoke/commonSmoke.lua +++ b/test_scripts/Smoke/commonSmoke.lua @@ -14,6 +14,7 @@ local consts = require("user_modules/consts") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') local events = require("events") --[[ Local Variables ]] @@ -166,7 +167,7 @@ function commonSmoke.getHMIAppId(pAppId) end function commonSmoke.getPathToFileInStorage(fileName) - return commonSmoke.getPathToSDL() .. "storage/" + return commonPreconditions:GetPathToSDL() .. "storage/" .. commonSmoke.getMobileAppId() .. "_" .. commonSmoke.getDeviceMAC() .. "/" .. fileName end From 4f5ab90c79a55a12d9b005cdd3968fe33c83d84a Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 10 Jan 2018 17:21:32 +0200 Subject: [PATCH 263/681] Add additional verification of data on mobile side --- ..._SetDisplayLayout_PositiveCase_SUCCESS.lua | 66 +++++++++++-------- test_scripts/Smoke/API/021_Speak_SUCCESS.lua | 9 ++- 2 files changed, 42 insertions(+), 33 deletions(-) diff --git a/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua index a4a62ececc..ddb94cea58 100644 --- a/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua @@ -110,39 +110,40 @@ local function getDisplayCapImageFieldsValues() end local function getDisplayCapTextFieldsValues() + -- some text fields are excluded due to SDL issue local names = { + "alertText1", + "alertText2", + "alertText3", + "audioPassThruDisplayText1", + "audioPassThruDisplayText2", + "ETA", + "initialInteractionText", + -- "phoneNumber", "mainField1", "mainField2", "mainField3", "mainField4", - "statusBar", "mediaClock", "mediaTrack", - "alertText1", - "alertText2", - "alertText3", - "scrollableMessageBody", - "initialInteractionText", + "menuName", + "menuTitle", + -- "addressLines", + -- "locationName", "navigationText1", "navigationText2", - "ETA", - "totalDistance", - "navigationText", - "audioPassThruDisplayText1", - "audioPassThruDisplayText2", - "sliderHeader", - "sliderFooter", - "notificationText", - "menuName", + -- "locationDescription", + "scrollableMessageBody", "secondaryText", + "sliderFooter", + "sliderHeader", + "statusBar", "tertiaryText", - "timeToDestination", - "turnText", - "menuTitle", - "locationName", - "locationDescription", - "addressLines", - "phoneNumber" + "totalDistance", + -- "notificationText", + -- "navigationText", + -- "timeToDestination", + -- "turnText" } local values = { } for _, v in pairs(names) do @@ -158,13 +159,14 @@ local function getDisplayCapTextFieldsValues() end local function getDisplayCapValues() + -- some capabilities are excluded due to SDL issue return { displayType = "GEN2_8_DMA", graphicSupported = true, - imageCapabilities = { - "DYNAMIC", - "STATIC" - }, + -- imageCapabilities = { + -- "DYNAMIC", + -- "STATIC" + -- }, imageFields = getDisplayCapImageFieldsValues(), mediaClockFormats = { "CLOCK1", @@ -208,12 +210,20 @@ local function getResponseParams() end local function setDisplaySuccess(self) + local responseParams = getResponseParams() local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams()) EXPECT_HMICALL("UI.SetDisplayLayout", getRequestParams()) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", getResponseParams()) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", responseParams) end) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS", + displayCapabilities = responseParams.displayCapabilities, + buttonCapabilities = responseParams.buttonCapabilities, + softButtonCapabilities = responseParams.softButtonCapabilities, + presetBankCapabilities = responseParams.presetBankCapabilities + }) end --[[ Scenario ]] diff --git a/test_scripts/Smoke/API/021_Speak_SUCCESS.lua b/test_scripts/Smoke/API/021_Speak_SUCCESS.lua index 6474d38d96..5b07038ae7 100644 --- a/test_scripts/Smoke/API/021_Speak_SUCCESS.lua +++ b/test_scripts/Smoke/API/021_Speak_SUCCESS.lua @@ -43,6 +43,7 @@ local function getRequestParams() end local function speakSuccess(self) + print("Waiting 20s ...") local cid = self.mobileSession1:SendRPC("Speak", getRequestParams()) EXPECT_HMICALL("TTS.Speak", getRequestParams()) :Do(function(_, data) @@ -56,19 +57,17 @@ local function speakSuccess(self) { appID = commonSmoke.getHMIAppId(), methodName = "TTS.Speak" }) end RUN_AFTER(sendOnResetTimeout, 9000) - RUN_AFTER(sendOnResetTimeout, 18000) - RUN_AFTER(sendOnResetTimeout, 24000) - RUN_AFTER(sendSpeakResponse, 33000) + RUN_AFTER(sendSpeakResponse, 18000) end) self.mobileSession1:ExpectNotification("OnHMIStatus", { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "ATTENUATED" }, { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }) :Times(2) - :Timeout(35000) + :Timeout(20000) self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) - :Timeout(35000) + :Timeout(20000) end --[[ Scenario ]] From ebff2eb85f4fbb52e4dc797de6ecb0a92f3d7738 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 12 Jan 2018 08:30:45 +0200 Subject: [PATCH 264/681] Separated scripts for GetVD and UpdateTurnList --- .../API/026_GetVehicleData_PositiveCase.lua | 204 ++++++++++++++++++ .../API/027_UpdateTurnList_PositiveCase.lua | 120 +++++++++++ 2 files changed, 324 insertions(+) create mode 100644 test_scripts/Smoke/API/026_GetVehicleData_PositiveCase.lua create mode 100644 test_scripts/Smoke/API/027_UpdateTurnList_PositiveCase.lua diff --git a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase.lua b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase.lua new file mode 100644 index 0000000000..d9f038216d --- /dev/null +++ b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase.lua @@ -0,0 +1,204 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: GetVehicleData +-- Item: Happy path +-- +-- Requirement summary: +-- [GetVehicleData] SUCCESS: getting SUCCESS:VehicleInfo.GetVehicleData() +-- +-- Description: +-- Mobile application sends valid GetVehicleData request and gets VehicleInfo.GetVehicleData "SUCCESS" +-- response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests GetVehicleData with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if VehicleInfo interface is available on HMI +-- SDL checks if GetVehicleData is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the VehicleInfo part of request with allowed parameters to HMI +-- SDL receives VehicleInfo part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local vehicleDataValues = { + gps = { + longitudeDegrees = 25.5, + latitudeDegrees = 45.5, + utcYear = 2010, + utcMonth = 1, + utcDay = 1, + utcHours = 2, + utcMinutes = 3, + utcSeconds = 4, + compassDirection = "NORTH", + pdop = 1.1, + hdop = 2.2, + vdop = 3.3, + actual = true, + satellites = 5, + dimension = "NO_FIX", + altitude = 4.4, + heading = 5.5, + speed = 100 + }, + speed = 100.5, + rpm = 1000, + fuelLevel = 50.5, + fuelLevel_State = "NORMAL", + instantFuelConsumption = 1000.5, + externalTemperature = 55.5, + vin = "123456", + prndl = "DRIVE", + tirePressure = { + pressureTelltale = "ON", + leftFront = { status = "NORMAL" }, + rightFront = { status = "NORMAL" }, + leftRear = { status = "NORMAL" }, + rightRear = { status = "NORMAL" }, + innerLeftRear = { status = "NORMAL" }, + innerRightRear = { status = "NORMAL" } + }, + odometer = 8888, + beltStatus = { + driverBeltDeployed = "NOT_SUPPORTED", + passengerBeltDeployed = "YES", + passengerBuckleBelted = "YES", + driverBuckleBelted = "YES", + leftRow2BuckleBelted = "YES", + passengerChildDetected = "YES", + rightRow2BuckleBelted = "YES", + middleRow2BuckleBelted = "YES", + middleRow3BuckleBelted = "YES", + leftRow3BuckleBelted = "YES", + rightRow3BuckleBelted = "YES", + leftRearInflatableBelted = "YES", + rightRearInflatableBelted = "YES", + middleRow1BeltDeployed = "YES", + middleRow1BuckleBelted = "YES" + }, + bodyInformation = { + parkBrakeActive = true, + ignitionStableStatus = "MISSING_FROM_TRANSMITTER", + ignitionStatus = "UNKNOWN" + }, + deviceStatus = { + voiceRecOn = true, + btIconOn = true, + callActive = true, + phoneRoaming = true, + textMsgAvailable = true, + battLevelStatus = "ONE_LEVEL_BARS", + stereoAudioOutputMuted = true, + monoAudioOutputMuted = true, + signalLevelStatus = "TWO_LEVEL_BARS", + primaryAudioSource = "USB", + eCallEventActive = true + }, + driverBraking = "NOT_SUPPORTED", + wiperStatus = "MAN_LOW", + headLampStatus = { + lowBeamsOn = true, + highBeamsOn = true, + ambientLightSensorStatus = "NIGHT" + }, + engineTorque = 555.5, + accPedalPosition = 55.5, + steeringWheelAngle = 555.5, + eCallInfo = { + eCallNotificationStatus = "NORMAL", + auxECallNotificationStatus = "NORMAL", + eCallConfirmationStatus = "NORMAL" + }, + airbagStatus = { + driverAirbagDeployed = "NOT_SUPPORTED", + driverSideAirbagDeployed = "NOT_SUPPORTED", + driverCurtainAirbagDeployed = "NOT_SUPPORTED", + passengerAirbagDeployed = "NOT_SUPPORTED", + passengerCurtainAirbagDeployed = "NOT_SUPPORTED", + driverKneeAirbagDeployed = "NOT_SUPPORTED", + passengerSideAirbagDeployed = "NOT_SUPPORTED", + passengerKneeAirbagDeployed = "NOT_SUPPORTED" + }, + emergencyEvent = { + emergencyEventType = "NO_EVENT", + fuelCutoffStatus = "NORMAL_OPERATION", + rolloverEvent = "NO_EVENT", + maximumChangeVelocity = 0, + multipleEvents = "NO_EVENT" + }, + clusterModeStatus = { + powerModeActive = true, + powerModeQualificationStatus = "POWER_MODE_UNDEFINED", + carModeStatus = "TRANSPORT", + powerModeStatus = "KEY_OUT" + }, + myKey = { + e911Override = "NO_DATA_EXISTS" + } +} + +local paramsList = {} +local requestParams = { } +for k, _ in pairs(vehicleDataValues) do + table.insert(paramsList, k) + requestParams[k] = true +end + +local allParams = { + requestParams = requestParams, + responseUiParams = vehicleDataValues, +} + +--[[ Local Functions ]] +local function ptuUpdateFunc(tbl) + local SVDgroup = { + rpcs = { + GetVehicleData = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, + --For now commented because SDL does not process successfully list of parameters with more then 24 items + -- parameters = paramsList + } + } + } + tbl.policy_table.functional_groupings.NewTestCaseGroup = SVDgroup + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = + { "Base-4", "NewTestCaseGroup" } +end + +local function getVD(pParams, self) + local cid = self.mobileSession1:SendRPC("GetVehicleData", pParams.requestParams) + EXPECT_HMICALL("VehicleInfo.GetVehicleData", pParams.requestParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", pParams.responseUiParams) + end) + local MobResp = pParams.responseUiParams + MobResp.success = true + MobResp.resultCode = "SUCCESS" + self.mobileSession1:ExpectResponse(cid, MobResp) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, ptuUpdateFunc }) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("GetVehicleData Positive Case", getVD, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/027_UpdateTurnList_PositiveCase.lua b/test_scripts/Smoke/API/027_UpdateTurnList_PositiveCase.lua new file mode 100644 index 0000000000..013d2fd75f --- /dev/null +++ b/test_scripts/Smoke/API/027_UpdateTurnList_PositiveCase.lua @@ -0,0 +1,120 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: UpdateTurnList +-- Item: Happy path +-- +-- Requirement summary: +-- [UpdateTurnList] SUCCESS: getting SUCCESS:VehicleInfo.UpdateTurnList() +-- +-- Description: +-- Mobile application sends valid UpdateTurnList request and gets Navigation.UpdateTurnList "SUCCESS" +-- response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests UpdateTurnList with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if Navigation interface is available on HMI +-- SDL checks if UpdateTurnList is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the Navigation part of request with allowed parameters to HMI +-- SDL receives Navigation part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local requestParams = { + turnList = { + { + navigationText = "Text", + turnIcon = { + value = "icon.png", + imageType = "DYNAMIC", + } + } + }, + softButtons = { + { + type = "BOTH", + text = "Close", + image = { + value = "icon.png", + imageType = "DYNAMIC", + }, + isHighlighted = true, + softButtonID = 111, + systemAction = "DEFAULT_ACTION", + } + } +} + +local responseUiParams = commonFunctions:cloneTable(requestParams) +responseUiParams.turnList[1].navigationText = { + fieldText = requestParams.turnList[1].navigationText, + fieldName = "turnText" +} +responseUiParams.turnList[1].turnIcon.value = commonSmoke.getPathToFileInStorage(requestParams.turnList[1].turnIcon.value) +responseUiParams.softButtons[1].image.value = commonSmoke.getPathToFileInStorage(requestParams.softButtons[1].image.value) + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams, +} + +--[[ Local Functions ]] +local function ptuUpdateFunc(tbl) + local UpdateTurnListGroup = { + rpcs = { + UpdateTurnList = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, + } + } + } + tbl.policy_table.functional_groupings.NewTestCaseGroup = UpdateTurnListGroup + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = + { "Base-4", "NewTestCaseGroup" } +end + +local function updateTurnList(pParams, self) + local cid = self.mobileSession1:SendRPC("UpdateTurnList", pParams.requestParams) + EXPECT_HMICALL("Navigation.UpdateTurnList", pParams.responseUiParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS") + end) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, ptuUpdateFunc }) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, { putFileParams }) + +runner.Title("Test") +runner.Step("UpdateTurnList Positive Case", updateTurnList, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From 934013856c093c1d9d9515a559f64f673ffaa3d5 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 11 Jan 2018 13:20:54 +0200 Subject: [PATCH 265/681] Separated scripts for Un/SubscribeVD --- .../024_SubscribeVehicleData_PositiveCase.lua | 136 ++++++++++++++++ ...25_UnsubscribeVehicleData_PositiveCase.lua | 152 ++++++++++++++++++ 2 files changed, 288 insertions(+) create mode 100644 test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase.lua create mode 100644 test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase.lua diff --git a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase.lua b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase.lua new file mode 100644 index 0000000000..b8b51b2e02 --- /dev/null +++ b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase.lua @@ -0,0 +1,136 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: SubscribeVehicleData +-- Item: Happy path +-- +-- Requirement summary: +-- [SubscribeVehicleData] SUCCESS: getting SUCCESS:VehicleInfo.SubscribeVehicleData() +-- +-- Description: +-- Mobile application sends valid SubscribeVehicleData request and gets VehicleInfo.SubscribeVehicleData "SUCCESS" +-- response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests SubscribeVehicleData with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if VehicleInfo interface is available on HMI +-- SDL checks if SubscribeVehicleData is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the VehicleInfo part of request with allowed parameters to HMI +-- SDL receives VehicleInfo part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local VDValues = { + gps = "VEHICLEDATA_GPS", + speed = "VEHICLEDATA_SPEED", + rpm = "VEHICLEDATA_RPM", + fuelLevel = "VEHICLEDATA_FUELLEVEL", + fuelLevel_State = "VEHICLEDATA_FUELLEVEL_STATE", + instantFuelConsumption = "VEHICLEDATA_FUELCONSUMPTION", + externalTemperature = "VEHICLEDATA_EXTERNTEMP", + prndl = "VEHICLEDATA_PRNDL", + tirePressure = "VEHICLEDATA_TIREPRESSURE", + odometer = "VEHICLEDATA_ODOMETER", + beltStatus = "VEHICLEDATA_BELTSTATUS", + bodyInformation = "VEHICLEDATA_BODYINFO", + deviceStatus = "VEHICLEDATA_DEVICESTATUS", + driverBraking = "VEHICLEDATA_BRAKING", + wiperStatus = "VEHICLEDATA_WIPERSTATUS", + headLampStatus = "VEHICLEDATA_HEADLAMPSTATUS", + engineTorque = "VEHICLEDATA_ENGINETORQUE", + accPedalPosition = "VEHICLEDATA_ACCPEDAL", + steeringWheelAngle = "VEHICLEDATA_STEERINGWHEEL", + eCallInfo = "VEHICLEDATA_ECALLINFO", + airbagStatus = "VEHICLEDATA_AIRBAGSTATUS", + emergencyEvent = "VEHICLEDATA_EMERGENCYEVENT", + clusterModeStatus = "VEHICLEDATA_CLUSTERMODESTATUS", + myKey="VEHICLEDATA_MYKEY" +} + +local paramsList = {} +local requestParams = { } +for k, _ in pairs(VDValues) do + table.insert(paramsList, k) + requestParams[k] = true +end + +local responseUiParams = { } + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams, +} + +--[[ Local Functions ]] +local function ptuUpdateFunc(tbl) + local SVDgroup = { + rpcs = { + SubscribeVehicleData = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, + parameters = paramsList + } + } + } + tbl.policy_table.functional_groupings.NewTestCaseGroup = SVDgroup + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = + { "Base-4", "NewTestCaseGroup" } +end + +local function setVDResponse() + local temp = { } + local vehicleDataResultCodeValue = "SUCCESS" + for k, v in pairs(VDValues) do + if "clusterModeStatus" == k then + temp["clusterModes"] = { + resultCode = vehicleDataResultCodeValue, + dataType = v + } + else + temp[k] = { + resultCode = vehicleDataResultCodeValue, + dataType = v + } + end + end + return temp +end + +local function subscribeVD(pParams, self) + local cid = self.mobileSession1:SendRPC("SubscribeVehicleData", pParams.requestParams) + pParams.responseUiParams = setVDResponse() + EXPECT_HMICALL("VehicleInfo.SubscribeVehicleData", pParams.requestParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", pParams.responseUiParams) + end) + local MobResp = pParams.responseUiParams + MobResp.success = true + MobResp.resultCode = "SUCCESS" + self.mobileSession1:ExpectResponse(cid, MobResp) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, ptuUpdateFunc }) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("SubscribeVehicleData Positive Case", subscribeVD, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase.lua b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase.lua new file mode 100644 index 0000000000..2aee3e7ea0 --- /dev/null +++ b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase.lua @@ -0,0 +1,152 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: UnsubscribeVehicleData +-- Item: Happy path +-- +-- Requirement summary: +-- [UnsubscribeVehicleData] SUCCESS: getting SUCCESS:VehicleInfo.UnsubscribeVehicleData() +-- +-- Description: +-- Mobile application sends valid UnsubscribeVehicleData request and gets VehicleInfo.UnsubscribeVehicleData "SUCCESS" +-- response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests UnsubscribeVehicleData with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if VehicleInfo interface is available on HMI +-- SDL checks if UnsubscribeVehicleData is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the VehicleInfo part of request with allowed parameters to HMI +-- SDL receives VehicleInfo part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local VDValues = { + gps = "VEHICLEDATA_GPS", + speed = "VEHICLEDATA_SPEED", + rpm = "VEHICLEDATA_RPM", + fuelLevel = "VEHICLEDATA_FUELLEVEL", + fuelLevel_State = "VEHICLEDATA_FUELLEVEL_STATE", + instantFuelConsumption = "VEHICLEDATA_FUELCONSUMPTION", + externalTemperature = "VEHICLEDATA_EXTERNTEMP", + prndl = "VEHICLEDATA_PRNDL", + tirePressure = "VEHICLEDATA_TIREPRESSURE", + odometer = "VEHICLEDATA_ODOMETER", + beltStatus = "VEHICLEDATA_BELTSTATUS", + bodyInformation = "VEHICLEDATA_BODYINFO", + deviceStatus = "VEHICLEDATA_DEVICESTATUS", + driverBraking = "VEHICLEDATA_BRAKING", + wiperStatus = "VEHICLEDATA_WIPERSTATUS", + headLampStatus = "VEHICLEDATA_HEADLAMPSTATUS", + engineTorque = "VEHICLEDATA_ENGINETORQUE", + accPedalPosition = "VEHICLEDATA_ACCPEDAL", + steeringWheelAngle = "VEHICLEDATA_STEERINGWHEEL", + eCallInfo = "VEHICLEDATA_ECALLINFO", + airbagStatus = "VEHICLEDATA_AIRBAGSTATUS", + emergencyEvent = "VEHICLEDATA_EMERGENCYEVENT", + clusterModeStatus = "VEHICLEDATA_CLUSTERMODESTATUS", + myKey="VEHICLEDATA_MYKEY" +} + +local paramsList = {} +local requestParams = { } +for k, _ in pairs(VDValues) do + table.insert(paramsList, k) + requestParams[k] = true +end + +local responseUiParams = { } + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams, +} + +--[[ Local Functions ]] +local function ptuUpdateFunc(tbl) + local SVDgroup = { + rpcs = { + SubscribeVehicleData = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, + parameters = paramsList + }, + UnsubscribeVehicleData = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, + parameters = paramsList + } + } + } + tbl.policy_table.functional_groupings.NewTestCaseGroup = SVDgroup + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = + { "Base-4", "NewTestCaseGroup" } +end + +local function setVDResponse() + local temp = { } + local vehicleDataResultCodeValue = "SUCCESS" + for k, v in pairs(VDValues) do + if "clusterModeStatus" == k then + temp["clusterModes"] = { + resultCode = vehicleDataResultCodeValue, + dataType = v + } + else + temp[k] = { + resultCode = vehicleDataResultCodeValue, + dataType = v + } + end + end + return temp +end + +local function subscribeVD(pParams, self) + local cid = self.mobileSession1:SendRPC("SubscribeVehicleData", pParams.requestParams) + pParams.responseUiParams = setVDResponse() + EXPECT_HMICALL("VehicleInfo.SubscribeVehicleData", pParams.requestParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", pParams.responseUiParams) + end) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +local function unsubscribeVD(pParams, self) + local cid = self.mobileSession1:SendRPC("UnsubscribeVehicleData", pParams.requestParams) + pParams.responseUiParams = setVDResponse() + EXPECT_HMICALL("VehicleInfo.UnsubscribeVehicleData", pParams.requestParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", pParams.responseUiParams) + end) + local MobResp = pParams.responseUiParams + MobResp.success = true + MobResp.resultCode = "SUCCESS" + self.mobileSession1:ExpectResponse(cid, MobResp) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, ptuUpdateFunc }) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("SubscribeVehicleData", subscribeVD, { allParams }) + +runner.Title("Test") +runner.Step("UnsubscribeVehicleData Positive Case", unsubscribeVD, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From 7f6131f5913599c3d626af023f80827f9349e80a Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 12 Jan 2018 08:37:59 +0200 Subject: [PATCH 266/681] Update according to review comments --- .../Smoke/API/024_SubscribeVehicleData_PositiveCase.lua | 4 ++-- .../Smoke/API/025_UnsubscribeVehicleData_PositiveCase.lua | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase.lua b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase.lua index b8b51b2e02..268f5d3425 100644 --- a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase.lua +++ b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase.lua @@ -57,7 +57,7 @@ local VDValues = { airbagStatus = "VEHICLEDATA_AIRBAGSTATUS", emergencyEvent = "VEHICLEDATA_EMERGENCYEVENT", clusterModeStatus = "VEHICLEDATA_CLUSTERMODESTATUS", - myKey="VEHICLEDATA_MYKEY" + myKey = "VEHICLEDATA_MYKEY" } local paramsList = {} @@ -112,7 +112,7 @@ local function subscribeVD(pParams, self) local cid = self.mobileSession1:SendRPC("SubscribeVehicleData", pParams.requestParams) pParams.responseUiParams = setVDResponse() EXPECT_HMICALL("VehicleInfo.SubscribeVehicleData", pParams.requestParams) - :Do(function(_,data) + :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", pParams.responseUiParams) end) local MobResp = pParams.responseUiParams diff --git a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase.lua b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase.lua index 2aee3e7ea0..7222eb1911 100644 --- a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase.lua +++ b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase.lua @@ -57,7 +57,7 @@ local VDValues = { airbagStatus = "VEHICLEDATA_AIRBAGSTATUS", emergencyEvent = "VEHICLEDATA_EMERGENCYEVENT", clusterModeStatus = "VEHICLEDATA_CLUSTERMODESTATUS", - myKey="VEHICLEDATA_MYKEY" + myKey = "VEHICLEDATA_MYKEY" } local paramsList = {} @@ -116,7 +116,7 @@ local function subscribeVD(pParams, self) local cid = self.mobileSession1:SendRPC("SubscribeVehicleData", pParams.requestParams) pParams.responseUiParams = setVDResponse() EXPECT_HMICALL("VehicleInfo.SubscribeVehicleData", pParams.requestParams) - :Do(function(_,data) + :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", pParams.responseUiParams) end) self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) @@ -127,7 +127,7 @@ local function unsubscribeVD(pParams, self) local cid = self.mobileSession1:SendRPC("UnsubscribeVehicleData", pParams.requestParams) pParams.responseUiParams = setVDResponse() EXPECT_HMICALL("VehicleInfo.UnsubscribeVehicleData", pParams.requestParams) - :Do(function(_,data) + :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", pParams.responseUiParams) end) local MobResp = pParams.responseUiParams From 568c68aec954a12aa569f48c68985a92433b0ac6 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 10 Jan 2018 09:08:58 +0200 Subject: [PATCH 267/681] Separated scripts for SendLocation and SetAppIcon --- .../API/018_SendLocation_PositiveCase.lua | 98 +++++++++++++++++++ .../Smoke/API/019_SetAppIcon_PositiveCase.lua | 84 ++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 test_scripts/Smoke/API/018_SendLocation_PositiveCase.lua create mode 100644 test_scripts/Smoke/API/019_SetAppIcon_PositiveCase.lua diff --git a/test_scripts/Smoke/API/018_SendLocation_PositiveCase.lua b/test_scripts/Smoke/API/018_SendLocation_PositiveCase.lua new file mode 100644 index 0000000000..c3d643197a --- /dev/null +++ b/test_scripts/Smoke/API/018_SendLocation_PositiveCase.lua @@ -0,0 +1,98 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: SendLocation +-- Item: Happy path +-- +-- Requirement summary: +-- [SendLocation] SUCCESS: getting SUCCESS:Navigation.SendLocation() +-- +-- Description: +-- Mobile application sends valid SendLocation request and gets Navigation.SendLocation "SUCCESS" response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests SendLocation with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if Navigation interface is available on HMI +-- SDL checks if SendLocation is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the Navigation part of request with allowed parameters to HMI +-- SDL receives Navigation part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local requestParams = { + longitudeDegrees = 1.1, + latitudeDegrees = 1.1, + locationName = "location Name", + locationDescription = "location Description", + addressLines = { + "line1", + "line2", + }, + phoneNumber = "phone Number", + locationImage ={ + value = "icon.png", + imageType = "DYNAMIC" + } +} + +--[[ Local Functions ]] +local function ptuUpdateFuncRPC(tbl) + local SLgroup = { + rpcs = { + SendLocation = { + hmi_levels = { "NONE", "BACKGROUND", "FULL", "LIMITED" } + } + } + } + tbl.policy_table.functional_groupings["NewTestCaseGroup"] = SLgroup + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = + { "Base-4", "NewTestCaseGroup" } +end + +local function sendLocation(params, self) + local cid = self.mobileSession1:SendRPC("SendLocation", params) + params.appID = commonSmoke.getHMIAppId() + params.locationImage.value = commonSmoke.getPathToFileInStorage(params.locationImage.value) + EXPECT_HMICALL("Navigation.SendLocation", params) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, ptuUpdateFuncRPC }) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, { putFileParams }) + +runner.Title("Test") +runner.Step("SendLocation Positive Case", sendLocation, { requestParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/019_SetAppIcon_PositiveCase.lua b/test_scripts/Smoke/API/019_SetAppIcon_PositiveCase.lua new file mode 100644 index 0000000000..6b87da2adb --- /dev/null +++ b/test_scripts/Smoke/API/019_SetAppIcon_PositiveCase.lua @@ -0,0 +1,84 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: SetAppIcon +-- Item: Happy path +-- +-- Requirement summary: +-- [SetAppIcon] SUCCESS: getting SUCCESS:UI.SetAppIcon() +-- +-- Description: +-- Mobile application sends valid SetAppIcon request and gets UI.SetAppIcon "SUCCESS" response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests SetAppIcon with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if SetAppIcon is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the UI part of request with allowed parameters to HMI +-- SDL receives UI part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'action.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local requestParams = { + syncFileName = "action.png" +} + +local requestUiParams = { + syncFileName = { + imageType = "DYNAMIC", + value = commonSmoke.getPathToFileInStorage(requestParams.syncFileName) + } +} + +local allParams = { + requestParams = requestParams, + requestUiParams = requestUiParams +} + +--[[ Local Functions ]] +local function setAppIcon(params, self) + local cid = self.mobileSession1:SendRPC("SetAppIcon", params.requestParams) + params.requestUiParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("UI.SetAppIcon", params.requestUiParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, { putFileParams }) + +runner.Title("Test") +runner.Step("SetAppIcon Positive Case", setAppIcon, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From 87403972486a44f8eb7fcf65dcbe04200182c50f Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 12 Jan 2018 08:43:51 +0200 Subject: [PATCH 268/681] Update according to review comments --- test_scripts/Smoke/API/018_SendLocation_PositiveCase.lua | 4 ++-- test_scripts/Smoke/API/019_SetAppIcon_PositiveCase.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test_scripts/Smoke/API/018_SendLocation_PositiveCase.lua b/test_scripts/Smoke/API/018_SendLocation_PositiveCase.lua index c3d643197a..effda4485e 100644 --- a/test_scripts/Smoke/API/018_SendLocation_PositiveCase.lua +++ b/test_scripts/Smoke/API/018_SendLocation_PositiveCase.lua @@ -67,7 +67,7 @@ local function ptuUpdateFuncRPC(tbl) } } } - tbl.policy_table.functional_groupings["NewTestCaseGroup"] = SLgroup + tbl.policy_table.functional_groupings.NewTestCaseGroup = SLgroup tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = { "Base-4", "NewTestCaseGroup" } end @@ -77,7 +77,7 @@ local function sendLocation(params, self) params.appID = commonSmoke.getHMIAppId() params.locationImage.value = commonSmoke.getPathToFileInStorage(params.locationImage.value) EXPECT_HMICALL("Navigation.SendLocation", params) - :Do(function(_,data) + :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) diff --git a/test_scripts/Smoke/API/019_SetAppIcon_PositiveCase.lua b/test_scripts/Smoke/API/019_SetAppIcon_PositiveCase.lua index 6b87da2adb..1f13b19252 100644 --- a/test_scripts/Smoke/API/019_SetAppIcon_PositiveCase.lua +++ b/test_scripts/Smoke/API/019_SetAppIcon_PositiveCase.lua @@ -63,7 +63,7 @@ local function setAppIcon(params, self) local cid = self.mobileSession1:SendRPC("SetAppIcon", params.requestParams) params.requestUiParams.appID = commonSmoke.getHMIAppId() EXPECT_HMICALL("UI.SetAppIcon", params.requestUiParams) - :Do(function(_,data) + :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) From 9c0827d09fcbc036e9df4633cac640738392824d Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Mon, 15 Jan 2018 13:13:36 +0200 Subject: [PATCH 269/681] Update according to review comments --- .../API/026_GetVehicleData_PositiveCase.lua | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase.lua b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase.lua index d9f038216d..4349aaacaa 100644 --- a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase.lua +++ b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase.lua @@ -150,26 +150,25 @@ local vehicleDataValues = { } } -local paramsList = {} -local requestParams = { } -for k, _ in pairs(vehicleDataValues) do - table.insert(paramsList, k) - requestParams[k] = true +local function setVDRequest() + local tmp = {} + for k, _ in pairs(vehicleDataValues) do + tmp[k] = true + end + return tmp end local allParams = { - requestParams = requestParams, + requestParams = setVDRequest(), responseUiParams = vehicleDataValues, } --[[ Local Functions ]] -local function ptuUpdateFunc(tbl) +local function PTUpdateFunc(tbl) local SVDgroup = { rpcs = { GetVehicleData = { hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, - --For now commented because SDL does not process successfully list of parameters with more then 24 items - -- parameters = paramsList } } } @@ -182,8 +181,8 @@ local function getVD(pParams, self) local cid = self.mobileSession1:SendRPC("GetVehicleData", pParams.requestParams) EXPECT_HMICALL("VehicleInfo.GetVehicleData", pParams.requestParams) :Do(function(_,data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", pParams.responseUiParams) - end) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", pParams.responseUiParams) + end) local MobResp = pParams.responseUiParams MobResp.success = true MobResp.resultCode = "SUCCESS" @@ -194,7 +193,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, ptuUpdateFunc }) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, PTUpdateFunc }) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") From d5d3d3d0a890b0291e8dddbf8266d6150c081b01 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Mon, 15 Jan 2018 13:46:05 +0200 Subject: [PATCH 270/681] Update according to review comments --- .../024_SubscribeVehicleData_PositiveCase.lua | 41 ++++++++--------- ...25_UnsubscribeVehicleData_PositiveCase.lua | 45 ++++++++----------- 2 files changed, 37 insertions(+), 49 deletions(-) diff --git a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase.lua b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase.lua index 268f5d3425..25c1b23b7c 100644 --- a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase.lua +++ b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase.lua @@ -60,27 +60,19 @@ local VDValues = { myKey = "VEHICLEDATA_MYKEY" } -local paramsList = {} -local requestParams = { } -for k, _ in pairs(VDValues) do - table.insert(paramsList, k) - requestParams[k] = true -end - local responseUiParams = { } - +local requestParams = { } local allParams = { requestParams = requestParams, responseUiParams = responseUiParams, } --[[ Local Functions ]] -local function ptuUpdateFunc(tbl) +local function PTUpdateFunc(tbl) local SVDgroup = { rpcs = { SubscribeVehicleData = { hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, - parameters = paramsList } } } @@ -89,32 +81,35 @@ local function ptuUpdateFunc(tbl) { "Base-4", "NewTestCaseGroup" } end +local function setVDRequest() + local tmp = {} + for k, _ in pairs(VDValues) do + tmp[k] = true + end + return tmp +end + local function setVDResponse() local temp = { } local vehicleDataResultCodeValue = "SUCCESS" - for k, v in pairs(VDValues) do - if "clusterModeStatus" == k then - temp["clusterModes"] = { - resultCode = vehicleDataResultCodeValue, - dataType = v - } - else - temp[k] = { + for key, value in pairs(VDValues) do + local paramName = "clusterModeStatus" == key and "clusterModes" or key + temp[paramName] = { resultCode = vehicleDataResultCodeValue, - dataType = v + dataType = value } - end end return temp end local function subscribeVD(pParams, self) + pParams.requestParams = setVDRequest() local cid = self.mobileSession1:SendRPC("SubscribeVehicleData", pParams.requestParams) pParams.responseUiParams = setVDResponse() EXPECT_HMICALL("VehicleInfo.SubscribeVehicleData", pParams.requestParams) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", pParams.responseUiParams) - end) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", pParams.responseUiParams) + end) local MobResp = pParams.responseUiParams MobResp.success = true MobResp.resultCode = "SUCCESS" @@ -126,7 +121,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, ptuUpdateFunc }) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, PTUpdateFunc }) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase.lua b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase.lua index 7222eb1911..7acc4665ea 100644 --- a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase.lua +++ b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase.lua @@ -60,31 +60,22 @@ local VDValues = { myKey = "VEHICLEDATA_MYKEY" } -local paramsList = {} local requestParams = { } -for k, _ in pairs(VDValues) do - table.insert(paramsList, k) - requestParams[k] = true -end - local responseUiParams = { } - local allParams = { requestParams = requestParams, responseUiParams = responseUiParams, } --[[ Local Functions ]] -local function ptuUpdateFunc(tbl) +local function PTUpdateFunc(tbl) local SVDgroup = { rpcs = { SubscribeVehicleData = { hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, - parameters = paramsList }, UnsubscribeVehicleData = { hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, - parameters = paramsList } } } @@ -93,43 +84,45 @@ local function ptuUpdateFunc(tbl) { "Base-4", "NewTestCaseGroup" } end +local function setVDRequest() + local tmp = {} + for k, _ in pairs(VDValues) do + tmp[k] = true + end + return tmp +end + local function setVDResponse() local temp = { } local vehicleDataResultCodeValue = "SUCCESS" - for k, v in pairs(VDValues) do - if "clusterModeStatus" == k then - temp["clusterModes"] = { - resultCode = vehicleDataResultCodeValue, - dataType = v - } - else - temp[k] = { + for key, value in pairs(VDValues) do + local paramName = "clusterModeStatus" == key and "clusterModes" or key + temp[paramName] = { resultCode = vehicleDataResultCodeValue, - dataType = v + dataType = value } - end end return temp end local function subscribeVD(pParams, self) + pParams.requestParams = setVDRequest() local cid = self.mobileSession1:SendRPC("SubscribeVehicleData", pParams.requestParams) pParams.responseUiParams = setVDResponse() EXPECT_HMICALL("VehicleInfo.SubscribeVehicleData", pParams.requestParams) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", pParams.responseUiParams) - end) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", pParams.responseUiParams) + end) self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) self.mobileSession1:ExpectNotification("OnHashChange") end local function unsubscribeVD(pParams, self) local cid = self.mobileSession1:SendRPC("UnsubscribeVehicleData", pParams.requestParams) - pParams.responseUiParams = setVDResponse() EXPECT_HMICALL("VehicleInfo.UnsubscribeVehicleData", pParams.requestParams) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", pParams.responseUiParams) - end) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", pParams.responseUiParams) + end) local MobResp = pParams.responseUiParams MobResp.success = true MobResp.resultCode = "SUCCESS" @@ -141,7 +134,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, ptuUpdateFunc }) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, PTUpdateFunc }) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("SubscribeVehicleData", subscribeVD, { allParams }) From 1beebeb781d5b1a642f48934f96fc83a8200f356 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 15 Jan 2018 15:10:30 +0200 Subject: [PATCH 271/681] Initial version of script for GetDTCs RPC --- .../Smoke/API/034_GetDTCs_SUCCESS.lua | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 test_scripts/Smoke/API/034_GetDTCs_SUCCESS.lua diff --git a/test_scripts/Smoke/API/034_GetDTCs_SUCCESS.lua b/test_scripts/Smoke/API/034_GetDTCs_SUCCESS.lua new file mode 100644 index 0000000000..0a50a35190 --- /dev/null +++ b/test_scripts/Smoke/API/034_GetDTCs_SUCCESS.lua @@ -0,0 +1,83 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: GetDTCs +-- Item: Happy path +-- +-- Requirement summary: +-- [GetDTCs] SUCCESS on VehicleInfo.GetDTCs +-- +-- Description: +-- Mobile application sends GetDTCs request with valid parameters to SDL +-- +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- +-- Steps: +-- Application sends GetDTCs request with valid parameters to SDL +-- +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if VehicleInfo interface is available on HMI +-- SDL checks if GetDTCs is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the VehicleInfo part of request with allowed parameters to HMI +-- SDL receives VehicleInfo part of response from HMI with "SUCCESS" result code +-- SDL transfers response to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Functions ]] +local function PTUpdateFunc(tbl) + local GetDTCs = { + rpcs = { + GetDTCs = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, + } + } + } + tbl.policy_table.functional_groupings.NewTestCaseGroup = GetDTCs + tbl.policy_table.app_policies[commonSmoke.getMobileAppId()].groups = { "Base-4", "NewTestCaseGroup" } +end + +local function getDTCsSuccess(self) + local requestParams = { + ecuName = 2, + dtcMask = 3 + } + local responseParams = { + ecuHeader = 2, + dtc = { "line 0", "line 1", "line 2" } + } + + local cid = self.mobileSession1:SendRPC("GetDTCs", requestParams) + + requestParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("VehicleInfo.GetDTCs", requestParams) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", responseParams) + end) + + self.mobileSession1:ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS", + ecuHeader = responseParams.ecuHeader, + dtc = responseParams.dtc + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, PTUpdateFunc }) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("GetDTCs Positive Case", getDTCsSuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From d175dd429ca93d5347c3aed00a9d208dd415dd00 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 15 Jan 2018 15:47:34 +0200 Subject: [PATCH 272/681] Initial version of script for ChangeRegistration RPC --- .../API/035_ChangeRegistration_SUCCESS.lua | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 test_scripts/Smoke/API/035_ChangeRegistration_SUCCESS.lua diff --git a/test_scripts/Smoke/API/035_ChangeRegistration_SUCCESS.lua b/test_scripts/Smoke/API/035_ChangeRegistration_SUCCESS.lua new file mode 100644 index 0000000000..14528bba6f --- /dev/null +++ b/test_scripts/Smoke/API/035_ChangeRegistration_SUCCESS.lua @@ -0,0 +1,95 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: ChangeRegistration +-- Item: Happy path +-- +-- Requirement summary: +-- [ChangeRegistration] SUCCESS on UI.ChangeRegistration +-- +-- Description: +-- Mobile application sends ChangeRegistration request with valid parameters to SDL +-- +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- +-- Steps: +-- Application sends ChangeRegistration request with valid parameters to SDL +-- +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if UI, VR, TTS interface is available on HMI +-- SDL checks if ChangeRegistration is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the UI, VR, TTS part of request with allowed parameters to HMI +-- SDL receives UI, VR, TTS part of response from HMI with "SUCCESS" result code +-- SDL transfers response to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Functions ]] +local function changeRegistrationSuccess(self) + local requestParams = { + language ="EN-US", + hmiDisplayLanguage ="EN-US", + appName ="SyncProxyTester", + ttsName = { + { + text ="SyncProxyTester", + type ="TEXT", + }, + }, + ngnMediaScreenAppName ="SPT", + vrSynonyms = { + "VRSyncProxyTester", + } + } + + local cid = self.mobileSession1:SendRPC("ChangeRegistration", requestParams) + + EXPECT_HMICALL("UI.ChangeRegistration", { + appName = requestParams.appName, + language = requestParams.hmiDisplayLanguage, + ngnMediaScreenAppName = requestParams.ngnMediaScreenAppName, + appID = commonSmoke.getHMIAppId() + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + EXPECT_HMICALL("VR.ChangeRegistration", { + language = requestParams.language, + vrSynonyms = requestParams.vrSynonyms, + appID = commonSmoke.getHMIAppId() + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + EXPECT_HMICALL("TTS.ChangeRegistration", { + language = requestParams.language, + ttsName = requestParams.ttsName, + appID = commonSmoke.getHMIAppId() + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("ChangeRegistration Positive Case", changeRegistrationSuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From bc99abf441e1b8cb39023f3354636305748498b9 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 15 Jan 2018 15:51:27 +0200 Subject: [PATCH 273/681] Correct indentations --- .../Smoke/API/034_GetDTCs_SUCCESS.lua | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/test_scripts/Smoke/API/034_GetDTCs_SUCCESS.lua b/test_scripts/Smoke/API/034_GetDTCs_SUCCESS.lua index 0a50a35190..66219634c2 100644 --- a/test_scripts/Smoke/API/034_GetDTCs_SUCCESS.lua +++ b/test_scripts/Smoke/API/034_GetDTCs_SUCCESS.lua @@ -44,29 +44,29 @@ local function PTUpdateFunc(tbl) end local function getDTCsSuccess(self) - local requestParams = { - ecuName = 2, - dtcMask = 3 - } - local responseParams = { - ecuHeader = 2, - dtc = { "line 0", "line 1", "line 2" } - } + local requestParams = { + ecuName = 2, + dtcMask = 3 + } + local responseParams = { + ecuHeader = 2, + dtc = { "line 0", "line 1", "line 2" } + } - local cid = self.mobileSession1:SendRPC("GetDTCs", requestParams) + local cid = self.mobileSession1:SendRPC("GetDTCs", requestParams) - requestParams.appID = commonSmoke.getHMIAppId() - EXPECT_HMICALL("VehicleInfo.GetDTCs", requestParams) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", responseParams) - end) + requestParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("VehicleInfo.GetDTCs", requestParams) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", responseParams) + end) - self.mobileSession1:ExpectResponse(cid, { - success = true, - resultCode = "SUCCESS", - ecuHeader = responseParams.ecuHeader, - dtc = responseParams.dtc - }) + self.mobileSession1:ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS", + ecuHeader = responseParams.ecuHeader, + dtc = responseParams.dtc + }) end --[[ Scenario ]] From 0153e0f6b20b26c0fb6683a47e60edb2228b9e1f Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Mon, 15 Jan 2018 12:24:33 +0200 Subject: [PATCH 274/681] Separated scripts for ReadDID and EndAudioPT --- .../API/032_EndAudioPassThru_PositiveCase.lua | 129 ++++++++++++++++++ .../Smoke/API/033_ReadDID_PositiveCase.lua | 98 +++++++++++++ 2 files changed, 227 insertions(+) create mode 100644 test_scripts/Smoke/API/032_EndAudioPassThru_PositiveCase.lua create mode 100644 test_scripts/Smoke/API/033_ReadDID_PositiveCase.lua diff --git a/test_scripts/Smoke/API/032_EndAudioPassThru_PositiveCase.lua b/test_scripts/Smoke/API/032_EndAudioPassThru_PositiveCase.lua new file mode 100644 index 0000000000..061bfc5b6e --- /dev/null +++ b/test_scripts/Smoke/API/032_EndAudioPassThru_PositiveCase.lua @@ -0,0 +1,129 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: EndAudioPassThru +-- Item: Happy path +-- +-- Requirement summary: +-- [EndAudioPassThru] SUCCESS: getting SUCCESS:UI.EndAudioPassThru() +-- +-- Description: +-- Mobile application sends valid EndAudioPassThru request and gets UI.EndAudioPassThru "SUCCESS" +-- response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests EndAudioPassThru with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if EndAudioPassThru is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the UI part of request with allowed parameters to HMI +-- SDL receives UI part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') + +--[[ Local Variables ]] +local requestParams = { + audioPassThruDisplayText1 = "DisplayText1", + audioPassThruDisplayText2 = "DisplayText2", + samplingRate = "8KHZ", + maxDuration = 2000, + bitsPerSample = "8_BIT", + audioType = "PCM", + muteAudio = true +} + +local requestUiParams = { + audioPassThruDisplayTexts = { }, + maxDuration = requestParams.maxDuration, + muteAudio = requestParams.muteAudio +} + +requestUiParams.audioPassThruDisplayTexts[1] = { + fieldName = "audioPassThruDisplayText1", + fieldText = requestParams.audioPassThruDisplayText1 +} + +requestUiParams.audioPassThruDisplayTexts[2] = { + fieldName = "audioPassThruDisplayText2", + fieldText = requestParams.audioPassThruDisplayText2 +} + +local allParams = { + requestParams = requestParams, + requestUiParams = requestUiParams, +} + +--[[ Local Functions ]] +local function file_check(file_name) + local file_found = io.open(file_name, "r") + if nil == file_found then + return false + end + return true +end + +local function sendOnSystemContext(self, pCtx, pAppID) + self.hmiConnection:SendNotification("UI.OnSystemContext", + { appID = pAppID, systemContext = pCtx }) +end + +local function EndAudioPassThru(pParams, self) + local uiPerformID + local AudibleState = commonSmoke.GetAudibleState() + local cid = self.mobileSession1:SendRPC("PerformAudioPassThru", pParams.requestParams) + pParams.requestUiParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("UI.PerformAudioPassThru", pParams.requestUiParams) + :Do(function(_,data) + sendOnSystemContext(self, "HMI_OBSCURED", pParams.requestUiParams.appID) + uiPerformID = data.id + end) + EXPECT_HMINOTIFICATION("UI.OnRecordStart", { appID = pParams.requestUiParams.appID }) + self.mobileSession1:ExpectNotification("OnAudioPassThru") + :Do(function() + local cidEndAudioPassThru = self.mobileSession1:SendRPC("EndAudioPassThru", { }) + EXPECT_HMICALL("UI.EndAudioPassThru") + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + self.hmiConnection:SendResponse(uiPerformID, "UI.PerformAudioPassThru", "SUCCESS", { }) + sendOnSystemContext(self, "MAIN", pParams.requestUiParams.appID) + end) + self.mobileSession1:ExpectResponse(cidEndAudioPassThru, { success = true, resultCode = "SUCCESS" }) + end) + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = AudibleState, systemContext = "HMI_OBSCURED" }, + { hmiLevel = "FULL", audioStreamingState = AudibleState, systemContext = "MAIN" }) + :Times(2) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + :ValidIf (function() + local file = commonPreconditions:GetPathToSDL() .. "storage/" .. "audio.wav" + if true ~= file_check(file) then + return false, "Can not found file: audio.wav" + end + return true + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("EndAudioPassThru Positive Case", EndAudioPassThru, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/033_ReadDID_PositiveCase.lua b/test_scripts/Smoke/API/033_ReadDID_PositiveCase.lua new file mode 100644 index 0000000000..0adcb32c39 --- /dev/null +++ b/test_scripts/Smoke/API/033_ReadDID_PositiveCase.lua @@ -0,0 +1,98 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: ReadDID +-- Item: Happy path +-- +-- Requirement summary: +-- [ReadDID] SUCCESS: getting SUCCESS:VehicleInfo.ReadDID() +-- +-- Description: +-- Mobile application sends valid ReadDID request and gets VehicleInfo.ReadDID "SUCCESS" response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests ReadDID with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if VehicleInfo interface is available on HMI +-- SDL checks if ReadDID is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the VehicleInfo part of request with allowed parameters to HMI +-- SDL receives VehicleInfo part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Functions ]] +local function PTUpdateFunc(tbl) + local ReadDIDgroup = { + rpcs = { + ReadDID = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, + } + } + } + tbl.policy_table.functional_groupings.NewTestCaseGroup = ReadDIDgroup + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = + { "Base-4", "NewTestCaseGroup" } +end + +local function setReadDIDRequest() + local temp = { + ecuName = 2000, + didLocation = { + 56832 + } + } + return temp +end + +local function setReadDIDSuccessResponse(didLocationValues) + local temp = { + didResult = {} + } + for i = 1, #didLocationValues do + temp.didResult[i] = { + resultCode = "SUCCESS", + didLocation = didLocationValues[i], + data = "123" + } + end + return temp +end + +local function readDID(self) + local paramsSend = setReadDIDRequest() + local response = setReadDIDSuccessResponse(paramsSend.didLocation) + local cid = self.mobileSession1:SendRPC("ReadDID",paramsSend) + paramsSend.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("VehicleInfo.ReadDID",paramsSend) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", response) + end) + local expectedResult = response + expectedResult.success = true + expectedResult.resultCode = "SUCCESS" + self.mobileSession1:ExpectResponse(cid, expectedResult) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, PTUpdateFunc}) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("ReadDID Positive Case", readDID) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From 6cf697e406b797f9d14008fa6e2511cf64dfc4c2 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 12 Jan 2018 11:48:06 +0200 Subject: [PATCH 275/681] Separated API scripts for AlertManeuver and OnDD --- .../API/028_AlertManeuver_PositiveCase.lua | 160 ++++++++++++++++++ .../029_OnDriverDistraction_PositiveCase.lua | 55 ++++++ 2 files changed, 215 insertions(+) create mode 100644 test_scripts/Smoke/API/028_AlertManeuver_PositiveCase.lua create mode 100644 test_scripts/Smoke/API/029_OnDriverDistraction_PositiveCase.lua diff --git a/test_scripts/Smoke/API/028_AlertManeuver_PositiveCase.lua b/test_scripts/Smoke/API/028_AlertManeuver_PositiveCase.lua new file mode 100644 index 0000000000..b052e26c0f --- /dev/null +++ b/test_scripts/Smoke/API/028_AlertManeuver_PositiveCase.lua @@ -0,0 +1,160 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: AlertManeuver +-- Item: Happy path +-- +-- Requirement summary: +-- [AlertManeuver] SUCCESS on Navigation.AlertManeuver +-- +-- Description: +-- Mobile application sends AlertManeuver request with valid parameters to SDL +-- +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- +-- Steps: +-- Application sends AlertManeuver request with valid parameters to SDL +-- +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if Navigation interface is available on HMI +-- SDL checks if TTS interface is available on HMI +-- SDL checks if AlertManeuver is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the Navigation part of request with allowed parameters to HMI +-- SDL transfers the TTS part of request with allowed parameters to HMI +-- SDL receives Navigation part of response from HMI with "SUCCESS" result code +-- SDL receives TTS part of response from HMI with "SUCCESS" result code +-- SDL transfers response to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local requestParams = { + ttsChunks = { + { + text = "FirstAlert", + type = "TEXT", + }, + { + text = "SecondAlert", + type = "TEXT", + }, + }, + softButtons = { + { + type = "BOTH", + text = "Close", + image = { + value = "icon.png", + imageType = "DYNAMIC", + }, + isHighlighted = true, + softButtonID = 821, + systemAction = "DEFAULT_ACTION", + }, + { + type = "BOTH", + text = "AnotherClose", + image = { + value = "icon.png", + imageType = "DYNAMIC", + }, + isHighlighted = false, + softButtonID = 822, + systemAction = "DEFAULT_ACTION", + }, + } +} + +local function naviParamsSet(tbl) + local Params = commonFunctions:cloneTable(tbl) + for k, _ in pairs(Params) do + if Params[k].image then + Params[k].image.value = commonSmoke.getPathToFileInStorage(Params[k].image.value) + end + end + return Params +end + +local responseNaviParams = { + softButtons = naviParamsSet(requestParams.softButtons) +} + +local responseTtsParams = { + ttsChunks = requestParams.ttsChunks +} + +local allParams = { + requestParams = requestParams, + responseNaviParams = responseNaviParams, + responseTtsParams = responseTtsParams +} + +--[[ Local Functions ]] +local function PTUpdateFunc(tbl) + local AlertMgroup = { + rpcs = { + AlertManeuver = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, + } + } + } + tbl.policy_table.functional_groupings.NewTestCaseGroup = AlertMgroup + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = + { "Base-4", "NewTestCaseGroup" } +end + +local function alertManeuver(pParams, self) + local cid = self.mobileSession1:SendRPC("AlertManeuver", pParams.requestParams) + EXPECT_HMICALL("Navigation.AlertManeuver", pParams.responseNaviParams) + :Do(function(_, data) + local function alertResp() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end + RUN_AFTER(alertResp, 2000) + end) + EXPECT_HMICALL("TTS.Speak", pParams.responseTtsParams) + :Do(function(_, data) + self.hmiConnection:SendNotification("TTS.Started") + local function SpeakResp() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + self.hmiConnection:SendNotification("TTS.Stopped") + end + RUN_AFTER(SpeakResp, 1000) + end) + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "ATTENUATED" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }) + :Times(2) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, PTUpdateFunc }) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, { putFileParams }) + +runner.Title("Test") +runner.Step("AlertManeuver Positive Case", alertManeuver, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/029_OnDriverDistraction_PositiveCase.lua b/test_scripts/Smoke/API/029_OnDriverDistraction_PositiveCase.lua new file mode 100644 index 0000000000..5700197df3 --- /dev/null +++ b/test_scripts/Smoke/API/029_OnDriverDistraction_PositiveCase.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: OnDriverDistraction +-- Item: Happy path +-- +-- Requirement summary: +-- [OnDriverDistraction] SUCCESS: getting SUCCESS:UI.OnDriverDistraction() +-- +-- Description: +-- HMI sends OnDriverDistraction notification with valid parameters to SDL, +-- SDL resends notification to mobile application successful + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- HMI sends OnDriverDistraction with valid parameters + +-- Expected: +-- SDL receives notification and validates parameters +-- SDL checks if OnDriverDistraction is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers notification with allowed parameters to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local OnDDValue = { "DD_ON", "DD_OFF" } + +--[[ Local Functions ]] +local function onDriverDistraction(pOnDDValue, self) + local request = { state = pOnDDValue } + self.hmiConnection:SendNotification("UI.OnDriverDistraction", request) + self.mobileSession1:ExpectNotification("OnDriverDistraction", request) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +for _, v in pairs(OnDDValue) do + runner.Step("OnDriverDistraction with state " .. v .. " Positive Case", onDriverDistraction, { v }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From 1422fe6237c5267a6553a1fbc7e03292cecd06b6 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 12 Jan 2018 14:03:20 +0200 Subject: [PATCH 276/681] Separates scripts for DialNumber and PerformAudioPT --- .../Smoke/API/030_DialNumber_PositiveCase.lua | 74 +++++++++ .../031_PerformAudioPassThru_PositiveCase.lua | 147 ++++++++++++++++++ 2 files changed, 221 insertions(+) create mode 100644 test_scripts/Smoke/API/030_DialNumber_PositiveCase.lua create mode 100644 test_scripts/Smoke/API/031_PerformAudioPassThru_PositiveCase.lua diff --git a/test_scripts/Smoke/API/030_DialNumber_PositiveCase.lua b/test_scripts/Smoke/API/030_DialNumber_PositiveCase.lua new file mode 100644 index 0000000000..78770302d0 --- /dev/null +++ b/test_scripts/Smoke/API/030_DialNumber_PositiveCase.lua @@ -0,0 +1,74 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: DialNumber +-- Item: Happy path +-- +-- Requirement summary: +-- [DialNumber] SUCCESS: getting SUCCESS:BasicCommunication.DialNumber() +-- +-- Description: +-- Mobile application sends valid DialNumber request and gets BasicCommunication.DialNumber "SUCCESS" response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests DialNumber with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if BasicCommunication interface is available on HMI +-- SDL checks if DialNumber is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the BasicCommunication part of request with allowed parameters to HMI +-- SDL receives BasicCommunication part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local requestParams = { + number = "#3804567654*" +} + +--[[ Local Functions ]] +local function PTUpdateFuncRPC(tbl) + local DialNumberGroup = { + rpcs = { + DialNumber = { + hmi_levels = { "NONE", "BACKGROUND", "FULL", "LIMITED" } + } + } + } + tbl.policy_table.functional_groupings.NewTestCaseGroup = DialNumberGroup + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = + { "Base-4", "NewTestCaseGroup" } +end + +local function dialNumber(pParams, self) + local cid = self.mobileSession1:SendRPC("DialNumber", pParams) + pParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("BasicCommunication.DialNumber", pParams) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, PTUpdateFuncRPC }) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("DialNumber Positive Case", dialNumber, { requestParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/031_PerformAudioPassThru_PositiveCase.lua b/test_scripts/Smoke/API/031_PerformAudioPassThru_PositiveCase.lua new file mode 100644 index 0000000000..3ce4a2ee06 --- /dev/null +++ b/test_scripts/Smoke/API/031_PerformAudioPassThru_PositiveCase.lua @@ -0,0 +1,147 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: PerformAudioPassThru +-- Item: Happy path +-- +-- Requirement summary: +-- [PerformAudioPassThru] SUCCESS: getting SUCCESS:UI.PerformAudioPassThru() +-- +-- Description: +-- Mobile application sends valid PerformAudioPassThru request and gets UI.PerformAudioPassThru "SUCCESS" +-- response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests PerformAudioPassThru with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if TTS interface is available on HMI +-- SDL checks if PerformAudioPassThru is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the UI part of request with allowed parameters to HMI +-- SDL transfers the TTS part of request with allowed parameters to HMI +-- SDL receives UI part of response from HMI with "SUCCESS" result code +-- SDL receives TTS part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') + +--[[ Local Variables ]] +local requestParams = { + initialPrompt = { + { + text = "Makeyourchoice", + type = "TEXT", + }, + }, + audioPassThruDisplayText1 = "DisplayText1", + audioPassThruDisplayText2 = "DisplayText2", + samplingRate = "8KHZ", + maxDuration = 2000, + bitsPerSample = "8_BIT", + audioType = "PCM", + muteAudio = true +} + +local requestUiParams = { + audioPassThruDisplayTexts = { }, + maxDuration = requestParams.maxDuration, + muteAudio = requestParams.muteAudio +} + +requestUiParams.audioPassThruDisplayTexts[1] = { + fieldName = "audioPassThruDisplayText1", + fieldText = requestParams.audioPassThruDisplayText1 +} + +requestUiParams.audioPassThruDisplayTexts[2] = { + fieldName = "audioPassThruDisplayText2", + fieldText = requestParams.audioPassThruDisplayText2 +} + +local requestTtsParams = {} +requestTtsParams.ttsChunks = commonFunctions:cloneTable(requestParams.initialPrompt) +requestTtsParams.speakType = "AUDIO_PASS_THRU" + +local allParams = { + requestParams = requestParams, + requestUiParams = requestUiParams, + requestTtsParams = requestTtsParams +} + +--[[ Local Functions ]] +local function file_check(file_name) + local file_found = io.open(file_name, "r") + if nil == file_found then + return false + end + return true +end + +local function sendOnSystemContext(self, pCtx, pAppID) + self.hmiConnection:SendNotification("UI.OnSystemContext", + { appID = pAppID, systemContext = pCtx }) +end + +local function performAudioPassThru(pParams, self) + local cid = self.mobileSession1:SendRPC("PerformAudioPassThru", pParams.requestParams) + pParams.requestUiParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("TTS.Speak", pParams.requestTtsParams) + :Do(function(_,data) + self.hmiConnection:SendNotification("TTS.Started") + local function ttsSpeakResponse() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + self.hmiConnection:SendNotification("TTS.Stopped") + end + RUN_AFTER(ttsSpeakResponse, 50) + end) + EXPECT_HMICALL("UI.PerformAudioPassThru", pParams.requestUiParams) + :Do(function(_,data) + sendOnSystemContext(self, "HMI_OBSCURED", pParams.requestUiParams.appID) + local function uiResponse() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + sendOnSystemContext(self, "MAIN", pParams.requestUiParams.appID) + end + RUN_AFTER(uiResponse, 1500) + end) + EXPECT_HMINOTIFICATION("UI.OnRecordStart", {appID = pParams.requestUiParams.appID}) + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "ATTENUATED", systemContext = "MAIN" }, + { hmiLevel = "FULL", audioStreamingState = "ATTENUATED", systemContext = "HMI_OBSCURED" }, + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "HMI_OBSCURED" }, + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + :Times(4) + self.mobileSession1:ExpectNotification("OnAudioPassThru") + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + :ValidIf (function() + local file = commonPreconditions:GetPathToSDL() .. "storage/" .. "audio.wav" + if true ~= file_check(file) then + return false, "Can not found file: audio.wav" + end + return true + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("PerformAudioPassThru Positive Case", performAudioPassThru, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From 63a3f17c4291e2b5c792f0a2267a33f84897c95b Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 11 Jan 2018 09:45:15 +0200 Subject: [PATCH 277/681] Separated scrtips for Un/SubscribeButton --- .../API/022_SubscribeButton_PositiveCase.lua | 73 ++++++++++++++++ .../023_UnsubscribeButton_PositiveCase.lua | 85 +++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 test_scripts/Smoke/API/022_SubscribeButton_PositiveCase.lua create mode 100644 test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase.lua diff --git a/test_scripts/Smoke/API/022_SubscribeButton_PositiveCase.lua b/test_scripts/Smoke/API/022_SubscribeButton_PositiveCase.lua new file mode 100644 index 0000000000..ef27276aa0 --- /dev/null +++ b/test_scripts/Smoke/API/022_SubscribeButton_PositiveCase.lua @@ -0,0 +1,73 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: SubscribeButton +-- Item: Happy path +-- +-- Requirement summary: +-- [SubscribeButton] SUCCESS: getting SUCCESS:SubscribeButton() +-- +-- Description: +-- Mobile application sends valid SubscribeButton request and gets SubscribeButton "SUCCESS" response from SDL + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests SubscribeButton with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if Buttons interface is available on HMI +-- SDL checks if SubscribeButton is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL sends the Buttons notificaton to HMI +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local buttonName = { + "OK", + "SEEKLEFT", + "SEEKRIGHT", + "TUNEUP", + "TUNEDOWN", + "PRESET_0", + "PRESET_1", + "PRESET_2", + "PRESET_3", + "PRESET_4", + "PRESET_5", + "PRESET_6", + "PRESET_7", + "PRESET_8" +} + +--[[ Local Functions ]] +local function subscribeButton(pButName, self) + local cid = self.mobileSession1:SendRPC("SubscribeButton", { buttonName = pButName }) + local appIDvalue = commonSmoke.getHMIAppId() + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", { appID = appIDvalue, name = pButName, isSubscribed = true }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +for _, v in pairs(buttonName) do + runner.Step("SubscribeButton " .. v .. " Positive Case", subscribeButton, { v }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase.lua b/test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase.lua new file mode 100644 index 0000000000..db7bae55e7 --- /dev/null +++ b/test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase.lua @@ -0,0 +1,85 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: UnsubscribeButton +-- Item: Happy path +-- +-- Requirement summary: +-- [UnsubscribeButton] SUCCESS: getting SUCCESS:UnsubscribeButton() +-- +-- Description: +-- Mobile application sends valid UnsubscribeButton request and gets UnsubscribeButton "SUCCESS" response from SDL + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests UnsubscribeButton with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if Buttons interface is available on HMI +-- SDL checks if UnsubscribeButton is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL sends the Buttons notificaton to HMI +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local buttonName = { + "OK", + "SEEKLEFT", + "SEEKRIGHT", + "TUNEUP", + "TUNEDOWN", + "PRESET_0", + "PRESET_1", + "PRESET_2", + "PRESET_3", + "PRESET_4", + "PRESET_5", + "PRESET_6", + "PRESET_7", + "PRESET_8" +} + +--[[ Local Functions ]] +local function subscribeButtons(pButName, self) + local cid = self.mobileSession1:SendRPC("SubscribeButton", { buttonName = pButName }) + local appIDvalue = commonSmoke.getHMIAppId() + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", { appID = appIDvalue, name = pButName, isSubscribed = true }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +local function unsubscribeButton(pButName, self) + local cid = self.mobileSession1:SendRPC("UnsubscribeButton", { buttonName = pButName }) + local appIDvalue = commonSmoke.getHMIAppId() + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", + { appID = appIDvalue, name = pButName, isSubscribed = false }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +for _, v in pairs(buttonName) do + runner.Step("SubscribeButton " .. v .. " Positive Case", subscribeButtons, { v }) +end + +runner.Title("Test") +for _, v in pairs(buttonName) do + runner.Step("UnsubscribeButton " .. v .. " Positive Case", unsubscribeButton, { v }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From d89c52b53037e2490aa3c1d9aee412dcbe748cb6 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 16 Jan 2018 10:50:19 +0200 Subject: [PATCH 278/681] REmoved code related to non-media app --- .../012_PerfomInteraction_PositiveCase.lua | 128 ++++-------------- .../013_ScrollableMessage_PositiveCase.lua | 9 +- 2 files changed, 34 insertions(+), 103 deletions(-) diff --git a/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase.lua b/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase.lua index 4d62cde730..770a575006 100644 --- a/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase.lua +++ b/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase.lua @@ -33,10 +33,8 @@ local runner = require('user_modules/script_runner') local commonSmoke = require('test_scripts/Smoke/commonSmoke') local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ Local Variables ]] -local isMediaApplication = commonSmoke.GetAppMediaStatus() local putFileParams = { requestParams = { syncFileName = 'icon.png', @@ -123,7 +121,7 @@ end --! @return: none local function SendOnSystemContext(self, ctx) self.hmiConnection:SendNotification("UI.OnSystemContext", - { appID = self.applications["Test Application"], systemContext = ctx }) + { appID = commonSmoke.getHMIAppId(), systemContext = ctx }) end --! @setExChoiseSet: ChoiceSet structure for UI.PerformInteraction request @@ -150,97 +148,32 @@ end --! @parameters: --! self - test object, --! request - interaction mode, ---! timeout - timeout value for expectation OnHMIStatus, ---! level - HMI level value, --! @return: none -local function ExpectOnHMIStatusWithAudioStateChanged_PI(self, request, timeout, level) - if nil == request then request = "BOTH" end - if nil == level then level = "FULL" end - if nil == timeout then timeout = 10000 end - commonSmoke.SetAppType(config.application1.registerAppInterfaceParams.appHMIType) - if "FULL" == level then - if true == isMediaApplication or - true == commonSmoke.HMITypeStatus.NAVIGATION then - if "BOTH" == request then - self.mobileSession1:ExpectNotification("OnHMIStatus", - { hmiLevel = level, audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, - { hmiLevel = level, audioStreamingState = "NOT_AUDIBLE", systemContext = "VRSESSION" }, - { hmiLevel = level, audioStreamingState = "ATTENUATED", systemContext = "VRSESSION" }, - { hmiLevel = level, audioStreamingState = "ATTENUATED", systemContext = "HMI_OBSCURED" }, - { hmiLevel = level, audioStreamingState = "AUDIBLE", systemContext = "HMI_OBSCURED" }, - { hmiLevel = level, audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) - :Times(6) - elseif "VR" == request then - self.mobileSession1:ExpectNotification("OnHMIStatus", - { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "ATTENUATED" }, - { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }, - { systemContext = "VRSESSION", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }, - { systemContext = "VRSESSION", hmiLevel = level, audioStreamingState = "AUDIBLE" }, - { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "AUDIBLE" }) - :Times(5) - :Timeout(timeout) - elseif "MANUAL" == request then - self.mobileSession1:ExpectNotification("OnHMIStatus", - { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "ATTENUATED" }, - { systemContext = "HMI_OBSCURED", hmiLevel = level, audioStreamingState = "ATTENUATED" }, - { systemContext = "HMI_OBSCURED", hmiLevel = level, audioStreamingState = "AUDIBLE" }, - { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "AUDIBLE" }) - :Times(4) - :Timeout(timeout) - end - elseif false == isMediaApplication then - if "BOTH" == request then - self.mobileSession1:ExpectNotification("OnHMIStatus", - { hmiLevel = level, audioStreamingState = "NOT_AUDIBLE", systemContext = "VRSESSION" }, - { hmiLevel = level, audioStreamingState = "NOT_AUDIBLE", systemContext = "HMI_OBSCURED" }, - { hmiLevel = level, audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - :Times(3) - :Timeout(timeout) - elseif "VR" == request then - self.mobileSession1:ExpectNotification("OnHMIStatus", - { systemContext = "VRSESSION", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }, - { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }) - :Times(2) - :Timeout(timeout) - elseif "MANUAL" == request then - self.mobileSession1:ExpectNotification("OnHMIStatus", - { hmiLevel = level, audioStreamingState = "NOT_AUDIBLE", systemContext = "HMI_OBSCURED" }, - { hmiLevel = level, audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - :Times(2) - end - end - elseif "LIMITED" == level then - if true == isMediaApplication or - true == commonSmoke.HMITypeStatus.NAVIGATION then - if "BOTH" == request then - self.mobileSession1:ExpectNotification("OnHMIStatus", - { hmiLevel = level, audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, - { hmiLevel = level, audioStreamingState = "ATTENUATED", systemContext = "MAIN" }, - { hmiLevel = level, audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) - :Times(3) - elseif "VR" == request then - self.mobileSession1:ExpectNotification("OnHMIStatus", - { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "ATTENUATED" }, - { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "NOT_AUDIBLE" }, - { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "AUDIBLE" }) - :Times(3) - :Timeout(timeout) - elseif "MANUAL" == request then - self.mobileSession1:ExpectNotification("OnHMIStatus", - { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "ATTENUATED" }, - { systemContext = "MAIN", hmiLevel = level, audioStreamingState = "AUDIBLE" }) - :Times(2) - :Timeout(timeout) - end - elseif false == isMediaApplication then - self.mobileSession1:ExpectNotification("OnHMIStatus") - :Times(0) - commonTestCases:DelayedExp(1000) - end - elseif "BACKGROUND" == level then - self.mobileSession1:ExpectNotification("OnHMIStatus") - :Times(0) - commonTestCases:DelayedExp(1000) +local function ExpectOnHMIStatusWithAudioStateChanged_PI(self, request) + if "BOTH" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "VRSESSION" }, + { hmiLevel = "FULL", audioStreamingState = "ATTENUATED", systemContext = "VRSESSION" }, + { hmiLevel = "FULL", audioStreamingState = "ATTENUATED", systemContext = "HMI_OBSCURED" }, + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "HMI_OBSCURED" }, + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + :Times(6) + elseif "VR" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "ATTENUATED" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE" }, + { systemContext = "VRSESSION", hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE" }, + { systemContext = "VRSESSION", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }) + :Times(5) + elseif "MANUAL" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "ATTENUATED" }, + { systemContext = "HMI_OBSCURED", hmiLevel = "FULL", audioStreamingState = "ATTENUATED" }, + { systemContext = "HMI_OBSCURED", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }) + :Times(4) end end @@ -272,7 +205,6 @@ end --! self - test object --! @return: none local function PI_PerformViaVR_ONLY(paramsSend, self) - local level = "FULL" paramsSend.interactionMode = "VR_ONLY" local cid = self.mobileSession1:SendRPC("PerformInteraction",paramsSend) EXPECT_HMICALL("VR.PerformInteraction", { @@ -303,7 +235,7 @@ local function PI_PerformViaVR_ONLY(paramsSend, self) :Do(function(_,data) self.hmiConnection:SendResponse( data.id, data.method, "SUCCESS", { } ) end) - ExpectOnHMIStatusWithAudioStateChanged_PI(self, "VR", nil, level) + ExpectOnHMIStatusWithAudioStateChanged_PI(self, "VR") self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", choiceID = paramsSend.interactionChoiceSetIDList[1] }) end @@ -314,7 +246,6 @@ end --! self - test object --! @return: none local function PI_PerformViaMANUAL_ONLY(paramsSend, self) - local level = "FULL" paramsSend.interactionMode = "MANUAL_ONLY" local cid = self.mobileSession1:SendRPC("PerformInteraction", paramsSend) EXPECT_HMICALL("VR.PerformInteraction", { @@ -345,7 +276,7 @@ local function PI_PerformViaMANUAL_ONLY(paramsSend, self) end RUN_AFTER(uiResponse, 1000) end) - ExpectOnHMIStatusWithAudioStateChanged_PI(self, "MANUAL", nil, level) + ExpectOnHMIStatusWithAudioStateChanged_PI(self, "MANUAL") self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", choiceID = paramsSend.interactionChoiceSetIDList[1] }) end @@ -356,7 +287,6 @@ end --! self - test object --! @return: none local function PI_PerformViaBOTH(paramsSend, self) - local level = "FULL" paramsSend.interactionMode = "BOTH" local cid = self.mobileSession1:SendRPC("PerformInteraction",paramsSend) EXPECT_HMICALL("VR.PerformInteraction", { @@ -402,7 +332,7 @@ local function PI_PerformViaBOTH(paramsSend, self) end RUN_AFTER(uiResponse, 30) end) - ExpectOnHMIStatusWithAudioStateChanged_PI(self, nil, nil, level) + ExpectOnHMIStatusWithAudioStateChanged_PI(self, "BOTH") self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "TIMED_OUT" }) end diff --git a/test_scripts/Smoke/API/013_ScrollableMessage_PositiveCase.lua b/test_scripts/Smoke/API/013_ScrollableMessage_PositiveCase.lua index 71fbc2d375..f10db381d5 100644 --- a/test_scripts/Smoke/API/013_ScrollableMessage_PositiveCase.lua +++ b/test_scripts/Smoke/API/013_ScrollableMessage_PositiveCase.lua @@ -92,17 +92,18 @@ local function ScrollableMessage(params, self) EXPECT_HMICALL("UI.ScrollableMessage", params.responseUiParams) :Do(function(_,data) self.hmiConnection:SendNotification("UI.OnSystemContext", - { appID = self.applications["Test Application"], systemContext = "HMI_OBSCURED" }) + { appID = params.responseUiParams.appID, systemContext = "HMI_OBSCURED" }) local function uiResponse() self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) self.hmiConnection:SendNotification("UI.OnSystemContext", - { appID = self.applications["Test Application"], systemContext = "MAIN" }) + { appID = params.responseUiParams.appID, systemContext = "MAIN" }) end RUN_AFTER(uiResponse, 1000) end) + local AudibleState = commonSmoke.GetAudibleState() self.mobileSession1:ExpectNotification("OnHMIStatus", - { systemContext = "HMI_OBSCURED", hmiLevel = "FULL", audioStreamingState = commonSmoke.GetAudibleState() }, - { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = commonSmoke.GetAudibleState() }) + { systemContext = "HMI_OBSCURED", hmiLevel = "FULL", audioStreamingState = AudibleState }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = AudibleState }) :Times(2) self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end From a9ba1564fd8676b8167fa116323449c0eaceee5b Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 16 Jan 2018 11:30:11 +0200 Subject: [PATCH 279/681] Update script name --- ...iveCase.lua => 012_PerfomInteraction_PositiveCase_SUCCESS.lua} | 0 ...iveCase.lua => 013_ScrollableMessage_PositiveCase_SUCCESS.lua} | 0 ...veCase.lua => 014_SetMediaClockTimer_PositiveCase_SUCCESS.lua} | 0 ...15_Show_PositiveCase.lua => 015_Show_PositiveCase_SUCCESS.lua} | 0 ...PositiveCase.lua => 018_SendLocation_PositiveCase_SUCCESS.lua} | 0 ...n_PositiveCase.lua => 019_SetAppIcon_PositiveCase_SUCCESS.lua} | 0 ...itiveCase.lua => 022_SubscribeButton_PositiveCase_SUCCESS.lua} | 0 ...iveCase.lua => 023_UnsubscribeButton_PositiveCase_SUCCESS.lua} | 0 ...Case.lua => 024_SubscribeVehicleData_PositiveCase_SUCCESS.lua} | 0 ...se.lua => 025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua} | 0 ...sitiveCase.lua => 026_GetVehicleData_PositiveCase_SUCCESS.lua} | 0 ...sitiveCase.lua => 027_UpdateTurnList_PositiveCase_SUCCESS.lua} | 0 ...ositiveCase.lua => 028_AlertManeuver_PositiveCase_SUCCESS.lua} | 0 ...eCase.lua => 029_OnDriverDistraction_PositiveCase_SUCCESS.lua} | 0 ...r_PositiveCase.lua => 030_DialNumber_PositiveCase_SUCCESS.lua} | 0 ...Case.lua => 031_PerformAudioPassThru_PositiveCase_SUCCESS.lua} | 0 ...tiveCase.lua => 032_EndAudioPassThru_PositiveCase_SUCCESS.lua} | 0 ...dDID_PositiveCase.lua => 033_ReadDID_PositiveCase_SUCCESS.lua} | 0 18 files changed, 0 insertions(+), 0 deletions(-) rename test_scripts/Smoke/API/{012_PerfomInteraction_PositiveCase.lua => 012_PerfomInteraction_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{013_ScrollableMessage_PositiveCase.lua => 013_ScrollableMessage_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{014_SetMediaClockTimer_PositiveCase.lua => 014_SetMediaClockTimer_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{015_Show_PositiveCase.lua => 015_Show_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{018_SendLocation_PositiveCase.lua => 018_SendLocation_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{019_SetAppIcon_PositiveCase.lua => 019_SetAppIcon_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{022_SubscribeButton_PositiveCase.lua => 022_SubscribeButton_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{023_UnsubscribeButton_PositiveCase.lua => 023_UnsubscribeButton_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{024_SubscribeVehicleData_PositiveCase.lua => 024_SubscribeVehicleData_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{025_UnsubscribeVehicleData_PositiveCase.lua => 025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{026_GetVehicleData_PositiveCase.lua => 026_GetVehicleData_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{027_UpdateTurnList_PositiveCase.lua => 027_UpdateTurnList_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{028_AlertManeuver_PositiveCase.lua => 028_AlertManeuver_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{029_OnDriverDistraction_PositiveCase.lua => 029_OnDriverDistraction_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{030_DialNumber_PositiveCase.lua => 030_DialNumber_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{031_PerformAudioPassThru_PositiveCase.lua => 031_PerformAudioPassThru_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{032_EndAudioPassThru_PositiveCase.lua => 032_EndAudioPassThru_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{033_ReadDID_PositiveCase.lua => 033_ReadDID_PositiveCase_SUCCESS.lua} (100%) diff --git a/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase.lua b/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase.lua rename to test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/013_ScrollableMessage_PositiveCase.lua b/test_scripts/Smoke/API/013_ScrollableMessage_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/013_ScrollableMessage_PositiveCase.lua rename to test_scripts/Smoke/API/013_ScrollableMessage_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase.lua b/test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase.lua rename to test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/015_Show_PositiveCase.lua b/test_scripts/Smoke/API/015_Show_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/015_Show_PositiveCase.lua rename to test_scripts/Smoke/API/015_Show_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/018_SendLocation_PositiveCase.lua b/test_scripts/Smoke/API/018_SendLocation_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/018_SendLocation_PositiveCase.lua rename to test_scripts/Smoke/API/018_SendLocation_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/019_SetAppIcon_PositiveCase.lua b/test_scripts/Smoke/API/019_SetAppIcon_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/019_SetAppIcon_PositiveCase.lua rename to test_scripts/Smoke/API/019_SetAppIcon_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/022_SubscribeButton_PositiveCase.lua b/test_scripts/Smoke/API/022_SubscribeButton_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/022_SubscribeButton_PositiveCase.lua rename to test_scripts/Smoke/API/022_SubscribeButton_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase.lua b/test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase.lua rename to test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase.lua b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase.lua rename to test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase.lua b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase.lua rename to test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase.lua b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/026_GetVehicleData_PositiveCase.lua rename to test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/027_UpdateTurnList_PositiveCase.lua b/test_scripts/Smoke/API/027_UpdateTurnList_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/027_UpdateTurnList_PositiveCase.lua rename to test_scripts/Smoke/API/027_UpdateTurnList_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/028_AlertManeuver_PositiveCase.lua b/test_scripts/Smoke/API/028_AlertManeuver_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/028_AlertManeuver_PositiveCase.lua rename to test_scripts/Smoke/API/028_AlertManeuver_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/029_OnDriverDistraction_PositiveCase.lua b/test_scripts/Smoke/API/029_OnDriverDistraction_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/029_OnDriverDistraction_PositiveCase.lua rename to test_scripts/Smoke/API/029_OnDriverDistraction_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/030_DialNumber_PositiveCase.lua b/test_scripts/Smoke/API/030_DialNumber_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/030_DialNumber_PositiveCase.lua rename to test_scripts/Smoke/API/030_DialNumber_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/031_PerformAudioPassThru_PositiveCase.lua b/test_scripts/Smoke/API/031_PerformAudioPassThru_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/031_PerformAudioPassThru_PositiveCase.lua rename to test_scripts/Smoke/API/031_PerformAudioPassThru_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/032_EndAudioPassThru_PositiveCase.lua b/test_scripts/Smoke/API/032_EndAudioPassThru_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/032_EndAudioPassThru_PositiveCase.lua rename to test_scripts/Smoke/API/032_EndAudioPassThru_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/033_ReadDID_PositiveCase.lua b/test_scripts/Smoke/API/033_ReadDID_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/033_ReadDID_PositiveCase.lua rename to test_scripts/Smoke/API/033_ReadDID_PositiveCase_SUCCESS.lua From ad588ad3fcb8e6365eef69dbcc661206d3750edf Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 9 Jan 2018 12:53:52 +0200 Subject: [PATCH 280/681] Separated scripts for API ShowCTBT, Slider --- ...6_ShowConstantTBT_PositiveCase_SUCCESS.lua | 152 ++++++++++++++++++ .../API/017_Slider_PositiveCase_SUCCESS.lua | 74 +++++++++ 2 files changed, 226 insertions(+) create mode 100644 test_scripts/Smoke/API/016_ShowConstantTBT_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/017_Slider_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/016_ShowConstantTBT_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/016_ShowConstantTBT_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..5c2e855227 --- /dev/null +++ b/test_scripts/Smoke/API/016_ShowConstantTBT_PositiveCase_SUCCESS.lua @@ -0,0 +1,152 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: ShowConstantTBT +-- Item: Happy path +-- +-- Requirement summary: +-- [ShowConstantTBT] SUCCESS: getting SUCCESS:Navigation.ShowConstantTBT() +-- +-- Description: +-- Mobile application sends valid ShowConstantTBT request and gets Navigation.ShowConstantTBT "SUCCESS" response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests ShowConstantTBT with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if Navigation interface is available on HMI +-- SDL checks if ShowConstantTBT is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the Navigation part of request with allowed parameters to HMI +-- SDL receives Navigation part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local requestParams = { + navigationText1 = "navigationText1", + navigationText2 = "navigationText2", + eta = "12:34", + totalDistance = "100miles", + timeToDestination = "10 minutes", + turnIcon = { + value = "icon.png", + imageType = "DYNAMIC", + }, + nextTurnIcon = { + value = "icon.png", + imageType = "DYNAMIC", + }, + distanceToManeuver = 50.5, + distanceToManeuverScale = 100.5, + maneuverComplete = false, + softButtons = { + { + type = "BOTH", + text = "Close", + image = { + value = "icon.png", + imageType = "DYNAMIC", + }, + isHighlighted = true, + softButtonID = 44, + systemAction ="DEFAULT_ACTION", + }, + }, +} + +local responseUiParams = { + navigationTexts = { + { + fieldName = "navigationText1", + fieldText = requestParams.navigationText1 + }, + { + fieldName = "navigationText2", + fieldText = requestParams.navigationText2 + }, + { + fieldName = "ETA", + fieldText = requestParams.eta + }, + { + fieldName = "totalDistance", + fieldText = requestParams.totalDistance + }, + { + fieldName = "timeToDestination", + fieldText = requestParams.timeToDestination + } + }, + turnIcon = requestParams.turnIcon, + nextTurnIcon = requestParams.nextTurnIcon, + distanceToManeuver = requestParams.distanceToManeuver, + distanceToManeuverScale = requestParams.distanceToManeuverScale, + maneuverComplete = requestParams.maneuverComplete, + softButtons = requestParams.softButtons +} + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams +} + +--[[ Local Functions ]] +local function PTUpdateFuncRPC(tbl) + local ShowCTBT = { + rpcs = { + ShowConstantTBT = { + hmi_levels = { "NONE", "BACKGROUND", "FULL", "LIMITED" } + } + } + } + tbl.policy_table.functional_groupings.NewTestCaseGroup = ShowCTBT + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = + { "Base-4", "NewTestCaseGroup" } +end + +local function showConstantTBT(params, self) + local cid = self.mobileSession1:SendRPC("ShowConstantTBT", params.requestParams) + params.responseUiParams.appID = commonSmoke.getHMIAppId() + params.responseUiParams.turnIcon.value = commonSmoke.getPathToFileInStorage(params.requestParams.turnIcon.value) + params.responseUiParams.nextTurnIcon.value = commonSmoke.getPathToFileInStorage(params.requestParams.nextTurnIcon.value) + params.responseUiParams.softButtons[1].image.value = commonSmoke.getPathToFileInStorage(params.requestParams.softButtons[1].image.value) + EXPECT_HMICALL("Navigation.ShowConstantTBT", params.responseUiParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { nil, PTUpdateFuncRPC }) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) + +runner.Title("Test") +runner.Step("ShowConstantTBT Positive Case", showConstantTBT, {allParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/017_Slider_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/017_Slider_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..4ffbaf9d78 --- /dev/null +++ b/test_scripts/Smoke/API/017_Slider_PositiveCase_SUCCESS.lua @@ -0,0 +1,74 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: Slider +-- Item: Happy path +-- +-- Requirement summary: +-- [Slider] SUCCESS: getting SUCCESS:UI.Slider() +-- +-- Description: +-- Mobile application sends valid Slider request and gets UI.Slider "SUCCESS" response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests Slider with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if Slider is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the UI part of request with allowed parameters to HMI +-- SDL receives UI part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local requestParams = { + numTicks = 7, + position = 1, + sliderHeader ="sliderHeader", + timeout = 1000, + sliderFooter = { "sliderFooter" } +} + +--[[ Local Functions ]] +local function slider(params, self) + local cid = self.mobileSession1:SendRPC("Slider", params) + params.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("UI.Slider", params) + :Do(function(_,data) + self.hmiConnection:SendNotification("UI.OnSystemContext",{ appID = params.appID, systemContext = "HMI_OBSCURED" }) + local function sendReponse() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {sliderPosition = 1}) + self.hmiConnection:SendNotification("UI.OnSystemContext",{ appID = params.appID, systemContext = "MAIN" }) + end + RUN_AFTER(sendReponse, 1000) + end) + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "HMI_OBSCURED", hmiLevel = "FULL", audioStreamingState = commonSmoke.GetAudibleState() }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = commonSmoke.GetAudibleState() }) + :Times(2) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", sliderPosition = 1 }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("Slider Positive Case", slider, {requestParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From 5903c9df6cb7350c199d0c155ef3f1b0a5564026 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 16 Jan 2018 08:15:18 +0200 Subject: [PATCH 281/681] Separated scripts for Register and UnregisterAppInterface --- ...isterAppInterface_PositiveCase_SUCCESS.lua | 50 ++++++++ ...isterAppInterface_PositiveCase_SUCCESS.lua | 116 ++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 test_scripts/Smoke/API/036_UnregisterAppInterface_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/036_UnregisterAppInterface_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/036_UnregisterAppInterface_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..d3110d397a --- /dev/null +++ b/test_scripts/Smoke/API/036_UnregisterAppInterface_PositiveCase_SUCCESS.lua @@ -0,0 +1,50 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: UnregisterAppInterface +-- Item: Happy path +-- +-- Requirement summary: +-- [UnregisterAppInterface] SUCCESS: getting SUCCESS:UnregisterAppInterface() +-- +-- Description: +-- Mobile application sends valid UnregisterAppInterface request and gets UnregisterAppInterface "SUCCESS" +-- response from SDL + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests UnregisterAppInterface + +-- Expected: +-- SDL checks if UnregisterAppInterface is allowed by Policies +-- SDL sends the BasicCommunication notification to HMI +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Functions ]] +local function unregisterAppInterface(self) + local cid = self.mobileSession1:SendRPC("UnregisterAppInterface", { }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", + { appID = commonSmoke.getHMIAppId(), unexpectedDisconnect = false }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("UnregisterAppInterface Positive Case", unregisterAppInterface) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..99aa2d93bd --- /dev/null +++ b/test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua @@ -0,0 +1,116 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: RegisterAppInterface +-- Item: Happy path +-- +-- Requirement summary: +-- [RegisterAppInterface] SUCCESS: getting SUCCESS:RegisterAppInterface() during reregistration +-- +-- Description: +-- Mobile application sends valid RegisterAppInterface request after unregistration and +-- gets RegisterAppInterface "SUCCESS" response from SDL + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests RegisterAppInterface + +-- Expected: +-- SDL checks if RegisterAppInterface is allowed by Policies +-- SDL sends the BasicCommunication notification to HMI +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local requestParams = { + syncMsgVersion = { + majorVersion = 2, + minorVersion = 2, + }, + appName = "SyncProxyTester", + ttsName = { + { + text ="SyncProxyTester", + type ="TEXT", + }, + }, + ngnMediaScreenAppName = "SPT", + vrSynonyms = { + "VRSyncProxyTester", + }, + isMediaApplication = true, + languageDesired = "EN-US", + hmiDisplayLanguageDesired = "EN-US", + appHMIType = { + "DEFAULT", + }, + appID = "123456", + deviceInfo = { + hardware = "hardware", + firmwareRev = "firmwareRev", + os = "os", + osVersion = "osVersion", + carrier = "carrier", + maxNumberRFCOMMPorts = 5 + } +} + +local function SetNotificationParams() + local notificationParams = { + application = {} + } + notificationParams.application.appName = requestParams.appName + notificationParams.application.ngnMediaScreenAppName = requestParams.ngnMediaScreenAppName + notificationParams.application.isMediaApplication = requestParams.isMediaApplication + notificationParams.application.hmiDisplayLanguageDesired = requestParams.hmiDisplayLanguageDesired + notificationParams.application.appType = requestParams.appHMIType + notificationParams.application.deviceInfo = { + name = "127.0.0.1", + id = config.deviceMAC, + transportType = "WIFI", + isSDLAllowed = true + } + notificationParams.application.policyAppID = requestParams.appID + notificationParams.ttsName = requestParams.ttsName + notificationParams.vrSynonyms = requestParams.vrSynonyms + return notificationParams +end + +--[[ Local Functions ]] +local function unregisterAppInterface(self) + local cid = self.mobileSession1:SendRPC("UnregisterAppInterface", { }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", + { appID = commonSmoke.getHMIAppId(), unexpectedDisconnect = false }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function RegisterAppInterface(self) + local CorIdRAI = self.mobileSession1:SendRPC("RegisterAppInterface", requestParams) + local notificationParams = SetNotificationParams() + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", notificationParams) + self.mobileSession1:ExpectResponse(CorIdRAI, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + self.mobileSession1:ExpectNotification("OnPermissionsChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("UnregisterAppInterface Positive Case", unregisterAppInterface) + +runner.Title("Test") +runner.Step("RegisterAppInterface Positive Case", RegisterAppInterface) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From 82a60d321d98459de48618a782f993ae3f6e2027 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 16 Jan 2018 13:51:24 +0200 Subject: [PATCH 282/681] Update smoke test set with separated API scripts --- .../Smoke/Policies/001_PTU_all_flows.lua | 354 ++++++++++++++++++ test_sets/smoke_tests.txt | 40 +- 2 files changed, 393 insertions(+), 1 deletion(-) create mode 100644 test_scripts/Smoke/Policies/001_PTU_all_flows.lua diff --git a/test_scripts/Smoke/Policies/001_PTU_all_flows.lua b/test_scripts/Smoke/Policies/001_PTU_all_flows.lua new file mode 100644 index 0000000000..d57ad1df72 --- /dev/null +++ b/test_scripts/Smoke/Policies/001_PTU_all_flows.lua @@ -0,0 +1,354 @@ +--------------------------------------------------------------------------------------------- +-- Script verifies PTU sequence +-- Supported PROPRIETARY, EXTERNAL_PROPRIETARY and HTTP flows +--------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local mobile_session = require("mobile_session") +local json = require("modules/json") +local atf_logger = require("atf_logger") +local sdl = require("SDL") +local commonSteps = require("user_modules/shared_testcases/commonSteps") + +--[[ General configuration parameters ]] +config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 + +--[[ Local Variables ]] +local flowType = { + PROPRIETARY = 1, + EXTERNAL_PROPRIETARY = 2, + HTTP = 3 +} + +--[[ Local Functions ]] +local function preconditions() + -- Stop SDL if process is still running + commonFunctions:SDLForceStop() + -- Remove Local Policy Update + commonSteps:DeletePolicyTable() + -- Delete log files + commonSteps:DeleteLogsFiles() +end + +-- Allow device from HMI +local function allowSDL(self) + -- sending notification OnAllowSDLFunctionality from HMI to allow connected device + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", + { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) +end + +-- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP +local function start(self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady() + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + self:connectMobile() + :Do(function() + commonFunctions:userPrint(35, "Mobile connected") + allowSDL(self) + end) + end) + end) + end) +end + +-- Loging messages in terminal +local function log(...) + local str = "[" .. atf_logger.formated_time(true) .. "]" + for i, p in pairs({...}) do + local delimiter = "\t" + if i == 1 then delimiter = " " end + str = str .. delimiter .. p + end + commonFunctions:userPrint(35, str) +end + +-- Convert snapshot form json to table +-- @tparam file pts_f snapshot file +local function ptsToTable(pts_f) + local f = io.open(pts_f, "r") + local content = f:read("*all") + f:close() + return json.decode(content) +end + +-- Creation policy table from snapshot +-- @tparam table ptu snapshot table +local function getPTUFromPTS(ptu) + -- remove messages in consumer_friendly_messages + ptu.policy_table.consumer_friendly_messages.messages = nil + -- remove device_data + ptu.policy_table.device_data = nil + -- remove module_meta + ptu.policy_table.module_meta = nil + -- remove usage_and_error_counts + ptu.policy_table.usage_and_error_counts = nil + -- write empty struct in "DataConsent-2".rpcs + ptu.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + -- remove preloaded_pt + ptu.policy_table.module_config.preloaded_pt = nil + -- remove preloaded_date + ptu.policy_table.module_config.preloaded_date = nil + -- Create structure in app_policies related to registered application + ptu.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE" + } + -- Added permissions for registered app from "Base-4", "Base-6" groups + ptu.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID]["groups"] = { + "Base-4", "Base-6" + } +end + +-- Save created PT in file +-- @tparam table ptu PT table +-- @tparam string ptu_file_name file name +local function storePTUInFile(ptu, ptu_file_name) + local f = io.open(ptu_file_name, "w") + f:write(json.encode(ptu)) + f:close() +end + +-- Check that PT is sent as binary data in OnSystem request +-- @tparam table bin_data binary data +-- @tparam number pFlow number of floe type from flowType +local function checkIfPTSIsSentAsBinary(bin_data, pFlow, self) + -- decode binary data to table depending on policy flow + local pt = nil + if bin_data ~= nil and string.len(bin_data) > 0 then + if flowType[pFlow] == flowType.PROPRIETARY then + pt = json.decode(bin_data).HTTPRequest.body + elseif flowType[pFlow] == flowType.EXTERNAL_PROPRIETARY or flowType[pFlow] == flowType.HTTP then + pt = bin_data + end + pt = json.decode(pt) + end + -- Check presence of policy_table in decoded PT + if pt == nil or not pt.policy_table then + self:FailTestCase("PTS was not sent to Mobile as binary data in payload of OnSystemRequest") + end +end + +-- Policy table update with Proprietary flow +-- @tparam table ptu_table PT table +-- @tparam string pFlow policy flow +local function ptuProprietary(ptu_table, self, pFlow) + -- Get path to snapshot + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" + .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + -- create ptu_file_name as tmp file + local ptu_file_name = os.tmpname() + -- Send GetURLS request from HMI to SDL with service 7 + local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) + log("HMI->SDL: RQ: SDL.GetURLS") + -- Expect response GetURLS on HMI side + EXPECT_HMIRESPONSE(requestId) + :Do(function() + log("SDL->HMI: RS: SDL.GetURLS") + -- After receiving GetURLS response send OnSystemRequest notification from HMI + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + { requestType = "PROPRIETARY", fileName = pts_file_name }) + log("HMI->SDL: N: BC.OnSystemRequest") + -- Prepare PT for update + getPTUFromPTS(ptu_table) + -- Save created PT for update in tmp file + storePTUInFile(ptu_table, ptu_file_name) + -- Expect receiving of OnSystemRequest notification with snapshot on mobile side + self.mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :Do(function(_, d) + -- After receiving OnSystemRequest notification on mobile side check that + -- data in notification was sent as binary data + checkIfPTSIsSentAsBinary(d.binaryData, pFlow, self) + log("SDL->MOB: N: OnSystemRequest") + -- Send SystemRequest request with PT for update from mobile side + local corIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", + { requestType = "PROPRIETARY" }, ptu_file_name) + log("MOB->SDL: RQ: SystemRequest") + -- Expect SystemRequest request on HMI side + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, dd) + log("SDL->HMI: RQ: BC.SystemRequest") + -- Send SystemRequest response form HMI with resultCode SUCCESS + self.hmiConnection:SendResponse(dd.id, dd.method, "SUCCESS", { }) + log("HMI->SDL: RS: SUCCESS: BC.SystemRequest") + -- Send OnReceivedPolicyUpdate notification from HMI + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", + { policyfile = dd.params.fileName }) + log("HMI->SDL: N: SDL.OnReceivedPolicyUpdate") + end) + -- Expect SystemRequest response with resultCode SUCCESS on mobile side + self.mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS"}) + -- remove tmp PT file after receiving SystemRequest response on mobile side + :Do(function() os.remove(ptu_file_name) end) + log("SDL->MOB: RS: SUCCESS: SystemRequest") + end) + end) +end + +-- Policy table update with HTTP flow +-- @tparam table ptu_table PT table +local function ptuHttp(ptu_table, self) + -- name for PT for SystemRequest + local policy_file_name = "PolicyTableUpdate" + -- tmp file name for PT file + local ptu_file_name = os.tmpname() + -- Prepare PT for update + getPTUFromPTS(ptu_table) + -- Save created PT for update in tmp file + storePTUInFile(ptu_table, ptu_file_name) + -- Send SystemRequest form mobile app with created PT + local corId = self.mobileSession:SendRPC("SystemRequest", + { requestType = "HTTP", fileName = policy_file_name }, ptu_file_name) + log("MOB->SDL: RQ: SystemRequest") + -- Expect successful SystemRequest response on mobile side + self.mobileSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + log("SDL->MOB: RS: SUCCESS: SystemRequest") + end) + -- remove tmp PT file + os.remove(ptu_file_name) +end + +-- Expect 3 OnStatusUpdate notification on HMI side during PTU +local function expOnStatusUpdate() + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, {status = "UP_TO_DATE" }) + :Do(function(_, d) + log("SDL->HMI: N: SDL.OnStatusUpdate", d.params.status) + end) + :Times(3) +end + +-- Fail test cases by incorrect PTU +-- @tparam string pRequestName request name of RPC that is failed expectations +local function failInCaseIncorrectPTU(pRequestName, self) + self:FailTestCase(pRequestName .. " was sent more than once (PTU update was incorrect)") +end + +-- Registration of application with policy table update +local function raiPTU(self) + expOnStatusUpdate() -- temp solution due to issue in SDL: + -- SDL.OnStatusUpdate(UPDATE_NEEDED) notification is sent before BC.OnAppRegistered (EXTERNAL_PROPRIETARY flow) + + -- creation mobile session + self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) + -- open RPC service in created session + self.mobileSession:StartService(7) + :Do(function() + -- Send RegisterAppInterface request from mobile application + local corId = self.mobileSession:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) + log("MOB->SDL: RQ: RegisterAppInterface") + -- Expect OnAppRegistered on HMI side from SDL + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config.application1.registerAppInterfaceParams.appName } }) + :Do(function() + log("SDL->HMI: N: BC.OnAppRegistered") + if sdl.buildOptions.extendedPolicy == "PROPRIETARY" + or sdl.buildOptions.extendedPolicy == "EXTERNAL_PROPRIETARY" then + -- Expect PolicyUpdate request on HMI side + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :Do(function(e, d) + if e.occurences == 1 then -- SDL send BC.PolicyUpdate more than once if PTU update was incorrect + log("SDL->HMI: RQ: BC.PolicyUpdate") + -- Create PT form snapshot + local ptu_table = ptsToTable(d.params.file) + -- Sending PolicyUpdate request from HMI with resultCode SUCCESS + self.hmiConnection:SendResponse(d.id, d.method, "SUCCESS", { }) + log("HMI->SDL: RS: BC.PolicyUpdate") + -- PTU proprietary flow + ptuProprietary(ptu_table, self, sdl.buildOptions.extendedPolicy) + else + failInCaseIncorrectPTU("BC.PolicyUpdate", self) + end + end) + elseif sdl.buildOptions.extendedPolicy == "HTTP" then + -- Expect OnSystemRequest notification on mobile side + self.mobileSession:ExpectNotification("OnSystemRequest") + :Do(function(e, d) + log("SDL->MOB: N: OnSystemRequest", e.occurences, d.payload.requestType) + if d.payload.requestType == "HTTP" then + if e.occurences <= 2 then -- SDL send OnSystemRequest more than once if PTU update was incorrect + -- Check data in receives OnSystemRequest notification on mobile side + checkIfPTSIsSentAsBinary(d.binaryData, sdl.buildOptions.extendedPolicy, self) + if d.binaryData then + -- Create PT form binary data + local ptu_table = json.decode(d.binaryData) + -- PTU HTTP flow + ptuHttp(ptu_table, self) + end + else + failInCaseIncorrectPTU("OnSystemRequest", self) + end + end + end) + :Times(2) + end + end) + -- Expect RegisterAppInterface response on mobile side with resultCode SUCCESS + self.mobileSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + log("SDL->MOB: RS: RegisterAppInterface") + -- Expect OnHMIStatus with hmiLevel NONE on mobile side form SDL + self.mobileSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Do(function(_, d) + log("SDL->MOB: N: OnHMIStatus", d.payload.hmiLevel) + end) + -- Expect OnPermissionsChange on mobile side form SDL + self.mobileSession:ExpectNotification("OnPermissionsChange") + :Do(function() + log("SDL->MOB: N: OnPermissionsChange") + end) + :Times(2) + end) + end) +end + +-- Check update status +local function checkPTUStatus(self) + -- Send GetStatusUpdate form HMI to SDL + local reqId = self.hmiConnection:SendRequest("SDL.GetStatusUpdate") + log("HMI->SDL: RQ: SDL.GetStatusUpdate") + -- Expect GetStatusUpdate response from SDL to HMI with update status + EXPECT_HMIRESPONSE(reqId, { result = { status = "UP_TO_DATE" }}) + :Do(function(_, d) + log("HMI->SDL: RS: SDL.GetStatusUpdate", tostring(d.result.status)) + end) +end + +-- Pring in terminal build options(RC status and policy slow) +local function printSDLConfig() + commonFunctions:printTable(sdl.buildOptions) +end + +local function postconditions() + StopSDL() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +-- Stop SDL if process is still running, delete local policy table and log files +runner.Step("Clean environment", preconditions) +-- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP +runner.Step("Start SDL, HMI, connect Mobile", start) +-- Pring in terminal build options(RC status and policy slow) +runner.Step("SDL Configuration", printSDLConfig) + +runner.Title("Test") +-- create mobile session, register application, perform PTU wit PT +runner.Step("RAI, PTU", raiPTU) +-- Check that PTU is performed successful +runner.Step("Check Status", checkPTUStatus) + +runner.Title("Postconditions") +runner.Step("Stop SDL", postconditions) diff --git a/test_sets/smoke_tests.txt b/test_sets/smoke_tests.txt index dc2b859f65..641fa8f672 100644 --- a/test_sets/smoke_tests.txt +++ b/test_sets/smoke_tests.txt @@ -1,3 +1,4 @@ +./test_scripts/Smoke/Policies/001_PTU_all_flows.lua ./test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua ./test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua ./test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua @@ -21,4 +22,41 @@ ./test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_send_HB.lua ./test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_but_respond.lua ./test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua -./test_scripts/smoke_api.lua +./test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/002_ResetGlobalProperties_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/003_AddCommand_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/004_DeleteCommand_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/005_AddSubMenu_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/006_DeleteSubMenu_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/007_Alert_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/009_DeleteInteractionChoiceSet_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/010_DeleteFile_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/011_ListFiles_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/013_ScrollableMessage_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/015_Show_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/016_ShowConstantTBT_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/017_Slider_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/018_SendLocation_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/019_SetAppIcon_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/021_Speak_SUCCESS.lua +./test_scripts/Smoke/API/022_SubscribeButton_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/027_UpdateTurnList_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/028_AlertManeuver_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/029_OnDriverDistraction_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/030_DialNumber_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/031_PerformAudioPassThru_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/032_EndAudioPassThru_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/033_ReadDID_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/034_GetDTCs_SUCCESS.lua +./test_scripts/Smoke/API/035_ChangeRegistration_SUCCESS.lua +./test_scripts/Smoke/API/036_UnregisterAppInterface_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua + From 8ba2a0b5a538299c82338042f8b5a81153714938 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 16 Jan 2018 14:11:09 +0200 Subject: [PATCH 283/681] Removed redundant new line --- test_sets/smoke_tests.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/test_sets/smoke_tests.txt b/test_sets/smoke_tests.txt index 641fa8f672..072c92d558 100644 --- a/test_sets/smoke_tests.txt +++ b/test_sets/smoke_tests.txt @@ -59,4 +59,3 @@ ./test_scripts/Smoke/API/035_ChangeRegistration_SUCCESS.lua ./test_scripts/Smoke/API/036_UnregisterAppInterface_PositiveCase_SUCCESS.lua ./test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua - From 9a56b9e99394d625432b097232cdb437bbba4734 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 18 Jan 2018 08:40:11 +0200 Subject: [PATCH 284/681] Test set and scritps for non-media app --- ...7_Alert_Non_Media_PositiveCase_SUCCESS.lua | 224 +++++++++++ ...raction_Non_Media_PositiveCase_SUCCESS.lua | 350 ++++++++++++++++++ ...ckTimer_Non_Media_PositiveCase_SUCCESS.lua | 80 ++++ ...1_Speak_Non_Media_PositiveCase_SUCCESS.lua | 84 +++++ ...eButton_Non_Media_PositiveCase_SUCCESS.lua | 92 +++++ ...eButton_Non_Media_PositiveCase_SUCCESS.lua | 104 ++++++ ...aneuver_Non_Media_PositiveCase_SUCCESS.lua | 161 ++++++++ ...assThru_Non_Media_PositiveCase_SUCCESS.lua | 148 ++++++++ test_sets/smoke_tests_non_media.txt | 9 + 9 files changed, 1252 insertions(+) create mode 100644 test_scripts/Smoke/API/007_Alert_Non_Media_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/012_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/014_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/021_Speak_Non_Media_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/022_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/023_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/028_AlertManeuver_Non_Media_PositiveCase_SUCCESS.lua create mode 100644 test_scripts/Smoke/API/031_PerformAudioPassThru_Non_Media_PositiveCase_SUCCESS.lua create mode 100644 test_sets/smoke_tests_non_media.txt diff --git a/test_scripts/Smoke/API/007_Alert_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/007_Alert_Non_Media_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..99d8c6e005 --- /dev/null +++ b/test_scripts/Smoke/API/007_Alert_Non_Media_PositiveCase_SUCCESS.lua @@ -0,0 +1,224 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: Alert +-- Item: Happy path +-- +-- Requirement summary: +-- [Alert] SUCCESS: request with UI portion and TTSChunks +-- +-- Description: +-- Mobile application sends valid Alert request with UI-related-params & with TTSChunks +-- and gets SUCCESS resultCode to both UI.Alert and TTS.Speak from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests Alert with UI-related-params & with TTSChunks + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if TTS interface is available on HMI +-- SDL checks if Alert is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the UI.Alert part of request with allowed parameters to HMI +-- SDL transfers the TTS.Speak part of request with allowed parameters to HMI +-- SDL receives UI.Alert part of response from HMI with "SUCCESS" result code +-- SDL receives TTS.Speak part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +config.application1.registerAppInterfaceParams.isMediaApplication = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local step1SpecificParams = { + softButtons = { + { + type = "BOTH", + text = "Close", + image = { + value = "icon.png", + imageType = "DYNAMIC", + }, + isHighlighted = true, + softButtonID = 3, + systemAction = "DEFAULT_ACTION", + }, + { + type = "TEXT", + text = "Keep", + isHighlighted = true, + softButtonID = 4, + systemAction = "KEEP_CONTEXT", + }, + { + type = "IMAGE", + image = { + value = "icon.png", + imageType = "DYNAMIC", + }, + softButtonID = 5, + systemAction = "STEAL_FOCUS", + } + } +} + +local step2SpecificParams = { + duration = 5000 +} + +local requestParams = { + alertText1 = "alertText1", + alertText2 = "alertText2", + alertText3 = "alertText3", + ttsChunks = { + { + text = "TTSChunk", + type = "TEXT", + } + }, + playTone = true, + progressIndicator = true +} + +local responseUiParams = { + alertStrings = { + { + fieldName = requestParams.alertText1, + fieldText = requestParams.alertText1 + }, + { + fieldName = requestParams.alertText2, + fieldText = requestParams.alertText2 + }, + { + fieldName = requestParams.alertText3, + fieldText = requestParams.alertText3 + } + }, + alertType = "BOTH", + progressIndicator = requestParams.progressIndicator, +} + +local ttsSpeakRequestParams = { + ttsChunks = requestParams.ttsChunks, + speakType = "ALERT", + playTone = requestParams.playTone +} + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams, + ttsSpeakRequestParams = ttsSpeakRequestParams +} + +--[[ Local Functions ]] +local function sendOnSystemContext(self, ctx) + self.hmiConnection:SendNotification("UI.OnSystemContext", + { + appID = commonSmoke.getHMIAppId(), + systemContext = ctx + }) +end + +local function prepareAlertParams(params, additionalParams) + params.responseUiParams.appID = commonSmoke.getHMIAppId() + + if additionalParams.softButtons ~= nil then + params.requestParams.duration = nil + params.requestParams.softButtons = additionalParams.softButtons + params.responseUiParams.duration = nil; + params.responseUiParams.softButtons = additionalParams.softButtons + params.responseUiParams.softButtons[1].image.value = + commonSmoke.getPathToFileInStorage(putFileParams.requestParams.syncFileName) + params.responseUiParams.softButtons[3].image.value = + commonSmoke.getPathToFileInStorage(putFileParams.requestParams.syncFileName) + elseif additionalParams.duration ~= nil then + params.requestParams.softButtons = nil + params.requestParams.duration = additionalParams.duration + params.responseUiParams.softButtons = nil + params.responseUiParams.duration = additionalParams.duration + end +end + +local function alert(params, additionalParams, self) + prepareAlertParams(params, additionalParams) + + local responseDelay = 3000 + local cid = self.mobileSession1:SendRPC("Alert", params.requestParams) + + EXPECT_HMICALL("UI.Alert", params.responseUiParams) + :Do(function(_,data) + sendOnSystemContext(self, "ALERT") + + local alertId = data.id + local function alertResponse() + self.hmiConnection:SendResponse(alertId, "UI.Alert", "SUCCESS", { }) + sendOnSystemContext(self, "MAIN") + end + + RUN_AFTER(alertResponse, responseDelay) + end) + + params.ttsSpeakRequestParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("TTS.Speak", params.ttsSpeakRequestParams) + :Do(function(_,data) + self.hmiConnection:SendNotification("TTS.Started") + + local speakId = data.id + local function speakResponse() + self.hmiConnection:SendResponse(speakId, "TTS.Speak", "SUCCESS", { }) + self.hmiConnection:SendNotification("TTS.Stopped") + end + + RUN_AFTER(speakResponse, responseDelay - 1000) + end) + :ValidIf(function(_,data) + if #data.params.ttsChunks == 1 then + return true + else + return false, "ttsChunks array in TTS.Speak request has wrong element number." .. + " Expected 1, actual " .. tostring(#data.params.ttsChunks) + end + end) + + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "ALERT", hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE" }) + :Times(2) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) + +runner.Title("Test") +runner.Step("Alert with soft buttons Positive Case", alert, {allParams, step1SpecificParams}) +runner.Step("Alert with duration Positive Case", alert, {allParams, step2SpecificParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/012_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/012_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..5f68c53a4f --- /dev/null +++ b/test_scripts/Smoke/API/012_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua @@ -0,0 +1,350 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: PerformInteraction +-- Item: Happy path +-- +-- Requirement summary: +-- [PerformInteraction]: +-- SUCCESS result code +-- TIMED_OUT result code +-- +-- Description: +-- Mobile application sends PerformInteraction request with valid parameters to SDL + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level +-- d. ChoiceSets are already added + +-- Steps: +-- appID requests PerformInteraction with valid parameters to SDL + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if PerformInteraction is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL provides ability to perform choice on HMI manually or by voice +-- After user provide the choice SDL responds with (resultCode: SUCCESS, success:true) to mobile application +-- After user does not provide the choice SDL responds with (resultCode: TIMED_OUT, success:false) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') + +config.application1.registerAppInterfaceParams.isMediaApplication = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local storagePath = commonPreconditions:GetPathToSDL() .. "storage/" .. +config.application1.registerAppInterfaceParams.appID .. "_" .. config.deviceMAC .. "/" + +local ImageValue = { + value = storagePath .. "icon.png", + imageType = "DYNAMIC", +} + +local function PromptValue(text) + local tmp = { + { + text = text, + type = "TEXT" + } + } + return tmp +end + +local initialPromptValue = PromptValue(" Make your choice ") + +local helpPromptValue = PromptValue(" Help Prompt ") + +local timeoutPromptValue = PromptValue(" Time out ") + +local vrHelpvalue = { + { + text = " New VRHelp ", + position = 1, + image = ImageValue + } +} + +local requestParams = { + initialText = "StartPerformInteraction", + initialPrompt = initialPromptValue, + interactionMode = "BOTH", + interactionChoiceSetIDList = { + 100, 200, 300 + }, + helpPrompt = helpPromptValue, + timeoutPrompt = timeoutPromptValue, + timeout = 5000, + vrHelp = vrHelpvalue, + interactionLayout = "ICON_ONLY" +} + +--[[ Local Functions ]] + +--! @setChoiseSet: Creates Choice structure +--! @parameters: +--! choiceIDValue - Id for created choice +--! @return: table of created choice structure +local function setChoiseSet(choiceIDValue) + local temp = { + { + choiceID = choiceIDValue, + menuName ="Choice" .. tostring(choiceIDValue), + vrCommands = { + "VrChoice" .. tostring(choiceIDValue), + }, + image = { + value ="icon.png", + imageType ="STATIC", + } + } + } + return temp +end + +--! @SendOnSystemContext: OnSystemContext notification +--! @parameters: +--! self - test object, +--! ctx - systemContext value +--! @return: none +local function SendOnSystemContext(self, ctx) + self.hmiConnection:SendNotification("UI.OnSystemContext", + { appID = commonSmoke.getHMIAppId(), systemContext = ctx }) +end + +--! @setExChoiseSet: ChoiceSet structure for UI.PerformInteraction request +--! @parameters: +--! choiceIDValues - value of choice id +--! @return: none +local function setExChoiseSet(choiceIDValues) + local exChoiceSet = { } + for i = 1, #choiceIDValues do + exChoiceSet[i] = { + choiceID = choiceIDValues[i], + image = { + value = "icon.png", + imageType = "STATIC", + }, + menuName = "Choice" .. choiceIDValues[i] + } + end + return exChoiceSet +end + +--! @ExpectOnHMIStatusWithAudioStateChanged_PI: Expectations of OnHMIStatus notification depending on interaction mode +--! @parameters: +--! self - test object, +--! request - interaction mode, +--! @return: none +local function ExpectOnHMIStatusWithAudioStateChanged_PI(self, request) + if request == "BOTH" then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "VRSESSION" }, + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "HMI_OBSCURED" }, + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(3) + elseif request == "VR" then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "VRSESSION", hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE" }) + :Times(2) + elseif request == "MANUAL" then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "HMI_OBSCURED" }, + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(2) + end +end + +--! @CreateInteractionChoiceSet: Creation of Choice Set +--! @parameters: +--! choiceSetID - id for choice set +--! self - test object +--! @return: none +local function CreateInteractionChoiceSet(choiceSetID, self) + local choiceID = choiceSetID + local cid = self.mobileSession1:SendRPC("CreateInteractionChoiceSet", { + interactionChoiceSetID = choiceSetID, + choiceSet = setChoiseSet(choiceID), + }) + EXPECT_HMICALL("VR.AddCommand", { + cmdID = choiceID, + type = "Choice", + vrCommands = { "VrChoice" .. tostring(choiceID) } + }) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + self.mobileSession1:ExpectResponse(cid, { resultCode = "SUCCESS", success = true }) +end + +--! @PI_PerformViaVR_ONLY: Processing PI with interaction mode VR_ONLY with performing selection +--! @parameters: +--! paramsSend - parameters for PI request +--! self - test object +--! @return: none +local function PI_PerformViaVR_ONLY(paramsSend, self) + paramsSend.interactionMode = "VR_ONLY" + local cid = self.mobileSession1:SendRPC("PerformInteraction",paramsSend) + EXPECT_HMICALL("VR.PerformInteraction", { + helpPrompt = paramsSend.helpPrompt, + initialPrompt = paramsSend.initialPrompt, + timeout = paramsSend.timeout, + timeoutPrompt = paramsSend.timeoutPrompt + }) + :Do(function(_,data) + local function vrResponse() + self.hmiConnection:SendNotification("TTS.Started") + self.hmiConnection:SendNotification("VR.Started") + SendOnSystemContext(self, "VRSESSION") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + { choiceID = paramsSend.interactionChoiceSetIDList[1] }) + self.hmiConnection:SendNotification("TTS.Stopped") + self.hmiConnection:SendNotification("VR.Stopped") + SendOnSystemContext(self, "MAIN") + end + RUN_AFTER(vrResponse, 1000) + end) + + EXPECT_HMICALL("UI.PerformInteraction", { + timeout = paramsSend.timeout, + vrHelp = paramsSend.vrHelp, + vrHelpTitle = paramsSend.initialText, + }) + :Do(function(_,data) + self.hmiConnection:SendResponse( data.id, data.method, "SUCCESS", { } ) + end) + ExpectOnHMIStatusWithAudioStateChanged_PI(self, "VR") + self.mobileSession1:ExpectResponse(cid, + { success = true, resultCode = "SUCCESS", choiceID = paramsSend.interactionChoiceSetIDList[1] }) +end + +--! @PI_PerformViaMANUAL_ONLY: Processing PI with interaction mode MANUAL_ONLY with performing selection +--! @parameters: +--! paramsSend - parameters for PI request +--! self - test object +--! @return: none +local function PI_PerformViaMANUAL_ONLY(paramsSend, self) + paramsSend.interactionMode = "MANUAL_ONLY" + local cid = self.mobileSession1:SendRPC("PerformInteraction", paramsSend) + EXPECT_HMICALL("VR.PerformInteraction", { + helpPrompt = paramsSend.helpPrompt, + initialPrompt = paramsSend.initialPrompt, + timeout = paramsSend.timeout, + timeoutPrompt = paramsSend.timeoutPrompt + }) + :Do(function(_,data) + self.hmiConnection:SendNotification("TTS.Started") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + EXPECT_HMICALL("UI.PerformInteraction", { + timeout = paramsSend.timeout, + choiceSet = setExChoiseSet(paramsSend.interactionChoiceSetIDList), + initialText = { + fieldName = "initialInteractionText", + fieldText = paramsSend.initialText + } + }) + :Do(function(_,data) + SendOnSystemContext(self,"HMI_OBSCURED") + local function uiResponse() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + { choiceID = paramsSend.interactionChoiceSetIDList[1] }) + self.hmiConnection:SendNotification("TTS.Stopped") + SendOnSystemContext(self,"MAIN") + end + RUN_AFTER(uiResponse, 1000) + end) + ExpectOnHMIStatusWithAudioStateChanged_PI(self, "MANUAL") + self.mobileSession1:ExpectResponse(cid, + { success = true, resultCode = "SUCCESS", choiceID = paramsSend.interactionChoiceSetIDList[1] }) +end + +--! @PI_PerformViaBOTH: Processing PI with interaction mode BOTH with timeout on VR and IU +--! @parameters: +--! paramsSend - parameters for PI request +--! self - test object +--! @return: none +local function PI_PerformViaBOTH(paramsSend, self) + paramsSend.interactionMode = "BOTH" + local cid = self.mobileSession1:SendRPC("PerformInteraction",paramsSend) + EXPECT_HMICALL("VR.PerformInteraction", { + helpPrompt = paramsSend.helpPrompt, + initialPrompt = paramsSend.initialPrompt, + timeout = paramsSend.timeout, + timeoutPrompt = paramsSend.timeoutPrompt + }) + :Do(function(_,data) + self.hmiConnection:SendNotification("VR.Started") + self.hmiConnection:SendNotification("TTS.Started") + SendOnSystemContext(self,"VRSESSION") + local function firstSpeakTimeOut() + self.hmiConnection:SendNotification("TTS.Stopped") + self.hmiConnection:SendNotification("TTS.Started") + end + RUN_AFTER(firstSpeakTimeOut, 5) + local function vrResponse() + self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", "Perform Interaction error response.") + self.hmiConnection:SendNotification("VR.Stopped") + end + RUN_AFTER(vrResponse, 20) + end) + EXPECT_HMICALL("UI.PerformInteraction", { + timeout = paramsSend.timeout, + choiceSet = setExChoiseSet(paramsSend.interactionChoiceSetIDList), + initialText = { + fieldName = "initialInteractionText", + fieldText = paramsSend.initialText + }, + vrHelp = paramsSend.vrHelp, + vrHelpTitle = paramsSend.initialText + }) + :Do(function(_,data) + local function choiceIconDisplayed() + SendOnSystemContext(self,"HMI_OBSCURED") + end + RUN_AFTER(choiceIconDisplayed, 25) + local function uiResponse() + self.hmiConnection:SendNotification("TTS.Stopped") + self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", "Perform Interaction error response.") + SendOnSystemContext(self,"MAIN") + end + RUN_AFTER(uiResponse, 30) + end) + ExpectOnHMIStatusWithAudioStateChanged_PI(self, "BOTH") + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "TIMED_OUT" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) +runner.Step("CreateInteractionChoiceSet with id 100", CreateInteractionChoiceSet, {100}) +runner.Step("CreateInteractionChoiceSet with id 200", CreateInteractionChoiceSet, {200}) +runner.Step("CreateInteractionChoiceSet with id 300", CreateInteractionChoiceSet, {300}) + +runner.Title("Test") +runner.Step("PerformInteraction with VR_ONLY interaction mode", PI_PerformViaVR_ONLY, {requestParams}) +runner.Step("PerformInteraction with MANUAL_ONLY interaction mode", PI_PerformViaMANUAL_ONLY, {requestParams}) +runner.Step("PerformInteraction with BOTH interaction mode", PI_PerformViaBOTH, {requestParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/014_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/014_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..3556a5b973 --- /dev/null +++ b/test_scripts/Smoke/API/014_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua @@ -0,0 +1,80 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: SetMediaClockTimer +-- Item: Happy path +-- +-- Requirement summary: +-- [SetMediaClockTimer] SUCCESS: getting SUCCESS:UI.SetMediaClockTimer() +-- +-- Description: +-- Mobile application sends valid SetMediaClockTimer request and gets UI.SetMediaClockTimer "SUCCESS" response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests SetMediaClockTimer with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if SetMediaClockTimer is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the UI part of request with allowed parameters to HMI +-- SDL receives UI part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +config.application1.registerAppInterfaceParams.isMediaApplication = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Variables ]] +local updateMode = {"COUNTUP", "COUNTDOWN", "PAUSE", "RESUME", "CLEAR"} + +local requestParams = { + startTime = { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = { + hours = 0, + minutes = 1 , + seconds = 35 + } +} + +--[[ Local Functions ]] +local function SetMediaClockTimer(pParams, pMode, self) + local Parameters = commonFunctions:cloneTable(pParams) + Parameters.updateMode = pMode + if pMode == "COUNTDOWN" then + Parameters.endTime.minutes = Parameters.startTime.minutes - 1 + end + local cid = self.mobileSession1:SendRPC("SetMediaClockTimer", Parameters) + EXPECT_HMICALL("UI.SetMediaClockTimer") + :Times(0) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +for _, value in pairs (updateMode) do + runner.Step("SetMediaClockTimer Positive Case with udate mode " .. value, SetMediaClockTimer, { requestParams,value }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/021_Speak_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/021_Speak_Non_Media_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..adaf0c5fb2 --- /dev/null +++ b/test_scripts/Smoke/API/021_Speak_Non_Media_PositiveCase_SUCCESS.lua @@ -0,0 +1,84 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: Speak +-- Item: Happy path +-- +-- Requirement summary: +-- [Speak] SUCCESS on TTS.Speak +-- +-- Description: +-- Mobile application sends Speak request with valid parameters to SDL +-- +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- +-- Steps: +-- Application sends Speak request with valid parameters to SDL +-- +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if TTS interface is available on HMI +-- SDL checks if Speak is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the TTS part of request with allowed parameters to HMI +-- SDL receives TTS part of response from HMI with "SUCCESS" result code +-- SDL transfers response to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +config.application1.registerAppInterfaceParams.isMediaApplication = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Functions ]] +local function getRequestParams() + return { + ttsChunks = { + { + text ="a", + type ="TEXT" + } + } + } +end + +local function speakSuccess(self) + print("Waiting 20s ...") + local cid = self.mobileSession1:SendRPC("Speak", getRequestParams()) + EXPECT_HMICALL("TTS.Speak", getRequestParams()) + :Do(function(_, data) + self.hmiConnection:SendNotification("TTS.Started") + local function sendSpeakResponse() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + self.hmiConnection:SendNotification("TTS.Stopped") + end + local function sendOnResetTimeout() + self.hmiConnection:SendNotification("TTS.OnResetTimeout", + { appID = commonSmoke.getHMIAppId(), methodName = "TTS.Speak" }) + end + RUN_AFTER(sendOnResetTimeout, 9000) + RUN_AFTER(sendSpeakResponse, 18000) + end) + + self.mobileSession1:ExpectNotification("OnHMIStatus") + :Times(0) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + :Timeout(20000) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("Speak Positive Case", speakSuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/022_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/022_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..2d11b6e04e --- /dev/null +++ b/test_scripts/Smoke/API/022_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua @@ -0,0 +1,92 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: SubscribeButton +-- Item: Happy path +-- +-- Requirement summary: +-- [SubscribeButton] SUCCESS: getting SUCCESS:SubscribeButton() +-- +-- Description: +-- Mobile application sends valid SubscribeButton request and gets SubscribeButton "SUCCESS" response from SDL + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests SubscribeButton with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if Buttons interface is available on HMI +-- SDL checks if SubscribeButton is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL sends the Buttons notificaton to HMI +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +config.application1.registerAppInterfaceParams.isMediaApplication = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Variables ]] +local buttonName = { + "OK", + "PRESET_0", + "PRESET_1", + "PRESET_2", + "PRESET_3", + "PRESET_4", + "PRESET_5", + "PRESET_6", + "PRESET_7", + "PRESET_8" +} + +local mediaButtonName = { + "SEEKLEFT", + "SEEKRIGHT", + "TUNEUP", + "TUNEDOWN" +} + +--[[ Local Functions ]] +local function subscribeButton(pButName, self) + local cid = self.mobileSession1:SendRPC("SubscribeButton", { buttonName = pButName }) + local appIDvalue = commonSmoke.getHMIAppId() + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", { appID = appIDvalue, name = pButName, isSubscribed = true }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +local function subscribeMediaButton(pButName, self) + local cid = self.mobileSession1:SendRPC("SubscribeButton", { buttonName = pButName }) + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription") + :Times(0) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) + self.mobileSession1:ExpectNotification("OnHashChange") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +for _, v in pairs(buttonName) do + runner.Step("SubscribeButton " .. v .. " Positive Case", subscribeButton, { v }) +end + +for _, v in pairs(mediaButtonName) do + runner.Step("SubscribeButton " .. v .. " Positive Case", subscribeMediaButton, { v }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/023_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/023_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..819d394391 --- /dev/null +++ b/test_scripts/Smoke/API/023_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua @@ -0,0 +1,104 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: UnsubscribeButton +-- Item: Happy path +-- +-- Requirement summary: +-- [UnsubscribeButton] SUCCESS: getting SUCCESS:UnsubscribeButton() +-- +-- Description: +-- Mobile application sends valid UnsubscribeButton request and gets UnsubscribeButton "SUCCESS" response from SDL + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests UnsubscribeButton with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if Buttons interface is available on HMI +-- SDL checks if UnsubscribeButton is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL sends the Buttons notificaton to HMI +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +config.application1.registerAppInterfaceParams.isMediaApplication = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Variables ]] +local buttonName = { + "OK", + "PRESET_0", + "PRESET_1", + "PRESET_2", + "PRESET_3", + "PRESET_4", + "PRESET_5", + "PRESET_6", + "PRESET_7", + "PRESET_8" +} + +local mediaButtonName = { + "SEEKLEFT", + "SEEKRIGHT", + "TUNEUP", + "TUNEDOWN" +} + +--[[ Local Functions ]] +local function subscribeButtons(pButName, self) + local cid = self.mobileSession1:SendRPC("SubscribeButton", { buttonName = pButName }) + local appIDvalue = commonSmoke.getHMIAppId() + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", { appID = appIDvalue, name = pButName, isSubscribed = true }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +local function unsubscribeButton(pButName, self) + local cid = self.mobileSession1:SendRPC("UnsubscribeButton", { buttonName = pButName }) + local appIDvalue = commonSmoke.getHMIAppId() + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", + { appID = appIDvalue, name = pButName, isSubscribed = false }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +local function unsubscribeMediaButton(pButName, self) + local cid = self.mobileSession1:SendRPC("UnsubscribeButton", { buttonName = pButName }) + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription") + :Times(0) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "IGNORED" }) + self.mobileSession1:ExpectNotification("OnHashChange") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) +for _, v in pairs(buttonName) do + runner.Step("SubscribeButton " .. v .. " Positive Case", subscribeButtons, { v }) +end + +runner.Title("Test") +for _, v in pairs(buttonName) do + runner.Step("UnsubscribeButton " .. v .. " Positive Case", unsubscribeButton, { v }) +end + +for _, v in pairs(mediaButtonName) do + runner.Step("UnsubscribeButton " .. v .. " Positive Case", unsubscribeMediaButton, { v }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/028_AlertManeuver_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/028_AlertManeuver_Non_Media_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..2d9af5eec7 --- /dev/null +++ b/test_scripts/Smoke/API/028_AlertManeuver_Non_Media_PositiveCase_SUCCESS.lua @@ -0,0 +1,161 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: AlertManeuver +-- Item: Happy path +-- +-- Requirement summary: +-- [AlertManeuver] SUCCESS on Navigation.AlertManeuver +-- +-- Description: +-- Mobile application sends AlertManeuver request with valid parameters to SDL +-- +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- +-- Steps: +-- Application sends AlertManeuver request with valid parameters to SDL +-- +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if Navigation interface is available on HMI +-- SDL checks if TTS interface is available on HMI +-- SDL checks if AlertManeuver is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the Navigation part of request with allowed parameters to HMI +-- SDL transfers the TTS part of request with allowed parameters to HMI +-- SDL receives Navigation part of response from HMI with "SUCCESS" result code +-- SDL receives TTS part of response from HMI with "SUCCESS" result code +-- SDL transfers response to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") + +config.application1.registerAppInterfaceParams.isMediaApplication = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local requestParams = { + ttsChunks = { + { + text = "FirstAlert", + type = "TEXT", + }, + { + text = "SecondAlert", + type = "TEXT", + }, + }, + softButtons = { + { + type = "BOTH", + text = "Close", + image = { + value = "icon.png", + imageType = "DYNAMIC", + }, + isHighlighted = true, + softButtonID = 821, + systemAction = "DEFAULT_ACTION", + }, + { + type = "BOTH", + text = "AnotherClose", + image = { + value = "icon.png", + imageType = "DYNAMIC", + }, + isHighlighted = false, + softButtonID = 822, + systemAction = "DEFAULT_ACTION", + }, + } +} + +local function naviParamsSet(tbl) + local Params = commonFunctions:cloneTable(tbl) + for k, _ in pairs(Params) do + if Params[k].image then + Params[k].image.value = commonSmoke.getPathToFileInStorage(Params[k].image.value) + end + end + return Params +end + +local responseNaviParams = { + softButtons = naviParamsSet(requestParams.softButtons) +} + +local responseTtsParams = { + ttsChunks = requestParams.ttsChunks +} + +local allParams = { + requestParams = requestParams, + responseNaviParams = responseNaviParams, + responseTtsParams = responseTtsParams +} + +--[[ Local Functions ]] +local function PTUpdateFunc(tbl) + local AlertMgroup = { + rpcs = { + AlertManeuver = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, + } + } + } + tbl.policy_table.functional_groupings.NewTestCaseGroup = AlertMgroup + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = + { "Base-4", "NewTestCaseGroup" } +end + +local function alertManeuver(pParams, self) + local cid = self.mobileSession1:SendRPC("AlertManeuver", pParams.requestParams) + EXPECT_HMICALL("Navigation.AlertManeuver", pParams.responseNaviParams) + :Do(function(_, data) + local function alertResp() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end + RUN_AFTER(alertResp, 2000) + end) + EXPECT_HMICALL("TTS.Speak", pParams.responseTtsParams) + :Do(function(_, data) + self.hmiConnection:SendNotification("TTS.Started") + local function SpeakResp() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + self.hmiConnection:SendNotification("TTS.Stopped") + end + RUN_AFTER(SpeakResp, 1000) + end) + self.mobileSession1:ExpectNotification("OnHMIStatus") + :Times(0) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, PTUpdateFunc }) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, { putFileParams }) + +runner.Title("Test") +runner.Step("AlertManeuver Positive Case", alertManeuver, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/031_PerformAudioPassThru_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/031_PerformAudioPassThru_Non_Media_PositiveCase_SUCCESS.lua new file mode 100644 index 0000000000..a79131e7b6 --- /dev/null +++ b/test_scripts/Smoke/API/031_PerformAudioPassThru_Non_Media_PositiveCase_SUCCESS.lua @@ -0,0 +1,148 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: PerformAudioPassThru +-- Item: Happy path +-- +-- Requirement summary: +-- [PerformAudioPassThru] SUCCESS: getting SUCCESS:UI.PerformAudioPassThru() +-- +-- Description: +-- Mobile application sends valid PerformAudioPassThru request and gets UI.PerformAudioPassThru "SUCCESS" +-- response from HMI + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests PerformAudioPassThru with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if UI interface is available on HMI +-- SDL checks if TTS interface is available on HMI +-- SDL checks if PerformAudioPassThru is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the UI part of request with allowed parameters to HMI +-- SDL transfers the TTS part of request with allowed parameters to HMI +-- SDL receives UI part of response from HMI with "SUCCESS" result code +-- SDL receives TTS part of response from HMI with "SUCCESS" result code +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') + +config.application1.registerAppInterfaceParams.isMediaApplication = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Variables ]] +local requestParams = { + initialPrompt = { + { + text = "Makeyourchoice", + type = "TEXT", + }, + }, + audioPassThruDisplayText1 = "DisplayText1", + audioPassThruDisplayText2 = "DisplayText2", + samplingRate = "8KHZ", + maxDuration = 2000, + bitsPerSample = "8_BIT", + audioType = "PCM", + muteAudio = true +} + +local requestUiParams = { + audioPassThruDisplayTexts = { }, + maxDuration = requestParams.maxDuration, + muteAudio = requestParams.muteAudio +} + +requestUiParams.audioPassThruDisplayTexts[1] = { + fieldName = "audioPassThruDisplayText1", + fieldText = requestParams.audioPassThruDisplayText1 +} + +requestUiParams.audioPassThruDisplayTexts[2] = { + fieldName = "audioPassThruDisplayText2", + fieldText = requestParams.audioPassThruDisplayText2 +} + +local requestTtsParams = {} +requestTtsParams.ttsChunks = commonFunctions:cloneTable(requestParams.initialPrompt) +requestTtsParams.speakType = "AUDIO_PASS_THRU" + +local allParams = { + requestParams = requestParams, + requestUiParams = requestUiParams, + requestTtsParams = requestTtsParams +} + +--[[ Local Functions ]] +local function file_check(file_name) + local file_found = io.open(file_name, "r") + if nil == file_found then + return false + end + return true +end + +local function sendOnSystemContext(self, pCtx, pAppID) + self.hmiConnection:SendNotification("UI.OnSystemContext", + { appID = pAppID, systemContext = pCtx }) +end + +local function performAudioPassThru(pParams, self) + local cid = self.mobileSession1:SendRPC("PerformAudioPassThru", pParams.requestParams) + pParams.requestUiParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("TTS.Speak", pParams.requestTtsParams) + :Do(function(_,data) + self.hmiConnection:SendNotification("TTS.Started") + local function ttsSpeakResponse() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + self.hmiConnection:SendNotification("TTS.Stopped") + end + RUN_AFTER(ttsSpeakResponse, 50) + end) + EXPECT_HMICALL("UI.PerformAudioPassThru", pParams.requestUiParams) + :Do(function(_,data) + sendOnSystemContext(self, "HMI_OBSCURED", pParams.requestUiParams.appID) + local function uiResponse() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + sendOnSystemContext(self, "MAIN", pParams.requestUiParams.appID) + end + RUN_AFTER(uiResponse, 1500) + end) + EXPECT_HMINOTIFICATION("UI.OnRecordStart", {appID = pParams.requestUiParams.appID}) + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "HMI_OBSCURED" }, + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(2) + self.mobileSession1:ExpectNotification("OnAudioPassThru") + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + :ValidIf (function() + local file = commonPreconditions:GetPathToSDL() .. "storage/" .. "audio.wav" + if true ~= file_check(file) then + return false, "Can not found file: audio.wav" + end + return true + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("PerformAudioPassThru Positive Case", performAudioPassThru, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_sets/smoke_tests_non_media.txt b/test_sets/smoke_tests_non_media.txt new file mode 100644 index 0000000000..83bfcae209 --- /dev/null +++ b/test_sets/smoke_tests_non_media.txt @@ -0,0 +1,9 @@ +./test_scripts/Smoke/Policies/001_PTU_all_flows.lua +./test_scripts/Smoke/API/007_Alert_Non_Media_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/012_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/014_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/021_Speak_Non_Media_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/022_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/023_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/028_AlertManeuver_Non_Media_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/031_PerformAudioPassThru_Non_Media_PositiveCase_SUCCESS.lua From 704ffa35ba0ae311a6ef9f6c21edd9809d22636a Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 18 Jan 2018 09:11:04 +0200 Subject: [PATCH 285/681] Updat script name in media set --- ...Speak_SUCCESS.lua => 021_Speak_PositiveCase_SUCCESS.lua} | 0 ...TCs_SUCCESS.lua => 034_GetDTCs_PositiveCase_SUCCESS.lua} | 0 ....lua => 035_ChangeRegistration_PositiveCase_SUCCESS.lua} | 0 test_sets/smoke_tests.txt | 6 +++--- 4 files changed, 3 insertions(+), 3 deletions(-) rename test_scripts/Smoke/API/{021_Speak_SUCCESS.lua => 021_Speak_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{034_GetDTCs_SUCCESS.lua => 034_GetDTCs_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{035_ChangeRegistration_SUCCESS.lua => 035_ChangeRegistration_PositiveCase_SUCCESS.lua} (100%) diff --git a/test_scripts/Smoke/API/021_Speak_SUCCESS.lua b/test_scripts/Smoke/API/021_Speak_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/021_Speak_SUCCESS.lua rename to test_scripts/Smoke/API/021_Speak_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/034_GetDTCs_SUCCESS.lua b/test_scripts/Smoke/API/034_GetDTCs_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/034_GetDTCs_SUCCESS.lua rename to test_scripts/Smoke/API/034_GetDTCs_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/035_ChangeRegistration_SUCCESS.lua b/test_scripts/Smoke/API/035_ChangeRegistration_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/035_ChangeRegistration_SUCCESS.lua rename to test_scripts/Smoke/API/035_ChangeRegistration_PositiveCase_SUCCESS.lua diff --git a/test_sets/smoke_tests.txt b/test_sets/smoke_tests.txt index 072c92d558..f7840be2d1 100644 --- a/test_sets/smoke_tests.txt +++ b/test_sets/smoke_tests.txt @@ -42,7 +42,7 @@ ./test_scripts/Smoke/API/018_SendLocation_PositiveCase_SUCCESS.lua ./test_scripts/Smoke/API/019_SetAppIcon_PositiveCase_SUCCESS.lua ./test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua -./test_scripts/Smoke/API/021_Speak_SUCCESS.lua +./test_scripts/Smoke/API/021_Speak_PositiveCase_SUCCESS.lua ./test_scripts/Smoke/API/022_SubscribeButton_PositiveCase_SUCCESS.lua ./test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase_SUCCESS.lua ./test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua @@ -55,7 +55,7 @@ ./test_scripts/Smoke/API/031_PerformAudioPassThru_PositiveCase_SUCCESS.lua ./test_scripts/Smoke/API/032_EndAudioPassThru_PositiveCase_SUCCESS.lua ./test_scripts/Smoke/API/033_ReadDID_PositiveCase_SUCCESS.lua -./test_scripts/Smoke/API/034_GetDTCs_SUCCESS.lua -./test_scripts/Smoke/API/035_ChangeRegistration_SUCCESS.lua +./test_scripts/Smoke/API/034_GetDTCs_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/035_ChangeRegistration_PositiveCase_SUCCESS.lua ./test_scripts/Smoke/API/036_UnregisterAppInterface_PositiveCase_SUCCESS.lua ./test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua From 86f0a7611d1228cebef608672f388ea687b89b7a Mon Sep 17 00:00:00 2001 From: "Andrey Oleynik (GitHub)" Date: Sun, 12 Nov 2017 17:08:38 +0200 Subject: [PATCH 286/681] Adds basic test for iAP2 transport switch happy path --- ...oth_to_USB_transport_switch_happy_path.lua | 158 +++ user_modules/connecttest_iap2_emulation.lua | 939 ++++++++++++++++++ 2 files changed, 1097 insertions(+) create mode 100644 test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua create mode 100644 user_modules/connecttest_iap2_emulation.lua diff --git a/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua b/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua new file mode 100644 index 0000000000..cd89f5b101 --- /dev/null +++ b/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua @@ -0,0 +1,158 @@ +-- Requirement summary: +-- TBD +-- +-- Description: +-- iAP2 Bluetooth connection is switched to iAP2 USB connection automatically, application(s) remains registered +-- +-- 1. Used precondition +-- SDL is built with BUILD_TEST = ON to enable iAP2 BT/USB transport adapter emulation +-- SDL, HMI are running on system. +-- +-- 2. Performed steps +-- iAP2 Bluetooth mobile device connects to system +-- appID_1->RegisterAppInterface(params) +-- RAI response is SUCCESS +-- +-- same iAP2 mobile device is connected over USB to system and re-registers within AppTransportChangeTimer timeout +-- appID_1->RegisterAppInterface(params) +-- +-- Expected behavior: +-- 1. SDL successfully registers application and notifies HMI and mobile +-- SDL->HMI: OnAppRegistered(params) +-- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() +-- +-- 2. SDL successfully registers application and notifies mobile only with RAI response +-- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() +-- application remains registered internally +-- application does not send OnAppUnregistered notification to HMI +-- application does not send OnAppRegistered notification to HMI + +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 + +-- [[ Required Shared Libraries ]] +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") + +local mobile = require("mobile_connection") +local mobile_session = require("mobile_session") + +local tcp = require("tcp_connection") +local file_connection = require("file_connection") + +--[[ General Settings for configuration ]] +Test = require("user_modules/connecttest_iap2_emulation") +require("cardinalities") +require("user_modules/AppTypes") + +-- [[Local variables]] +local app_RAI_params = config["application1"].registerAppInterfaceParams + +--[[ +IN ORDER TO USE IAP2 EMULATION IN SDL IT MUST BE BUILT ON +https://github.com/dev-gh/sdl_core/tree/experimental/IAP_adapters_emulation +WITH +BUILD_TESTS = ON +]] +local iAP2_BT_DeviceID = "127.0.0.1" +local iAP2_BT_Port = 23456 +local iAP2_BT_out = "iap2bt.out" +local iAP2_BT_Type = "BLUETOOTH" + +-- Device IDs must be the same in order to trigger switching logic +local iAP2_USB_DeviceID = iAP2_BT_DeviceID +local iAP2_USB_Port = 34567 +local iAP2_USB_out = "iap2usb.out" +local iAP2_USB_Type = "USB_IOS" + +--[[ Preconditions ]] +commonFunctions:newTestCasesGroup("Preconditions") +commonSteps:DeletePolicyTable() +commonSteps:DeleteLogsFiles() + +local function createIAP2Device(deviceID, devicePort, deviceOut) + local iap2Connection = tcp.Connection(deviceID, devicePort) + local fileConnection = file_connection.FileConnection(deviceOut, iap2Connection) + local iap2Device = mobile.MobileConnection(fileConnection) + + event_dispatcher:AddConnection(iap2Device) + + return iap2Device +end + +--[[ Test ]] +commonFunctions:newTestCasesGroup("Test") + +local iap2bt_device = 0 + +Test["Connecting iAP2 Bluetooth"] = + function(self) + -- iAP2 Bluetooth connection with application registered + iap2bt_device = createIAP2Device(iAP2_BT_DeviceID, iAP2_BT_Port, iAP2_BT_out) + + EXPECT_HMICALL( + "BasicCommunication.UpdateDeviceList", + { + deviceList = {{id = config.deviceMAC, name = iAP2_BT_DeviceID, transportType = iAP2_BT_Type}} + } + ):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ) + + Test:connectMobile(iap2bt_device) + + local iap2bt_mobileSession = mobile_session.MobileSession(self, iap2bt_device, app_RAI_params) + + Test:startSession(iap2bt_mobileSession) +end + +Test["Connecting iAP2 USB"] = + function(self) + -- iAP2 USB connection with same application + local iap2usb_device = createIAP2Device(iAP2_USB_DeviceID, iAP2_USB_Port, iAP2_USB_out) + + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered"):Times(0) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Times(0) + + EXPECT_HMICALL( + "BasicCommunication.UpdateDeviceList", + { + -- To check why two devices are in list, maybe an issue + deviceList = { + {id = config.deviceMAC, name = iAP2_BT_DeviceID, transportType = iAP2_BT_Type}, + {id = config.deviceMAC, name = iAP2_USB_DeviceID, transportType = iAP2_USB_Type} + } + } + ):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + + -- Disconnect Bluetooth connection + iap2bt_device:Close() + end + ) + + Test:connectMobile(iap2usb_device) + + local iap2usb_mobileSession = mobile_session.MobileSession(self, iap2usb_device, app_RAI_params) + + local rpc_service_id = 7 + iap2usb_mobileSession:StartService(rpc_service_id):Do( + function() + local correlationId = iap2usb_mobileSession:SendRPC("RegisterAppInterface", app_RAI_params) + iap2usb_mobileSession:ExpectResponse(correlationId, {success = true, resultCode = "SUCCESS"}) + end + ) +end + +-- [[ Postconditions ]] +commonFunctions:newTestCasesGroup("Postcondition") +function Test.Stop_SDL() + StopSDL() +end + +return Test diff --git a/user_modules/connecttest_iap2_emulation.lua b/user_modules/connecttest_iap2_emulation.lua new file mode 100644 index 0000000000..4e1bc1488c --- /dev/null +++ b/user_modules/connecttest_iap2_emulation.lua @@ -0,0 +1,939 @@ +---- Provides high level interface for test script creation and base precondition snippets +-- +-- +-- *Dependencies:* `atf.util`, `testbase`, `mobile_connection`, `tcp_connection`, `file_connection`, +-- `mobile_session`, `websocket_connection`, `hmi_connection`, `events`, `expectations`, `function_id`, +-- `SDL`, `exit_codes`, `load_schema` +-- +-- *Globals:* `config`, `event_dispatcher`, `xmlReporter`, `table2str`, `func_name_str`, `compareValues`, `qt`, `timers` +-- `event_str`, `critical()`, `errmsg`, `quit()`, `AnyNumber()`, `enableFullLoggintTestCase()`, `disableFullLoggintTestCase()` +-- @module connecttest +-- @copyright [Ford Motor Company](https://smartdevicelink.com/partners/ford/) and [SmartDeviceLink Consortium](https://smartdevicelink.com/consortium/) +-- @license + +require("atf.util") +local Test = require("testbase") +local SDL = require("SDL") + +local websocket = require("websocket_connection") +local hmi_connection = require("hmi_connection") + +local functionId = require("function_id") +local exit_codes = require("exit_codes") +local load_schema = require("load_schema") +local mob_schema = load_schema.mob_schema +local hmi_schema = load_schema.hmi_schema + +local events = require("events") +local Event = events.Event + +local expectations = require("expectations") +local Expectation = expectations.Expectation +local SUCCESS = expectations.SUCCESS +local FAILED = expectations.FAILED + +--- Type Test extends Test from testbase module +-- @type Test + +--- HMI connection +Test.hmiConnection = hmi_connection.Connection(websocket.WebSocketConnection(config.hmiUrl, config.hmiPort)) +event_dispatcher:AddConnection(Test.hmiConnection) + +--- Notification counter +Test.notification_counter = 1 +--- Tist of timers for specific test +Test.timers = {} + +-- ========================================================================= +-- ========================================================================= +-- ========================= AUTO-RUN TEST BASE EXTENTIONS ================= +-- ========================================================================= +-- ========================================================================= + +--- Add test step with start SDL +function Test:RunSDL() + self:runSDL() +end + +--- Add critical test step with initialize +-- HMI with base checks +function Test:InitHMI() + critical(true) + self:initHMI() +end + +--- Add critical test step with performing of onReady communications with base checks +function Test:InitHMI_onReady() + critical(true) + self:initHMI_onReady() +end + +-- ========================================================================= +-- ========================================================================= +-- ========================= TEST BASE EXTENTIONS ========================== +-- ========================================================================= +-- ========================================================================= + +--- Start SDL +function Test:runSDL() + if config.autorunSDL ~= true then + SDL.autoStarted = false + return + end + local result, errmsg = SDL:StartSDL(config.pathToSDL, config.SDL, config.ExitOnCrash) + if not result then + quit(exit_codes.aborted) + end + SDL.autoStarted = true +end + +--- Initialize HMI with base checks +function Test:initHMI() + local function registerComponent(name, subscriptions) + local rid = Test.hmiConnection:SendRequest("MB.registerComponent", {componentName = name}) + local exp = EXPECT_HMIRESPONSE(rid) + if subscriptions then + for _, s in ipairs(subscriptions) do + exp:Do( + function() + local rid = Test.hmiConnection:SendRequest("MB.subscribeTo", {propertyName = s}) + EXPECT_HMIRESPONSE(rid) + end + ) + end + end + end + + EXPECT_HMIEVENT(events.connectedEvent, "Connected websocket"):Do( + function() + registerComponent("Buttons", {"Buttons.OnButtonSubscription"}) + registerComponent("TTS") + registerComponent("VR") + registerComponent( + "BasicCommunication", + { + "BasicCommunication.OnPutFile", + "SDL.OnStatusUpdate", + "SDL.OnAppPermissionChanged", + "BasicCommunication.OnSDLPersistenceComplete", + "BasicCommunication.OnFileRemoved", + "BasicCommunication.OnAppRegistered", + "BasicCommunication.OnAppUnregistered", + "BasicCommunication.PlayTone", + "BasicCommunication.OnSDLClose", + "SDL.OnSDLConsentNeeded", + "BasicCommunication.OnResumeAudioSource" + } + ) + registerComponent( + "UI", + { + "UI.OnRecordStart" + } + ) + registerComponent("VehicleInfo") + registerComponent( + "Navigation", + { + "Navigation.OnAudioDataStreaming", + "Navigation.OnVideoDataStreaming" + } + ) + end + ) + self.hmiConnection:Connect() +end + +--- Perform onReady communications with base checks +function Test:initHMI_onReady() + local function ExpectRequest(name, mandatory, params) + local event = events.Event() + event.level = 2 + event.matches = function(self, data) + return data.method == name + end + return EXPECT_HMIEVENT(event, name):Times(mandatory and 1 or AnyNumber()):Do( + function(_, data) + xmlReporter.AddMessage( + "hmi_connection", + "SendResponse", + { + ["methodName"] = tostring(name), + ["mandatory"] = mandatory, + ["params"] = params + } + ) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", params) + end + ) + end + + local function ExpectNotification(name, mandatory) + xmlReporter.AddMessage(debug.getinfo(1, "n").name, tostring(name)) + local event = events.Event() + event.level = 2 + event.matches = function(self, data) + return data.method == name + end + return EXPECT_HMIEVENT(event, name):Times(mandatory and 1 or AnyNumber()) + end + + ExpectRequest("BasicCommunication.MixingAudioSupported", true, {attenuatedSupported = true}) + ExpectRequest( + "BasicCommunication.GetSystemInfo", + false, + { + ccpu_version = "ccpu_version", + language = "EN-US", + wersCountryCode = "wersCountryCode" + } + ) + ExpectRequest("UI.GetLanguage", true, {language = "EN-US"}) + ExpectRequest("VR.GetLanguage", true, {language = "EN-US"}) + ExpectRequest("TTS.GetLanguage", true, {language = "EN-US"}) + ExpectRequest("UI.ChangeRegistration", false, {}):Pin() + ExpectRequest("TTS.SetGlobalProperties", false, {}):Pin() + ExpectRequest("BasicCommunication.UpdateDeviceList", false, {}):Pin() + ExpectRequest("VR.ChangeRegistration", false, {}):Pin() + ExpectRequest("TTS.ChangeRegistration", false, {}):Pin() + ExpectRequest( + "VR.GetSupportedLanguages", + true, + { + languages = { + "EN-US", + "ES-MX", + "FR-CA", + "DE-DE", + "ES-ES", + "EN-GB", + "RU-RU", + "TR-TR", + "PL-PL", + "FR-FR", + "IT-IT", + "SV-SE", + "PT-PT", + "NL-NL", + "ZH-TW", + "JA-JP", + "AR-SA", + "KO-KR", + "PT-BR", + "CS-CZ", + "DA-DK", + "NO-NO", + "NL-BE", + "EL-GR", + "HU-HU", + "FI-FI", + "SK-SK" + } + } + ) + ExpectRequest( + "TTS.GetSupportedLanguages", + true, + { + languages = { + "EN-US", + "ES-MX", + "FR-CA", + "DE-DE", + "ES-ES", + "EN-GB", + "RU-RU", + "TR-TR", + "PL-PL", + "FR-FR", + "IT-IT", + "SV-SE", + "PT-PT", + "NL-NL", + "ZH-TW", + "JA-JP", + "AR-SA", + "KO-KR", + "PT-BR", + "CS-CZ", + "DA-DK", + "NO-NO", + "NL-BE", + "EL-GR", + "HU-HU", + "FI-FI", + "SK-SK" + } + } + ) + ExpectRequest( + "UI.GetSupportedLanguages", + true, + { + languages = { + "EN-US", + "ES-MX", + "FR-CA", + "DE-DE", + "ES-ES", + "EN-GB", + "RU-RU", + "TR-TR", + "PL-PL", + "FR-FR", + "IT-IT", + "SV-SE", + "PT-PT", + "NL-NL", + "ZH-TW", + "JA-JP", + "AR-SA", + "KO-KR", + "PT-BR", + "CS-CZ", + "DA-DK", + "NO-NO", + "NL-BE", + "EL-GR", + "HU-HU", + "FI-FI", + "SK-SK" + } + } + ) + ExpectRequest( + "VehicleInfo.GetVehicleType", + true, + { + vehicleType = { + make = "Ford", + model = "Fiesta", + modelYear = "2013", + trim = "SE" + } + } + ) + ExpectRequest("VehicleInfo.GetVehicleData", true, {vin = "52-452-52-752"}) + + local function button_capability(name, shortPressAvailable, longPressAvailable, upDownAvailable) + return { + name = name, + shortPressAvailable = shortPressAvailable == nil and true or shortPressAvailable, + longPressAvailable = longPressAvailable == nil and true or longPressAvailable, + upDownAvailable = upDownAvailable == nil and true or upDownAvailable + } + end + + local buttons_capabilities = { + capabilities = { + button_capability("PRESET_0"), + button_capability("PRESET_1"), + button_capability("PRESET_2"), + button_capability("PRESET_3"), + button_capability("PRESET_4"), + button_capability("PRESET_5"), + button_capability("PRESET_6"), + button_capability("PRESET_7"), + button_capability("PRESET_8"), + button_capability("PRESET_9"), + button_capability("OK", true, false, true), + button_capability("SEEKLEFT"), + button_capability("SEEKRIGHT"), + button_capability("TUNEUP"), + button_capability("TUNEDOWN") + }, + presetBankCapabilities = {onScreenPresetsAvailable = true} + } + ExpectRequest("Buttons.GetCapabilities", true, buttons_capabilities) + ExpectRequest("VR.GetCapabilities", true, {vrCapabilities = {"TEXT"}}) + ExpectRequest( + "TTS.GetCapabilities", + true, + { + speechCapabilities = {"TEXT", "PRE_RECORDED"}, + prerecordedSpeechCapabilities = { + "HELP_JINGLE", + "INITIAL_JINGLE", + "LISTEN_JINGLE", + "POSITIVE_JINGLE", + "NEGATIVE_JINGLE" + } + } + ) + + local function text_field(name, characterSet, width, rows) + return { + name = name, + characterSet = characterSet or "TYPE2SET", + width = width or 500, + rows = rows or 1 + } + end + local function image_field(name, width, height) + return { + name = name, + imageTypeSupported = { + "GRAPHIC_BMP", + "GRAPHIC_JPEG", + "GRAPHIC_PNG" + }, + imageResolution = { + resolutionWidth = width or 64, + resolutionHeight = height or 64 + } + } + end + + ExpectRequest( + "UI.GetCapabilities", + true, + { + displayCapabilities = { + displayType = "GEN2_8_DMA", + textFields = { + text_field("mainField1"), + text_field("mainField2"), + text_field("mainField3"), + text_field("mainField4"), + text_field("statusBar"), + text_field("mediaClock"), + text_field("mediaTrack"), + text_field("alertText1"), + text_field("alertText2"), + text_field("alertText3"), + text_field("scrollableMessageBody"), + text_field("initialInteractionText"), + text_field("navigationText1"), + text_field("navigationText2"), + text_field("ETA"), + text_field("totalDistance"), + text_field("navigationText"), + text_field("audioPassThruDisplayText1"), + text_field("audioPassThruDisplayText2"), + text_field("sliderHeader"), + text_field("sliderFooter"), + text_field("notificationText"), + text_field("menuName"), + text_field("secondaryText"), + text_field("tertiaryText"), + text_field("timeToDestination"), + text_field("turnText"), + text_field("menuTitle"), + text_field("locationName"), + text_field("locationDescription"), + text_field("addressLines"), + text_field("phoneNumber") + }, + imageFields = { + image_field("softButtonImage"), + image_field("choiceImage"), + image_field("choiceSecondaryImage"), + image_field("vrHelpItem"), + image_field("turnIcon"), + image_field("menuIcon"), + image_field("cmdIcon"), + image_field("showConstantTBTIcon"), + image_field("locationImage") + }, + mediaClockFormats = { + "CLOCK1", + "CLOCK2", + "CLOCK3", + "CLOCKTEXT1", + "CLOCKTEXT2", + "CLOCKTEXT3", + "CLOCKTEXT4" + }, + graphicSupported = true, + imageCapabilities = {"DYNAMIC", "STATIC"}, + templatesAvailable = {"TEMPLATE"}, + screenParams = { + resolution = {resolutionWidth = 800, resolutionHeight = 480}, + touchEventAvailable = { + pressAvailable = true, + multiTouchAvailable = true, + doublePressAvailable = false + } + }, + numCustomPresetsAvailable = 10 + }, + audioPassThruCapabilities = { + samplingRate = "44KHZ", + bitsPerSample = "8_BIT", + audioType = "PCM" + }, + hmiZoneCapabilities = "FRONT", + softButtonCapabilities = { + { + shortPressAvailable = true, + longPressAvailable = true, + upDownAvailable = true, + imageSupported = true + } + }, + systemCapabilities = { + navigationCapability = { + sendLocationEnabled = true, + getWayPointsEnabled = true + }, + phoneCapability = { + dialNumberEnabled = true + } + } + } + ) + + ExpectRequest("VR.IsReady", true, {available = true}) + ExpectRequest("TTS.IsReady", true, {available = true}) + ExpectRequest("UI.IsReady", true, {available = true}) + ExpectRequest("Navigation.IsReady", true, {available = true}) + ExpectRequest("VehicleInfo.IsReady", true, {available = true}) + + self.applications = {} + ExpectRequest("BasicCommunication.UpdateAppList", false, {}):Pin():Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + self.applications = {} + for _, app in pairs(data.params.applications) do + self.applications[app.appName] = app.appID + end + end + ) + + self.hmiConnection:SendNotification("BasicCommunication.OnReady") +end + +--- Open default mobile conection and add mobile disconnect expectation +function Test:connectMobile(device, exitOnDisconnect) + -- Disconnected expectation + EXPECT_EVENT(events.disconnectedEvent, "Disconnected", device):Pin():Times(AnyNumber()):Do( + function() + print("Device disconnected: " .. device.connection.filename) + if exitOnDisconnect then + quit(exit_codes.aborted) + end + end + ) + device:Connect() + return EXPECT_EVENT(events.connectedEvent, "Connected", device) +end + +--- Start default mobile session on default mobile conection +function Test:startSession(session) + session:Start() + EXPECT_HMICALL("BasicCommunication.UpdateAppList"):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + self.applications = {} + for _, app in pairs(data.params.applications) do + self.applications[app.appName] = app.appID + end + end + ) +end + +-- ========================================================================= +-- ========================================================================= +-- ========================= GLOBAL DEFINITIONS ============================ +-- ========================================================================= +-- ========================================================================= + +function Test.hmiConnection:EXPECT_HMIRESPONSE(id, args) + local event = events.Event() + event.matches = function(self, data) + return data.id == id + end + local ret = Expectation("HMI response " .. id, self) + ret:ValidIf( + function(self, data) + local arguments + if self.occurences > #args then + arguments = args[#args] + else + arguments = args[self.occurences] + end + + xmlReporter.AddMessage( + "EXPECT_HMIRESPONSE", + {["Id"] = tostring(id), ["Type"] = "EXPECTED_RESULT"}, + arguments + ) + xmlReporter.AddMessage("EXPECT_HMIRESPONSE", {["Id"] = tostring(id), ["Type"] = "AVALIABLE_RESULT"}, data) + local func_name = data.method + local results_args = arguments + local results_args2 = arguments + if (table2str(arguments):match("result")) then + results_args = arguments.result + results_args2 = arguments.result + elseif (table2str(arguments):match("error")) then + results_args = arguments.error + results_args2 = arguments.error + end + + if results_args2 then + if results_args2.code then + results_args2 = table.removeKey(results_args2, "code") + end + if results_args2.method then + results_args2 = table.removeKey(results_args2, "method") + elseif results_args2.data and results_args2.data.method then + results_args2 = table.removeKey(results_args2.data, "method") + end + end + + if func_name == nil and type(data.result) == "table" then + func_name = data.result.method + elseif func_name == nil and type(data.error) == "table" then + func_name = data.error.data.method + end + + local _res, _err + _res = true + if not (table2str(arguments):match("error")) then + _res, _err = hmi_schema:Validate(func_name, load_schema.response, data.params) + end + if (not _res) then + return _res, _err + end + + if func_name and results_args and data.result then + return compareValues(results_args, data.result, "result") + elseif func_name and results_args and data.error then + return compareValues(results_args, data.error, "error") + else + return compareValues(results_args, data.params, "params") + end + end + ) + ret.event = event + event_dispatcher:AddEvent(Test.hmiConnection, event, ret) + Test:AddExpectation(ret) + return ret +end + +--- Global functions +-- @section Global + +--- Create expectation for specific HMI resonse and add it to expectation list +-- @tparam number id Correlation identifier +-- @tparam table ... Expectation parameters +-- @treturn Expectation Expectation +function EXPECT_HMIRESPONSE(id, ...) + local args = table.pack(...) + return Test.hmiConnection:EXPECT_HMIRESPONSE(id, args) +end + +--- Create expectation for specific HMI notification and add it to expectation list +-- @tparam string name Notification name +-- @tparam table ... Expectation parameters +-- @treturn Expectation Expectation +function EXPECT_HMINOTIFICATION(name, ...) + local args = table.pack(...) + local event = events.Event() + event.matches = function(self, data) + return data.method == name + end + local ret = Expectation("HMI notification " .. name, Test.hmiConnection) + if #args > 0 then + ret:ValidIf( + function(self, data) + local arguments + if self.occurences > #args then + arguments = args[#args] + else + arguments = args[self.occurences] + end + local correlation_id = Test.notification_counter + Test.notification_counter = Test.notification_counter + 1 + xmlReporter.AddMessage( + "EXPECT_HMINOTIFICATION", + {["Id"] = correlation_id, ["name"] = tostring(name), ["Type"] = "EXPECTED_RESULT"}, + arguments + ) + xmlReporter.AddMessage( + "EXPECT_HMINOTIFICATION", + {["Id"] = correlation_id, ["name"] = tostring(name), ["Type"] = "AVALIABLE_RESULT"}, + data + ) + local _res, _err = hmi_schema:Validate(name, load_schema.notification, data.params) + if (not _res) then + return _res, _err + end + return compareValues(arguments, data.params, "params") + end + ) + end + ret.event = event + event_dispatcher:AddEvent(Test.hmiConnection, event, ret) + Test:AddExpectation(ret) + return ret +end + +--- Create expectation for specific HMI call and add it to expectation list +-- @tparam string methodName Method name +-- @tparam table ... Expectation parameters +-- @treturn Expectation Expectation +function EXPECT_HMICALL(methodName, ...) + local args = table.pack(...) + -- TODO: Avoid copy-paste + local event = events.Event() + event.matches = function(self, data) + return data.method == methodName + end + local ret = Expectation("HMI call " .. methodName, Test.hmiConnection) + if #args > 0 then + ret:ValidIf( + function(self, data) + local arguments + if self.occurences > #args then + arguments = args[#args] + else + arguments = args[self.occurences] + end + xmlReporter.AddMessage( + "EXPECT_HMICALL", + {["Id"] = data.id, ["name"] = tostring(methodName), ["Type"] = "EXPECTED_RESULT"}, + arguments + ) + xmlReporter.AddMessage( + "EXPECT_HMICALL", + {["Id"] = data.id, ["name"] = tostring(methodName), ["Type"] = "AVALIABLE_RESULT"}, + data.params + ) + _res, _err = hmi_schema:Validate(methodName, load_schema.request, data.params) + if (not _res) then + return _res, _err + end + return compareValues(arguments, data.params, "params") + end + ) + end + ret.event = event + event_dispatcher:AddEvent(Test.hmiConnection, event, ret) + Test:AddExpectation(ret) + return ret +end + +--- Create expectation for specific mobile notification from default session and add it to expectation list +-- @tparam string func Notification name +-- @tparam table ... Expectation parameters +-- @treturn Expectation Expectation +function EXPECT_NOTIFICATION(func, session, ...) + -- xmlReporter.AddMessage(debug.getinfo(1, "n").name, "EXPECTED_RESULT", ... ) + local args = table.pack(...) + local args_count = 1 + if #args > 0 then + local arguments = {} + if #args > 1 then + for args_count = 1, #args do + if (type(args[args_count])) == "table" then + table.insert(arguments, args[args_count]) + end + end + else + arguments = args + end + return session:ExpectNotification(func, arguments) + end + return session:ExpectNotification(func, args) +end + +--- Create expectation for specific mobile notification from any session and add it to expectation list +-- @tparam string funcName Notification name +-- @tparam table ... Expectation parameters +-- @treturn Expectation Expectation +function EXPECT_ANY_SESSION_NOTIFICATION(funcName, device, ...) + local args = table.pack(...) + local event = events.Event() + event.matches = function(_, data) + return data.rpcFunctionId == functionId[funcName] + end + local ret = Expectation(funcName .. " notification", device) + if #args > 0 then + ret:ValidIf( + function(self, data) + local arguments + if self.occurences > #args then + arguments = args[#args] + else + arguments = args[self.occurences] + end + local _res, _err = mob_schema:Validate(funcName, load_schema.notification, data.payload) + xmlReporter.AddMessage( + "EXPECT_ANY_SESSION_NOTIFICATION", + {["name"] = tostring(funcName), ["Type"] = "EXPECTED_RESULT"}, + arguments + ) + xmlReporter.AddMessage( + "EXPECT_ANY_SESSION_NOTIFICATION", + {["name"] = tostring(funcName), ["Type"] = "AVALIABLE_RESULT"}, + data.payload + ) + if (not _res) then + return _res, _err + end + return compareValues(arguments, data.payload, "payload") + end + ) + end + ret.event = event + event_dispatcher:AddEvent(device, event, ret) + Test.expectations_list:Add(ret) + return ret +end + +--- Run function after specified delay +-- @tparam function func Function to run +-- @tparam number timeout Delay in msec +-- @tparam ?string funcName function name +function RUN_AFTER(func, timeout, funcName) + func_name_str = "noname" + if funcName then + func_name_str = funcName + end + -- xmlReporter.AddMessage(debug.getinfo(1, "n").name, func_name_str, + -- {["functionLine"] = debug.getinfo(func, "S").linedefined, ["Timeout"] = tostring(timeout)}) + local d = qt.dynamic() + d.timeout = function(self) + func() + Test.timers[self] = nil + end + local timer = timers.Timer() + Test.timers[timer] = true + qt.connect(timer, "timeout()", d, "timeout()") + timer:setSingleShot(true) + timer:start(timeout) +end + +--- Create expectation for specific mobile response from default session and add it to expectation list +-- @tparam number correlationId Correlation identifier +-- @tparam table ... Expectation parameters +-- @treturn Expectation Expectation +function EXPECT_RESPONSE(correlationId, session, ...) + xmlReporter.AddMessage(debug.getinfo(1, "n").name, "EXPECTED_RESULT", ...) + return session:ExpectResponse(correlationId, ...) +end + +--- Create expectation for specific mobile response from any session and add it to expectation list +-- @tparam number correlationId Correlation identifier +-- @tparam table ... Expectation parameters +-- @treturn Expectation Expectation +function EXPECT_ANY_SESSION_RESPONSE(correlationId, device, ...) + xmlReporter.AddMessage(debug.getinfo(1, "n").name, {["CorrelationId"] = tostring(correlationId)}) + local args = table.pack(...) + local event = events.Event() + event.matches = function(_, data) + return data.rpcCorrelationId == correlationId + end + local ret = Expectation("response to " .. correlationId, device) + if #args > 0 then + ret:ValidIf( + function(self, data) + local arguments + if self.occurences > #args then + arguments = args[#args] + else + arguments = args[self.occurences] + end + xmlReporter.AddMessage("EXPECT_ANY_SESSION_RESPONSE", "EXPECTED_RESULT", arguments) + xmlReporter.AddMessage("EXPECT_ANY_SESSION_RESPONSE", "AVALIABLE_RESULT", data.payload) + return compareValues(arguments, data.payload, "payload") + end + ) + end + ret.event = event + event_dispatcher:AddEvent(device, event, ret) + Test.expectations_list:Add(ret) + return ret +end + +--- Create expectation for any mobile event and add it to expectation list +-- @treturn Expectation Expectation +function EXPECT_ANY(session) + xmlReporter.AddMessage(debug.getinfo(1, "n").name, "") + return session:ExpectAny() +end + +--- Create expectation for specific mobile event and add it to expectation list +-- @tparam Event event Event for expectation +-- @tparam string name Event name +-- @treturn Expectation Expectation +function EXPECT_EVENT(event, name, device) + local ret = Expectation(name, device) + ret.event = event + event_dispatcher:AddEvent(device, event, ret) + Test:AddExpectation(ret) + return ret +end + +--- Raise specific event +-- @tparam Event event Event +-- @tparam table data Data for rise event +-- @tparam ?string eventName Event name +function RAISE_EVENT(event, data, eventName, device) + event_str = "noname" + if eventName then + event_str = eventName + end + xmlReporter.AddMessage(debug.getinfo(1, "n").name, event_str) + event_dispatcher:RaiseEvent(device, data) +end + +--- Create expectation for specific HMI event and add it to expectation list +-- @tparam Event event Event for expectation +-- @tparam string name Event name +-- @treturn Expectation Expectation +function EXPECT_HMIEVENT(event, name) + xmlReporter.AddMessage(debug.getinfo(1, "n").name, name) + local ret = Expectation(name, Test.hmiConnection) + ret.event = event + event_dispatcher:AddEvent(Test.hmiConnection, event, ret) + Test:AddExpectation(ret) + return ret +end + +--- Start SDL +-- @tparam string SDLPathName Path to SDL +-- @tparam boolean ExitOnCrash Flag whether Stop ATF in case SDL shutdown +-- @treturn boolean The main result. Indicates whether the launch of SDL was successful +-- @treturn string Additional information on the main SDL startup result +function StartSDL(SDLPathName, ExitOnCrash) + return SDL:StartSDL(SDLPathName, config.SDL, ExitOnCrash) +end + +--- Stop SDL +-- @treturn nil The main result. Always nil. +-- @treturn string Additional information on the main result of stopping SDL +function StopSDL() + event_dispatcher:ClearEvents() + Test.expectations_list:Clear() + return SDL:StopSDL() +end + +--- Create test step for enable full ATF logs +function enableFullATFLogs() + function enableFullLoggintTestCase() + if (config.storeFullATFLogs) then + Test:FailTestCase("full ATF logs already enabled") + else + config.storeFullATFLogs = true + end + end + Test["EnableFullATFLogs"] = nil + Test["EnableFullATFLogs"] = enableFullLoggintTestCase +end + +--- Create test step for disable full ATF logs +function disableFullATFLogs() + function disableFullLoggintTestCase() + if (not config.storeFullATFLogs) then + Test:FailTestCase("full ATF logs already disabled") + else + config.storeFullATFLogs = false + end + end + Test["DisableFullATFLogs"] = nil + Test["DisableFullATFLogs"] = disableFullLoggintTestCase +end + +return Test From 5fe4acd299e773e1019449aa15fc8f1951e23050 Mon Sep 17 00:00:00 2001 From: "Andrey Oleynik (GitHub)" Date: Mon, 13 Nov 2017 16:01:47 +0200 Subject: [PATCH 287/681] Adds case for wrong hashID in RAI during transport switching Also adds preloaded policy table with all RPCs allowed --- files/jsons/sdl_preloaded_pt_all_allowed.json | 1747 +++++++++++++++++ ...sport_switch_resume_failed_simple_case.lua | 188 ++ user_modules/connecttest_iap2_emulation.lua | 5 + 3 files changed, 1940 insertions(+) create mode 100644 files/jsons/sdl_preloaded_pt_all_allowed.json create mode 100644 test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua diff --git a/files/jsons/sdl_preloaded_pt_all_allowed.json b/files/jsons/sdl_preloaded_pt_all_allowed.json new file mode 100644 index 0000000000..74a40c99b5 --- /dev/null +++ b/files/jsons/sdl_preloaded_pt_all_allowed.json @@ -0,0 +1,1747 @@ +{ + "policy_table": { + "module_config": { + "preloaded_pt": true, + "exchange_after_x_ignition_cycles": 100, + "exchange_after_x_kilometers": 1800, + "exchange_after_x_days": 30, + "timeout_after_x_seconds": 60, + "seconds_between_retries": [ + 1, + 5, + 25, + 125, + 625 + ], + "endpoints": { + "0x07": { + "default": [ + "http://policies.telematics.ford.com/api/policies" + ] + }, + "0x04": { + "default": [ + "http://ivsu.software.ford.com/api/getsoftwareupdates" + ] + }, + "queryAppsUrl": { + "default": [ + "http://sdl.shaid.server" + ] + }, + "lock_screen_icon_url": { + "default": [ + "http://i.imgur.com/QwZ9uKG.png" + ] + } + }, + "notifications_per_minute_by_priority": { + "EMERGENCY": 60, + "NAVIGATION": 15, + "VOICECOM": 20, + "COMMUNICATION": 6, + "NORMAL": 4, + "NONE": 0 + } + }, + "functional_groupings": { + "Base-4": { + "rpcs": { + "AddCommand": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "AddSubMenu": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "Alert": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "ChangeRegistration": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "CreateInteractionChoiceSet": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "DeleteCommand": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "DeleteFile": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "DeleteInteractionChoiceSet": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "DeleteSubMenu": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "EncodedSyncPData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "EndAudioPassThru": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "GenericResponse": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "ListFiles": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnAppInterfaceUnregistered": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnAudioPassThru": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "OnButtonEvent": { + "hmi_levels": [ + "NONE", + "FULL", + "LIMITED", + "BACKGROUND" + ] + }, + "OnButtonPress": { + "hmi_levels": [ + "NONE", + "FULL", + "LIMITED", + "BACKGROUND" + ] + }, + "OnCommand": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "OnDriverDistraction": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "OnEncodedSyncPData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnHashChange": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnHMIStatus": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnLanguageChange": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnPermissionsChange": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnSystemRequest": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "PerformAudioPassThru": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "PerformInteraction": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "PutFile": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "RegisterAppInterface": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "ResetGlobalProperties": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "ScrollableMessage": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "LIMITED", + "FULL" + ] + }, + "SetAppIcon": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "SetDisplayLayout": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "SetGlobalProperties": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "SetMediaClockTimer": { + "hmi_levels": [ + "NONE", + "FULL", + "LIMITED", + "BACKGROUND" + ] + }, + "Show": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "Slider": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "LIMITED", + "FULL" + ] + }, + "Speak": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "SubscribeButton": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "SystemRequest": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "UnregisterAppInterface": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "UnsubscribeButton": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + } + } + }, + "DataConsent-2": { + "user_consent_prompt": "DataConsent", + "rpcs": null + } + }, + "consumer_friendly_messages": { + "version": "001.001.021", + "messages": { + "AppPermissions": { + "languages": { + "de-de": { + "tts": "%appName% benötigt die folgenden Fahrzeuginformationen und Zugriffsberechtigungen: %functionalGroupLabels%. Wenn Sie Ja drücken, erklären Sie sich damit einverstanden, dass %vehicleMake% nicht für Schäden oder Verletzungen der Privatsphäre haftet, die im Zusammenhang mit der Nutzung Ihrer Benutzerdaten durch %appName% entstehen. Mit Ja stimmen Sie zu; mit Nein lehnen Sie ab.", + "line1": "Zugriffsanfrage(n)", + "line2": "erlauben?" + }, + "en-au": { + "tts": "%appName% is requesting the use of the following vehicle information and permissions: %functionalGroupLabels%. If you press Yes, you agree that %vehicleMake% will not be liable for any damages or loss of privacy related to %appName%'s use of your data. Please press Yes to allow or No to deny.", + "line1": "Grant requested", + "line2": "permission(s)?" + }, + "en-gb": { + "tts": "%appName% is requesting the use of the following vehicle information and permissions: %functionalGroupLabels%. If you press Yes, you agree that %vehicleMake% will not be liable for any damages or loss of privacy related to %appName%`s use of your data. Please press Yes to allow or No to deny.", + "line1": "Grant requested", + "line2": "permission(s)?", + "textBody": "%appName% is requesting the use of the following vehicle information and permissions: %functionalGroupLabels%. If you press yes, you agree that %vehicleMake% will not be liable for any damages or loss of privacy related to %appName%`s use of your data. You can change these permissions and hear detailed descriptions in the mobile apps settings menu." + }, + "en-ie": { + "tts": "%appName% is requesting the use of the following vehicle information and permissions: %functionalGroupLabels%. If you press Yes, you agree that %vehicleMake% will not be liable for any damages or loss of privacy related to %appName%'s use of your data. Please press Yes to allow or No to deny.", + "line1": "Grant requested", + "line2": "permission(s)?" + }, + "en-us": { + "tts": "%appName% is requesting the use of the following vehicle information and permissions: %functionalGroupLabels%. If you press yes, you agree that %vehicleMake% will not be liable for any damages or loss of privacy related to %appName%’s use of your data. Please press yes to allow or no to deny.", + "line1": "Grant Requested", + "line2": "Permission(s)?", + "textBody": "%appName% is requesting the use of the following vehicle information and permissions: %functionalGroupLabels%. \n\nIf you press yes, you agree that %vehicleMake% will not be liable for any damages or loss of privacy related to %appName%’s use of your data. You can change these permissions and hear detailed descriptions in the mobile apps settings menu." + }, + "es-en": { + "tts": "%appName% solicita el uso de la siguiente información y permisos del vehículo: %functionalGroupLabels%. Si presiona Sí, acepta que %vehicleMake% no se hará responsable por los daños o pérdidas de privacidad relacionados con el uso que %appName% haga de sus datos. Presione Sí para permitir y No para denegar.", + "line1": "¿Otorgar permiso(s)", + "line2": "solicitado(s)?", + "textBody": "%appName% solicita el uso de la siguiente información y permisos del vehículo: %functionalGroupLabels%. Si presiona Sí, acepta que %vehicleMake% no se hará responsable por los daños o pérdidas de privacidad relacionados con el uso que %appName% haga de sus datos. Presione Sí para permitir y No para denegar. \n\n Puede cambiar estos permisos y consultar descripciones detalladas en el menú de configuración de las aplicaciones móviles." + }, + "es-es": { + "tts": "%appName% está solicitando el uso de los siguientes permisos e información del vehículo: %functionalGroupLabels%. Si pulsa sí, acepta que %vehicleMake% no será responsable de los daños o la pérdida de privacidad relacionados con el uso de sus datos por parte de %appName%. Pulse sí para permitir o no para denegar.", + "line1": "¿Conceder permisos", + "line2": "solicitados?" + }, + "es-mx": { + "tts": "%appName% solicita el uso de la siguiente información y permisos del vehículo: %functionalGroupLabels%. Si presiona Sí, acepta que %vehicleMake% no se hará responsable por los daños o pérdidas de privacidad relacionados con el uso que %appName% haga de sus datos. Presione Sí para permitir y No para denegar.", + "line1": "¿Otorgar permiso(s)", + "line2": "solicitado(s)?", + "textBody": "%appName% solicita el uso de la siguiente información y permisos del vehículo: %functionalGroupLabels%. \n\nSi presiona Sí, acepta que %vehicleMake% no se hará responsable por los daños o pérdidas de privacidad relacionados con el uso que %appName% haga de sus datos. Presione Sí para permitir y No para denegar. Puede cambiar estos permisos y consultar descripciones detalladas en el menú de configuración de las aplicaciones móviles." + }, + "fr-ca": { + "tts": "%appName% demande d’utiliser les informations du véhicule et les permissions suivantes : %functionalGroupLabels%. Si vous appuyez sur Oui, vous acceptez que %vehicleMake% ne sera pas responsable des dommages ou des pertes de confidentialité reliées à l’utilisation de vos données par %appName%. Veuillez appuyer sur Oui pour autoriser ou sur Non pour refuser.", + "line1": "Accorder permission(s)", + "line2": "demandée(s)", + "textBody": "%appName% demande d’utiliser les informations du véhicule et les permissions suivantes : %functionalGroupLabels%. Si vous appuyez sur Oui, vous acceptez que %vehicleMake% ne sera pas responsable des dommages ou des pertes de confidentialité reliées à l’utilisation de vos données par %appName%. Vous pouvez modifier ces permissions et entendre les descriptions détaillées dans le menu des réglages des applications mobiles." + }, + "fr-fr": { + "tts": "%appName% demande d’utiliser les informations du véhicule et les permissions suivantes : %functionalGroupLabels%. Si vous appuyez sur Oui, vous acceptez que %vehicleMake% ne sera pas responsable des dommages ou des pertes de confidentialité reliées à l’utilisation de vos données par %appName%. Veuillez appuyer sur Oui pour autoriser ou sur Non pour refuser.", + "line1": "Accorder permission(s)", + "line2": "demandée(s)" + }, + "it-it": { + "tts": "%appName% richiede l'uso delle seguenti informazioni e autorizzazioni sul veicolo: %functionalGroupLabels%. Se si preme Sì, si acconsente che %vehicleMake% non sarà responsabile per danni o perdita di privacy in relazione all'impiego dei dati da parte di %appName%. Premere Sì per consentire e No per negare.", + "line1": "Concedi autorizzaz.", + "line2": "richiesta(e)?" + }, + "nl-nl": { + "tts": "%appName% vraagt gebruikmaking van de volgende voertuiginformatie en toestemmingen aan: %functionalGroupLabels%. Als u op Ja drukt, gaat u ermee akkoord dat %vehicleMake% in geen geval aansprakelijk gesteld kan worden voor schade of verlies van privacy als gevolg van het feit dat %appName% gebruik maakt van uw gegevens. Druk op Ja om dit toe te staan of Nee om te weigeren.", + "line1": "Aangevraagde", + "line2": "permissie(s) verlenen?" + }, + "pl-pl": { + "tts": "%appName% wymaga nastÄ™pujÄ…cych informacji o pojeździe oraz pozwoleÅ„: %functionalGroupLabels%. NaciÅ›niÄ™cie TAK oznacza zgodÄ™ na fakt, iż %vehicleMake% nie bÄ™dzie ponosić odpowiedzialnoÅ›ci za szkody ani utratÄ™ prywatnoÅ›ci w zwiÄ…zku z wykorzystaniem przez %appName% danych, należących do użytkownika. NaciÅ›nij TAK w celu udzielenia zgody lub NIE w celu odrzucenia żądania.", + "line1": "Udzielić żądanych", + "line2": "pozwoleÅ„?" + }, + "pt-br": { + "tts": "%appName% está solicitando o uso das seguintes informações e permissões do veículo: %functionalGroupLabels%. Se pressionar sim, você concorda que a %vehicleMake% não será responsável por danos ou perdas de privacidade relacionados ao uso dos seus dados por %appName%. Pressione sim para permitir ou não para negar.", + "line1": "Conceder permissão", + "line2": "solicitada?" + }, + "pt-pt": { + "tts": "%appName% está a solicitar a utilização das seguintes informações e permissões do veículo: %functionalGroupLabels%. Se premir “Simâ€, concorda que %vehicleMake% não será responsável por quaisquer danos ou perda de privacidade relacionada com a utilização dos seus dados por parte de %appName%. Prima “Sim†para permitir ou “Não†para recusar.", + "line1": "Conceder permiss.", + "line2": "solicitada(s)?" + }, + "ru-ru": { + "tts": "%appName% запрашивает Ñледующую информацию об автомобиле и разрешениÑ: %functionalGroupLabels%. Ðажатием \"\"да\"\", Ð’Ñ‹ ÑоглашаетеÑÑŒ, что %vehicleMake% не будет неÑти ответÑтвенноÑÑ‚ÑŒ за какие-либо убытки или потерю прайвеÑи, ÑвÑзанные Ñ Ð¸Ñпользованием Ваших данных компанией %appName%. Ðажмите \"\"Да\"\", еÑли Ð’Ñ‹ ÑоглаÑны, или \"\"Ðет\"\" - еÑли не ÑоглаÑны.", + "line1": "ПредоÑÑ‚. заправш.", + "line2": "разрешениÑ?" + }, + "sv-se": { + "tts": "%appName% begär att fÃ¥ tillgÃ¥ng till följande fordonsinformation och tillstÃ¥nd: %functionalGroupLabels%. Om du trycker Ja godkänner du att %vehicleMake% ska hÃ¥llas skadeslös för alla skador som kan uppstÃ¥ eller eventuella integritetsintrÃ¥ng som uppstÃ¥r när %appName% använder dina data. Tryck Ja för att godkänna eller Nej för att neka.", + "line1": "Vill du ge", + "line2": "tillstÃ¥nd?" + }, + "tr-tr": { + "tts": "%appName%, ÅŸu araç bilgilerini ve izinleri kullanma isteÄŸinde bulunuyor: %functionalGroupLabels%. Evet'e basarsanız, %appName%'in verilerinizi kullanması sonucunda oluÅŸabilecek hasarlardan veya gizlilik kaybından %vehicleMake%'in sorumlu olmayacağını kabul etmiÅŸ olacaksınız. Lütfen kabul etmek için Evet'e veya reddetmek için Hayır'a basın.", + "line1": "Ä°stenen izinler", + "line2": "verilsin mi?" + }, + "zh-cn": { + "tts": "%appName% 正在请求使用下列车辆信æ¯å’Œæƒé™ï¼š %functionalGroupLabels%。如果您按“是â€ï¼Œåˆ™è¡¨ç¤ºæ‚¨åŒæ„。 %vehicleMake% å°†ä¸ä¼šå¯¹å›  %appName% 使用您的数æ®è€Œå¼•èµ·çš„任何æŸæ¯æˆ–éšç§æŸå¤±è´Ÿè´£ã€‚ 请按“是â€å…许或按“å¦â€æ‹’ç»ã€‚", + "line1": "是å¦å…许请求的", + "line2": "æƒé™ï¼Ÿ" + }, + "zh-tw": { + "tts": "%appName% 正請求使用 %functionalGroupLabels% 的車輛資訊和許å¯ã€‚按「是ã€ï¼Œè¡¨ç¤ºæ‚¨åŒæ„,如因 %appName% 使用您的資料導致任何æ害或æ失,%vehicleMake% å°‡ä¸è² è³ å„Ÿè²¬ä»»ã€‚åŒæ„請按「是ã€ï¼Œæ‹’絕請按「å¦ã€ã€‚", + "line1": "å…許", + "line2": "授權請求?" + } + } + }, + "AppPermissionsHelp": { + "languages": { + "de-de": { + "tts": "%appName% fordert folgende Fahrzeuginformationen und Zugriffsberechtigungen: %functionalGroupLabels%. Im Einstellungsmenü der mobilen Apps können Sie diese Berechtigungen ändern und sich detaillierte Beschreibungen anhören. Mit Ja stimmen Sie zu; mit Nein lehnen Sie ab." + }, + "en-au": { + "tts": "%appName% is requesting the following vehicle information and permissions: %functionalGroupLabels%. You can change these permissions and hear detailed descriptions in the mobile apps settings menu. Please press Yes to grant permissions or No to deny." + }, + "en-gb": { + "tts": "%appName% is requesting the following vehicle information and permissions: %functionalGroupLabels%. You can change these permissions and hear detailed descriptions in the mobile apps settings menu. Please press Yes to grant permissions or No to deny." + }, + "en-ie": { + "tts": "%appName% is requesting the following vehicle information and permissions: %functionalGroupLabels%. You can change these permissions and hear detailed descriptions in the mobile apps settings menu. Please press Yes to grant permissions or No to deny." + }, + "en-us": { + "tts": "%appName% is requesting the following vehicle information and permissions: %functionalGroupLabels%. You can change these permissions and hear detailed descriptions in the mobile apps settings menu. Please press yes to grant permissions or no to deny." + }, + "es-en": { + "tts": "%appName% solicita la siguiente información y permisos del vehículo: %functionalGroupLabels%. Puede cambiar estos permisos y consultar descripciones detalladas en el menú de configuración de las aplicaciones móviles. Presione Sí para otorgar permisos y No para denegar." + }, + "es-es": { + "tts": "%appName% está solicitando los siguientes permisos e información del vehículo: %functionalGroupLabels%. Puede cambiar estos permisos y escuchar descripciones detalladas en el menú de configuración de la aplicación móvil. Pulse sí para conceder el permiso o no para denegarlo." + }, + "es-mx": { + "tts": "%appName% solicita la siguiente información y permisos del vehículo: %functionalGroupLabels%. Puede cambiar estos permisos y consultar descripciones detalladas en el menú de configuración de las aplicaciones móviles. Presione Sí para otorgar permisos y No para denegar." + }, + "fr-ca": { + "tts": "%appName% demande d’utiliser les informations du véhicule et les permissions suivantes : %functionalGroupLabels%. Vous pouvez modifier ces permissions et entendre les descriptions détaillées dans le menu des réglages des applications mobiles. Veuillez appuyer sur Oui pour accorder les permissions ou sur Non pour refuser." + }, + "fr-fr": { + "tts": "%appName% demande d’utiliser les informations du véhicule et les permissions suivantes : %functionalGroupLabels%. Vous pouvez modifier ces permissions et entendre les descriptions détaillées dans le menu des réglages des applications mobiles. Veuillez appuyer sur Oui pour accorder les permissions ou sur Non pour refuser." + }, + "it-it": { + "tts": "%appName% richiede le seguenti informazioni e autorizzazioni riguardo il veicolo: %functionalGroupLabels%. È possibile modificare tali autorizzazioni e ascoltare descrizioni dettagliate nel menu impostazioni delle app mobili. Premere Sì per concedere le autorizzazioni e No per negarle." + }, + "nl-nl": { + "tts": "%appName% vraagt gebruikmaking van de volgende voertuiginformatie en toestemmingen aan: %functionalGroupLabels%. U kunt deze toestemmingen wijzigen en gedetailleerde beschrijvingen beluisteren in het instellingenmenu voor mobiele apps. Druk op Ja om permissies te verlenen of op Nee om te weigeren." + }, + "pl-pl": { + "tts": "%appName% wymaga nastÄ™pujÄ…cych informacji o pojeździe oraz zezwoleÅ„: %functionalGroupLabels%. W menu ustawieÅ„ aplikacji mobilnych można zmienić owe zezwolenia i usÅ‚yszeć ich szczegółowy opis. NaciÅ›nij TAK, aby wyrazić zgodÄ™ lub NIE w celu odrzucenia żądania." + }, + "pt-br": { + "tts": "%appName% está solicitando as seguintes informações e permissões do veículo: %functionalGroupLabels%. Você pode alterar estas permissões e ouvir descrições detalhadas no menu de configurações de aplicativos móveis. Pressione sim para conceder as permissões ou não para negar." + }, + "pt-pt": { + "tts": "%appName% está a solicitar as seguintes informações e permissões do veículo: %functionalGroupLabels%. Pode alterar estas permissões e ouvir descrições detalhadas no menu de definições das aplicações móveis. Prima \"\"Sim\"\" para permitir ou \"\"Não\"\" para recusar." + }, + "ru-ru": { + "tts": "%appName% запрашивает Ñледующую информацию об автомобиле и разрешениÑ: %functionalGroupLabels%. Ð’Ñ‹ можете изменить Ñти Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¸ проÑлушать подробные их опиÑÐ°Ð½Ð¸Ñ Ð² меню наÑтроек мобильного приложениÑ. Ðажмите \"\"да\"\", чтобы предоÑтавить разрешениÑ, или \"\"нет\"\", чтобы не предоÑтавлÑÑ‚ÑŒ." + }, + "sv-se": { + "tts": "%appName% begär tillgÃ¥ng till följande fordonsinformation och tillstÃ¥nd: %functionalGroupLabels%. Du kan ändra tillstÃ¥nden och höra detaljerade beskrivningar i menyn för mobilappsinställningar. Tryck Ja för att ge tillstÃ¥nd eller Nej för att neka." + }, + "tr-tr": { + "tts": "%appName%, ÅŸu araç bilgilerini ve izinleri istiyor: %functionalGroupLabels%. Bu izinleri deÄŸiÅŸtirebilir ve mobil uygulamalar ayarlar menüsünden ayrıntılı açıklamaları dinleyebilirsiniz. Lütfen izin vermek için Evet'e veya reddetmek için Hayır'a basın." + }, + "zh-cn": { + "tts": "%appName% 正在请求下列车辆信æ¯å’Œæƒé™ï¼š %functionalGroupLabels%。您å¯åœ¨ç§»åŠ¨åº”用程åºè®¾ç½®èœå•ä¸­æ›´æ”¹è¿™äº›æƒé™ï¼Œå¹¶å¬å–详细说明。请按“是â€å…许æƒé™æˆ–按“å¦â€æ‹’ç»ã€‚" + }, + "zh-tw": { + "tts": "%appName% 正請求使用 %functionalGroupLabels% 的車輛資訊和許å¯ã€‚您å¯åœ¨è¡Œå‹•æ‡‰ç”¨ç¨‹å¼è¨­å®šæ¸…單中更改這些許å¯ï¼Œä¸¦è†è½è©³ç´°èªªæ˜Žã€‚給予許å¯è«‹æŒ‰ã€Œæ˜¯ã€ï¼Œæ‹’絕請按「å¦ã€ã€‚" + } + } + }, + "AppPermissionsRevoked": { + "languages": { + "de-de": { + "tts": "Die Autorisierungsdaten der App wurden geändert. %appName% hat keinen Zugriff auf %functionalGroupLabels% mehr. Installieren Sie die neueste Version der App auf Ihrem Gerät.." + }, + "en-au": { + "tts": "App authorizations have changed. %appName% can no longer access %functionalGroupLabels%. Please ensure you have the most recent app version installed on your mobile device." + }, + "en-gb": { + "tts": "App authorizations have changed. %appName% can no longer access %functionalGroupLabels%. Please ensure you have the most recent app version installed on your mobile device." + }, + "en-ie": { + "tts": "App authorizations have changed. %appName% can no longer access %functionalGroupLabels%. Please ensure you have the most recent app version installed on your mobile device." + }, + "en-us": { + "tts": "App authorizations have changed. %appName% can no longer access %functionalGroupLabels%. Please ensure you have the most recent app version installed on your mobile device." + }, + "es-en": { + "tts": "Las autorizaciones de la aplicación han cambiado. %appName% ya no puede acceder a %functionalGroupLabels%. Asegúrese de haber instalado la versión más reciente de la aplicación en su dispositivo móvil." + }, + "es-es": { + "tts": "Las autorizaciones de la aplicación han cambiado. %appName% ya no puede acceder a %functionalGroupLabels%. Asegúrese de que tiene la versión más reciente de la aplicación instalada en su dispositivo móvil." + }, + "es-mx": { + "tts": "Las autorizaciones de la aplicación han cambiado. %appName% ya no puede acceder a %functionalGroupLabels%. Asegúrese de haber instalado la versión más reciente de la aplicación en su dispositivo móvil." + }, + "fr-ca": { + "tts": "Les autorisations pour app ont changé. %appName% ne peut plus accéder à %functionalGroupLabels%. Veuillez vous assurer que la plus récente version de l’application est installée sur votre appareil mobile." + }, + "fr-fr": { + "tts": "Les autorisations pour app ont changé. %appName% ne peut plus accéder à %functionalGroupLabels%. Veuillez vous assurer que la plus récente version de l’application est installée sur votre appareil mobile." + }, + "it-it": { + "tts": "Le autorizzazioni dell'app sono cambiate. %appName% non è più in grado di accedere a %functionalGroupLabels%. Assicurarsi di avere la versione più recente dell'app installata sul dispositivo mobile." + }, + "nl-nl": { + "tts": "De app-autorisaties zijn gewijzigd. %appName% heeft geen toegang meer tot %functionalGroupLabels%. Zorg ervoor dat u de meest recente app-versie op uw mobiele apparaat geïnstalleerd hebt." + }, + "pl-pl": { + "tts": "Dane dostÄ™pu aplikacji zostaÅ‚y zmienione. %appName% nie ma już dostÄ™pu do %functionalGroupLabels%. Sprawdź, czy na telefonie komórkowym zainstalowano najnowszÄ… wersjÄ™ aplikacji." + }, + "pt-br": { + "tts": "As autorizações dos aplicativos foram alteradas. %appName% não pode mais acessar %functionalGroupLabels%. Certifique-se de que a versão mais recente do aplicativo está instalada no seu dispositivo móvel." + }, + "pt-pt": { + "tts": "As autorizações das aplicações mudaram. %appName% já não consegue aceder a %functionalGroupLabels%. Certifique-se de que tem a última versão da aplicação no seu dispositivo móvel." + }, + "ru-ru": { + "tts": "Ðвторизации Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ñ‹. %appName% больше не имеет доÑтупа к %functionalGroupLabels%. УбедитеÑÑŒ, что на вашем мобильном уÑтройÑтве уÑтановлена ÑÐ°Ð¼Ð°Ñ Ð½Ð¾Ð²Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ." + }, + "sv-se": { + "tts": "Appens behörigheter har ändrats. %appName% har inte längre Ã¥tkomst till %functionalGroupLabels%. Kontrollera att du har installerat den senaste versionen av appen pÃ¥ mobilenheten." + }, + "tr-tr": { + "tts": "Uygulama yetkileri deÄŸiÅŸti. %appName% artık %functionalGroupLabels%'e eriÅŸemeyecek. Lütfen mobil aygıtınızda en son uygulama sürümünün yüklü olduÄŸundan emin olun." + }, + "zh-cn": { + "tts": "应用程åºæŽˆæƒå·²å˜æ›´ã€‚ %appName% å°†ä¸èƒ½å†è®¿é—® %functionalGroupLabels%。 请确认您的移动设备上安装的应用程åºæ˜¯æœ€æ–°ç‰ˆæœ¬ã€‚" + }, + "zh-tw": { + "tts": "應用程å¼æŽˆæ¬Šå·²æ”¹è®Šã€‚%appName% 已無法進入 %functionalGroupLabels%。請確èªæ‚¨çš„行動è£ç½®ä¸Šå®‰è£äº†æœ€æ–°ç‰ˆæ‡‰ç”¨ç¨‹å¼ã€‚" + } + } + }, + "AppUnauthorized": { + "languages": { + "de-de": { + "tts": "Diese Version von %appName% ist nicht autorisiert und wird nicht mit SYNC funktionieren.", + "line1": "nicht autorisiert" + }, + "en-au": { + "tts": "This version of %appName% is not authorized and will not work with SYNC.", + "line1": "not authorized" + }, + "en-gb": { + "tts": "This version of %appName% is not authorized and will not work with SYNC.", + "line1": "not authorized", + "textBody": "This version of %appName% is not authorized and will not work with SYNC." + }, + "en-ie": { + "tts": "This version of %appName% is not authorized and will not work with SYNC.", + "line1": "not authorized" + }, + "en-us": { + "tts": "This version of %appName% is not authorized and will not work with SYNC.", + "line1": "Not Authorized", + "textBody": "This version of %appName% is no longer authorized to work with AppLink. Please update to the latest version of %appName%." + }, + "es-en": { + "tts": "Esta versión de %appName% no tiene autorización y no funcionará con SYNC.", + "line1": "no autorizada", + "textBody": "Esta versión de %appName% no tiene autorización y no funcionará con SYNC." + }, + "es-es": { + "tts": "Esta versión de %appName% no está autorizada y no funcionará con SYNC.", + "line1": "No autorizada" + }, + "es-mx": { + "tts": "Esta versión de %appName% no tiene autorización y no funcionará con SYNC.", + "line1": "no autorizada", + "textBody": "Esta versión de %appName% no tiene autorización y no funcionará con SYNC." + }, + "fr-ca": { + "tts": "Cette version de %appName% n’est pas autorisée et ne fonctionnera pas avec SYNC.", + "line1": "non autorisée", + "textBody": "Cette version de %appName% n’est pas autorisée et ne fonctionnera pas avec SYNC." + }, + "fr-fr": { + "tts": "Cette version de %appName% n’est pas autorisée et ne fonctionnera pas avec SYNC.", + "line1": "non autorisée" + }, + "it-it": { + "tts": "Questa versione di %appName% non è autorizzata e non funziona con il SYNC.", + "line1": "non autorizzata" + }, + "nl-nl": { + "tts": "Deze versie van %appName% is niet geautoriseerd en werkt niet met SYNC.", + "line1": "niet geautoriseerd" + }, + "pl-pl": { + "tts": "Niniejsza wersja %appName% nie posiada autoryzacji i nie bÄ™dzie dziaÅ‚ać z SYNC.", + "line1": "brak autoryzacji" + }, + "pt-br": { + "tts": "Esta versão do %appName% não tem autorização e não funcionará com o SYNC.", + "line1": "não autorizado" + }, + "pt-pt": { + "tts": "Esta versão de %appName% não está autorizada e não funcionará com o SYNC.", + "line1": "não autorizada" + }, + "ru-ru": { + "tts": "Эта верÑÐ¸Ñ %appName% не авторизирована и не будет работать Ñ SYNC.", + "line1": "не авторизировано" + }, + "sv-se": { + "tts": "Den här versionen av %appName% är inte godkänd och fungerar inte med SYNC.", + "line1": "är ej godkänd" + }, + "tr-tr": { + "tts": "Bu %appName% sürümüne izin verilmediÄŸinden SYNC ile çalışamaz.", + "line1": "için izin yok" + }, + "zh-cn": { + "tts": "此版本的%appName% 未得到授æƒï¼Œæ— æ³•åœ¨SYNC上使用。", + "line1": "未得到授æƒ" + }, + "zh-tw": { + "tts": "%appName% 的版本未ç²å¾—授權,將無法é€éŽ SYNC 使用。", + "line1": "無授權" + } + } + }, + "AppUnsupported": { + "languages": { + "de-de": { + "tts": "Diese Version von %appName% wird von SYNC nicht unterstützt.", + "line1": "nicht unterstützt" + }, + "en-au": { + "tts": "This version of %appName% is not supported by SYNC.", + "line1": "not supported" + }, + "en-gb": { + "tts": "This version of %appName% is not supported by SYNC.", + "line1": "not supported", + "textBody": "This version of %appName% is not supported by SYNC." + }, + "en-ie": { + "tts": "This version of %appName% is not supported by SYNC.", + "line1": "not supported" + }, + "en-us": { + "tts": "This version of %appName% is not supported by SYNC.", + "line1": "Not Supported", + "textBody": "Your version of %appName% is not supported by SYNC." + }, + "es-en": { + "tts": "Esta versión de %appName% no es compatible con SYNC.", + "line1": "no compatible", + "textBody": "Esta versión de %appName% no es compatible con SYNC." + }, + "es-es": { + "tts": "Esta versión de %appName% no es compatible con SYNC.", + "line1": "No compatible" + }, + "es-mx": { + "tts": "Esta versión de %appName% no es compatible con SYNC.", + "line1": "no compatible", + "textBody": "Esta versión de %appName% no es compatible con SYNC." + }, + "fr-ca": { + "tts": "Cette version de %appName% n’est pas prise en charge par SYNC.", + "line1": "incompatible", + "textBody": "Cette version de %appName% n’est pas prise en charge par SYNC." + }, + "fr-fr": { + "tts": "Cette version de %appName% n’est pas prise en charge par SYNC.", + "line1": "incompatible" + }, + "it-it": { + "tts": "Questa versione di %appName% non è supportata dal SYNC.", + "line1": "non supportata" + }, + "nl-nl": { + "tts": "Deze versie van %appName% wordt niet ondersteund door SYNC.", + "line1": "niet ondersteund" + }, + "pl-pl": { + "tts": "Niniejsza wersja %appName% nie jest obsÅ‚ugiwana przez system SYNC.", + "line1": "aplikacja nie obsÅ‚ug." + }, + "pt-br": { + "tts": "Esta versão do %appName% não é suportada pelo SYNC.", + "line1": "não suportado" + }, + "pt-pt": { + "tts": "Esta versão de %appName% não é suportado pelo SYNC.", + "line1": "não suportada" + }, + "ru-ru": { + "tts": "Эта верÑÐ¸Ñ %appName% не поддерживаетÑÑ SYNC.", + "line1": "не поддерживаетÑÑ" + }, + "sv-se": { + "tts": "SYNC har inte stöd för den här versionen av %appName%.", + "line1": "stöds ej" + }, + "tr-tr": { + "tts": "Bu %appName% sürümü SYNC tarafından desteklenmiyor.", + "line1": "desteklenmiyor" + }, + "zh-cn": { + "tts": "SYNCä¸æ”¯æŒæ­¤ç‰ˆæœ¬çš„%appName%。", + "line1": "ä¸å—支æŒ" + }, + "zh-tw": { + "tts": "SYNC ä¸æ”¯æ´æ­¤ç‰ˆæœ¬çš„%appName% 。", + "line1": "ä¸æ”¯æ´" + } + } + }, + "DataConsent": { + "languages": { + "en-gb": { + "textBody": "Would you like to enable Mobile Apps on SYNC? To use Mobile Apps with SYNC, SYNC will communicate with Ford at least once per month using your mobile device’s data plan. Standard rates may apply. SYNC will send your VIN and SYNC module number to Ford U.S. \r\n\r\nUpdates are about the size of an email, and the occurrence of updates depends on your vehicle usage and when a new app is found on your device. To turn on or off, visit the SYNC Settings menu. See your Owner Guide for more information." + }, + "en-us": { + "line1": "Enable Mobile Apps", + "line2": "on SYNC? (Uses Data)", + "textBody": "Would you like to enable Mobile Apps on SYNC?\r\n\r\nTo use Mobile Apps with SYNC, SYNC will communicate with Ford at least once per month using your mobile device’s data plan. Standard rates may apply. SYNC will send your VIN and SYNC module number to Ford U.S.\r\n\r\nUpdates are about the size of an email, and the occurrence of updates depends on your vehicle usage and when a new app is found on your device. To turn on or off, visit the SYNC Settings menu. See your Owner Guide for more information." + }, + "es-mx": { + "textBody": "Para usar aplicaciones móviles con SYNC, este debe comunicarse con Ford al menos una vez al mes a través del plan de datos de su dispositivo móvil. Pueden aplicar tarifas normales. SYNC enviará su VIN y el número de módulo de SYNC a Ford de Estados Unidos de América. \n\nLas actualizaciones tienen el tamaño aproximado de un mensaje de correo electrónico, y la frecuencia de las actualizaciones depende del uso de su vehículo y de si se encuentran nuevas aplicaciones en su dispositivo. Para obtener más información, consulte la Guía del propietario. \n\nPresione Sí para permitir y No para denegar." + }, + "fr-ca": { + "textBody": "Pour utiliser AppLink, SYNC devra communiquer avec Ford au moins une fois par mois en utilisant le forfait de données de votre appareil mobile. Les tarifs réguliers peuvent s’appliquer. SYNC enverra votre NIV et le numéro de votre module SYNC à Ford États-Unis. Les mises à jour ont la taille d’un courriel et la fréquence des mises à jour dépend de l’utilisation de votre véhicule et si une nouvelle application se trouve sur votre appareil. Consultez le Guide de l’utilisateur pour obtenir d’autres renseignements.\r\n\r\nVeuillez appuyer sur Oui pour autoriser ou sur Non pour refuser." + } + } + }, + "DataConsentHelp": { + "languages": { + "en-us": { + "textBody": "By enabling mobile apps, you consent to allowing SYNC to communicate with Ford at least once per month using your mobile device’s data plan. Disabling will stop all data usage, but you will not be able to use mobile apps on SYNC. See your Owner Guide for more information." + }, + "es-mx": { + "textBody": "Las actualizaciones tienen el tamaño aproximado de un mensaje de correo electrónico, y la frecuencia de las actualizaciones depende del uso de su vehículo y de si se encuentran nuevas aplicaciones en su dispositivo. Para obtener más información, consulte la Guía del propietario." + }, + "fr-ca": { + "textBody": "Les mises à jour ont la taille d’un courriel et la fréquence des mises à jour dépend de l’utilisation de votre véhicule et si une nouvelle application se trouve sur votre appareil. Consultez le Guide de l’utilisateur pour obtenir d’autres renseignements." + } + } + }, + "DisableApps": { + "languages": { + "de-de": { + "tts": "Ausschalten der automatischen Updates führt zum Ausschalten von SYNC mobile Apps. Sie können Ihre mobilen Apps dann nicht mehr mit SYNC nutzen. Bitte drücken Sie Ja zur Bestätigung oder Nein, um abzubrechen.", + "line1": "Auto-Update", + "line2": "und Mobile Apps deaktivieren" + }, + "en-au": { + "tts": "Disabling automatic updates will also disable SYNC mobile apps. You will not be able to use any mobile apps with SYNC. Please press Yes to confirm or No to cancel.", + "line1": "Disable auto-updates", + "line2": "and Mobile Apps?" + }, + "en-gb": { + "tts": "Disabling automatic updates will also disable SYNC mobile apps. You will not be able to use any mobile apps with SYNC. Please press Yes to confirm or No to cancel.", + "line1": "Disable auto-updates", + "line2": "and Mobile Apps?", + "textBody": "Disabling automatic updates will also disable SYNC mobile apps. You will not be able to use any mobile apps with SYNC. Please press Yes to confirm or No to cancel." + }, + "en-ie": { + "tts": "Disabling automatic updates will also disable SYNC mobile apps. You will not be able to use any mobile apps with SYNC. Please press Yes to confirm or No to cancel.", + "line1": "Disable auto-updates", + "line2": "and Mobile Apps?" + }, + "en-us": { + "tts": "Disabling automatic updates will also disable sync mobile apps. You will not be able to use any mobile apps with SYNC. Please press yes to confirm or no to cancel.", + "line1": "Disable Auto-Updates", + "line2": "and Mobile Apps?", + "textBody": "If you disable, you will not be able to use any mobile apps with SYNC and your vehicle will stop receiving mobile app permission updates via your device`s data plan. Please press yes to disable mobile apps or no to cancel." + }, + "es-en": { + "tts": "Si se desactivan las actualizaciones automáticas, también se desactivarán las aplicaciones móviles de SYNC. No podrá usar ninguna aplicación móvil con SYNC. Presione Sí para confirmar o No para cancelar.", + "line1": "¿Deshab. actualiz.", + "line2": "autom. y aplic. móv.?", + "textBody": "Si se desactivan las actualizaciones automáticas, también se desactivarán las aplicaciones móviles de SYNC. No podrá usar ninguna aplicación móvil con SYNC. Presione Sí para confirmar o No para cancelar." + }, + "es-es": { + "tts": "Si desactiva las actualizaciones automáticas, también se desactivará la sincronización de las aplicaciones móviles. No podrá utilizar ninguna aplicación móvil con SYNC. Pulse sí para confirmar o no para cancelar.", + "line1": "¿Desact. actual. auto", + "line2": "y apl. móviles?" + }, + "es-mx": { + "tts": "Si se desactivan las actualizaciones automáticas, también se desactivarán las aplicaciones móviles de SYNC. No podrá usar ninguna aplicación móvil con SYNC. Presione Sí para confirmar o No para cancelar.", + "line1": "¿Deshab. actualiz.", + "line2": "autom. y aplic. móv.?", + "textBody": "Si se desactivan las actualizaciones automáticas, también se desactivarán las aplicaciones móviles de SYNC. No podrá usar ninguna aplicación móvil con SYNC. Presione Sí para confirmar o No para cancelar." + }, + "fr-ca": { + "tts": "La désactivation des mises à jour automatiques désactivera aussi les applications mobiles SYNC. Vous ne pourrez pas utiliser d’application mobile avec SYNC. Veuillez appuyer sur Oui pour confirmer ou sur Non pour annuler.", + "line1": "Désactiver màj autom.", + "line2": "et app. mobiles?", + "textBody": "La désactivation des mises à jour automatiques désactivera aussi les applications mobiles SYNC. Vous ne pourrez pas utiliser d’application mobile avec SYNC. Veuillez appuyer sur Oui pour confirmer ou sur Non pour annuler." + }, + "fr-fr": { + "tts": "La désactivation des mises à jour automatiques désactivera aussi les applications mobiles SYNC. Vous ne pourrez pas utiliser d’application mobile avec SYNC. Veuillez appuyer sur Oui pour confirmer ou sur Non pour annuler.", + "line1": "Désactiver màj autom.", + "line2": "et app. mobiles?" + }, + "it-it": { + "tts": "Disabilitando gli aggiornamenti automatici si disattiva anche la sincronizzazione delle app mobili. Non sarà possibile usare app mobili con il SYNC. Premere Sì per confermare e No per cancellare.", + "line1": "Disabilitare agg. aut.", + "line2": "e app mobili?" + }, + "nl-nl": { + "tts": "Door automatische updates uit te schakelen, schakelt u ook SYNC-mobiele apps uit. U kunt dan geen mobiele apps meer gebruiken met SYNC. Druk op Ja om te bevestigen of op Nee om te annuleren.", + "line1": "Auto-updates en mob.", + "line2": "apps uitschakelen?" + }, + "pl-pl": { + "tts": "WyÅ‚Ä…czenie automatycznych aktualizacji spowoduje także wyÅ‚Ä…czenie aplikacji mobilnych SYNC. Korzystanie z mobilnych aplikacji za pomocÄ… SYNC bÄ™dzie niemożliwe. NaciÅ›nij TAK, by potwierdzić lub NIE, by anulować.", + "line1": "WyÅ‚. automat. aktual.", + "line2": "i aplikacje mobilne?" + }, + "pt-br": { + "tts": "Se as atualizações automáticas forem desativadas, os aplicativos também serão desativados. Você não poderá usar nenhum aplicativo com o SYNC. Pressione sim para confirmar ou não para cancelar.", + "line1": "Desativar atualizações", + "line2": "autom. e aplicativos?" + }, + "pt-pt": { + "tts": "A desactivação das actualizações automáticas desactiva igualmente as aplicações móveis do SYNC. Não poderá utilizar quaisquer aplicações móveis com o SYNC. Prima \"\"Sim\"\" para confirmar ou \"\"Não\"\" para cancelar.", + "line1": "Desact. actual. autom.", + "line2": "e aplicações móveis?" + }, + "ru-ru": { + "tts": "При отключении автоматичеÑких обновлений также будут отключены мобильные Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ sync. Ð’Ñ‹ не Ñможете иÑпользовать какие-либо мобильные Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ñ SYNC. Ðажмите \"\"Да\"\" Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ \"\"Ðет\"\" Ð´Ð»Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ñ‹.", + "line1": "Откл. автообновлениÑ", + "line2": "и мобил. прилож.?" + }, + "sv-se": { + "tts": "Om du avaktiverar automatisk uppdatering avaktiverar du även synkning av mobilappar. Du kommer inte längre att kunna använda dina mobilappar med SYNC. Tryck Ja för att bekräfta eller Nej för att avbryta.", + "line1": "Avaktiverar autouppdat.", + "line2": "och mobilappar?" + }, + "tr-tr": { + "tts": "Otomatik güncellemeleri devre dışı bırakırsanız sync mobil uygulamalar da devre dışı kalır. SYNC ile mobil uygulama kullanmanız mümkün olmaz. Lütfen onaylamak için Evet'e veya iptal etmek için Hayır'a basın.", + "line1": "Oto. güncelleme ve", + "line2": "mobil uygul. kapat?" + }, + "zh-cn": { + "tts": "ç¦ç”¨è‡ªåŠ¨æ›´æ–°åŒæ—¶ä¹Ÿä¼šç¦ç”¨SYNC移动应用程åºã€‚您将无法在 SYNC 中使用任何移动应用程åºã€‚请按“是â€ç¡®è®¤æˆ–按“å¦â€å–消。", + "line1": "是å¦ç¦ç”¨è‡ªåŠ¨æ›´æ–°å’Œ", + "line2": "移动应用程åºï¼Ÿ" + }, + "zh-tw": { + "tts": "åœç”¨è‡ªå‹•æ›´æ–°ä¹Ÿå°‡åœç”¨ sync 行動應用程å¼ã€‚您將無法é€éŽ SYNC 使用任何行動應用程å¼ã€‚確èªè«‹æŒ‰ã€Œæ˜¯ã€ï¼Œå–消請按「å¦ã€ã€‚", + "line1": "åœç”¨è‡ªå‹•æ›´æ–°", + "line2": "和行動應用程å¼ï¼Ÿ" + } + } + }, + "DrivingCharacteristics": { + "languages": { + "de-de": { + "tts": "Eine App hat Zugriff auf die folgenden Fahreigenschaften: Kraftstoffverbrauch, MyKey, Sicherheitsgurtstatus.", + "label": "Fahreigenschaften" + }, + "en-au": { + "tts": "An app can access the following driving characteristics: Fuel consumption, MyKey, Seat belt status.", + "label": "Driving characteristics" + }, + "en-gb": { + "tts": "An app can access the following driving characteristics: Fuel consumption, MyKey, Seat belt status.", + "label": "Driving characteristics", + "textBody": "An app can access the following driving characteristics: Fuel consumption, MyKey, Seat belt status." + }, + "en-ie": { + "tts": "An app can access the following driving characteristics: Fuel consumption, MyKey, Seat belt status.", + "label": "Driving characteristics" + }, + "en-us": { + "tts": "An app can access the following driving characteristics: Fuel Consumption, MyKey, Seat Belt Status.", + "label": "Driving Characteristics", + "textBody": "An app can access the following driving characteristics: Fuel Consumption, MyKey, Seat Belt Status." + }, + "es-en": { + "tts": "Las aplicaciones pueden acceder a las siguientes características del manejo: Consumo de combustible, MyKey, Estado del cinturón de seguridad.", + "label": "Características del manejo", + "textBody": "Las aplicaciones pueden acceder a las siguientes características del manejo: Consumo de combustible, MyKey, Estado del cinturón de seguridad." + }, + "es-es": { + "tts": "Una aplicación puede acceder a las siguientes características de conducción: Consumo de combustible, MyKey, Estado cinturones de seguridad.", + "label": "Características de conducción" + }, + "es-mx": { + "tts": "Las aplicaciones pueden acceder a las siguientes características del manejo: Consumo de combustible, MyKey, Estado del cinturón de seguridad.", + "label": "Características del manejo", + "textBody": "Las aplicaciones pueden acceder a las siguientes características del manejo: Consumo de combustible, MyKey, Estado del cinturón de seguridad." + }, + "fr-ca": { + "tts": "Une application peut accéder aux caractéristiques de conduite suivantes: Consommation de carburant, MyKey, État des ceintures de sécurité.", + "label": "Caractéristiques de conduite", + "textBody": "Une application peut accéder aux caractéristiques de conduite suivantes: Consommation de carburant, MyKey, État des ceintures de sécurité." + }, + "fr-fr": { + "tts": "Une application peut accéder aux caractéristiques de conduite suivantes: Consommation de carburant, MyKey, État des ceintures de sécurité.", + "label": "Caractéristiques de conduite" + }, + "it-it": { + "tts": "Un'app può avere accesso alle seguenti caratteristiche di guida: Consumo carburante, MyKey, Stato cinture di sicurezza.", + "label": "Caratteristiche di guida" + }, + "nl-nl": { + "tts": "Een app heeft toegang tot de volgende rijkenmerken: Brandstofverbruik, MyKey, Veiligheidsgordelstatus.", + "label": "Rijkenmerken" + }, + "pl-pl": { + "tts": "Aplikacja może uzyskać dostÄ™p do nastÄ™pujÄ…cych informacji dotyczÄ…cych jazdy: Zużycie paliwa, MyKey, Stan pasów bezpieczeÅ„stwa.", + "label": "Informacje dotyczÄ…ce stylu jazdy" + }, + "pt-br": { + "tts": "Um aplicativo pode acessar as seguintes características de condução: Consumo de combustível, MyKey, Estado do cinto de segurança.", + "label": "Características de condução" + }, + "pt-pt": { + "tts": "Uma aplicação consegue aceder às seguintes informações de condução: Consumo de combustível, MyKey, Estado dos cintos de segurança.", + "label": "Características de condução" + }, + "ru-ru": { + "tts": "Приложение имеет доÑтуп к Ñледующим характериÑтикам движениÑ: РаÑход топлива, MyKey, СоÑтоÑние ремней безопаÑноÑти.", + "label": "ХарактериÑтики движениÑ" + }, + "sv-se": { + "tts": "Appen kan komma Ã¥t följande köregenskaper: Bränsleförbrukning, MyKey, Bältesstatus.", + "label": "Köregenskaper" + }, + "tr-tr": { + "tts": "Bir uygulama ÅŸu sürüş karakteristiklerine eriÅŸebilir: Yakıt tüketimi, MyKey, Emniyet kemeri durumu.", + "label": "Sürüş karakteristikleri" + }, + "zh-cn": { + "tts": "移动应用程åºå¯è®¿é—®ä¸‹åˆ—行驶特性: 油耗, MyKey, 安全带状æ€", + "label": "行驶特性" + }, + "zh-tw": { + "tts": "應用程å¼å¯å­˜å–以下駕駛特性: 油耗, MyKey, 安全帶狀態", + "label": "駕駛特性" + } + } + }, + "Location": { + "languages": { + "de-de": { + "tts": "Eine App hat Zugriff auf die GPS-Daten und die Geschwindigkeit des Fahrzeugs.", + "label": "GPS und Geschwindigkeit" + }, + "en-au": { + "tts": "An app can access vehicle GPS and speed.", + "label": "GPS and speed" + }, + "en-gb": { + "tts": "An app can access vehicle GPS and speed.", + "label": "GPS and speed", + "textBody": "An app can access vehicle GPS and speed." + }, + "en-ie": { + "tts": "An app can access vehicle GPS and speed.", + "label": "GPS and speed" + }, + "en-us": { + "tts": "An app can access vehicle GPS and speed.", + "label": "GPS and speed", + "textBody": "An app can access vehicle GPS and speed." + }, + "es-en": { + "tts": "Las aplicaciones pueden acceder al GPS y a la velocidad del vehículo.", + "label": "GPS y velocidad", + "textBody": "Las aplicaciones pueden acceder al GPS y a la velocidad del vehículo." + }, + "es-es": { + "tts": "Una aplicación puede acceder al GPS y la velocidad del vehículo.", + "label": "GPS y velocidad" + }, + "es-mx": { + "tts": "Las aplicaciones pueden acceder al GPS y a la velocidad del vehículo.", + "label": "GPS y velocidad", + "textBody": "Las aplicaciones pueden acceder al GPS y a la velocidad del vehículo." + }, + "fr-ca": { + "tts": "Une application peut accéder au GPS et à la vitesse du véhicule.", + "label": "GPS et vitesse", + "textBody": "Une application peut accéder au GPS et à la vitesse du véhicule." + }, + "fr-fr": { + "tts": "Une application peut accéder au GPS et à la vitesse du véhicule.", + "label": "GPS et vitesse" + }, + "it-it": { + "tts": "Un'app può avere accesso a GPS e velocità del veicolo.", + "label": "GPS e velocità" + }, + "nl-nl": { + "tts": "Een app heeft toegang tot gps en de snelheid van het voertuig.", + "label": "Gps en snelheid" + }, + "pl-pl": { + "tts": "Aplikacja może uzyskać dostÄ™p do moduÅ‚u GPS i prÄ™dkoÅ›ci pojazdu.", + "label": "GPS i prÄ™dkość" + }, + "pt-br": { + "tts": "Um aplicativo pode acessar o GPS e a velocidade do veículo.", + "label": "GPS e velocidade" + }, + "pt-pt": { + "tts": "Uma aplicação consegue aceder ao GPS e à velocidade do veículo.", + "label": "GPS e velocidade" + }, + "ru-ru": { + "tts": "Приложение имеет доÑтуп к GPS и ÑкороÑти автомобилÑ.", + "label": "GPS и ÑкороÑÑ‚ÑŒ" + }, + "sv-se": { + "tts": "Appen kan komma Ã¥t fordonets GPS och hastighetsmätare.", + "label": "GPS och hastighet" + }, + "tr-tr": { + "tts": "Bu uygulama aracın GPS ve hız bilgilerine eriÅŸebilir.", + "label": "GPS ve hız" + }, + "zh-cn": { + "tts": "移动应用程åºå¯ä»¥è®¿é—®è½¦è¾† GPS 和车速信æ¯ã€‚", + "label": "GPS 和车速" + }, + "zh-tw": { + "tts": "應用程å¼å¯å­˜å–車輛的GPS和速度。", + "label": "GPS和車速" + } + } + }, + "Notifications": { + "languages": { + "de-de": { + "tts": "Läuft die App im Hintergrund, kann Sie Benachrichtigungen senden.", + "label": "Push-Benachrichtigungen" + }, + "en-au": { + "tts": "An app can send notifications when running in the background.", + "label": "Push notifications" + }, + "en-gb": { + "tts": "An app can send notifications when running in the background.", + "label": "Push notifications", + "textBody": "An app can send notifications when running in the background." + }, + "en-ie": { + "tts": "An app can send notifications when running in the background.", + "label": "Push notifications" + }, + "en-us": { + "tts": "An app can send notifications when running in the background.", + "label": "Push notifications", + "textBody": "An app can send notifications when running in the background." + }, + "es-en": { + "tts": "Las aplicaciones pueden enviar notificaciones cuando se ejecutan en segundo plano.", + "label": "Notificaciones tipo Push", + "textBody": "Las aplicaciones pueden enviar notificaciones cuando se ejecutan en segundo plano." + }, + "es-es": { + "tts": "Una aplicación puede enviar notificaciones cuando se está ejecutando en segundo plano.", + "label": "Notificaciones push" + }, + "es-mx": { + "tts": "Las aplicaciones pueden enviar notificaciones cuando se ejecutan en segundo plano.", + "label": "Notificaciones tipo Push", + "textBody": "Las aplicaciones pueden enviar notificaciones cuando se ejecutan en segundo plano." + }, + "fr-ca": { + "tts": "Une application peut envoyer des avis lorsqu’elle fonctionne en arrière-plan.", + "label": "Notifications instantanées", + "textBody": "Une application peut envoyer des avis lorsqu’elle fonctionne en arrière-plan." + }, + "fr-fr": { + "tts": "Une application peut envoyer des avis lorsqu’elle fonctionne en arrière-plan.", + "label": "Notifications push" + }, + "it-it": { + "tts": "Un'app può inviare notifiche se eseguita in background.", + "label": "Notifiche push" + }, + "nl-nl": { + "tts": "Een app kan meldingen versturen als deze op de achtergrond actief is.", + "label": "Push-meldingen" + }, + "pl-pl": { + "tts": "Aplikacja może wysyÅ‚ać powiadomienia, dziaÅ‚ajÄ…c w tle.", + "label": "Powiadomienia Push" + }, + "pt-br": { + "tts": "Um aplicativo pode enviar notificações quando estiver sendo executado em segundo plano.", + "label": "Notificações Push" + }, + "pt-pt": { + "tts": "Uma aplicação consegue enviar notificações quando está activa em segundo plano.", + "label": "Notificações push" + }, + "ru-ru": { + "tts": "ЕÑли приложение работает в фоновом режиме, оно может отправлÑÑ‚ÑŒ оповещениÑ.", + "label": "ÐžÐ¿Ð¾Ð²ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¾ переÑылке" + }, + "sv-se": { + "tts": "Appen kan skicka meddelanden när den körs i bakgrunden.", + "label": "Push-notiser" + }, + "tr-tr": { + "tts": "Bir uygulama arka planda çalışırken bildirim gönderebilir.", + "label": "Anlık bildirimleri" + }, + "zh-cn": { + "tts": "移动应用程åºåœ¨åŽå°è¿è¡Œæ—¶å¯æŽ¨é€é€šçŸ¥ã€‚", + "label": "推é€é€šçŸ¥" + }, + "zh-tw": { + "tts": "車輛行進時,應用程å¼å¯åœ¨èƒŒæ™¯ä¸­å‚³é€é€šçŸ¥ã€‚", + "label": "傳é€é€šçŸ¥" + } + } + }, + "SettingDisableUpdates": { + "languages": { + "de-de": { + "line1": "Updates deakt." + }, + "en-au": { + "line1": "Disable updates" + }, + "en-gb": { + "line1": "Disable updates" + }, + "en-ie": { + "line1": "Disable updates" + }, + "en-us": { + "line1": "Disable Updates", + "textBody": "Disable Updates" + }, + "es-en": { + "line1": "Deshab. actual.", + "textBody": "Deshab. actual." + }, + "es-es": { + "line1": "Desact. actual." + }, + "es-mx": { + "line1": "Deshab. actual.", + "textBody": "Deshab. actual." + }, + "fr-ca": { + "line1": "Désactiver MAJ", + "textBody": "Désactiver MAJ" + }, + "fr-fr": { + "line1": "Désactiver màj" + }, + "it-it": { + "line1": "Disabilita agg." + }, + "nl-nl": { + "line1": "Upd. uitschak." + }, + "pl-pl": { + "line1": "WyÅ‚Ä…cz aktual." + }, + "pt-br": { + "line1": "Desat. atualiz." + }, + "pt-pt": { + "line1": "Desact. actualiz." + }, + "ru-ru": { + "line1": "Откл. обновл." + }, + "sv-se": { + "line1": "Inaktivera uppd." + }, + "tr-tr": { + "line1": "Güncell. Kapat" + }, + "zh-cn": { + "line1": "ç¦ç”¨æ›´æ–°" + }, + "zh-tw": { + "line1": "åœç”¨æ›´æ–°" + } + } + }, + "SettingEnableUpdates": { + "languages": { + "de-de": { + "line1": "Apps aktivieren" + }, + "en-au": { + "line1": "Enable Apps" + }, + "en-gb": { + "line1": "Enable Apps" + }, + "en-ie": { + "line1": "Enable Apps" + }, + "en-us": { + "line1": "Enable Apps" + }, + "es-en": { + "line1": "Hab. aplic." + }, + "es-es": { + "line1": "Activar apl." + }, + "es-mx": { + "line1": "Hab. aplic." + }, + "fr-ca": { + "line1": "Activer app.", + "textBody": "Activer app." + }, + "fr-fr": { + "line1": "Activer app." + }, + "it-it": { + "line1": "Abilita app" + }, + "nl-nl": { + "line1": "Apps inschak." + }, + "pl-pl": { + "line1": "WÅ‚Ä…cz aplikacje" + }, + "pt-br": { + "line1": "Ativar aplic." + }, + "pt-pt": { + "line1": "Activar actualiz." + }, + "ru-ru": { + "line1": "Вкл. прилож." + }, + "sv-se": { + "line1": "Aktivera appar" + }, + "tr-tr": { + "line1": "Uygulamaları aç" + }, + "zh-cn": { + "line1": "å¯ç”¨åº”用程åº" + }, + "zh-tw": { + "line1": "啟用應用程å¼" + } + } + }, + "SettingUpdateAuto": { + "languages": { + "de-de": { + "line1": "Update anford." + }, + "en-au": { + "line1": "Request update" + }, + "en-gb": { + "line1": "Request update" + }, + "en-ie": { + "line1": "Request update" + }, + "en-us": { + "line1": "Request Update", + "textBody": "Select `Update now` to receive app permissions for your SYNC-enabled mobile apps. This may enable additional functionality depending on the app and your settings. If your phone has a working data connection, an update should complete in less than 1 minute." + }, + "es-en": { + "line1": "Solicit. actualiz.", + "textBody": "Solicit. actualiz." + }, + "es-es": { + "line1": "Solicitar actual." + }, + "es-mx": { + "line1": "Solicit. actualiz.", + "textBody": "Solicit. actualiz." + }, + "fr-ca": { + "line1": "Demander MAJ", + "textBody": "Demander MAJ" + }, + "fr-fr": { + "line1": "Demander màj" + }, + "it-it": { + "line1": "Rich. aggiorn." + }, + "nl-nl": { + "line1": "Upd. aanvragen" + }, + "pl-pl": { + "line1": "Zażądaj aktual." + }, + "pt-br": { + "line1": "Solicitar atualiz." + }, + "pt-pt": { + "line1": "Solicit. actualiz." + }, + "ru-ru": { + "line1": "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° обн." + }, + "sv-se": { + "line1": "Begär uppdat." + }, + "tr-tr": { + "line1": "Güncelleme iste" + }, + "zh-cn": { + "line1": "请求更新" + }, + "zh-tw": { + "line1": "請求更新" + } + } + }, + "StatusNeeded": { + "languages": { + "de-de": { + "line1": "Update benötigt" + }, + "en-au": { + "line1": "Update needed" + }, + "en-gb": { + "line1": "Update needed", + "textBody": "Update needed" + }, + "en-ie": { + "line1": "Update needed" + }, + "en-us": { + "line1": "Update Needed", + "textBody": "Update Needed" + }, + "es-en": { + "line1": "Actualiz. neces.", + "textBody": "Actualiz. neces." + }, + "es-es": { + "line1": "Actu. necesaria" + }, + "es-mx": { + "line1": "Actualiz. neces.", + "textBody": "Actualiz. neces." + }, + "fr-ca": { + "line1": "Màj requise", + "textBody": "Màj requise" + }, + "fr-fr": { + "line1": "Mise à jour requise" + }, + "it-it": { + "line1": "Necess. aggiorn." + }, + "nl-nl": { + "line1": "Update nodig" + }, + "pl-pl": { + "line1": "Potrzeba aktual." + }, + "pt-br": { + "line1": "Atualiz. necess." + }, + "pt-pt": { + "line1": "Actual. necess." + }, + "ru-ru": { + "line1": "Ðеобх. обновл." + }, + "sv-se": { + "line1": "Uppdat. krävs" + }, + "tr-tr": { + "line1": "Güncellenmeli" + }, + "zh-cn": { + "line1": "需è¦è¿›è¡Œæ›´æ–°" + }, + "zh-tw": { + "line1": "需更新" + } + } + }, + "StatusPending": { + "languages": { + "de-de": { + "line1": "Aktualisieren..." + }, + "en-au": { + "line1": "Updating..." + }, + "en-gb": { + "line1": "Updating...", + "textBody": "Updating..." + }, + "en-ie": { + "line1": "Updating..." + }, + "en-us": { + "line1": "Updating...", + "textBody": "Updating..." + }, + "es-en": { + "line1": "Actualizando...", + "textBody": "Actualizando..." + }, + "es-es": { + "line1": "Actualizando..." + }, + "es-mx": { + "line1": "Actualizando...", + "textBody": "Actualizando..." + }, + "fr-ca": { + "line1": "MAJ en cours...", + "textBody": "MAJ en cours..." + }, + "fr-fr": { + "line1": "Màj en cours..." + }, + "it-it": { + "line1": "Aggiornamento" + }, + "nl-nl": { + "line1": "Updaten..." + }, + "pl-pl": { + "line1": "Aktualizowanie" + }, + "pt-br": { + "line1": "Atualizando..." + }, + "pt-pt": { + "line1": "A actualizar..." + }, + "ru-ru": { + "line1": "Обновление..." + }, + "sv-se": { + "line1": "Uppdaterar..." + }, + "tr-tr": { + "line1": "Güncelleniyor..." + }, + "zh-cn": { + "line1": "正在更新......" + }, + "zh-tw": { + "line1": "更新中..." + } + } + }, + "StatusUpToDate": { + "languages": { + "de-de": { + "line1": "Aktuelle Version" + }, + "en-au": { + "line1": "Up-to-date" + }, + "en-gb": { + "line1": "Up-to-date", + "textBody": "Up-to-date" + }, + "en-ie": { + "line1": "Up-to-date" + }, + "en-us": { + "line1": "Up-To-Date", + "textBody": "Up-To-Date" + }, + "es-en": { + "line1": "Actualizado", + "textBody": "Actualizado" + }, + "es-es": { + "line1": "Actualizada" + }, + "es-mx": { + "line1": "Actualizado", + "textBody": "Actualizado" + }, + "fr-ca": { + "line1": "Déjà à jour", + "textBody": "Déjà à jour" + }, + "fr-fr": { + "line1": "Déjà à jour" + }, + "it-it": { + "line1": "più recente" + }, + "nl-nl": { + "line1": "Up-to-date" + }, + "pl-pl": { + "line1": "Aktualne" + }, + "pt-br": { + "line1": "Atualizado" + }, + "pt-pt": { + "line1": "Actualizado" + }, + "ru-ru": { + "line1": "Обновлено" + }, + "sv-se": { + "line1": "Uppdat. krävs ej" + }, + "tr-tr": { + "line1": "Güncel" + }, + "zh-cn": { + "line1": "最新更新" + }, + "zh-tw": { + "line1": "更新最新" + } + } + }, + "VehicleInfo": { + "languages": { + "de-de": { + "tts": "Eine App hat Zugriff auf die folgenden Fahrzeuginformationen: Kraftstoff-Füllstand, Kraftstoffverbrauch, Motordrehzahl, Kilometerzähler, FIN, Außentemperatur, Gangstellung, Reifenluftdruck.", + "label": "Fahrzeuginformationen" + }, + "en-au": { + "tts": "An app can access the following vehicle information: Fuel level, Fuel economy, Engine RPMs, Odometer, VIN, Outside air temperature, Gear position, Tyre pressure.", + "label": "Vehicle information" + }, + "en-gb": { + "tts": "An app can access the following vehicle information: Fuel level, Fuel economy, Engine RPMs, Odometer, VIN, Outside air temperature, Gear position, Tire pressure.", + "label": "Vehicle information", + "textBody": "An app can access the following vehicle information: Fuel level, Fuel economy, Engine RPMs, Odometer, VIN, Outside air temperature, Gear position, Tire pressure." + }, + "en-ie": { + "tts": "An app can access the following vehicle information: Fuel level, Fuel economy, Engine RPMs, Odometer, VIN, Outside air temperature, Gear position, Tyre pressure.", + "label": "Vehicle information" + }, + "en-us": { + "tts": "An app can access the following vehicle information: Fuel Level, Fuel Economy, Engine RPMs, Odometer, VIN, External Temperature, Gear Position, Tire Pressure.", + "label": "Vehicle information", + "textBody": "An app can access the following vehicle information: Fuel Level, Fuel Economy, Engine RPMs, Odometer, VIN, External Temperature, Gear Position, Tire Pressure." + }, + "es-en": { + "tts": "Las aplicaciones pueden acceder a la siguiente información del vehículo: Nivel de combustible, Economía de combustible, RPM del motor, Cuentakilómetros, Número de identificación del vehículo, Temperatura externa, Posición del cambio, Presión de los neumáticos.", + "label": "Información del vehículo", + "textBody": "Las aplicaciones pueden acceder a la siguiente información del vehículo: Nivel de combustible, Economía de combustible, RPM del motor, Cuentakilómetros, Número de identificación del vehículo, Temperatura externa, Posición del cambio, Presión de los neumáticos." + }, + "es-es": { + "tts": "Una aplicación puede acceder a la siguiente información del vehículo: Nivel de combustible, Ahorro de combustible, RPM del motor, Cuentakilómetros, VIN, Temperatura aire exterior, Marcha engranada, Presión de neumáticos.", + "label": "Información del vehículo" + }, + "es-mx": { + "tts": "Las aplicaciones pueden acceder a la siguiente información del vehículo: Nivel de combustible, Economía de combustible, RPM del motor, Cuentakilómetros, Número de identificación del vehículo, Temperatura externa, Posición del cambio, Presión de los neumáticos.", + "label": "Información del vehículo", + "textBody": "Las aplicaciones pueden acceder a la siguiente información del vehículo: Nivel de combustible, Economía de combustible, RPM del motor, Cuentakilómetros, Número de identificación del vehículo, Temperatura externa, Posición del cambio, Presión de los neumáticos." + }, + "fr-ca": { + "tts": "Une application peut accéder aux informations suivantes du véhicule: Niveau de carburant, Économie de carburant, Au régime du moteur, Odomètre, NIV, Température extérieure, Position d’embrayage, Pression des pneus.", + "label": "Renseignements du véhicule", + "textBody": "Une application peut accéder aux informations suivantes du véhicule: Niveau de carburant, Économie de carburant, Au régime du moteur, Odomètre, NIV, Température extérieure, Position d’embrayage, Pression des pneus." + }, + "fr-fr": { + "tts": "Une application peut accéder aux informations suivantes du véhicule: Niveau de carburant, Économie de carburant, Vitesse de moteur, Compteur kilométrique, NIV, Température extérieure, Position de vitesse, Pression des pneus.", + "label": "Renseignements du véhicule" + }, + "it-it": { + "tts": "Un'app può avere accesso alle seguenti informazioni del veicolo: Livello carburante, Consumi carburante, Numero giri motore, Contachilometri, VIN, Temperatura esterna, Posizione marcia, Pressione pneumatici.", + "label": "Informazioni sul veicolo" + }, + "nl-nl": { + "tts": "Een app heeft toegang tot de volgende voertuiginformatie: Brandstofpeil, Brandstofverbruik, Motortoerental, Kilometerteller, VIN, Buitentemperatuur, Versnellingsstand, Bandenspanning.", + "label": "Voertuiginformatie" + }, + "pl-pl": { + "tts": "Aplikacja może uzyskać dostÄ™p do nastÄ™pujÄ…cych informacji o pojeździe: Poziom paliwa, Zużycie paliwa, Obroty silnika, Licznik przebiegu, Numer VIN, Temperatura zewnÄ™trzna, Aktualny bieg, CiÅ›nienie opon.", + "label": "Informacje o pojeździe" + }, + "pt-br": { + "tts": "Um aplicativo pode acessar as seguintes informações sobre o veículo: Nível de combustível, Economia de combustível, RPM do motor, Hodômetro, VIN, Temperatura externa, Posição das marchas, Pressão dos pneus.", + "label": "Informações sobre o veículo" + }, + "pt-pt": { + "tts": "Uma aplicação consegue aceder às seguintes informações do veículo: Nível de combustível, Poupança de combustível, RPM do motor, Conta-quilómetros, VIN, Temperatura exterior, Posição da mudança de velocidade, Pressão dos pneus.", + "label": "Informações do veículo" + }, + "ru-ru": { + "tts": "Приложение имеет доÑтуп к Ñледующим данным автомобилÑ: Уровень топлива, Ð•ÐºÐ¾Ð½Ð¾Ð¼Ð¸Ñ Ñ‚Ð¾Ð¿Ð»Ð¸Ð²Ð°, ЧиÑло оборотов двигателÑ, Одометр, Ðомер VIN, Температура за бортом, Положение передачи, Давление шин.", + "label": "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± автомобиле" + }, + "sv-se": { + "tts": "Appen kan komma Ã¥t följande fordonsinformation: BränslenivÃ¥, Bränsleekonomi, Motorns varvtal, Vägmätare, VIN, Utetemperatur, Växelläge, Däcktryck.", + "label": "Fordonsinformation" + }, + "tr-tr": { + "tts": "Bir uygulama ÅŸu araç bilgilerine eriÅŸebilir: Yakıt seviyesi, Yakıt ekonomisi, Motor devirleri, Kilometre sayacı, VIN, Dış sıcaklık, Vites konumu, Lastik basıncı.", + "label": "Araç bilgisi" + }, + "zh-cn": { + "tts": "移动应用程åºå¯è®¿é—®ä¸‹åˆ—è½¦è¾†ä¿¡æ¯ ï¼š 燃油é‡, 燃油ç»æµŽæ€§, å‘动机转速(RPM), 里程表, VIN, 车外温度, æ¡£ä½, 胎压.", + "label": "车辆信æ¯" + }, + "zh-tw": { + "tts": "一個應用程å¼å¯å­˜å–以下車輛資訊 : 燃油存é‡, 燃油經濟性, 引擎轉速, 里程表, 車輛識別號碼, 車外溫度, 檔ä½, 胎壓.", + "label": "車輛資訊" + } + } + } + } + }, + "app_policies": { + "default": { + "keep_context": true, + "steal_focus": true, + "priority": "NONE", + "default_hmi": "NONE", + "groups": [ + "Base-4" + ] + }, + "device": { + "keep_context": false, + "steal_focus": false, + "priority": "NONE", + "default_hmi": "NONE", + "groups": [ + "DataConsent-2" + ] + }, + "pre_DataConsent": { + "keep_context": false, + "steal_focus": false, + "priority": "NONE", + "default_hmi": "NONE", + "groups": [ + "Base-4" + ] + } + } + } + } \ No newline at end of file diff --git a/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua b/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua new file mode 100644 index 0000000000..a60d5a3803 --- /dev/null +++ b/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua @@ -0,0 +1,188 @@ +-- Requirement summary: +-- TBD +-- +-- Description: +-- iAP2 Bluetooth connection is switched to iAP2 USB connection automatically, application(s) remains registered, +-- but application(s) sends wrong hashID or it's absent +-- +-- 1. Used precondition +-- SDL is built with BUILD_TEST = ON to enable iAP2 BT/USB transport adapter emulation +-- SDL, HMI are running on system. +-- +-- 2. Performed steps +-- iAP2 Bluetooth mobile device connects to system +-- appID_1->RegisterAppInterface(params) +-- RAI response is SUCCESS +-- application sends SubscribeButton for PRESET_0 button (resume data) +-- SDL sends OnHashChange to application +-- +-- same iAP2 mobile device is connected over USB to system and re-registers within AppTransportChangeTimer timeout +-- appID_1->RegisterAppInterface(params), but with wrong hashID +-- +-- Expected behavior: +-- 1. SDL successfully registers application and notifies HMI and mobile +-- SDL->HMI: OnAppRegistered(params) +-- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() +-- SDL->appID: SUCCESS, success:"true": SubscribeButtons() +-- SDL->appID: OnHashChange +-- +-- 2. SDL successfully registers application and notifies mobile only with RAI response +-- SDL->appID: RESUME_FAILED, success:"true":RegisterAppInterface() +-- application remains registered internally +-- application does not send OnAppUnregistered notification to HMI +-- application does not send OnAppRegistered notification to HMI +-- SDL->HMI: Buttons.OnButtonSubscription, isSubscribed = false, name = PRESET_0 + +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 + +-- [[ Required Shared Libraries ]] +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") + +local mobile = require("mobile_connection") +local mobile_session = require("mobile_session") + +local tcp = require("tcp_connection") +local file_connection = require("file_connection") + +--[[ General Settings for configuration ]] +Test = require("user_modules/connecttest_iap2_emulation") +require("cardinalities") +require("user_modules/AppTypes") + +-- [[Local variables]] +local app_RAI_params = config["application1"].registerAppInterfaceParams + +--[[ +IN ORDER TO USE IAP2 EMULATION IN SDL IT MUST BE BUILT ON +https://github.com/dev-gh/sdl_core/tree/experimental/IAP_adapters_emulation +WITH +BUILD_TESTS = ON +]] +local iAP2_BT_DeviceID = "127.0.0.1" +local iAP2_BT_Port = 23456 +local iAP2_BT_out = "iap2bt.out" +local iAP2_BT_Type = "BLUETOOTH" + +-- Device IDs must be the same in order to trigger switching logic +local iAP2_USB_DeviceID = iAP2_BT_DeviceID +local iAP2_USB_Port = 34567 +local iAP2_USB_out = "iap2usb.out" +local iAP2_USB_Type = "USB_IOS" + +--[[ Preconditions ]] +commonFunctions:newTestCasesGroup("Preconditions") +commonSteps:DeletePolicyTable() +commonSteps:DeleteLogsFiles() + +local function createIAP2Device(deviceID, devicePort, deviceOut) + local iap2Connection = tcp.Connection(deviceID, devicePort) + local fileConnection = file_connection.FileConnection(deviceOut, iap2Connection) + local iap2Device = mobile.MobileConnection(fileConnection) + + event_dispatcher:AddConnection(iap2Device) + + return iap2Device +end + +--[[ Test ]] +commonFunctions:newTestCasesGroup("Test") + +local iap2bt_device = 0 +local iap2bt_mobileSession = 0 + +Test["Connecting iAP2 Bluetooth"] = + function(self) + -- iAP2 Bluetooth connection with application registered + iap2bt_device = createIAP2Device(iAP2_BT_DeviceID, iAP2_BT_Port, iAP2_BT_out) + + Test:connectMobile(iap2bt_device) + + iap2bt_mobileSession = mobile_session.MobileSession(self, iap2bt_device, app_RAI_params) + + local rpc_service_id = 7 + iap2bt_mobileSession:StartService(rpc_service_id):Do( + function() + local correlation_id = iap2bt_mobileSession:SendRPC("RegisterAppInterface", app_RAI_params) + iap2bt_mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "SUCCESS"}) + + EXPECT_HMINOTIFICATION( + "Buttons.OnButtonSubscription", + { + isSubscribed = true, + name = "CUSTOM_BUTTON" + } + ) + end + ) +end + +Test["Adding data for resumption"] = + function() + local correlation_id = iap2bt_mobileSession:SendRPC("SubscribeButton", {buttonName = "PRESET_0"}) + + EXPECT_HMINOTIFICATION( + "Buttons.OnButtonSubscription", + { + isSubscribed = true, + name = "PRESET_0" + } + ) + + EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) + + EXPECT_NOTIFICATION("OnHashChange", iap2bt_mobileSession) +end + +Test["Connecting iAP2 USB"] = + function(self) + -- iAP2 USB connection with same application + local iap2usb_device = createIAP2Device(iAP2_USB_DeviceID, iAP2_USB_Port, iAP2_USB_out) + + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered"):Times(0) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Times(0) + + EXPECT_HMICALL( + "BasicCommunication.UpdateDeviceList", + { + -- To check why two devices are in list, maybe an issue + deviceList = { + {id = config.deviceMAC, name = iAP2_BT_DeviceID, transportType = iAP2_BT_Type}, + {id = config.deviceMAC, name = iAP2_USB_DeviceID, transportType = iAP2_USB_Type} + } + } + ):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + + -- Disconnect Bluetooth connection + iap2bt_device:Close() + end + ) + + Test:connectMobile(iap2usb_device) + + local iap2usb_mobileSession = mobile_session.MobileSession(self, iap2usb_device, app_RAI_params) + + local rpc_service_id = 7 + iap2usb_mobileSession:StartService(rpc_service_id):Do( + function() + app_RAI_params.hashID = "some_wrong_hash_id" + local correlation_id = iap2usb_mobileSession:SendRPC("RegisterAppInterface", app_RAI_params) + iap2usb_mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "RESUME_FAILED"}) + end + ) + + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", {isSubscribed = false, name = "PRESET_0"}):Times(1) +end + +-- [[ Postconditions ]] +commonFunctions:newTestCasesGroup("Postcondition") +function Test.Stop_SDL() + StopSDL() +end + +return Test diff --git a/user_modules/connecttest_iap2_emulation.lua b/user_modules/connecttest_iap2_emulation.lua index 4e1bc1488c..a34b55c72b 100644 --- a/user_modules/connecttest_iap2_emulation.lua +++ b/user_modules/connecttest_iap2_emulation.lua @@ -14,6 +14,7 @@ require("atf.util") local Test = require("testbase") local SDL = require("SDL") +local policyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") local websocket = require("websocket_connection") local hmi_connection = require("hmi_connection") @@ -52,6 +53,9 @@ Test.timers = {} --- Add test step with start SDL function Test:RunSDL() + print("Updating policy table") + policyTable:Precondition_updatePolicy_By_overwriting_preloaded_pt("files/jsons/sdl_preloaded_pt_all_allowed.json") + print("Policy table updated") self:runSDL() end @@ -905,6 +909,7 @@ end -- @treturn nil The main result. Always nil. -- @treturn string Additional information on the main result of stopping SDL function StopSDL() + policyTable:Restore_preloaded_pt() event_dispatcher:ClearEvents() Test.expectations_list:Clear() return SDL:StopSDL() From 2ebe6f9499be72b6c0fc5b4e82a91d2ec03565c5 Mon Sep 17 00:00:00 2001 From: "Andrey Oleynik (GitHub)" Date: Wed, 15 Nov 2017 10:43:19 +0200 Subject: [PATCH 288/681] Removes unused code from connecttest_iap... and rename a stop function --- ...oth_to_USB_transport_switch_happy_path.lua | 4 +- ...sport_switch_resume_failed_simple_case.lua | 4 +- user_modules/connecttest_iap2_emulation.lua | 855 +----------------- 3 files changed, 14 insertions(+), 849 deletions(-) diff --git a/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua b/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua index cd89f5b101..a42bf80469 100644 --- a/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua +++ b/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua @@ -151,8 +151,8 @@ end -- [[ Postconditions ]] commonFunctions:newTestCasesGroup("Postcondition") -function Test.Stop_SDL() - StopSDL() +function Test:StopSDL() + StopSDLAndRestorePT() end return Test diff --git a/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua b/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua index a60d5a3803..0b91a158c1 100644 --- a/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua +++ b/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua @@ -181,8 +181,8 @@ end -- [[ Postconditions ]] commonFunctions:newTestCasesGroup("Postcondition") -function Test.Stop_SDL() - StopSDL() +function Test:StopSDL() + StopSDLAndRestorePT() end return Test diff --git a/user_modules/connecttest_iap2_emulation.lua b/user_modules/connecttest_iap2_emulation.lua index a34b55c72b..1edddba69e 100644 --- a/user_modules/connecttest_iap2_emulation.lua +++ b/user_modules/connecttest_iap2_emulation.lua @@ -1,49 +1,10 @@ ----- Provides high level interface for test script creation and base precondition snippets --- --- --- *Dependencies:* `atf.util`, `testbase`, `mobile_connection`, `tcp_connection`, `file_connection`, --- `mobile_session`, `websocket_connection`, `hmi_connection`, `events`, `expectations`, `function_id`, --- `SDL`, `exit_codes`, `load_schema` --- --- *Globals:* `config`, `event_dispatcher`, `xmlReporter`, `table2str`, `func_name_str`, `compareValues`, `qt`, `timers` --- `event_str`, `critical()`, `errmsg`, `quit()`, `AnyNumber()`, `enableFullLoggintTestCase()`, `disableFullLoggintTestCase()` --- @module connecttest --- @copyright [Ford Motor Company](https://smartdevicelink.com/partners/ford/) and [SmartDeviceLink Consortium](https://smartdevicelink.com/consortium/) --- @license +local module = require("user_modules/dummy_connecttest") -require("atf.util") -local Test = require("testbase") local SDL = require("SDL") local policyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") - -local websocket = require("websocket_connection") -local hmi_connection = require("hmi_connection") - -local functionId = require("function_id") -local exit_codes = require("exit_codes") -local load_schema = require("load_schema") -local mob_schema = load_schema.mob_schema -local hmi_schema = load_schema.hmi_schema - -local events = require("events") -local Event = events.Event - local expectations = require("expectations") -local Expectation = expectations.Expectation -local SUCCESS = expectations.SUCCESS -local FAILED = expectations.FAILED ---- Type Test extends Test from testbase module --- @type Test - ---- HMI connection -Test.hmiConnection = hmi_connection.Connection(websocket.WebSocketConnection(config.hmiUrl, config.hmiPort)) -event_dispatcher:AddConnection(Test.hmiConnection) - ---- Notification counter -Test.notification_counter = 1 ---- Tist of timers for specific test -Test.timers = {} +local Expectation = expectations.Expectation -- ========================================================================= -- ========================================================================= @@ -51,23 +12,19 @@ Test.timers = {} -- ========================================================================= -- ========================================================================= ---- Add test step with start SDL -function Test:RunSDL() +function module:RunSDL() print("Updating policy table") policyTable:Precondition_updatePolicy_By_overwriting_preloaded_pt("files/jsons/sdl_preloaded_pt_all_allowed.json") print("Policy table updated") self:runSDL() end ---- Add critical test step with initialize --- HMI with base checks -function Test:InitHMI() +function module:InitHMI() critical(true) self:initHMI() end ---- Add critical test step with performing of onReady communications with base checks -function Test:InitHMI_onReady() +function module:InitHMI_onReady() critical(true) self:initHMI_onReady() end @@ -78,438 +35,7 @@ end -- ========================================================================= -- ========================================================================= ---- Start SDL -function Test:runSDL() - if config.autorunSDL ~= true then - SDL.autoStarted = false - return - end - local result, errmsg = SDL:StartSDL(config.pathToSDL, config.SDL, config.ExitOnCrash) - if not result then - quit(exit_codes.aborted) - end - SDL.autoStarted = true -end - ---- Initialize HMI with base checks -function Test:initHMI() - local function registerComponent(name, subscriptions) - local rid = Test.hmiConnection:SendRequest("MB.registerComponent", {componentName = name}) - local exp = EXPECT_HMIRESPONSE(rid) - if subscriptions then - for _, s in ipairs(subscriptions) do - exp:Do( - function() - local rid = Test.hmiConnection:SendRequest("MB.subscribeTo", {propertyName = s}) - EXPECT_HMIRESPONSE(rid) - end - ) - end - end - end - - EXPECT_HMIEVENT(events.connectedEvent, "Connected websocket"):Do( - function() - registerComponent("Buttons", {"Buttons.OnButtonSubscription"}) - registerComponent("TTS") - registerComponent("VR") - registerComponent( - "BasicCommunication", - { - "BasicCommunication.OnPutFile", - "SDL.OnStatusUpdate", - "SDL.OnAppPermissionChanged", - "BasicCommunication.OnSDLPersistenceComplete", - "BasicCommunication.OnFileRemoved", - "BasicCommunication.OnAppRegistered", - "BasicCommunication.OnAppUnregistered", - "BasicCommunication.PlayTone", - "BasicCommunication.OnSDLClose", - "SDL.OnSDLConsentNeeded", - "BasicCommunication.OnResumeAudioSource" - } - ) - registerComponent( - "UI", - { - "UI.OnRecordStart" - } - ) - registerComponent("VehicleInfo") - registerComponent( - "Navigation", - { - "Navigation.OnAudioDataStreaming", - "Navigation.OnVideoDataStreaming" - } - ) - end - ) - self.hmiConnection:Connect() -end - ---- Perform onReady communications with base checks -function Test:initHMI_onReady() - local function ExpectRequest(name, mandatory, params) - local event = events.Event() - event.level = 2 - event.matches = function(self, data) - return data.method == name - end - return EXPECT_HMIEVENT(event, name):Times(mandatory and 1 or AnyNumber()):Do( - function(_, data) - xmlReporter.AddMessage( - "hmi_connection", - "SendResponse", - { - ["methodName"] = tostring(name), - ["mandatory"] = mandatory, - ["params"] = params - } - ) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", params) - end - ) - end - - local function ExpectNotification(name, mandatory) - xmlReporter.AddMessage(debug.getinfo(1, "n").name, tostring(name)) - local event = events.Event() - event.level = 2 - event.matches = function(self, data) - return data.method == name - end - return EXPECT_HMIEVENT(event, name):Times(mandatory and 1 or AnyNumber()) - end - - ExpectRequest("BasicCommunication.MixingAudioSupported", true, {attenuatedSupported = true}) - ExpectRequest( - "BasicCommunication.GetSystemInfo", - false, - { - ccpu_version = "ccpu_version", - language = "EN-US", - wersCountryCode = "wersCountryCode" - } - ) - ExpectRequest("UI.GetLanguage", true, {language = "EN-US"}) - ExpectRequest("VR.GetLanguage", true, {language = "EN-US"}) - ExpectRequest("TTS.GetLanguage", true, {language = "EN-US"}) - ExpectRequest("UI.ChangeRegistration", false, {}):Pin() - ExpectRequest("TTS.SetGlobalProperties", false, {}):Pin() - ExpectRequest("BasicCommunication.UpdateDeviceList", false, {}):Pin() - ExpectRequest("VR.ChangeRegistration", false, {}):Pin() - ExpectRequest("TTS.ChangeRegistration", false, {}):Pin() - ExpectRequest( - "VR.GetSupportedLanguages", - true, - { - languages = { - "EN-US", - "ES-MX", - "FR-CA", - "DE-DE", - "ES-ES", - "EN-GB", - "RU-RU", - "TR-TR", - "PL-PL", - "FR-FR", - "IT-IT", - "SV-SE", - "PT-PT", - "NL-NL", - "ZH-TW", - "JA-JP", - "AR-SA", - "KO-KR", - "PT-BR", - "CS-CZ", - "DA-DK", - "NO-NO", - "NL-BE", - "EL-GR", - "HU-HU", - "FI-FI", - "SK-SK" - } - } - ) - ExpectRequest( - "TTS.GetSupportedLanguages", - true, - { - languages = { - "EN-US", - "ES-MX", - "FR-CA", - "DE-DE", - "ES-ES", - "EN-GB", - "RU-RU", - "TR-TR", - "PL-PL", - "FR-FR", - "IT-IT", - "SV-SE", - "PT-PT", - "NL-NL", - "ZH-TW", - "JA-JP", - "AR-SA", - "KO-KR", - "PT-BR", - "CS-CZ", - "DA-DK", - "NO-NO", - "NL-BE", - "EL-GR", - "HU-HU", - "FI-FI", - "SK-SK" - } - } - ) - ExpectRequest( - "UI.GetSupportedLanguages", - true, - { - languages = { - "EN-US", - "ES-MX", - "FR-CA", - "DE-DE", - "ES-ES", - "EN-GB", - "RU-RU", - "TR-TR", - "PL-PL", - "FR-FR", - "IT-IT", - "SV-SE", - "PT-PT", - "NL-NL", - "ZH-TW", - "JA-JP", - "AR-SA", - "KO-KR", - "PT-BR", - "CS-CZ", - "DA-DK", - "NO-NO", - "NL-BE", - "EL-GR", - "HU-HU", - "FI-FI", - "SK-SK" - } - } - ) - ExpectRequest( - "VehicleInfo.GetVehicleType", - true, - { - vehicleType = { - make = "Ford", - model = "Fiesta", - modelYear = "2013", - trim = "SE" - } - } - ) - ExpectRequest("VehicleInfo.GetVehicleData", true, {vin = "52-452-52-752"}) - - local function button_capability(name, shortPressAvailable, longPressAvailable, upDownAvailable) - return { - name = name, - shortPressAvailable = shortPressAvailable == nil and true or shortPressAvailable, - longPressAvailable = longPressAvailable == nil and true or longPressAvailable, - upDownAvailable = upDownAvailable == nil and true or upDownAvailable - } - end - - local buttons_capabilities = { - capabilities = { - button_capability("PRESET_0"), - button_capability("PRESET_1"), - button_capability("PRESET_2"), - button_capability("PRESET_3"), - button_capability("PRESET_4"), - button_capability("PRESET_5"), - button_capability("PRESET_6"), - button_capability("PRESET_7"), - button_capability("PRESET_8"), - button_capability("PRESET_9"), - button_capability("OK", true, false, true), - button_capability("SEEKLEFT"), - button_capability("SEEKRIGHT"), - button_capability("TUNEUP"), - button_capability("TUNEDOWN") - }, - presetBankCapabilities = {onScreenPresetsAvailable = true} - } - ExpectRequest("Buttons.GetCapabilities", true, buttons_capabilities) - ExpectRequest("VR.GetCapabilities", true, {vrCapabilities = {"TEXT"}}) - ExpectRequest( - "TTS.GetCapabilities", - true, - { - speechCapabilities = {"TEXT", "PRE_RECORDED"}, - prerecordedSpeechCapabilities = { - "HELP_JINGLE", - "INITIAL_JINGLE", - "LISTEN_JINGLE", - "POSITIVE_JINGLE", - "NEGATIVE_JINGLE" - } - } - ) - - local function text_field(name, characterSet, width, rows) - return { - name = name, - characterSet = characterSet or "TYPE2SET", - width = width or 500, - rows = rows or 1 - } - end - local function image_field(name, width, height) - return { - name = name, - imageTypeSupported = { - "GRAPHIC_BMP", - "GRAPHIC_JPEG", - "GRAPHIC_PNG" - }, - imageResolution = { - resolutionWidth = width or 64, - resolutionHeight = height or 64 - } - } - end - - ExpectRequest( - "UI.GetCapabilities", - true, - { - displayCapabilities = { - displayType = "GEN2_8_DMA", - textFields = { - text_field("mainField1"), - text_field("mainField2"), - text_field("mainField3"), - text_field("mainField4"), - text_field("statusBar"), - text_field("mediaClock"), - text_field("mediaTrack"), - text_field("alertText1"), - text_field("alertText2"), - text_field("alertText3"), - text_field("scrollableMessageBody"), - text_field("initialInteractionText"), - text_field("navigationText1"), - text_field("navigationText2"), - text_field("ETA"), - text_field("totalDistance"), - text_field("navigationText"), - text_field("audioPassThruDisplayText1"), - text_field("audioPassThruDisplayText2"), - text_field("sliderHeader"), - text_field("sliderFooter"), - text_field("notificationText"), - text_field("menuName"), - text_field("secondaryText"), - text_field("tertiaryText"), - text_field("timeToDestination"), - text_field("turnText"), - text_field("menuTitle"), - text_field("locationName"), - text_field("locationDescription"), - text_field("addressLines"), - text_field("phoneNumber") - }, - imageFields = { - image_field("softButtonImage"), - image_field("choiceImage"), - image_field("choiceSecondaryImage"), - image_field("vrHelpItem"), - image_field("turnIcon"), - image_field("menuIcon"), - image_field("cmdIcon"), - image_field("showConstantTBTIcon"), - image_field("locationImage") - }, - mediaClockFormats = { - "CLOCK1", - "CLOCK2", - "CLOCK3", - "CLOCKTEXT1", - "CLOCKTEXT2", - "CLOCKTEXT3", - "CLOCKTEXT4" - }, - graphicSupported = true, - imageCapabilities = {"DYNAMIC", "STATIC"}, - templatesAvailable = {"TEMPLATE"}, - screenParams = { - resolution = {resolutionWidth = 800, resolutionHeight = 480}, - touchEventAvailable = { - pressAvailable = true, - multiTouchAvailable = true, - doublePressAvailable = false - } - }, - numCustomPresetsAvailable = 10 - }, - audioPassThruCapabilities = { - samplingRate = "44KHZ", - bitsPerSample = "8_BIT", - audioType = "PCM" - }, - hmiZoneCapabilities = "FRONT", - softButtonCapabilities = { - { - shortPressAvailable = true, - longPressAvailable = true, - upDownAvailable = true, - imageSupported = true - } - }, - systemCapabilities = { - navigationCapability = { - sendLocationEnabled = true, - getWayPointsEnabled = true - }, - phoneCapability = { - dialNumberEnabled = true - } - } - } - ) - - ExpectRequest("VR.IsReady", true, {available = true}) - ExpectRequest("TTS.IsReady", true, {available = true}) - ExpectRequest("UI.IsReady", true, {available = true}) - ExpectRequest("Navigation.IsReady", true, {available = true}) - ExpectRequest("VehicleInfo.IsReady", true, {available = true}) - - self.applications = {} - ExpectRequest("BasicCommunication.UpdateAppList", false, {}):Pin():Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - self.applications = {} - for _, app in pairs(data.params.applications) do - self.applications[app.appName] = app.appID - end - end - ) - - self.hmiConnection:SendNotification("BasicCommunication.OnReady") -end - ---- Open default mobile conection and add mobile disconnect expectation -function Test:connectMobile(device, exitOnDisconnect) - -- Disconnected expectation +function module:connectMobile(device, exitOnDisconnect) EXPECT_EVENT(events.disconnectedEvent, "Disconnected", device):Pin():Times(AnyNumber()):Do( function() print("Device disconnected: " .. device.connection.filename) @@ -522,8 +48,7 @@ function Test:connectMobile(device, exitOnDisconnect) return EXPECT_EVENT(events.connectedEvent, "Connected", device) end ---- Start default mobile session on default mobile conection -function Test:startSession(session) +function module:startSession(session) session:Start() EXPECT_HMICALL("BasicCommunication.UpdateAppList"):Do( function(_, data) @@ -542,188 +67,7 @@ end -- ========================================================================= -- ========================================================================= -function Test.hmiConnection:EXPECT_HMIRESPONSE(id, args) - local event = events.Event() - event.matches = function(self, data) - return data.id == id - end - local ret = Expectation("HMI response " .. id, self) - ret:ValidIf( - function(self, data) - local arguments - if self.occurences > #args then - arguments = args[#args] - else - arguments = args[self.occurences] - end - - xmlReporter.AddMessage( - "EXPECT_HMIRESPONSE", - {["Id"] = tostring(id), ["Type"] = "EXPECTED_RESULT"}, - arguments - ) - xmlReporter.AddMessage("EXPECT_HMIRESPONSE", {["Id"] = tostring(id), ["Type"] = "AVALIABLE_RESULT"}, data) - local func_name = data.method - local results_args = arguments - local results_args2 = arguments - if (table2str(arguments):match("result")) then - results_args = arguments.result - results_args2 = arguments.result - elseif (table2str(arguments):match("error")) then - results_args = arguments.error - results_args2 = arguments.error - end - - if results_args2 then - if results_args2.code then - results_args2 = table.removeKey(results_args2, "code") - end - if results_args2.method then - results_args2 = table.removeKey(results_args2, "method") - elseif results_args2.data and results_args2.data.method then - results_args2 = table.removeKey(results_args2.data, "method") - end - end - - if func_name == nil and type(data.result) == "table" then - func_name = data.result.method - elseif func_name == nil and type(data.error) == "table" then - func_name = data.error.data.method - end - - local _res, _err - _res = true - if not (table2str(arguments):match("error")) then - _res, _err = hmi_schema:Validate(func_name, load_schema.response, data.params) - end - if (not _res) then - return _res, _err - end - - if func_name and results_args and data.result then - return compareValues(results_args, data.result, "result") - elseif func_name and results_args and data.error then - return compareValues(results_args, data.error, "error") - else - return compareValues(results_args, data.params, "params") - end - end - ) - ret.event = event - event_dispatcher:AddEvent(Test.hmiConnection, event, ret) - Test:AddExpectation(ret) - return ret -end - ---- Global functions --- @section Global - ---- Create expectation for specific HMI resonse and add it to expectation list --- @tparam number id Correlation identifier --- @tparam table ... Expectation parameters --- @treturn Expectation Expectation -function EXPECT_HMIRESPONSE(id, ...) - local args = table.pack(...) - return Test.hmiConnection:EXPECT_HMIRESPONSE(id, args) -end - ---- Create expectation for specific HMI notification and add it to expectation list --- @tparam string name Notification name --- @tparam table ... Expectation parameters --- @treturn Expectation Expectation -function EXPECT_HMINOTIFICATION(name, ...) - local args = table.pack(...) - local event = events.Event() - event.matches = function(self, data) - return data.method == name - end - local ret = Expectation("HMI notification " .. name, Test.hmiConnection) - if #args > 0 then - ret:ValidIf( - function(self, data) - local arguments - if self.occurences > #args then - arguments = args[#args] - else - arguments = args[self.occurences] - end - local correlation_id = Test.notification_counter - Test.notification_counter = Test.notification_counter + 1 - xmlReporter.AddMessage( - "EXPECT_HMINOTIFICATION", - {["Id"] = correlation_id, ["name"] = tostring(name), ["Type"] = "EXPECTED_RESULT"}, - arguments - ) - xmlReporter.AddMessage( - "EXPECT_HMINOTIFICATION", - {["Id"] = correlation_id, ["name"] = tostring(name), ["Type"] = "AVALIABLE_RESULT"}, - data - ) - local _res, _err = hmi_schema:Validate(name, load_schema.notification, data.params) - if (not _res) then - return _res, _err - end - return compareValues(arguments, data.params, "params") - end - ) - end - ret.event = event - event_dispatcher:AddEvent(Test.hmiConnection, event, ret) - Test:AddExpectation(ret) - return ret -end - ---- Create expectation for specific HMI call and add it to expectation list --- @tparam string methodName Method name --- @tparam table ... Expectation parameters --- @treturn Expectation Expectation -function EXPECT_HMICALL(methodName, ...) - local args = table.pack(...) - -- TODO: Avoid copy-paste - local event = events.Event() - event.matches = function(self, data) - return data.method == methodName - end - local ret = Expectation("HMI call " .. methodName, Test.hmiConnection) - if #args > 0 then - ret:ValidIf( - function(self, data) - local arguments - if self.occurences > #args then - arguments = args[#args] - else - arguments = args[self.occurences] - end - xmlReporter.AddMessage( - "EXPECT_HMICALL", - {["Id"] = data.id, ["name"] = tostring(methodName), ["Type"] = "EXPECTED_RESULT"}, - arguments - ) - xmlReporter.AddMessage( - "EXPECT_HMICALL", - {["Id"] = data.id, ["name"] = tostring(methodName), ["Type"] = "AVALIABLE_RESULT"}, - data.params - ) - _res, _err = hmi_schema:Validate(methodName, load_schema.request, data.params) - if (not _res) then - return _res, _err - end - return compareValues(arguments, data.params, "params") - end - ) - end - ret.event = event - event_dispatcher:AddEvent(Test.hmiConnection, event, ret) - Test:AddExpectation(ret) - return ret -end - ---- Create expectation for specific mobile notification from default session and add it to expectation list --- @tparam string func Notification name --- @tparam table ... Expectation parameters --- @treturn Expectation Expectation function EXPECT_NOTIFICATION(func, session, ...) - -- xmlReporter.AddMessage(debug.getinfo(1, "n").name, "EXPECTED_RESULT", ... ) local args = table.pack(...) local args_count = 1 if #args > 0 then @@ -742,203 +86,24 @@ function EXPECT_NOTIFICATION(func, session, ...) return session:ExpectNotification(func, args) end ---- Create expectation for specific mobile notification from any session and add it to expectation list --- @tparam string funcName Notification name --- @tparam table ... Expectation parameters --- @treturn Expectation Expectation -function EXPECT_ANY_SESSION_NOTIFICATION(funcName, device, ...) - local args = table.pack(...) - local event = events.Event() - event.matches = function(_, data) - return data.rpcFunctionId == functionId[funcName] - end - local ret = Expectation(funcName .. " notification", device) - if #args > 0 then - ret:ValidIf( - function(self, data) - local arguments - if self.occurences > #args then - arguments = args[#args] - else - arguments = args[self.occurences] - end - local _res, _err = mob_schema:Validate(funcName, load_schema.notification, data.payload) - xmlReporter.AddMessage( - "EXPECT_ANY_SESSION_NOTIFICATION", - {["name"] = tostring(funcName), ["Type"] = "EXPECTED_RESULT"}, - arguments - ) - xmlReporter.AddMessage( - "EXPECT_ANY_SESSION_NOTIFICATION", - {["name"] = tostring(funcName), ["Type"] = "AVALIABLE_RESULT"}, - data.payload - ) - if (not _res) then - return _res, _err - end - return compareValues(arguments, data.payload, "payload") - end - ) - end - ret.event = event - event_dispatcher:AddEvent(device, event, ret) - Test.expectations_list:Add(ret) - return ret -end - ---- Run function after specified delay --- @tparam function func Function to run --- @tparam number timeout Delay in msec --- @tparam ?string funcName function name -function RUN_AFTER(func, timeout, funcName) - func_name_str = "noname" - if funcName then - func_name_str = funcName - end - -- xmlReporter.AddMessage(debug.getinfo(1, "n").name, func_name_str, - -- {["functionLine"] = debug.getinfo(func, "S").linedefined, ["Timeout"] = tostring(timeout)}) - local d = qt.dynamic() - d.timeout = function(self) - func() - Test.timers[self] = nil - end - local timer = timers.Timer() - Test.timers[timer] = true - qt.connect(timer, "timeout()", d, "timeout()") - timer:setSingleShot(true) - timer:start(timeout) -end - ---- Create expectation for specific mobile response from default session and add it to expectation list --- @tparam number correlationId Correlation identifier --- @tparam table ... Expectation parameters --- @treturn Expectation Expectation function EXPECT_RESPONSE(correlationId, session, ...) xmlReporter.AddMessage(debug.getinfo(1, "n").name, "EXPECTED_RESULT", ...) return session:ExpectResponse(correlationId, ...) end ---- Create expectation for specific mobile response from any session and add it to expectation list --- @tparam number correlationId Correlation identifier --- @tparam table ... Expectation parameters --- @treturn Expectation Expectation -function EXPECT_ANY_SESSION_RESPONSE(correlationId, device, ...) - xmlReporter.AddMessage(debug.getinfo(1, "n").name, {["CorrelationId"] = tostring(correlationId)}) - local args = table.pack(...) - local event = events.Event() - event.matches = function(_, data) - return data.rpcCorrelationId == correlationId - end - local ret = Expectation("response to " .. correlationId, device) - if #args > 0 then - ret:ValidIf( - function(self, data) - local arguments - if self.occurences > #args then - arguments = args[#args] - else - arguments = args[self.occurences] - end - xmlReporter.AddMessage("EXPECT_ANY_SESSION_RESPONSE", "EXPECTED_RESULT", arguments) - xmlReporter.AddMessage("EXPECT_ANY_SESSION_RESPONSE", "AVALIABLE_RESULT", data.payload) - return compareValues(arguments, data.payload, "payload") - end - ) - end - ret.event = event - event_dispatcher:AddEvent(device, event, ret) - Test.expectations_list:Add(ret) - return ret -end - ---- Create expectation for any mobile event and add it to expectation list --- @treturn Expectation Expectation -function EXPECT_ANY(session) - xmlReporter.AddMessage(debug.getinfo(1, "n").name, "") - return session:ExpectAny() -end - ---- Create expectation for specific mobile event and add it to expectation list --- @tparam Event event Event for expectation --- @tparam string name Event name --- @treturn Expectation Expectation function EXPECT_EVENT(event, name, device) local ret = Expectation(name, device) ret.event = event event_dispatcher:AddEvent(device, event, ret) - Test:AddExpectation(ret) + module:AddExpectation(ret) return ret end ---- Raise specific event --- @tparam Event event Event --- @tparam table data Data for rise event --- @tparam ?string eventName Event name -function RAISE_EVENT(event, data, eventName, device) - event_str = "noname" - if eventName then - event_str = eventName - end - xmlReporter.AddMessage(debug.getinfo(1, "n").name, event_str) - event_dispatcher:RaiseEvent(device, data) -end - ---- Create expectation for specific HMI event and add it to expectation list --- @tparam Event event Event for expectation --- @tparam string name Event name --- @treturn Expectation Expectation -function EXPECT_HMIEVENT(event, name) - xmlReporter.AddMessage(debug.getinfo(1, "n").name, name) - local ret = Expectation(name, Test.hmiConnection) - ret.event = event - event_dispatcher:AddEvent(Test.hmiConnection, event, ret) - Test:AddExpectation(ret) - return ret -end - ---- Start SDL --- @tparam string SDLPathName Path to SDL --- @tparam boolean ExitOnCrash Flag whether Stop ATF in case SDL shutdown --- @treturn boolean The main result. Indicates whether the launch of SDL was successful --- @treturn string Additional information on the main SDL startup result -function StartSDL(SDLPathName, ExitOnCrash) - return SDL:StartSDL(SDLPathName, config.SDL, ExitOnCrash) -end - ---- Stop SDL --- @treturn nil The main result. Always nil. --- @treturn string Additional information on the main result of stopping SDL -function StopSDL() +function StopSDLAndRestorePT() policyTable:Restore_preloaded_pt() event_dispatcher:ClearEvents() Test.expectations_list:Clear() return SDL:StopSDL() end ---- Create test step for enable full ATF logs -function enableFullATFLogs() - function enableFullLoggintTestCase() - if (config.storeFullATFLogs) then - Test:FailTestCase("full ATF logs already enabled") - else - config.storeFullATFLogs = true - end - end - Test["EnableFullATFLogs"] = nil - Test["EnableFullATFLogs"] = enableFullLoggintTestCase -end - ---- Create test step for disable full ATF logs -function disableFullATFLogs() - function disableFullLoggintTestCase() - if (not config.storeFullATFLogs) then - Test:FailTestCase("full ATF logs already disabled") - else - config.storeFullATFLogs = false - end - end - Test["DisableFullATFLogs"] = nil - Test["DisableFullATFLogs"] = disableFullLoggintTestCase -end - -return Test +return module From ccc5a7bc16a9eca9ef3a2b1fd8c210bdbab639cd Mon Sep 17 00:00:00 2001 From: "Andrey Oleynik (GitHub)" Date: Tue, 21 Nov 2017 15:42:34 +0200 Subject: [PATCH 289/681] Adds full resume data check test for failed resume for swiched app If switched application sends wrong hash id (or it is missing) all resume data must be cleaned up, files removed etc. --- ...switch_resume_failed_remove_data_check.lua | 527 ++++++++++++++++++ 1 file changed, 527 insertions(+) create mode 100644 test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_remove_data_check.lua diff --git a/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_remove_data_check.lua b/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_remove_data_check.lua new file mode 100644 index 0000000000..79973d92ca --- /dev/null +++ b/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_remove_data_check.lua @@ -0,0 +1,527 @@ +-- Requirement summary: +-- TBD +-- +-- Description: +-- iAP2 Bluetooth connection is switched to iAP2 USB connection automatically, application(s) remains registered, +-- but application(s) sends wrong hashID or it's absent so all resume data must be cleaned up +-- +-- 1. Used precondition +-- SDL is built with BUILD_TEST = ON to enable iAP2 BT/USB transport adapter emulation +-- SDL, HMI are running on system. +-- +-- 2. Performed steps +-- iAP2 Bluetooth mobile device connects to system +-- appID_1->RegisterAppInterface(params) +-- RAI response is SUCCESS +-- application subscribes for buttons, vehicle data, waypoints, sends files, commands, choices etc. +-- +-- same iAP2 mobile device is connected over USB to system and re-registers within AppTransportChangeTimer timeout +-- appID_1->RegisterAppInterface(params), but with wrong hashID +-- all resume data must be cleaned up, global properties should be reset, files (except icon) removed +-- +-- Expected behavior: +-- 1. SDL successfully registers application and notifies HMI and mobile +-- SDL->HMI: OnAppRegistered(params) +-- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() +-- application send all possible data for resumption and files +-- +-- 2. SDL successfully registers application and notifies mobile only with RAI response +-- SDL->appID: RESUME_FAILED, success:"true":RegisterAppInterface() +-- application remains registered internally +-- application does not send OnAppUnregistered notification to HMI +-- application does not send OnAppRegistered notification to HMI +-- all resume data cleaned up or reset, files (except icon) removed + +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 + +-- [[ Required Shared Libraries ]] +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") + +local mobile = require("mobile_connection") +local mobile_session = require("mobile_session") + +local tcp = require("tcp_connection") +local file_connection = require("file_connection") + +--[[ General Settings for configuration ]] +Test = require("user_modules/connecttest_iap2_emulation") +require("cardinalities") +require("user_modules/AppTypes") + +-- [[Local variables]] +local app_RAI_params = config["application1"].registerAppInterfaceParams +local light_cyan_color = 36 +local put_file_name = "file.json" +local icon_file_name = "icon.png" + +--[[ +IN ORDER TO USE IAP2 EMULATION IN SDL IT MUST BE BUILT ON +https://github.com/dev-gh/sdl_core/tree/experimental/IAP_adapters_emulation +WITH +BUILD_TESTS = ON +]] +local iAP2_BT_DeviceID = "127.0.0.1" +local iAP2_BT_Port = 23456 +local iAP2_BT_out = "iap2bt.out" +local iAP2_BT_Type = "BLUETOOTH" + +-- Device IDs must be the same in order to trigger switching logic +local iAP2_USB_DeviceID = iAP2_BT_DeviceID +local iAP2_USB_Port = 34567 +local iAP2_USB_out = "iap2usb.out" +local iAP2_USB_Type = "USB_IOS" + +local function createIAP2Device(deviceID, devicePort, deviceOut) + local iap2Connection = tcp.Connection(deviceID, devicePort) + local fileConnection = file_connection.FileConnection(deviceOut, iap2Connection) + local iap2Device = mobile.MobileConnection(fileConnection) + + event_dispatcher:AddConnection(iap2Device) + + return iap2Device +end + +local function isFileExisting(file_name) + -- Device id produced for iAP2 Bluetooth by SDL = hashed device id + local device_id = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" + return commonFunctions:File_exists( + config.pathToSDL .. "storage/" .. app_RAI_params.appID .. "_" .. device_id .. "/" .. file_name + ) +end + +local function AddFileForApplication(session, file_name, file_type) + local correlation_id = + session:SendRPC( + "PutFile", + { + syncFileName = file_name, + fileType = file_type, + persistentFile = false, + systemFile = false + }, + "files/" .. file_name + ) + EXPECT_RESPONSE(correlation_id, session, {success = true}):Do( + function(_, data) + if true ~= isFileExisting(file_name) then + Test:FailTestCase("File '" .. file_name .. "' is not found") + end + end + ) +end + +--[[ Preconditions ]] +commonFunctions:newTestCasesGroup("Preconditions") +commonSteps:DeletePolicyTable() +commonSteps:DeleteLogsFiles() + +local iap2bt_device = 0 +local iap2bt_mobileSession = 0 + +Test["Connecting iAP2 Bluetooth"] = + function(self) + -- iAP2 Bluetooth connection with application registered + iap2bt_device = createIAP2Device(iAP2_BT_DeviceID, iAP2_BT_Port, iAP2_BT_out) + + Test:connectMobile(iap2bt_device) + + iap2bt_mobileSession = mobile_session.MobileSession(self, iap2bt_device, app_RAI_params) + + local rpc_service_id = 7 + iap2bt_mobileSession:StartService(rpc_service_id):Do( + function() + local correlation_id = iap2bt_mobileSession:SendRPC("RegisterAppInterface", app_RAI_params) + iap2bt_mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "SUCCESS"}) + + EXPECT_HMINOTIFICATION( + "Buttons.OnButtonSubscription", + { + isSubscribed = true, + name = "CUSTOM_BUTTON" + } + ) + end + ) +end + +Test["Adding way points subsription"] = + function(self) + local correlation_id = iap2bt_mobileSession:SendRPC("SubscribeWayPoints", {}) + EXPECT_HMICALL("Navigation.SubscribeWayPoints"):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ) + EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) + EXPECT_NOTIFICATION("OnHashChange", iap2bt_mobileSession) +end + +Test["Adding command"] = + function(self) + local correlation_id = + iap2bt_mobileSession:SendRPC( + "AddCommand", + { + cmdID = 1, + menuParams = { + position = 0, + menuName = "Command" + }, + vrCommands = { + "VRCommandonepositive" + } + } + ) + + EXPECT_HMICALL( + "UI.AddCommand", + { + cmdID = 1, + menuParams = { + position = 0, + menuName = "Command" + } + } + ):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ) + + EXPECT_HMICALL( + "VR.AddCommand", + { + cmdID = 1, + type = "Command", + vrCommands = { + "VRCommandonepositive" + } + } + ):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ) + + EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) + EXPECT_NOTIFICATION("OnHashChange", iap2bt_mobileSession) +end + +Test["Adding submenu"] = + function(self) + local id = 11 + local correlation_id = + iap2bt_mobileSession:SendRPC( + "AddSubMenu", + { + menuID = id, + menuName = "SubMenumandatoryonly" + } + ) + EXPECT_HMICALL( + "UI.AddSubMenu", + { + menuID = id, + menuParams = { + menuName = "SubMenumandatoryonly" + } + } + ):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ) + + EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) + EXPECT_NOTIFICATION("OnHashChange", iap2bt_mobileSession) +end + +Test["Adding choice set"] = + function(self) + local id = 123 + local correlation_id = + iap2bt_mobileSession:SendRPC( + "CreateInteractionChoiceSet", + { + interactionChoiceSetID = id, + choiceSet = { + { + choiceID = id, + menuName = "Choice" .. id, + vrCommands = { + "VRChoice" .. id + } + } + } + } + ) + + EXPECT_HMICALL( + "VR.AddCommand", + { + cmdID = id, + type = "Choice", + vrCommands = {"VRChoice" .. id} + } + ):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ) + + EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) + EXPECT_NOTIFICATION("OnHashChange", iap2bt_mobileSession) +end + +Test["Adding global properties"] = + function(self) + local correlation_id = + iap2bt_mobileSession:SendRPC( + "SetGlobalProperties", + { + helpPrompt = {{text = "Speak", type = "TEXT"}}, + timeoutPrompt = {{text = "Hello", type = "TEXT"}}, + vrHelpTitle = "Options", + vrHelp = {{position = 1, text = "OK"}} + } + ) + + EXPECT_HMICALL("UI.SetGlobalProperties"):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ) + + EXPECT_HMICALL("TTS.SetGlobalProperties"):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ) + + EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) + EXPECT_NOTIFICATION("OnHashChange", iap2bt_mobileSession) +end + +Test["Adding button subscription"] = + function() + local correlation_id = iap2bt_mobileSession:SendRPC("SubscribeButton", {buttonName = "PRESET_0"}) + + EXPECT_HMINOTIFICATION( + "Buttons.OnButtonSubscription", + { + isSubscribed = true, + name = "PRESET_0" + } + ) + + EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) + + EXPECT_NOTIFICATION("OnHashChange", iap2bt_mobileSession) +end + +Test["Adding vehicle info subsription"] = + function(self) + local correlation_id = iap2bt_mobileSession:SendRPC("SubscribeVehicleData", {odometer = true}) + EXPECT_HMICALL("VehicleInfo.SubscribeVehicleData"):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ) + EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) +end + +Test["Adding regular file"] = function(self) + AddFileForApplication(iap2bt_mobileSession, put_file_name, "JSON") +end + +Test["Adding application icon"] = + function(self) + AddFileForApplication(iap2bt_mobileSession, icon_file_name, "GRAPHIC_PNG") + + local correlation_id = iap2bt_mobileSession:SendRPC("SetAppIcon", {syncFileName = icon_file_name}) + + EXPECT_HMICALL("UI.SetAppIcon"):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ) + + EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {resultCode = "SUCCESS", success = true}) +end + +--[[ Test ]] +commonFunctions:newTestCasesGroup("Test") + +local isChoiceRemoved = false +local isCommandRemoved = false + +Test["Connecting iAP2 USB"] = + function(self) + -- iAP2 USB connection with same application + local iap2usb_device = createIAP2Device(iAP2_USB_DeviceID, iAP2_USB_Port, iAP2_USB_out) + + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered"):Times(0) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Times(0) + + EXPECT_HMICALL( + "BasicCommunication.UpdateDeviceList", + { + -- To check why two devices are in list, maybe an issue + deviceList = { + {id = config.deviceMAC, name = iAP2_BT_DeviceID, transportType = iAP2_BT_Type}, + {id = config.deviceMAC, name = iAP2_USB_DeviceID, transportType = iAP2_USB_Type} + } + } + ):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + + -- Disconnect Bluetooth connection + iap2bt_device:Close() + end + ) + + Test:connectMobile(iap2usb_device) + + local iap2usb_mobileSession = mobile_session.MobileSession(self, iap2usb_device, app_RAI_params) + + local rpc_service_id = 7 + iap2usb_mobileSession:StartService(rpc_service_id):Do( + function() + app_RAI_params.hashID = "some_wrong_hash_id" + local correlation_id = iap2usb_mobileSession:SendRPC("RegisterAppInterface", app_RAI_params) + iap2usb_mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "RESUME_FAILED"}) + end + ) + + EXPECT_HMICALL("Navigation.UnsubscribeWayPoints"):Do( + function(_, data) + commonFunctions:userPrint(light_cyan_color, "Unsubscribed from waypoints") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ) + + EXPECT_HMICALL( + "UI.DeleteCommand", + { + cmdID = 1 + } + ):Do( + function(_, data) + commonFunctions:userPrint(light_cyan_color, "UI commands removed") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ) + + EXPECT_HMICALL( + "UI.DeleteSubMenu", + { + menuID = 11 + } + ):Do( + function(_, data) + commonFunctions:userPrint(light_cyan_color, "Submenus removed") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ) + + EXPECT_HMICALL("VR.DeleteCommand"):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ):ValidIf( + function(_, data) + if data.params["type"] == "Choice" then + commonFunctions:userPrint(light_cyan_color, "Choices removed") + isChoiceRemoved = true + end + if data.params["type"] == "Command" then + commonFunctions:userPrint(light_cyan_color, "VR command removed") + isCommandRemoved = true + end + + return true + end + ):Times(AtLeast(1)) + + EXPECT_HMICALL( + "UI.SetGlobalProperties", + { + -- TODO: add more parameters to check + keyboardProperties = { + keyboardLayout = "QWERTY", + language = "EN-US" + }, + vrHelpTitle = "Test Application" + } + ):Do( + function(_, data) + commonFunctions:userPrint(light_cyan_color, "UI global properties removed") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ) + + EXPECT_HMICALL("TTS.SetGlobalProperties"):Do( + function(_, data) + commonFunctions:userPrint(light_cyan_color, "TTS global properties removed") + -- TODO: add more parameters to check + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ) + + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", {isSubscribed = false, name = "PRESET_0"}):Times(1):Do( + function(_, data) + commonFunctions:userPrint(light_cyan_color, "Buttons subscriptions removed") + end + ) + + EXPECT_HMICALL("VehicleInfo.UnsubscribeVehicleData", {odometer = true}):Do( + function(_, data) + commonFunctions:userPrint(light_cyan_color, "Vehicle data subscriptions removed") + self.hmiConnection:SendResponse( + data.id, + data.method, + "SUCCESS", + {odometer = {resultCode = "SUCCESS", dataType = "VEHICLEDATA_ODOMETER"}} + ) + end + ) +end + +Test["Verifying choice/command expectations"] = function(self) + if true ~= isChoiceRemoved then + Test:FailTestCase("Choice hasn't been removed") + end + + if true ~= isCommandRemoved then + Test:FailTestCase("Command hasn't been removed") + end +end + +Test["Verifying file(s) existence after clean-up"] = function(self) + -- Icon must be preserved + if true == isFileExisting(icon_file_name) then + commonFunctions:userPrint(light_cyan_color, "File '" .. icon_file_name .. "' is preserved as expected") + else + Test:FailTestCase("File '" .. icon_file_name .. "' is removed") + end + + -- Other file(s) must be removed + if true ~= isFileExisting(put_file_name) then + commonFunctions:userPrint(light_cyan_color, "File '" .. put_file_name .. "' is removed") + else + Test:FailTestCase("File '" .. put_file_name .. "' is not removed") + end +end + +-- [[ Postconditions ]] +commonFunctions:newTestCasesGroup("Postcondition") +function Test:StopSDL() + StopSDLAndRestorePT() +end + +return Test From ff4277bcb97830b7ee9735dde5ffdf2101f23c56 Mon Sep 17 00:00:00 2001 From: "Andrey Oleynik (GitHub)" Date: Wed, 22 Nov 2017 16:28:26 +0200 Subject: [PATCH 290/681] Adds test for RPCs holding during transport switching --- ...t_switch_commands_hold_while_switching.lua | 184 ++++++++++++++++++ user_modules/connecttest_iap2_emulation.lua | 6 +- 2 files changed, 188 insertions(+), 2 deletions(-) create mode 100644 test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_commands_hold_while_switching.lua diff --git a/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_commands_hold_while_switching.lua b/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_commands_hold_while_switching.lua new file mode 100644 index 0000000000..95e70b2268 --- /dev/null +++ b/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_commands_hold_while_switching.lua @@ -0,0 +1,184 @@ +-- Requirement summary: +-- TBD +-- +-- Description: +-- iAP2 Bluetooth connection is switched to iAP2 USB connection automatically, application(s) remains registered +-- +-- 1. Used precondition +-- SDL is built with BUILD_TEST = ON to enable iAP2 BT/USB transport adapter emulation +-- SDL, HMI are running on system. +-- +-- 2. Performed steps +-- iAP2 Bluetooth mobile device connects to system +-- appID_1->RegisterAppInterface(params) +-- RAI response is SUCCESS +-- +-- same iAP2 mobile device is connected over USB to system and re-registers within AppTransportChangeTimer timeout +-- appID_1->RegisterAppInterface(params) +-- +-- Expected behavior: +-- 1. SDL successfully registers application and notifies HMI and mobile +-- SDL->HMI: OnAppRegistered(params) +-- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() +-- +-- 2. SDL successfully registers application and notifies mobile only with RAI response +-- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() +-- application remains registered internally +-- application does not send OnAppUnregistered notification to HMI +-- application does not send OnAppRegistered notification to HMI + +--------------------------------------------------------------------------------------------------- +--[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 + +-- [[ Required Shared Libraries ]] +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") + +local mobile = require("mobile_connection") +local mobile_session = require("mobile_session") + +local tcp = require("tcp_connection") +local file_connection = require("file_connection") + +--[[ General Settings for configuration ]] +Test = require("user_modules/connecttest_iap2_emulation") +require("cardinalities") +require("user_modules/AppTypes") + +-- [[Local variables]] +local app_RAI_params = config["application1"].registerAppInterfaceParams + +--[[ +IN ORDER TO USE IAP2 EMULATION IN SDL IT MUST BE BUILT ON +https://github.com/dev-gh/sdl_core/tree/experimental/IAP_adapters_emulation +WITH +BUILD_TESTS = ON +]] +local iAP2_BT_DeviceID = "127.0.0.1" +local iAP2_BT_Port = 23456 +local iAP2_BT_out = "iap2bt.out" +local iAP2_BT_Type = "BLUETOOTH" + +-- Device IDs must be the same in order to trigger switching logic +local iAP2_USB_DeviceID = iAP2_BT_DeviceID +local iAP2_USB_Port = 34567 +local iAP2_USB_out = "iap2usb.out" +local iAP2_USB_Type = "USB_IOS" + +local function createIAP2Device(deviceID, devicePort, deviceOut) + local iap2Connection = tcp.Connection(deviceID, devicePort) + local fileConnection = file_connection.FileConnection(deviceOut, iap2Connection) + local iap2Device = mobile.MobileConnection(fileConnection) + + event_dispatcher:AddConnection(iap2Device) + + return iap2Device +end + +--[[ Preconditions ]] +commonFunctions:newTestCasesGroup("Preconditions") +commonSteps:DeletePolicyTable() +commonSteps:DeleteLogsFiles() + +--[[ Test ]] +commonFunctions:newTestCasesGroup("Test") + +local iap2bt_device = 0 +local hmi_app_id = 0 +local iap2usb_mobileSession = 0 + +Test["Connecting iAP2 Bluetooth"] = + function(self) + -- iAP2 Bluetooth connection with application registered + iap2bt_device = createIAP2Device(iAP2_BT_DeviceID, iAP2_BT_Port, iAP2_BT_out) + + EXPECT_HMICALL( + "BasicCommunication.UpdateDeviceList", + { + deviceList = {{id = config.deviceMAC, name = iAP2_BT_DeviceID, transportType = iAP2_BT_Type}} + } + ):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ) + + Test:connectMobile(iap2bt_device) + + local iap2bt_mobileSession = mobile_session.MobileSession(self, iap2bt_device, app_RAI_params) + + Test:startSession(iap2bt_mobileSession) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Do( + function(_, data) + hmi_app_id = data.params.application.appID + end + ) +end + +Test["Connecting iAP2 USB"] = + function(self) + -- iAP2 USB connection with same application + local iap2usb_device = createIAP2Device(iAP2_USB_DeviceID, iAP2_USB_Port, iAP2_USB_out) + + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered"):Times(0) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Times(0) + + EXPECT_HMICALL( + "BasicCommunication.UpdateDeviceList", + { + -- To check why two devices are in list, maybe an issue + deviceList = { + {id = config.deviceMAC, name = iAP2_BT_DeviceID, transportType = iAP2_BT_Type}, + {id = config.deviceMAC, name = iAP2_USB_DeviceID, transportType = iAP2_USB_Type} + } + } + ):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + + -- Disconnect Bluetooth connection + iap2bt_device:Close() + end + ) + + Test:connectMobile(iap2usb_device) + + iap2usb_mobileSession = mobile_session.MobileSession(self, iap2usb_device, app_RAI_params) +end + +local hmi_request_id = 0 +Test["Sending request from HMI, command hold expected"] = function(self) + hmi_request_id = self.hmiConnection:SendRequest("SDL.ActivateApp", {appID = hmi_app_id}) + + EXPECT_HMIRESPONSE(hmi_request_id):Times(0) +end + +Test["Sending notification from HMI, command hold expected"] = function(self) + self.hmiConnection:SendNotification("UI.OnDriverDistraction", {state = "DD_OFF"}) + + EXPECT_NOTIFICATION("OnDriverDistraction", iap2usb_mobileSession):Times(0) +end + +Test["Register app, response is sent to HMI"] = + function(self) + local rpc_service_id = 7 + iap2usb_mobileSession:StartService(rpc_service_id):Do( + function() + local correlationId = iap2usb_mobileSession:SendRPC("RegisterAppInterface", app_RAI_params) + iap2usb_mobileSession:ExpectResponse(correlationId, {success = true, resultCode = "SUCCESS"}) + end + ) + + EXPECT_NOTIFICATION("OnDriverDistraction", iap2usb_mobileSession) + EXPECT_HMIRESPONSE(hmi_request_id, {result = {code = 0, method = "SDL.ActivateApp"}}) +end + +-- [[ Postconditions ]] +commonFunctions:newTestCasesGroup("Postcondition") +function Test:StopSDL() + StopSDLAndRestorePT() +end + +return Test diff --git a/user_modules/connecttest_iap2_emulation.lua b/user_modules/connecttest_iap2_emulation.lua index 1edddba69e..0a9e969848 100644 --- a/user_modules/connecttest_iap2_emulation.lua +++ b/user_modules/connecttest_iap2_emulation.lua @@ -2,6 +2,7 @@ local module = require("user_modules/dummy_connecttest") local SDL = require("SDL") local policyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local expectations = require("expectations") local Expectation = expectations.Expectation @@ -13,9 +14,10 @@ local Expectation = expectations.Expectation -- ========================================================================= function module:RunSDL() - print("Updating policy table") + print("Setting preloaded policy table") policyTable:Precondition_updatePolicy_By_overwriting_preloaded_pt("files/jsons/sdl_preloaded_pt_all_allowed.json") - print("Policy table updated") + print("Setting .ini values") + commonFunctions:SetValuesInIniFile("AppTransportChangeTimer%s-=%s-[%d]-%s-\n", "AppTransportChangeTimer", "5000") self:runSDL() end From 502fe26c5838e95375e5c1705ad91c176bed3095 Mon Sep 17 00:00:00 2001 From: "Andrey Oleynik (GitHub)" Date: Thu, 23 Nov 2017 17:50:22 +0200 Subject: [PATCH 291/681] Renames tests, adds wait function --- ...th_to_USB_transport_switch_happy_path.lua} | 33 +------- ...port_switch_resume_failed_simple_case.lua} | 33 +------- ...witch_resume_failed_remove_data_check.lua} | 75 ++++++------------- ..._switch_commands_hold_while_switching.lua} | 38 ++-------- .../connecttest_iap2_emulation.lua | 50 +++++++++++++ 5 files changed, 84 insertions(+), 145 deletions(-) rename test_scripts/iAP2_Emulation/{iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua => 001_iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua} (80%) rename test_scripts/iAP2_Emulation/{iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua => 002_iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua} (84%) rename test_scripts/iAP2_Emulation/{iAP2_Bluetooth_to_USB_transport_switch_resume_failed_remove_data_check.lua => 003_iAP2_Bluetooth_to_USB_transport_switch_resume_failed_remove_data_check.lua} (92%) rename test_scripts/iAP2_Emulation/{iAP2_Bluetooth_to_USB_transport_switch_commands_hold_while_switching.lua => 004_iAP2_Bluetooth_to_USB_transport_switch_commands_hold_while_switching.lua} (83%) rename {user_modules => test_scripts/iAP2_Emulation}/connecttest_iap2_emulation.lua (72%) diff --git a/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua b/test_scripts/iAP2_Emulation/001_iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua similarity index 80% rename from test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua rename to test_scripts/iAP2_Emulation/001_iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua index a42bf80469..2196a52168 100644 --- a/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua +++ b/test_scripts/iAP2_Emulation/001_iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua @@ -36,52 +36,22 @@ local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") -local mobile = require("mobile_connection") local mobile_session = require("mobile_session") -local tcp = require("tcp_connection") -local file_connection = require("file_connection") - --[[ General Settings for configuration ]] -Test = require("user_modules/connecttest_iap2_emulation") +Test = require("test_scripts/iAP2_Emulation/connecttest_iap2_emulation") require("cardinalities") require("user_modules/AppTypes") -- [[Local variables]] local app_RAI_params = config["application1"].registerAppInterfaceParams ---[[ -IN ORDER TO USE IAP2 EMULATION IN SDL IT MUST BE BUILT ON -https://github.com/dev-gh/sdl_core/tree/experimental/IAP_adapters_emulation -WITH -BUILD_TESTS = ON -]] -local iAP2_BT_DeviceID = "127.0.0.1" -local iAP2_BT_Port = 23456 -local iAP2_BT_out = "iap2bt.out" -local iAP2_BT_Type = "BLUETOOTH" - --- Device IDs must be the same in order to trigger switching logic -local iAP2_USB_DeviceID = iAP2_BT_DeviceID -local iAP2_USB_Port = 34567 -local iAP2_USB_out = "iap2usb.out" -local iAP2_USB_Type = "USB_IOS" --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") commonSteps:DeletePolicyTable() commonSteps:DeleteLogsFiles() -local function createIAP2Device(deviceID, devicePort, deviceOut) - local iap2Connection = tcp.Connection(deviceID, devicePort) - local fileConnection = file_connection.FileConnection(deviceOut, iap2Connection) - local iap2Device = mobile.MobileConnection(fileConnection) - - event_dispatcher:AddConnection(iap2Device) - - return iap2Device -end - --[[ Test ]] commonFunctions:newTestCasesGroup("Test") @@ -147,6 +117,7 @@ Test["Connecting iAP2 USB"] = iap2usb_mobileSession:ExpectResponse(correlationId, {success = true, resultCode = "SUCCESS"}) end ) + Test:waitForAllEvents(2000) end -- [[ Postconditions ]] diff --git a/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua b/test_scripts/iAP2_Emulation/002_iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua similarity index 84% rename from test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua rename to test_scripts/iAP2_Emulation/002_iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua index 0b91a158c1..b1a446723a 100644 --- a/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua +++ b/test_scripts/iAP2_Emulation/002_iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua @@ -42,52 +42,22 @@ local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") -local mobile = require("mobile_connection") local mobile_session = require("mobile_session") -local tcp = require("tcp_connection") -local file_connection = require("file_connection") --[[ General Settings for configuration ]] -Test = require("user_modules/connecttest_iap2_emulation") +Test = require("test_scripts/iAP2_Emulation/connecttest_iap2_emulation") require("cardinalities") require("user_modules/AppTypes") -- [[Local variables]] local app_RAI_params = config["application1"].registerAppInterfaceParams ---[[ -IN ORDER TO USE IAP2 EMULATION IN SDL IT MUST BE BUILT ON -https://github.com/dev-gh/sdl_core/tree/experimental/IAP_adapters_emulation -WITH -BUILD_TESTS = ON -]] -local iAP2_BT_DeviceID = "127.0.0.1" -local iAP2_BT_Port = 23456 -local iAP2_BT_out = "iap2bt.out" -local iAP2_BT_Type = "BLUETOOTH" - --- Device IDs must be the same in order to trigger switching logic -local iAP2_USB_DeviceID = iAP2_BT_DeviceID -local iAP2_USB_Port = 34567 -local iAP2_USB_out = "iap2usb.out" -local iAP2_USB_Type = "USB_IOS" - --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") commonSteps:DeletePolicyTable() commonSteps:DeleteLogsFiles() -local function createIAP2Device(deviceID, devicePort, deviceOut) - local iap2Connection = tcp.Connection(deviceID, devicePort) - local fileConnection = file_connection.FileConnection(deviceOut, iap2Connection) - local iap2Device = mobile.MobileConnection(fileConnection) - - event_dispatcher:AddConnection(iap2Device) - - return iap2Device -end - --[[ Test ]] commonFunctions:newTestCasesGroup("Test") @@ -177,6 +147,7 @@ Test["Connecting iAP2 USB"] = ) EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", {isSubscribed = false, name = "PRESET_0"}):Times(1) + Test:waitForAllEvents(2000) end -- [[ Postconditions ]] diff --git a/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_remove_data_check.lua b/test_scripts/iAP2_Emulation/003_iAP2_Bluetooth_to_USB_transport_switch_resume_failed_remove_data_check.lua similarity index 92% rename from test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_remove_data_check.lua rename to test_scripts/iAP2_Emulation/003_iAP2_Bluetooth_to_USB_transport_switch_resume_failed_remove_data_check.lua index 79973d92ca..eef80f6fbb 100644 --- a/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_resume_failed_remove_data_check.lua +++ b/test_scripts/iAP2_Emulation/003_iAP2_Bluetooth_to_USB_transport_switch_resume_failed_remove_data_check.lua @@ -41,50 +41,20 @@ local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") -local mobile = require("mobile_connection") local mobile_session = require("mobile_session") -local tcp = require("tcp_connection") -local file_connection = require("file_connection") - --[[ General Settings for configuration ]] -Test = require("user_modules/connecttest_iap2_emulation") +Test = require("test_scripts/iAP2_Emulation/connecttest_iap2_emulation") require("cardinalities") require("user_modules/AppTypes") -- [[Local variables]] local app_RAI_params = config["application1"].registerAppInterfaceParams +app_RAI_params.appHMIType = {"MEDIA"} local light_cyan_color = 36 local put_file_name = "file.json" local icon_file_name = "icon.png" ---[[ -IN ORDER TO USE IAP2 EMULATION IN SDL IT MUST BE BUILT ON -https://github.com/dev-gh/sdl_core/tree/experimental/IAP_adapters_emulation -WITH -BUILD_TESTS = ON -]] -local iAP2_BT_DeviceID = "127.0.0.1" -local iAP2_BT_Port = 23456 -local iAP2_BT_out = "iap2bt.out" -local iAP2_BT_Type = "BLUETOOTH" - --- Device IDs must be the same in order to trigger switching logic -local iAP2_USB_DeviceID = iAP2_BT_DeviceID -local iAP2_USB_Port = 34567 -local iAP2_USB_out = "iap2usb.out" -local iAP2_USB_Type = "USB_IOS" - -local function createIAP2Device(deviceID, devicePort, deviceOut) - local iap2Connection = tcp.Connection(deviceID, devicePort) - local fileConnection = file_connection.FileConnection(deviceOut, iap2Connection) - local iap2Device = mobile.MobileConnection(fileConnection) - - event_dispatcher:AddConnection(iap2Device) - - return iap2Device -end - local function isFileExisting(file_name) -- Device id produced for iAP2 Bluetooth by SDL = hashed device id local device_id = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" @@ -148,18 +118,6 @@ Test["Connecting iAP2 Bluetooth"] = ) end -Test["Adding way points subsription"] = - function(self) - local correlation_id = iap2bt_mobileSession:SendRPC("SubscribeWayPoints", {}) - EXPECT_HMICALL("Navigation.SubscribeWayPoints"):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ) - EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) - EXPECT_NOTIFICATION("OnHashChange", iap2bt_mobileSession) -end - Test["Adding command"] = function(self) local correlation_id = @@ -334,6 +292,18 @@ Test["Adding vehicle info subsription"] = EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) end +Test["disabled - Adding way points subsription"] = + function(self) + local correlation_id = iap2bt_mobileSession:SendRPC("SubscribeWayPoints", {}) + EXPECT_HMICALL("Navigation.SubscribeWayPoints"):Do( + function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + ) + EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) + EXPECT_NOTIFICATION("OnHashChange", iap2bt_mobileSession) +end + Test["Adding regular file"] = function(self) AddFileForApplication(iap2bt_mobileSession, put_file_name, "JSON") end @@ -398,13 +368,6 @@ Test["Connecting iAP2 USB"] = end ) - EXPECT_HMICALL("Navigation.UnsubscribeWayPoints"):Do( - function(_, data) - commonFunctions:userPrint(light_cyan_color, "Unsubscribed from waypoints") - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ) - EXPECT_HMICALL( "UI.DeleteCommand", { @@ -490,6 +453,16 @@ Test["Connecting iAP2 USB"] = ) end ) + + -- Temporary disabled + -- EXPECT_HMICALL("Navigation.UnsubscribeWayPoints"):Do( + -- function(_, data) + -- commonFunctions:userPrint(light_cyan_color, "Unsubscribed from waypoints") + -- self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + -- end + -- ) + + Test:waitForAllEvents(3000) end Test["Verifying choice/command expectations"] = function(self) diff --git a/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_commands_hold_while_switching.lua b/test_scripts/iAP2_Emulation/004_iAP2_Bluetooth_to_USB_transport_switch_commands_hold_while_switching.lua similarity index 83% rename from test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_commands_hold_while_switching.lua rename to test_scripts/iAP2_Emulation/004_iAP2_Bluetooth_to_USB_transport_switch_commands_hold_while_switching.lua index 95e70b2268..15ed0589a6 100644 --- a/test_scripts/iAP2_Emulation/iAP2_Bluetooth_to_USB_transport_switch_commands_hold_while_switching.lua +++ b/test_scripts/iAP2_Emulation/004_iAP2_Bluetooth_to_USB_transport_switch_commands_hold_while_switching.lua @@ -36,46 +36,16 @@ local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") -local mobile = require("mobile_connection") local mobile_session = require("mobile_session") -local tcp = require("tcp_connection") -local file_connection = require("file_connection") - --[[ General Settings for configuration ]] -Test = require("user_modules/connecttest_iap2_emulation") +Test = require("test_scripts/iAP2_Emulation/connecttest_iap2_emulation") require("cardinalities") require("user_modules/AppTypes") -- [[Local variables]] local app_RAI_params = config["application1"].registerAppInterfaceParams ---[[ -IN ORDER TO USE IAP2 EMULATION IN SDL IT MUST BE BUILT ON -https://github.com/dev-gh/sdl_core/tree/experimental/IAP_adapters_emulation -WITH -BUILD_TESTS = ON -]] -local iAP2_BT_DeviceID = "127.0.0.1" -local iAP2_BT_Port = 23456 -local iAP2_BT_out = "iap2bt.out" -local iAP2_BT_Type = "BLUETOOTH" - --- Device IDs must be the same in order to trigger switching logic -local iAP2_USB_DeviceID = iAP2_BT_DeviceID -local iAP2_USB_Port = 34567 -local iAP2_USB_out = "iap2usb.out" -local iAP2_USB_Type = "USB_IOS" - -local function createIAP2Device(deviceID, devicePort, deviceOut) - local iap2Connection = tcp.Connection(deviceID, devicePort) - local fileConnection = file_connection.FileConnection(deviceOut, iap2Connection) - local iap2Device = mobile.MobileConnection(fileConnection) - - event_dispatcher:AddConnection(iap2Device) - - return iap2Device -end --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") @@ -145,7 +115,8 @@ Test["Connecting iAP2 USB"] = Test:connectMobile(iap2usb_device) - iap2usb_mobileSession = mobile_session.MobileSession(self, iap2usb_device, app_RAI_params) + iap2usb_mobileSession = mobile_session.MobileSession(self, iap2usb_device, app_RAI_params) + Test:waitForAllEvents(1000) end local hmi_request_id = 0 @@ -153,12 +124,14 @@ Test["Sending request from HMI, command hold expected"] = function(self) hmi_request_id = self.hmiConnection:SendRequest("SDL.ActivateApp", {appID = hmi_app_id}) EXPECT_HMIRESPONSE(hmi_request_id):Times(0) + Test:waitForAllEvents(1000) end Test["Sending notification from HMI, command hold expected"] = function(self) self.hmiConnection:SendNotification("UI.OnDriverDistraction", {state = "DD_OFF"}) EXPECT_NOTIFICATION("OnDriverDistraction", iap2usb_mobileSession):Times(0) + Test:waitForAllEvents(1000) end Test["Register app, response is sent to HMI"] = @@ -173,6 +146,7 @@ Test["Register app, response is sent to HMI"] = EXPECT_NOTIFICATION("OnDriverDistraction", iap2usb_mobileSession) EXPECT_HMIRESPONSE(hmi_request_id, {result = {code = 0, method = "SDL.ActivateApp"}}) + Test:waitForAllEvents(1000) end -- [[ Postconditions ]] diff --git a/user_modules/connecttest_iap2_emulation.lua b/test_scripts/iAP2_Emulation/connecttest_iap2_emulation.lua similarity index 72% rename from user_modules/connecttest_iap2_emulation.lua rename to test_scripts/iAP2_Emulation/connecttest_iap2_emulation.lua index 0a9e969848..2cec93298a 100644 --- a/user_modules/connecttest_iap2_emulation.lua +++ b/test_scripts/iAP2_Emulation/connecttest_iap2_emulation.lua @@ -4,9 +4,26 @@ local SDL = require("SDL") local policyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local expectations = require("expectations") +local mobile = require("mobile_connection") +local mobile_session = require("mobile_session") +local tcp = require("tcp_connection") +local file_connection = require("file_connection") local Expectation = expectations.Expectation +--[[ IN ORDER TO USE IAP2 EMULATION IN SDL IT MUST BE BUILT ON WITH BUILD_TESTS = ON ]] +iAP2_BT_DeviceID = "127.0.0.1" +iAP2_BT_Port = 23456 +iAP2_BT_out = "iap2bt.out" +iAP2_BT_Type = "BLUETOOTH" + +-- Device IDs must be the same in order to trigger switching logic +iAP2_USB_DeviceID = iAP2_BT_DeviceID +iAP2_USB_Port = 34567 +iAP2_USB_out = "iap2usb.out" +iAP2_USB_Type = "USB_IOS" + + -- ========================================================================= -- ========================================================================= -- ========================= AUTO-RUN TEST BASE EXTENTIONS ================= @@ -63,6 +80,19 @@ function module:startSession(session) ) end +function module:waitForAllEvents(milliseconds) + local event = events.Event() + event.matches = function(self, e) + return self == e + end + EXPECT_HMIEVENT(event, "Delayed event"):Timeout(milliseconds + 1000) + local function toRun() + event_dispatcher:RaiseEvent(self.hmiConnection, event) + end + RUN_AFTER(toRun, milliseconds) +end + + -- ========================================================================= -- ========================================================================= -- ========================= GLOBAL DEFINITIONS ============================ @@ -101,6 +131,15 @@ function EXPECT_EVENT(event, name, device) return ret end +function RAISE_EVENT(event, data, eventName, device) + event_str = "noname" + if eventName then + event_str = eventName + end + xmlReporter.AddMessage(debug.getinfo(1, "n").name, event_str) + event_dispatcher:RaiseEvent(device, data) +end + function StopSDLAndRestorePT() policyTable:Restore_preloaded_pt() event_dispatcher:ClearEvents() @@ -108,4 +147,15 @@ function StopSDLAndRestorePT() return SDL:StopSDL() end + +function createIAP2Device(deviceID, devicePort, deviceOut) + local iap2Connection = tcp.Connection(deviceID, devicePort) + local fileConnection = file_connection.FileConnection(deviceOut, iap2Connection) + local iap2Device = mobile.MobileConnection(fileConnection) + + event_dispatcher:AddConnection(iap2Device) + + return iap2Device +end + return module From fd007f8c685f419015aa4ed811ed4e0a34c31456 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 24 Nov 2017 15:31:11 +0200 Subject: [PATCH 292/681] iAP2 Transport Switch: Refactoring of test scripts --- files/jsons/sdl_preloaded_pt_all_allowed.json | 24 + .../iAP2TransportSwitch/001_happy_path.lua | 113 ++++ .../002_resume_failed_simple_case.lua | 145 +++++ .../003_resume_failed_remove_data_check.lua | 427 +++++++++++++++ .../004_commands_hold_while_switching.lua | 148 ++++++ test_scripts/iAP2TransportSwitch/common.lua | 122 +++++ ...oth_to_USB_transport_switch_happy_path.lua | 129 ----- ...sport_switch_resume_failed_simple_case.lua | 159 ------ ...switch_resume_failed_remove_data_check.lua | 500 ------------------ ...t_switch_commands_hold_while_switching.lua | 158 ------ .../connecttest_iap2_emulation.lua | 161 ------ 11 files changed, 979 insertions(+), 1107 deletions(-) create mode 100644 test_scripts/iAP2TransportSwitch/001_happy_path.lua create mode 100644 test_scripts/iAP2TransportSwitch/002_resume_failed_simple_case.lua create mode 100644 test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua create mode 100644 test_scripts/iAP2TransportSwitch/004_commands_hold_while_switching.lua create mode 100644 test_scripts/iAP2TransportSwitch/common.lua delete mode 100644 test_scripts/iAP2_Emulation/001_iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua delete mode 100644 test_scripts/iAP2_Emulation/002_iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua delete mode 100644 test_scripts/iAP2_Emulation/003_iAP2_Bluetooth_to_USB_transport_switch_resume_failed_remove_data_check.lua delete mode 100644 test_scripts/iAP2_Emulation/004_iAP2_Bluetooth_to_USB_transport_switch_commands_hold_while_switching.lua delete mode 100644 test_scripts/iAP2_Emulation/connecttest_iap2_emulation.lua diff --git a/files/jsons/sdl_preloaded_pt_all_allowed.json b/files/jsons/sdl_preloaded_pt_all_allowed.json index 74a40c99b5..5313ae0716 100644 --- a/files/jsons/sdl_preloaded_pt_all_allowed.json +++ b/files/jsons/sdl_preloaded_pt_all_allowed.json @@ -382,6 +382,30 @@ "FULL", "LIMITED" ] + }, + "SubscribeVehicleData": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "SubscribeWayPoints": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "UnsubscribeWayPoints": { + "hmi_levels": [ + "NONE", + "BACKGROUND", + "FULL", + "LIMITED" + ] } } }, diff --git a/test_scripts/iAP2TransportSwitch/001_happy_path.lua b/test_scripts/iAP2TransportSwitch/001_happy_path.lua new file mode 100644 index 0000000000..691a2b91f0 --- /dev/null +++ b/test_scripts/iAP2TransportSwitch/001_happy_path.lua @@ -0,0 +1,113 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- TBD +-- +-- Description: +-- iAP2 Bluetooth connection is switched to iAP2 USB connection automatically, application(s) remains registered +-- +-- 1. Used precondition +-- SDL is built with BUILD_TEST = ON to enable iAP2 BT/USB transport adapter emulation +-- SDL, HMI are running on system. +-- +-- 2. Performed steps +-- iAP2 Bluetooth mobile device connects to system +-- appID_1->RegisterAppInterface(params) +-- RAI response is SUCCESS +-- +-- same iAP2 mobile device is connected over USB to system and re-registers within AppTransportChangeTimer timeout +-- appID_1->RegisterAppInterface(params) +-- +-- Expected behavior: +-- 1. SDL successfully registers application and notifies HMI and mobile +-- SDL->HMI: OnAppRegistered(params) +-- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() +-- +-- 2. SDL successfully registers application and notifies mobile only with RAI response +-- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() +-- application remains registered internally +-- application does not send OnAppUnregistered notification to HMI +-- application does not send OnAppRegistered notification to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/iAP2TransportSwitch/common') +local mobSession = require("mobile_session") + +--[[ Local Variables ]] +local deviceBluetooth + +--[[ Local Functions ]] +local function connectBluetoothDevice(self) + deviceBluetooth = self:createIAP2Device(common.device.bluetooth.id, + common.device.bluetooth.port, common.device.bluetooth.out) + + EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { + deviceList = { + { + id = config.deviceMAC, + name = common.device.bluetooth.id, + transportType = common.device.bluetooth.type + } + } + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + + self:connectMobile(deviceBluetooth) + :Do(function() + local sessionBluetooth = mobSession.MobileSession(self, deviceBluetooth, common.appParams) + sessionBluetooth:Start() + EXPECT_HMICALL("BasicCommunication.UpdateAppList") + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + end) +end + +local function connectUSBDevice(self) + local deviceUsb = self:createIAP2Device(common.device.usb.id, + common.device.usb.port, common.device.usb.out) + + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered"):Times(0) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Times(0) + EXPECT_HMICALL("BasicCommunication.UpdateAppList"):Times(0) + + EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { + deviceList = { + { + id = config.deviceMAC, + name = common.device.bluetooth.id, + transportType = common.device.bluetooth.type + }, + { + id = config.deviceMAC, + name = common.device.usb.id, + transportType = common.device.usb.type + } + } + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + deviceBluetooth:Close() + end) + + self:connectMobile(deviceUsb) + :Do(function() + local sessionUsb = mobSession.MobileSession(self, deviceUsb, common.appParams) + sessionUsb:Start() + end) + self:waitForAllEvents(2000) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI", common.start) + +runner.Title("Test") +runner.Step("Connect Bluetooth Device", connectBluetoothDevice) +runner.Step("Connect USB Device", connectUSBDevice) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/iAP2TransportSwitch/002_resume_failed_simple_case.lua b/test_scripts/iAP2TransportSwitch/002_resume_failed_simple_case.lua new file mode 100644 index 0000000000..449b31196f --- /dev/null +++ b/test_scripts/iAP2TransportSwitch/002_resume_failed_simple_case.lua @@ -0,0 +1,145 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- TBD +-- +-- Description: +-- iAP2 Bluetooth connection is switched to iAP2 USB connection automatically, application(s) remains registered, +-- but application(s) sends wrong hashID or it's absent +-- +-- 1. Used precondition +-- SDL is built with BUILD_TEST = ON to enable iAP2 BT/USB transport adapter emulation +-- SDL, HMI are running on system. +-- +-- 2. Performed steps +-- iAP2 Bluetooth mobile device connects to system +-- appID_1->RegisterAppInterface(params) +-- RAI response is SUCCESS +-- application sends SubscribeButton for PRESET_0 button (resume data) +-- SDL sends OnHashChange to application +-- +-- same iAP2 mobile device is connected over USB to system and re-registers within AppTransportChangeTimer timeout +-- appID_1->RegisterAppInterface(params), but with wrong hashID +-- +-- Expected behavior: +-- 1. SDL successfully registers application and notifies HMI and mobile +-- SDL->HMI: OnAppRegistered(params) +-- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() +-- SDL->appID: SUCCESS, success:"true": SubscribeButtons() +-- SDL->appID: OnHashChange +-- +-- 2. SDL successfully registers application and notifies mobile only with RAI response +-- SDL->appID: RESUME_FAILED, success:"true":RegisterAppInterface() +-- application remains registered internally +-- application does not send OnAppUnregistered notification to HMI +-- application does not send OnAppRegistered notification to HMI +-- SDL->HMI: Buttons.OnButtonSubscription, isSubscribed = false, name = PRESET_0 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/iAP2TransportSwitch/common') +local mobSession = require("mobile_session") + +--[[ Local Variables ]] +local deviceBluetooth +local sessionBluetooth + +--[[ Local Functions ]] +local function connectBluetoothDevice(self) + deviceBluetooth = self:createIAP2Device(common.device.bluetooth.id, + common.device.bluetooth.port, common.device.bluetooth.out) + + EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { + deviceList = { + { + id = config.deviceMAC, + name = common.device.bluetooth.id, + transportType = common.device.bluetooth.type + } + } + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + + self:connectMobile(deviceBluetooth) + :Do(function() + sessionBluetooth = mobSession.MobileSession(self, deviceBluetooth, common.appParams) + sessionBluetooth:StartService(7) + :Do(function() + local cid = sessionBluetooth:SendRPC("RegisterAppInterface", common.appParams) + sessionBluetooth:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + end) + EXPECT_HMICALL("BasicCommunication.UpdateAppList") + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", { + isSubscribed = true, + name = "CUSTOM_BUTTON" + }) + end) +end + +local function addDataForResumption() + local cid = sessionBluetooth:SendRPC("SubscribeButton", { buttonName = "PRESET_0" }) + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", { + isSubscribed = true, + name = "PRESET_0" + }) + sessionBluetooth:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + sessionBluetooth:ExpectNotification("OnHashChange") +end + +local function connectUSBDevice(self) + local deviceUsb = self:createIAP2Device(common.device.usb.id, + common.device.usb.port, common.device.usb.out) + + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered"):Times(0) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Times(0) + EXPECT_HMICALL("BasicCommunication.UpdateAppList"):Times(0) + + EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { + deviceList = { + { + id = config.deviceMAC, + name = common.device.bluetooth.id, + transportType = common.device.bluetooth.type + }, + { + id = config.deviceMAC, + name = common.device.usb.id, + transportType = common.device.usb.type + } + } + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + deviceBluetooth:Close() + end) + + self:connectMobile(deviceUsb) + :Do(function() + local sessionUsb = mobSession.MobileSession(self, deviceUsb, common.appParams) + sessionUsb:StartService(7) + :Do(function() + common.appParams.hashID = "some_wrong_hash_id" + local cid = sessionUsb:SendRPC("RegisterAppInterface", common.appParams) + sessionUsb:ExpectResponse(cid, { success = true, resultCode = "RESUME_FAILED" }) + end) + end) + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", { isSubscribed = false, name = "PRESET_0" }) + self:waitForAllEvents(2000, self) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI", common.start) + +runner.Title("Test") +runner.Step("Connect Bluetooth Device", connectBluetoothDevice) +runner.Step("Add Data for Resumption", addDataForResumption) +runner.Step("Connect USB Device", connectUSBDevice) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua b/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua new file mode 100644 index 0000000000..a2b55f01f1 --- /dev/null +++ b/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua @@ -0,0 +1,427 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- TBD +-- +-- Description: +-- iAP2 Bluetooth connection is switched to iAP2 USB connection automatically, application(s) remains registered, +-- but application(s) sends wrong hashID or it's absent so all resume data must be cleaned up +-- +-- 1. Used precondition +-- SDL is built with BUILD_TEST = ON to enable iAP2 BT/USB transport adapter emulation +-- SDL, HMI are running on system. +-- +-- 2. Performed steps +-- iAP2 Bluetooth mobile device connects to system +-- appID_1->RegisterAppInterface(params) +-- RAI response is SUCCESS +-- application subscribes for buttons, vehicle data, waypoints, sends files, commands, choices etc. +-- +-- same iAP2 mobile device is connected over USB to system and re-registers within AppTransportChangeTimer timeout +-- appID_1->RegisterAppInterface(params), but with wrong hashID +-- all resume data must be cleaned up, global properties should be reset, files (except icon) removed +-- +-- Expected behavior: +-- 1. SDL successfully registers application and notifies HMI and mobile +-- SDL->HMI: OnAppRegistered(params) +-- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() +-- application send all possible data for resumption and files +-- +-- 2. SDL successfully registers application and notifies mobile only with RAI response +-- SDL->appID: RESUME_FAILED, success:"true":RegisterAppInterface() +-- application remains registered internally +-- application does not send OnAppUnregistered notification to HMI +-- application does not send OnAppRegistered notification to HMI +-- all resume data cleaned up or reset, files (except icon) removed +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/iAP2TransportSwitch/common') +local mobSession = require("mobile_session") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") + +--[[ Local Variables ]] +local deviceBluetooth +local sessionBluetooth +local isChoiceRemoved = false +local isCommandRemoved = false +local putFileName = "file.json" +local iconFileName = "icon.png" + +--[[ Local Functions ]] +local function isFileExisting(pFileName) + local device_id = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" + return commonFunctions:File_exists(config.pathToSDL .. "storage/" .. common.appParams.appID + .. "_" .. device_id .. "/" .. pFileName) +end + +local function AddFileForApplication(session, pFileName, file_type, self) + local cid = session:SendRPC("PutFile", { + syncFileName = pFileName, + fileType = file_type, + persistentFile = false, + systemFile = false + }, + "files/" .. pFileName) + session:ExpectResponse(cid, { success = true }) + :Do(function() + if true ~= isFileExisting(pFileName) then + self:FailTestCase("File '" .. pFileName .. "' is not found") + end + end) +end + +local function connectBluetoothDevice(self) + deviceBluetooth = self:createIAP2Device(common.device.bluetooth.id, + common.device.bluetooth.port, common.device.bluetooth.out) + + EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { + deviceList = { + { + id = config.deviceMAC, + name = common.device.bluetooth.id, + transportType = common.device.bluetooth.type + } + } + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + + self:connectMobile(deviceBluetooth) + :Do(function() + sessionBluetooth = mobSession.MobileSession(self, deviceBluetooth, common.appParams) + sessionBluetooth:StartService(7) + :Do(function() + local cid = sessionBluetooth:SendRPC("RegisterAppInterface", common.appParams) + sessionBluetooth:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + end) + + EXPECT_HMICALL("BasicCommunication.UpdateAppList") + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", { + isSubscribed = true, + name = "CUSTOM_BUTTON" + }) + end) +end + +local function addCommand(self) + local cid = sessionBluetooth:SendRPC("AddCommand", { + cmdID = 1, + menuParams = { + position = 0, + menuName = "Command" + }, + vrCommands = { + "VRCommandonepositive" + } + }) + + EXPECT_HMICALL("UI.AddCommand", { + cmdID = 1, + menuParams = { + position = 0, + menuName = "Command" + } + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + + EXPECT_HMICALL("VR.AddCommand", { + cmdID = 1, + type = "Command", + vrCommands = { + "VRCommandonepositive" + } + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + + sessionBluetooth:ExpectResponse(cid, {success = true, resultCode = "SUCCESS"}) + sessionBluetooth:ExpectNotification("OnHashChange") +end + +local function addSubmenu(self) + local id = 11 + local cid = sessionBluetooth:SendRPC("AddSubMenu", { + menuID = id, + menuName = "SubMenumandatoryonly" + }) + EXPECT_HMICALL("UI.AddSubMenu", { + menuID = id, + menuParams = { + menuName = "SubMenumandatoryonly" + } + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + sessionBluetooth:ExpectResponse(cid, {success = true, resultCode = "SUCCESS"}) + sessionBluetooth:ExpectNotification("OnHashChange") +end + +local function addChoiceSet(self) + local id = 123 + local cid = sessionBluetooth:SendRPC("CreateInteractionChoiceSet", { + interactionChoiceSetID = id, + choiceSet = { + { + choiceID = id, + menuName = "Choice" .. id, + vrCommands = { + "VRChoice" .. id + } + } + } + }) + EXPECT_HMICALL("VR.AddCommand", { + cmdID = id, + type = "Choice", + vrCommands = { + "VRChoice" .. id + } + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + sessionBluetooth:ExpectResponse(cid, {success = true, resultCode = "SUCCESS"}) + sessionBluetooth:ExpectNotification("OnHashChange") +end + +local function addGlobalProperties(self) + local cid = sessionBluetooth:SendRPC("SetGlobalProperties", { + helpPrompt = { + { + text = "Speak", + type = "TEXT" + } + }, + timeoutPrompt = { + { + text = "Hello", + type = "TEXT" + } + }, + vrHelpTitle = "Options", + vrHelp = { + { + position = 1, + text = "OK" + } + } + }) + EXPECT_HMICALL("UI.SetGlobalProperties") + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + EXPECT_HMICALL("TTS.SetGlobalProperties") + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + sessionBluetooth:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + sessionBluetooth:ExpectNotification("OnHashChange") +end + +local function addButtonSubscription(self) + local cid = sessionBluetooth:SendRPC("SubscribeButton", { buttonName = "PRESET_0" }) + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", { isSubscribed = true, name = "PRESET_0" }) + sessionBluetooth:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + sessionBluetooth:ExpectNotification("OnHashChange") +end + +local function addVehicleInfoSubscription(self) + local cid = sessionBluetooth:SendRPC("SubscribeVehicleData", { odometer = true }) + EXPECT_HMICALL("VehicleInfo.SubscribeVehicleData") + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + sessionBluetooth:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function addWayPointsSubsription(self) + local cid = sessionBluetooth:SendRPC("SubscribeWayPoints", { }) + EXPECT_HMICALL("Navigation.SubscribeWayPoints") + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + sessionBluetooth:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + sessionBluetooth:ExpectNotification("OnHashChange") +end + +local function addRegularFile(self) + AddFileForApplication(sessionBluetooth, putFileName, "JSON", self) +end + +local function addApplicationIcon(self) + AddFileForApplication(sessionBluetooth, iconFileName, "GRAPHIC_PNG") + local cid = sessionBluetooth:SendRPC("SetAppIcon", { syncFileName = iconFileName }) + EXPECT_HMICALL("UI.SetAppIcon") + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + sessionBluetooth:ExpectResponse(cid, { resultCode = "SUCCESS", success = true }) +end + +local function connectUSBDevice(self) + local deviceUsb = self:createIAP2Device(common.device.usb.id, + common.device.usb.port, common.device.usb.out) + + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered"):Times(0) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Times(0) + EXPECT_HMICALL("BasicCommunication.UpdateAppList"):Times(0) + + EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { + deviceList = { + { + id = config.deviceMAC, + name = common.device.bluetooth.id, + transportType = common.device.bluetooth.type + }, + { + id = config.deviceMAC, + name = common.device.usb.id, + transportType = common.device.usb.type + } + } + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + deviceBluetooth:Close() + end) + + self:connectMobile(deviceUsb) + :Do(function() + local sessionUsb = mobSession.MobileSession(self, deviceUsb, common.appParams) + sessionUsb:StartService(7) + :Do(function() + common.appParams.hashID = "some_wrong_hash_id" + local cid = sessionUsb:SendRPC("RegisterAppInterface", common.appParams) + sessionUsb:ExpectResponse(cid, { success = true, resultCode = "RESUME_FAILED" }) + end) + end) + + EXPECT_HMICALL("UI.DeleteCommand", { cmdID = 1 }) + :Do(function(_, data) + common.print("UI commands removed") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + + EXPECT_HMICALL("UI.DeleteSubMenu", { menuID = 11 }) + :Do(function(_, data) + common.print("Submenus removed") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + + EXPECT_HMICALL("VR.DeleteCommand") + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + :ValidIf(function(_, data) + if data.params["type"] == "Choice" then + common.print("Choices removed") + isChoiceRemoved = true + end + if data.params["type"] == "Command" then + common.print("VR command removed") + isCommandRemoved = true + end + return true + end) + :Times(AtLeast(1)) + + EXPECT_HMICALL("UI.SetGlobalProperties", { + -- TODO: add more parameters to check + keyboardProperties = { + keyboardLayout = "QWERTY", + language = "EN-US" + }, + vrHelpTitle = "Test Application" + }) + :Do(function(_, data) + common.print("UI global properties removed") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + + EXPECT_HMICALL("TTS.SetGlobalProperties") + :Do(function(_, data) + common.print("TTS global properties removed") + -- TODO: add more parameters to check + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", { isSubscribed = false, name = "PRESET_0" }) + :Do(function() + common.print("Buttons subscriptions removed") + end) + + EXPECT_HMICALL("VehicleInfo.UnsubscribeVehicleData", { odometer = true }) + :Do(function(_, data) + common.print("Vehicle data subscriptions removed") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + odometer = { + resultCode = "SUCCESS", + dataType = "VEHICLEDATA_ODOMETER" + } + }) + end) + + -- Temporary disabled + EXPECT_HMICALL("Navigation.UnsubscribeWayPoints") + :Do(function(_, data) + common.print("Unsubscribed from waypoints") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + + self:waitForAllEvents(2000) +end + +local function verifyChoiceCommandExpectations(self) + if true ~= isChoiceRemoved then + self:FailTestCase("Choice hasn't been removed") + end + if true ~= isCommandRemoved then + self:FailTestCase("Command hasn't been removed") + end +end + +local function verifyFilesExistenceAfterCleanUp(self) + if true == isFileExisting(iconFileName) then + common.print("File '" .. iconFileName .. "' is preserved as expected") + else + self:FailTestCase("File '" .. iconFileName .. "' is removed") + end + if true ~= isFileExisting(putFileName) then + common.print("File '" .. putFileName .. "' is removed") + else + self:FailTestCase("File '" .. putFileName .. "' is not removed") + end +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI", common.start) + +runner.Step("Connect Bluetooth Device", connectBluetoothDevice) +runner.Step("Add Command", addCommand) +runner.Step("Add Submenu", addSubmenu) +runner.Step("Add ChoiceSet", addChoiceSet) +runner.Step("Add GlobalProperties", addGlobalProperties) +runner.Step("Add ButtonSubscription", addButtonSubscription) +runner.Step("Add VehicleInfoSubscription", addVehicleInfoSubscription) +runner.Step("Add WayPointsSubsription", addWayPointsSubsription) +runner.Step("Add RegularFile", addRegularFile) +runner.Step("Add ApplicationIcon", addApplicationIcon) + +runner.Title("Test") + +runner.Step("Connect USB Device", connectUSBDevice) +runner.Step("Verify ChoiceCommandExpectations", verifyChoiceCommandExpectations) +runner.Step("Verify FilesExistenceAfterCleanUp", verifyFilesExistenceAfterCleanUp) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/iAP2TransportSwitch/004_commands_hold_while_switching.lua b/test_scripts/iAP2TransportSwitch/004_commands_hold_while_switching.lua new file mode 100644 index 0000000000..36722fa017 --- /dev/null +++ b/test_scripts/iAP2TransportSwitch/004_commands_hold_while_switching.lua @@ -0,0 +1,148 @@ +--------------------------------------------------------------------------------------------------- +-- Requirement summary: +-- TBD +-- +-- Description: +-- iAP2 Bluetooth connection is switched to iAP2 USB connection automatically, application(s) remains registered +-- +-- 1. Used precondition +-- SDL is built with BUILD_TEST = ON to enable iAP2 BT/USB transport adapter emulation +-- SDL, HMI are running on system. +-- +-- 2. Performed steps +-- iAP2 Bluetooth mobile device connects to system +-- appID_1->RegisterAppInterface(params) +-- RAI response is SUCCESS +-- +-- same iAP2 mobile device is connected over USB to system and re-registers within AppTransportChangeTimer timeout +-- appID_1->RegisterAppInterface(params) +-- +-- Expected behavior: +-- 1. SDL successfully registers application and notifies HMI and mobile +-- SDL->HMI: OnAppRegistered(params) +-- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() +-- +-- 2. SDL successfully registers application and notifies mobile only with RAI response +-- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() +-- application remains registered internally +-- application does not send OnAppUnregistered notification to HMI +-- application does not send OnAppRegistered notification to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/iAP2TransportSwitch/common') +local mobSession = require("mobile_session") + +--[[ Local Variables ]] +local deviceBluetooth +local sessionBluetooth +local sessionUsb +local hmiAppId +local hmiRequestId + +--[[ Local Functions ]] +local function connectBluetoothDevice(self) + deviceBluetooth = self:createIAP2Device(common.device.bluetooth.id, + common.device.bluetooth.port, common.device.bluetooth.out) + + EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { + deviceList = { + { + id = config.deviceMAC, + name = common.device.bluetooth.id, + transportType = common.device.bluetooth.type + } + } + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + + self:connectMobile(deviceBluetooth) + :Do(function() + sessionBluetooth = mobSession.MobileSession(self, deviceBluetooth, common.appParams) + sessionBluetooth:StartService(7) + :Do(function() + local cid = sessionBluetooth:SendRPC("RegisterAppInterface", common.appParams) + sessionBluetooth:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + end) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered") + :Do(function(_, data) + hmiAppId = data.params.application.appID + end) + end) +end + +local function connectUSBDevice(self) + local deviceUsb = self:createIAP2Device(common.device.usb.id, + common.device.usb.port, common.device.usb.out) + + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered"):Times(0) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Times(0) + EXPECT_HMICALL("BasicCommunication.UpdateAppList"):Times(0) + + EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { + deviceList = { + { + id = config.deviceMAC, + name = common.device.bluetooth.id, + transportType = common.device.bluetooth.type + }, + { + id = config.deviceMAC, + name = common.device.usb.id, + transportType = common.device.usb.type + } + } + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + deviceBluetooth:Close() + end) + + self:connectMobile(deviceUsb) + :Do(function() + sessionUsb = mobSession.MobileSession(self, deviceUsb, common.appParams) + end) + self:waitForAllEvents(1000) +end + + +local function sendRequestFromHMI(self) + hmiRequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = hmiAppId }) + EXPECT_HMIRESPONSE(hmiRequestId):Times(0) + self:waitForAllEvents(1000) +end + +local function sendNotificationFromHMI(self) + self.hmiConnection:SendNotification("UI.OnDriverDistraction", { state = "DD_OFF" }) + sessionUsb:ExpectNotification("OnDriverDistraction"):Times(0) + self:waitForAllEvents(1000) +end + +local function sendResponseToHMI(self) + local rpc_service_id = 7 + sessionUsb:StartService(rpc_service_id) + :Do(function() + local correlationId = sessionUsb:SendRPC("RegisterAppInterface", common.appParams) + sessionUsb:ExpectResponse(correlationId, { success = true, resultCode = "SUCCESS" }) + end) + sessionUsb:ExpectNotification("OnDriverDistraction") + EXPECT_HMIRESPONSE(hmiRequestId, { result = { code = 0, method = "SDL.ActivateApp" }}) + self:waitForAllEvents(1000) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI", common.start) + +runner.Title("Test") +runner.Step("Connect Bluetooth Device", connectBluetoothDevice) +runner.Step("Connect USB Device", connectUSBDevice) +runner.Step("Sending request from HMI, command hold expected", sendRequestFromHMI) +runner.Step("Sending notification from HMI, command hold expected", sendNotificationFromHMI) +runner.Step("Register app, response is sent to HMI", sendResponseToHMI) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/iAP2TransportSwitch/common.lua b/test_scripts/iAP2TransportSwitch/common.lua new file mode 100644 index 0000000000..cefa3ced0b --- /dev/null +++ b/test_scripts/iAP2TransportSwitch/common.lua @@ -0,0 +1,122 @@ +--------------------------------------------------------------------------------------------------- +-- iAP2TransportSwitch common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 2 + +--[[ Required Shared libraries ]] +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local SDL = require("SDL") +local commonPreconditions = require("user_modules/shared_testcases/commonPreconditions") +local tcp = require("tcp_connection") +local file_connection = require("file_connection") +local mobile = require("mobile_connection") +local events = require("events") +local expectations = require('expectations') +local hmi_values = require('user_modules/hmi_values') +local module = require("user_modules/dummy_connecttest") + +--[[ Local Variables ]] +local Expectation = expectations.Expectation + +local m = {} + +m.device = { + bluetooth = { + id = "127.0.0.1", + port = 23456, + out = "iap2bt.out", + type = "BLUETOOTH" + }, + usb = { + id = "127.0.0.1", + port = 34567, + out = "iap2usb.out", + type = "USB_IOS" + } +} + +m.appParams = config["application1"].registerAppInterfaceParams + +function module:start() + local pHMIParams = hmi_values.getDefaultHMITable() + pHMIParams.BasicCommunication.UpdateDeviceList.mandatory = true + pHMIParams.BasicCommunication.UpdateDeviceList.pinned = false + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady(pHMIParams) + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + end) + end) + end) +end + +function module:waitForAllEvents(pTimeout) + local event = events.Event() + event.matches = function(self, e) return self == e end + EXPECT_HMIEVENT(event, "Delayed event"):Timeout(pTimeout + 1000) + local function toRun() + event_dispatcher:RaiseEvent(self.hmiConnection, event) + end + RUN_AFTER(toRun, pTimeout) +end + +function module:expectEvent(pEvent, pName, pDevice) + local ret = Expectation(pName, pDevice) + ret.event = pEvent + event_dispatcher:AddEvent(pDevice, pEvent, ret) + self:AddExpectation(ret) + return ret +end + +function module:createIAP2Device(pDeviceId, pDevicePort, pDeviceOut) + local connection = tcp.Connection(pDeviceId, pDevicePort) + local fileConnection = file_connection.FileConnection(pDeviceOut, connection) + local device = mobile.MobileConnection(fileConnection) + event_dispatcher:AddConnection(device) + return device +end + +function module:connectMobile(pDevice) + module:expectEvent(events.disconnectedEvent, "Disconnected", pDevice) + :Pin() + :Times(AnyNumber()) + :Do(function() + print("Device disconnected: " .. pDevice.connection.filename) + end) + pDevice:Connect() + return module:expectEvent(events.connectedEvent, "Connected", pDevice) +end + +function m.preconditions() + local ptFileName = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + local ptName = "files/jsons/sdl_preloaded_pt_all_allowed.json" + commonFunctions:SDLForceStop() + commonSteps:DeleteLogsFiles() + commonSteps:DeletePolicyTable() + commonPreconditions:BackupFile(ptFileName) + os.execute("cp -f " .. ptName .. " " .. commonPreconditions:GetPathToSDL() .. "/" .. ptFileName) + commonFunctions:SetValuesInIniFile("AppTransportChangeTimer%s-=%s-[%d]-%s-\n", "AppTransportChangeTimer", "5000") +end + +function m.postconditions() + SDL:StopSDL() + local ptFileName = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + commonPreconditions:RestoreFile(ptFileName) +end + +function m:start() + module.start(self) +end + +function m.print(pMsg) + commonFunctions:userPrint(35, pMsg) +end + +return m diff --git a/test_scripts/iAP2_Emulation/001_iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua b/test_scripts/iAP2_Emulation/001_iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua deleted file mode 100644 index 2196a52168..0000000000 --- a/test_scripts/iAP2_Emulation/001_iAP2_Bluetooth_to_USB_transport_switch_happy_path.lua +++ /dev/null @@ -1,129 +0,0 @@ --- Requirement summary: --- TBD --- --- Description: --- iAP2 Bluetooth connection is switched to iAP2 USB connection automatically, application(s) remains registered --- --- 1. Used precondition --- SDL is built with BUILD_TEST = ON to enable iAP2 BT/USB transport adapter emulation --- SDL, HMI are running on system. --- --- 2. Performed steps --- iAP2 Bluetooth mobile device connects to system --- appID_1->RegisterAppInterface(params) --- RAI response is SUCCESS --- --- same iAP2 mobile device is connected over USB to system and re-registers within AppTransportChangeTimer timeout --- appID_1->RegisterAppInterface(params) --- --- Expected behavior: --- 1. SDL successfully registers application and notifies HMI and mobile --- SDL->HMI: OnAppRegistered(params) --- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() --- --- 2. SDL successfully registers application and notifies mobile only with RAI response --- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() --- application remains registered internally --- application does not send OnAppUnregistered notification to HMI --- application does not send OnAppRegistered notification to HMI - ---------------------------------------------------------------------------------------------------- ---[[ General Precondition before ATF start ]] -config.defaultProtocolVersion = 2 - --- [[ Required Shared Libraries ]] -local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local commonSteps = require("user_modules/shared_testcases/commonSteps") -local commonTestCases = require("user_modules/shared_testcases/commonTestCases") - -local mobile_session = require("mobile_session") - ---[[ General Settings for configuration ]] -Test = require("test_scripts/iAP2_Emulation/connecttest_iap2_emulation") -require("cardinalities") -require("user_modules/AppTypes") - --- [[Local variables]] -local app_RAI_params = config["application1"].registerAppInterfaceParams - - ---[[ Preconditions ]] -commonFunctions:newTestCasesGroup("Preconditions") -commonSteps:DeletePolicyTable() -commonSteps:DeleteLogsFiles() - ---[[ Test ]] -commonFunctions:newTestCasesGroup("Test") - -local iap2bt_device = 0 - -Test["Connecting iAP2 Bluetooth"] = - function(self) - -- iAP2 Bluetooth connection with application registered - iap2bt_device = createIAP2Device(iAP2_BT_DeviceID, iAP2_BT_Port, iAP2_BT_out) - - EXPECT_HMICALL( - "BasicCommunication.UpdateDeviceList", - { - deviceList = {{id = config.deviceMAC, name = iAP2_BT_DeviceID, transportType = iAP2_BT_Type}} - } - ):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ) - - Test:connectMobile(iap2bt_device) - - local iap2bt_mobileSession = mobile_session.MobileSession(self, iap2bt_device, app_RAI_params) - - Test:startSession(iap2bt_mobileSession) -end - -Test["Connecting iAP2 USB"] = - function(self) - -- iAP2 USB connection with same application - local iap2usb_device = createIAP2Device(iAP2_USB_DeviceID, iAP2_USB_Port, iAP2_USB_out) - - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered"):Times(0) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Times(0) - - EXPECT_HMICALL( - "BasicCommunication.UpdateDeviceList", - { - -- To check why two devices are in list, maybe an issue - deviceList = { - {id = config.deviceMAC, name = iAP2_BT_DeviceID, transportType = iAP2_BT_Type}, - {id = config.deviceMAC, name = iAP2_USB_DeviceID, transportType = iAP2_USB_Type} - } - } - ):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - - -- Disconnect Bluetooth connection - iap2bt_device:Close() - end - ) - - Test:connectMobile(iap2usb_device) - - local iap2usb_mobileSession = mobile_session.MobileSession(self, iap2usb_device, app_RAI_params) - - local rpc_service_id = 7 - iap2usb_mobileSession:StartService(rpc_service_id):Do( - function() - local correlationId = iap2usb_mobileSession:SendRPC("RegisterAppInterface", app_RAI_params) - iap2usb_mobileSession:ExpectResponse(correlationId, {success = true, resultCode = "SUCCESS"}) - end - ) - Test:waitForAllEvents(2000) -end - --- [[ Postconditions ]] -commonFunctions:newTestCasesGroup("Postcondition") -function Test:StopSDL() - StopSDLAndRestorePT() -end - -return Test diff --git a/test_scripts/iAP2_Emulation/002_iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua b/test_scripts/iAP2_Emulation/002_iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua deleted file mode 100644 index b1a446723a..0000000000 --- a/test_scripts/iAP2_Emulation/002_iAP2_Bluetooth_to_USB_transport_switch_resume_failed_simple_case.lua +++ /dev/null @@ -1,159 +0,0 @@ --- Requirement summary: --- TBD --- --- Description: --- iAP2 Bluetooth connection is switched to iAP2 USB connection automatically, application(s) remains registered, --- but application(s) sends wrong hashID or it's absent --- --- 1. Used precondition --- SDL is built with BUILD_TEST = ON to enable iAP2 BT/USB transport adapter emulation --- SDL, HMI are running on system. --- --- 2. Performed steps --- iAP2 Bluetooth mobile device connects to system --- appID_1->RegisterAppInterface(params) --- RAI response is SUCCESS --- application sends SubscribeButton for PRESET_0 button (resume data) --- SDL sends OnHashChange to application --- --- same iAP2 mobile device is connected over USB to system and re-registers within AppTransportChangeTimer timeout --- appID_1->RegisterAppInterface(params), but with wrong hashID --- --- Expected behavior: --- 1. SDL successfully registers application and notifies HMI and mobile --- SDL->HMI: OnAppRegistered(params) --- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() --- SDL->appID: SUCCESS, success:"true": SubscribeButtons() --- SDL->appID: OnHashChange --- --- 2. SDL successfully registers application and notifies mobile only with RAI response --- SDL->appID: RESUME_FAILED, success:"true":RegisterAppInterface() --- application remains registered internally --- application does not send OnAppUnregistered notification to HMI --- application does not send OnAppRegistered notification to HMI --- SDL->HMI: Buttons.OnButtonSubscription, isSubscribed = false, name = PRESET_0 - ---------------------------------------------------------------------------------------------------- ---[[ General Precondition before ATF start ]] -config.defaultProtocolVersion = 2 - --- [[ Required Shared Libraries ]] -local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local commonSteps = require("user_modules/shared_testcases/commonSteps") -local commonTestCases = require("user_modules/shared_testcases/commonTestCases") - -local mobile_session = require("mobile_session") - - ---[[ General Settings for configuration ]] -Test = require("test_scripts/iAP2_Emulation/connecttest_iap2_emulation") -require("cardinalities") -require("user_modules/AppTypes") - --- [[Local variables]] -local app_RAI_params = config["application1"].registerAppInterfaceParams - ---[[ Preconditions ]] -commonFunctions:newTestCasesGroup("Preconditions") -commonSteps:DeletePolicyTable() -commonSteps:DeleteLogsFiles() - ---[[ Test ]] -commonFunctions:newTestCasesGroup("Test") - -local iap2bt_device = 0 -local iap2bt_mobileSession = 0 - -Test["Connecting iAP2 Bluetooth"] = - function(self) - -- iAP2 Bluetooth connection with application registered - iap2bt_device = createIAP2Device(iAP2_BT_DeviceID, iAP2_BT_Port, iAP2_BT_out) - - Test:connectMobile(iap2bt_device) - - iap2bt_mobileSession = mobile_session.MobileSession(self, iap2bt_device, app_RAI_params) - - local rpc_service_id = 7 - iap2bt_mobileSession:StartService(rpc_service_id):Do( - function() - local correlation_id = iap2bt_mobileSession:SendRPC("RegisterAppInterface", app_RAI_params) - iap2bt_mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "SUCCESS"}) - - EXPECT_HMINOTIFICATION( - "Buttons.OnButtonSubscription", - { - isSubscribed = true, - name = "CUSTOM_BUTTON" - } - ) - end - ) -end - -Test["Adding data for resumption"] = - function() - local correlation_id = iap2bt_mobileSession:SendRPC("SubscribeButton", {buttonName = "PRESET_0"}) - - EXPECT_HMINOTIFICATION( - "Buttons.OnButtonSubscription", - { - isSubscribed = true, - name = "PRESET_0" - } - ) - - EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) - - EXPECT_NOTIFICATION("OnHashChange", iap2bt_mobileSession) -end - -Test["Connecting iAP2 USB"] = - function(self) - -- iAP2 USB connection with same application - local iap2usb_device = createIAP2Device(iAP2_USB_DeviceID, iAP2_USB_Port, iAP2_USB_out) - - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered"):Times(0) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Times(0) - - EXPECT_HMICALL( - "BasicCommunication.UpdateDeviceList", - { - -- To check why two devices are in list, maybe an issue - deviceList = { - {id = config.deviceMAC, name = iAP2_BT_DeviceID, transportType = iAP2_BT_Type}, - {id = config.deviceMAC, name = iAP2_USB_DeviceID, transportType = iAP2_USB_Type} - } - } - ):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - - -- Disconnect Bluetooth connection - iap2bt_device:Close() - end - ) - - Test:connectMobile(iap2usb_device) - - local iap2usb_mobileSession = mobile_session.MobileSession(self, iap2usb_device, app_RAI_params) - - local rpc_service_id = 7 - iap2usb_mobileSession:StartService(rpc_service_id):Do( - function() - app_RAI_params.hashID = "some_wrong_hash_id" - local correlation_id = iap2usb_mobileSession:SendRPC("RegisterAppInterface", app_RAI_params) - iap2usb_mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "RESUME_FAILED"}) - end - ) - - EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", {isSubscribed = false, name = "PRESET_0"}):Times(1) - Test:waitForAllEvents(2000) -end - --- [[ Postconditions ]] -commonFunctions:newTestCasesGroup("Postcondition") -function Test:StopSDL() - StopSDLAndRestorePT() -end - -return Test diff --git a/test_scripts/iAP2_Emulation/003_iAP2_Bluetooth_to_USB_transport_switch_resume_failed_remove_data_check.lua b/test_scripts/iAP2_Emulation/003_iAP2_Bluetooth_to_USB_transport_switch_resume_failed_remove_data_check.lua deleted file mode 100644 index eef80f6fbb..0000000000 --- a/test_scripts/iAP2_Emulation/003_iAP2_Bluetooth_to_USB_transport_switch_resume_failed_remove_data_check.lua +++ /dev/null @@ -1,500 +0,0 @@ --- Requirement summary: --- TBD --- --- Description: --- iAP2 Bluetooth connection is switched to iAP2 USB connection automatically, application(s) remains registered, --- but application(s) sends wrong hashID or it's absent so all resume data must be cleaned up --- --- 1. Used precondition --- SDL is built with BUILD_TEST = ON to enable iAP2 BT/USB transport adapter emulation --- SDL, HMI are running on system. --- --- 2. Performed steps --- iAP2 Bluetooth mobile device connects to system --- appID_1->RegisterAppInterface(params) --- RAI response is SUCCESS --- application subscribes for buttons, vehicle data, waypoints, sends files, commands, choices etc. --- --- same iAP2 mobile device is connected over USB to system and re-registers within AppTransportChangeTimer timeout --- appID_1->RegisterAppInterface(params), but with wrong hashID --- all resume data must be cleaned up, global properties should be reset, files (except icon) removed --- --- Expected behavior: --- 1. SDL successfully registers application and notifies HMI and mobile --- SDL->HMI: OnAppRegistered(params) --- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() --- application send all possible data for resumption and files --- --- 2. SDL successfully registers application and notifies mobile only with RAI response --- SDL->appID: RESUME_FAILED, success:"true":RegisterAppInterface() --- application remains registered internally --- application does not send OnAppUnregistered notification to HMI --- application does not send OnAppRegistered notification to HMI --- all resume data cleaned up or reset, files (except icon) removed - ---------------------------------------------------------------------------------------------------- ---[[ General Precondition before ATF start ]] -config.defaultProtocolVersion = 2 - --- [[ Required Shared Libraries ]] -local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local commonSteps = require("user_modules/shared_testcases/commonSteps") -local commonTestCases = require("user_modules/shared_testcases/commonTestCases") - -local mobile_session = require("mobile_session") - ---[[ General Settings for configuration ]] -Test = require("test_scripts/iAP2_Emulation/connecttest_iap2_emulation") -require("cardinalities") -require("user_modules/AppTypes") - --- [[Local variables]] -local app_RAI_params = config["application1"].registerAppInterfaceParams -app_RAI_params.appHMIType = {"MEDIA"} -local light_cyan_color = 36 -local put_file_name = "file.json" -local icon_file_name = "icon.png" - -local function isFileExisting(file_name) - -- Device id produced for iAP2 Bluetooth by SDL = hashed device id - local device_id = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - return commonFunctions:File_exists( - config.pathToSDL .. "storage/" .. app_RAI_params.appID .. "_" .. device_id .. "/" .. file_name - ) -end - -local function AddFileForApplication(session, file_name, file_type) - local correlation_id = - session:SendRPC( - "PutFile", - { - syncFileName = file_name, - fileType = file_type, - persistentFile = false, - systemFile = false - }, - "files/" .. file_name - ) - EXPECT_RESPONSE(correlation_id, session, {success = true}):Do( - function(_, data) - if true ~= isFileExisting(file_name) then - Test:FailTestCase("File '" .. file_name .. "' is not found") - end - end - ) -end - ---[[ Preconditions ]] -commonFunctions:newTestCasesGroup("Preconditions") -commonSteps:DeletePolicyTable() -commonSteps:DeleteLogsFiles() - -local iap2bt_device = 0 -local iap2bt_mobileSession = 0 - -Test["Connecting iAP2 Bluetooth"] = - function(self) - -- iAP2 Bluetooth connection with application registered - iap2bt_device = createIAP2Device(iAP2_BT_DeviceID, iAP2_BT_Port, iAP2_BT_out) - - Test:connectMobile(iap2bt_device) - - iap2bt_mobileSession = mobile_session.MobileSession(self, iap2bt_device, app_RAI_params) - - local rpc_service_id = 7 - iap2bt_mobileSession:StartService(rpc_service_id):Do( - function() - local correlation_id = iap2bt_mobileSession:SendRPC("RegisterAppInterface", app_RAI_params) - iap2bt_mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "SUCCESS"}) - - EXPECT_HMINOTIFICATION( - "Buttons.OnButtonSubscription", - { - isSubscribed = true, - name = "CUSTOM_BUTTON" - } - ) - end - ) -end - -Test["Adding command"] = - function(self) - local correlation_id = - iap2bt_mobileSession:SendRPC( - "AddCommand", - { - cmdID = 1, - menuParams = { - position = 0, - menuName = "Command" - }, - vrCommands = { - "VRCommandonepositive" - } - } - ) - - EXPECT_HMICALL( - "UI.AddCommand", - { - cmdID = 1, - menuParams = { - position = 0, - menuName = "Command" - } - } - ):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ) - - EXPECT_HMICALL( - "VR.AddCommand", - { - cmdID = 1, - type = "Command", - vrCommands = { - "VRCommandonepositive" - } - } - ):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ) - - EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) - EXPECT_NOTIFICATION("OnHashChange", iap2bt_mobileSession) -end - -Test["Adding submenu"] = - function(self) - local id = 11 - local correlation_id = - iap2bt_mobileSession:SendRPC( - "AddSubMenu", - { - menuID = id, - menuName = "SubMenumandatoryonly" - } - ) - EXPECT_HMICALL( - "UI.AddSubMenu", - { - menuID = id, - menuParams = { - menuName = "SubMenumandatoryonly" - } - } - ):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ) - - EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) - EXPECT_NOTIFICATION("OnHashChange", iap2bt_mobileSession) -end - -Test["Adding choice set"] = - function(self) - local id = 123 - local correlation_id = - iap2bt_mobileSession:SendRPC( - "CreateInteractionChoiceSet", - { - interactionChoiceSetID = id, - choiceSet = { - { - choiceID = id, - menuName = "Choice" .. id, - vrCommands = { - "VRChoice" .. id - } - } - } - } - ) - - EXPECT_HMICALL( - "VR.AddCommand", - { - cmdID = id, - type = "Choice", - vrCommands = {"VRChoice" .. id} - } - ):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ) - - EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) - EXPECT_NOTIFICATION("OnHashChange", iap2bt_mobileSession) -end - -Test["Adding global properties"] = - function(self) - local correlation_id = - iap2bt_mobileSession:SendRPC( - "SetGlobalProperties", - { - helpPrompt = {{text = "Speak", type = "TEXT"}}, - timeoutPrompt = {{text = "Hello", type = "TEXT"}}, - vrHelpTitle = "Options", - vrHelp = {{position = 1, text = "OK"}} - } - ) - - EXPECT_HMICALL("UI.SetGlobalProperties"):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ) - - EXPECT_HMICALL("TTS.SetGlobalProperties"):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ) - - EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) - EXPECT_NOTIFICATION("OnHashChange", iap2bt_mobileSession) -end - -Test["Adding button subscription"] = - function() - local correlation_id = iap2bt_mobileSession:SendRPC("SubscribeButton", {buttonName = "PRESET_0"}) - - EXPECT_HMINOTIFICATION( - "Buttons.OnButtonSubscription", - { - isSubscribed = true, - name = "PRESET_0" - } - ) - - EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) - - EXPECT_NOTIFICATION("OnHashChange", iap2bt_mobileSession) -end - -Test["Adding vehicle info subsription"] = - function(self) - local correlation_id = iap2bt_mobileSession:SendRPC("SubscribeVehicleData", {odometer = true}) - EXPECT_HMICALL("VehicleInfo.SubscribeVehicleData"):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ) - EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) -end - -Test["disabled - Adding way points subsription"] = - function(self) - local correlation_id = iap2bt_mobileSession:SendRPC("SubscribeWayPoints", {}) - EXPECT_HMICALL("Navigation.SubscribeWayPoints"):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ) - EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {success = true, resultCode = "SUCCESS"}) - EXPECT_NOTIFICATION("OnHashChange", iap2bt_mobileSession) -end - -Test["Adding regular file"] = function(self) - AddFileForApplication(iap2bt_mobileSession, put_file_name, "JSON") -end - -Test["Adding application icon"] = - function(self) - AddFileForApplication(iap2bt_mobileSession, icon_file_name, "GRAPHIC_PNG") - - local correlation_id = iap2bt_mobileSession:SendRPC("SetAppIcon", {syncFileName = icon_file_name}) - - EXPECT_HMICALL("UI.SetAppIcon"):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ) - - EXPECT_RESPONSE(correlation_id, iap2bt_mobileSession, {resultCode = "SUCCESS", success = true}) -end - ---[[ Test ]] -commonFunctions:newTestCasesGroup("Test") - -local isChoiceRemoved = false -local isCommandRemoved = false - -Test["Connecting iAP2 USB"] = - function(self) - -- iAP2 USB connection with same application - local iap2usb_device = createIAP2Device(iAP2_USB_DeviceID, iAP2_USB_Port, iAP2_USB_out) - - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered"):Times(0) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Times(0) - - EXPECT_HMICALL( - "BasicCommunication.UpdateDeviceList", - { - -- To check why two devices are in list, maybe an issue - deviceList = { - {id = config.deviceMAC, name = iAP2_BT_DeviceID, transportType = iAP2_BT_Type}, - {id = config.deviceMAC, name = iAP2_USB_DeviceID, transportType = iAP2_USB_Type} - } - } - ):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - - -- Disconnect Bluetooth connection - iap2bt_device:Close() - end - ) - - Test:connectMobile(iap2usb_device) - - local iap2usb_mobileSession = mobile_session.MobileSession(self, iap2usb_device, app_RAI_params) - - local rpc_service_id = 7 - iap2usb_mobileSession:StartService(rpc_service_id):Do( - function() - app_RAI_params.hashID = "some_wrong_hash_id" - local correlation_id = iap2usb_mobileSession:SendRPC("RegisterAppInterface", app_RAI_params) - iap2usb_mobileSession:ExpectResponse(correlation_id, {success = true, resultCode = "RESUME_FAILED"}) - end - ) - - EXPECT_HMICALL( - "UI.DeleteCommand", - { - cmdID = 1 - } - ):Do( - function(_, data) - commonFunctions:userPrint(light_cyan_color, "UI commands removed") - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ) - - EXPECT_HMICALL( - "UI.DeleteSubMenu", - { - menuID = 11 - } - ):Do( - function(_, data) - commonFunctions:userPrint(light_cyan_color, "Submenus removed") - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ) - - EXPECT_HMICALL("VR.DeleteCommand"):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ):ValidIf( - function(_, data) - if data.params["type"] == "Choice" then - commonFunctions:userPrint(light_cyan_color, "Choices removed") - isChoiceRemoved = true - end - if data.params["type"] == "Command" then - commonFunctions:userPrint(light_cyan_color, "VR command removed") - isCommandRemoved = true - end - - return true - end - ):Times(AtLeast(1)) - - EXPECT_HMICALL( - "UI.SetGlobalProperties", - { - -- TODO: add more parameters to check - keyboardProperties = { - keyboardLayout = "QWERTY", - language = "EN-US" - }, - vrHelpTitle = "Test Application" - } - ):Do( - function(_, data) - commonFunctions:userPrint(light_cyan_color, "UI global properties removed") - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ) - - EXPECT_HMICALL("TTS.SetGlobalProperties"):Do( - function(_, data) - commonFunctions:userPrint(light_cyan_color, "TTS global properties removed") - -- TODO: add more parameters to check - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ) - - EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", {isSubscribed = false, name = "PRESET_0"}):Times(1):Do( - function(_, data) - commonFunctions:userPrint(light_cyan_color, "Buttons subscriptions removed") - end - ) - - EXPECT_HMICALL("VehicleInfo.UnsubscribeVehicleData", {odometer = true}):Do( - function(_, data) - commonFunctions:userPrint(light_cyan_color, "Vehicle data subscriptions removed") - self.hmiConnection:SendResponse( - data.id, - data.method, - "SUCCESS", - {odometer = {resultCode = "SUCCESS", dataType = "VEHICLEDATA_ODOMETER"}} - ) - end - ) - - -- Temporary disabled - -- EXPECT_HMICALL("Navigation.UnsubscribeWayPoints"):Do( - -- function(_, data) - -- commonFunctions:userPrint(light_cyan_color, "Unsubscribed from waypoints") - -- self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - -- end - -- ) - - Test:waitForAllEvents(3000) -end - -Test["Verifying choice/command expectations"] = function(self) - if true ~= isChoiceRemoved then - Test:FailTestCase("Choice hasn't been removed") - end - - if true ~= isCommandRemoved then - Test:FailTestCase("Command hasn't been removed") - end -end - -Test["Verifying file(s) existence after clean-up"] = function(self) - -- Icon must be preserved - if true == isFileExisting(icon_file_name) then - commonFunctions:userPrint(light_cyan_color, "File '" .. icon_file_name .. "' is preserved as expected") - else - Test:FailTestCase("File '" .. icon_file_name .. "' is removed") - end - - -- Other file(s) must be removed - if true ~= isFileExisting(put_file_name) then - commonFunctions:userPrint(light_cyan_color, "File '" .. put_file_name .. "' is removed") - else - Test:FailTestCase("File '" .. put_file_name .. "' is not removed") - end -end - --- [[ Postconditions ]] -commonFunctions:newTestCasesGroup("Postcondition") -function Test:StopSDL() - StopSDLAndRestorePT() -end - -return Test diff --git a/test_scripts/iAP2_Emulation/004_iAP2_Bluetooth_to_USB_transport_switch_commands_hold_while_switching.lua b/test_scripts/iAP2_Emulation/004_iAP2_Bluetooth_to_USB_transport_switch_commands_hold_while_switching.lua deleted file mode 100644 index 15ed0589a6..0000000000 --- a/test_scripts/iAP2_Emulation/004_iAP2_Bluetooth_to_USB_transport_switch_commands_hold_while_switching.lua +++ /dev/null @@ -1,158 +0,0 @@ --- Requirement summary: --- TBD --- --- Description: --- iAP2 Bluetooth connection is switched to iAP2 USB connection automatically, application(s) remains registered --- --- 1. Used precondition --- SDL is built with BUILD_TEST = ON to enable iAP2 BT/USB transport adapter emulation --- SDL, HMI are running on system. --- --- 2. Performed steps --- iAP2 Bluetooth mobile device connects to system --- appID_1->RegisterAppInterface(params) --- RAI response is SUCCESS --- --- same iAP2 mobile device is connected over USB to system and re-registers within AppTransportChangeTimer timeout --- appID_1->RegisterAppInterface(params) --- --- Expected behavior: --- 1. SDL successfully registers application and notifies HMI and mobile --- SDL->HMI: OnAppRegistered(params) --- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() --- --- 2. SDL successfully registers application and notifies mobile only with RAI response --- SDL->appID: SUCCESS, success:"true":RegisterAppInterface() --- application remains registered internally --- application does not send OnAppUnregistered notification to HMI --- application does not send OnAppRegistered notification to HMI - ---------------------------------------------------------------------------------------------------- ---[[ General Precondition before ATF start ]] -config.defaultProtocolVersion = 2 - --- [[ Required Shared Libraries ]] -local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local commonSteps = require("user_modules/shared_testcases/commonSteps") -local commonTestCases = require("user_modules/shared_testcases/commonTestCases") - -local mobile_session = require("mobile_session") - ---[[ General Settings for configuration ]] -Test = require("test_scripts/iAP2_Emulation/connecttest_iap2_emulation") -require("cardinalities") -require("user_modules/AppTypes") - --- [[Local variables]] -local app_RAI_params = config["application1"].registerAppInterfaceParams - - ---[[ Preconditions ]] -commonFunctions:newTestCasesGroup("Preconditions") -commonSteps:DeletePolicyTable() -commonSteps:DeleteLogsFiles() - ---[[ Test ]] -commonFunctions:newTestCasesGroup("Test") - -local iap2bt_device = 0 -local hmi_app_id = 0 -local iap2usb_mobileSession = 0 - -Test["Connecting iAP2 Bluetooth"] = - function(self) - -- iAP2 Bluetooth connection with application registered - iap2bt_device = createIAP2Device(iAP2_BT_DeviceID, iAP2_BT_Port, iAP2_BT_out) - - EXPECT_HMICALL( - "BasicCommunication.UpdateDeviceList", - { - deviceList = {{id = config.deviceMAC, name = iAP2_BT_DeviceID, transportType = iAP2_BT_Type}} - } - ):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end - ) - - Test:connectMobile(iap2bt_device) - - local iap2bt_mobileSession = mobile_session.MobileSession(self, iap2bt_device, app_RAI_params) - - Test:startSession(iap2bt_mobileSession) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Do( - function(_, data) - hmi_app_id = data.params.application.appID - end - ) -end - -Test["Connecting iAP2 USB"] = - function(self) - -- iAP2 USB connection with same application - local iap2usb_device = createIAP2Device(iAP2_USB_DeviceID, iAP2_USB_Port, iAP2_USB_out) - - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered"):Times(0) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Times(0) - - EXPECT_HMICALL( - "BasicCommunication.UpdateDeviceList", - { - -- To check why two devices are in list, maybe an issue - deviceList = { - {id = config.deviceMAC, name = iAP2_BT_DeviceID, transportType = iAP2_BT_Type}, - {id = config.deviceMAC, name = iAP2_USB_DeviceID, transportType = iAP2_USB_Type} - } - } - ):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - - -- Disconnect Bluetooth connection - iap2bt_device:Close() - end - ) - - Test:connectMobile(iap2usb_device) - - iap2usb_mobileSession = mobile_session.MobileSession(self, iap2usb_device, app_RAI_params) - Test:waitForAllEvents(1000) -end - -local hmi_request_id = 0 -Test["Sending request from HMI, command hold expected"] = function(self) - hmi_request_id = self.hmiConnection:SendRequest("SDL.ActivateApp", {appID = hmi_app_id}) - - EXPECT_HMIRESPONSE(hmi_request_id):Times(0) - Test:waitForAllEvents(1000) -end - -Test["Sending notification from HMI, command hold expected"] = function(self) - self.hmiConnection:SendNotification("UI.OnDriverDistraction", {state = "DD_OFF"}) - - EXPECT_NOTIFICATION("OnDriverDistraction", iap2usb_mobileSession):Times(0) - Test:waitForAllEvents(1000) -end - -Test["Register app, response is sent to HMI"] = - function(self) - local rpc_service_id = 7 - iap2usb_mobileSession:StartService(rpc_service_id):Do( - function() - local correlationId = iap2usb_mobileSession:SendRPC("RegisterAppInterface", app_RAI_params) - iap2usb_mobileSession:ExpectResponse(correlationId, {success = true, resultCode = "SUCCESS"}) - end - ) - - EXPECT_NOTIFICATION("OnDriverDistraction", iap2usb_mobileSession) - EXPECT_HMIRESPONSE(hmi_request_id, {result = {code = 0, method = "SDL.ActivateApp"}}) - Test:waitForAllEvents(1000) -end - --- [[ Postconditions ]] -commonFunctions:newTestCasesGroup("Postcondition") -function Test:StopSDL() - StopSDLAndRestorePT() -end - -return Test diff --git a/test_scripts/iAP2_Emulation/connecttest_iap2_emulation.lua b/test_scripts/iAP2_Emulation/connecttest_iap2_emulation.lua deleted file mode 100644 index 2cec93298a..0000000000 --- a/test_scripts/iAP2_Emulation/connecttest_iap2_emulation.lua +++ /dev/null @@ -1,161 +0,0 @@ -local module = require("user_modules/dummy_connecttest") - -local SDL = require("SDL") -local policyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") -local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local expectations = require("expectations") -local mobile = require("mobile_connection") -local mobile_session = require("mobile_session") -local tcp = require("tcp_connection") -local file_connection = require("file_connection") - -local Expectation = expectations.Expectation - ---[[ IN ORDER TO USE IAP2 EMULATION IN SDL IT MUST BE BUILT ON WITH BUILD_TESTS = ON ]] -iAP2_BT_DeviceID = "127.0.0.1" -iAP2_BT_Port = 23456 -iAP2_BT_out = "iap2bt.out" -iAP2_BT_Type = "BLUETOOTH" - --- Device IDs must be the same in order to trigger switching logic -iAP2_USB_DeviceID = iAP2_BT_DeviceID -iAP2_USB_Port = 34567 -iAP2_USB_out = "iap2usb.out" -iAP2_USB_Type = "USB_IOS" - - --- ========================================================================= --- ========================================================================= --- ========================= AUTO-RUN TEST BASE EXTENTIONS ================= --- ========================================================================= --- ========================================================================= - -function module:RunSDL() - print("Setting preloaded policy table") - policyTable:Precondition_updatePolicy_By_overwriting_preloaded_pt("files/jsons/sdl_preloaded_pt_all_allowed.json") - print("Setting .ini values") - commonFunctions:SetValuesInIniFile("AppTransportChangeTimer%s-=%s-[%d]-%s-\n", "AppTransportChangeTimer", "5000") - self:runSDL() -end - -function module:InitHMI() - critical(true) - self:initHMI() -end - -function module:InitHMI_onReady() - critical(true) - self:initHMI_onReady() -end - --- ========================================================================= --- ========================================================================= --- ========================= TEST BASE EXTENTIONS ========================== --- ========================================================================= --- ========================================================================= - -function module:connectMobile(device, exitOnDisconnect) - EXPECT_EVENT(events.disconnectedEvent, "Disconnected", device):Pin():Times(AnyNumber()):Do( - function() - print("Device disconnected: " .. device.connection.filename) - if exitOnDisconnect then - quit(exit_codes.aborted) - end - end - ) - device:Connect() - return EXPECT_EVENT(events.connectedEvent, "Connected", device) -end - -function module:startSession(session) - session:Start() - EXPECT_HMICALL("BasicCommunication.UpdateAppList"):Do( - function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - self.applications = {} - for _, app in pairs(data.params.applications) do - self.applications[app.appName] = app.appID - end - end - ) -end - -function module:waitForAllEvents(milliseconds) - local event = events.Event() - event.matches = function(self, e) - return self == e - end - EXPECT_HMIEVENT(event, "Delayed event"):Timeout(milliseconds + 1000) - local function toRun() - event_dispatcher:RaiseEvent(self.hmiConnection, event) - end - RUN_AFTER(toRun, milliseconds) -end - - --- ========================================================================= --- ========================================================================= --- ========================= GLOBAL DEFINITIONS ============================ --- ========================================================================= --- ========================================================================= - -function EXPECT_NOTIFICATION(func, session, ...) - local args = table.pack(...) - local args_count = 1 - if #args > 0 then - local arguments = {} - if #args > 1 then - for args_count = 1, #args do - if (type(args[args_count])) == "table" then - table.insert(arguments, args[args_count]) - end - end - else - arguments = args - end - return session:ExpectNotification(func, arguments) - end - return session:ExpectNotification(func, args) -end - -function EXPECT_RESPONSE(correlationId, session, ...) - xmlReporter.AddMessage(debug.getinfo(1, "n").name, "EXPECTED_RESULT", ...) - return session:ExpectResponse(correlationId, ...) -end - -function EXPECT_EVENT(event, name, device) - local ret = Expectation(name, device) - ret.event = event - event_dispatcher:AddEvent(device, event, ret) - module:AddExpectation(ret) - return ret -end - -function RAISE_EVENT(event, data, eventName, device) - event_str = "noname" - if eventName then - event_str = eventName - end - xmlReporter.AddMessage(debug.getinfo(1, "n").name, event_str) - event_dispatcher:RaiseEvent(device, data) -end - -function StopSDLAndRestorePT() - policyTable:Restore_preloaded_pt() - event_dispatcher:ClearEvents() - Test.expectations_list:Clear() - return SDL:StopSDL() -end - - -function createIAP2Device(deviceID, devicePort, deviceOut) - local iap2Connection = tcp.Connection(deviceID, devicePort) - local fileConnection = file_connection.FileConnection(deviceOut, iap2Connection) - local iap2Device = mobile.MobileConnection(fileConnection) - - event_dispatcher:AddConnection(iap2Device) - - return iap2Device -end - -return module From 1401c4ef98fcb798a1b2803e5482f7c536c2ab03 Mon Sep 17 00:00:00 2001 From: Dmytro Boltovskyi Date: Fri, 24 Nov 2017 18:50:36 +0200 Subject: [PATCH 293/681] iAP2 Transport Switch: Fix issue regarding enabled bluetooth device --- test_scripts/iAP2TransportSwitch/common.lua | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test_scripts/iAP2TransportSwitch/common.lua b/test_scripts/iAP2TransportSwitch/common.lua index cefa3ced0b..923d04004f 100644 --- a/test_scripts/iAP2TransportSwitch/common.lua +++ b/test_scripts/iAP2TransportSwitch/common.lua @@ -40,16 +40,13 @@ m.device = { m.appParams = config["application1"].registerAppInterfaceParams function module:start() - local pHMIParams = hmi_values.getDefaultHMITable() - pHMIParams.BasicCommunication.UpdateDeviceList.mandatory = true - pHMIParams.BasicCommunication.UpdateDeviceList.pinned = false self:runSDL() commonFunctions:waitForSDLStart(self) :Do(function() self:initHMI(self) :Do(function() commonFunctions:userPrint(35, "HMI initialized") - self:initHMI_onReady(pHMIParams) + self:initHMI_onReady() :Do(function() commonFunctions:userPrint(35, "HMI is ready") end) From 6201a51397dc392460c9cfb3193a400f1c011a00 Mon Sep 17 00:00:00 2001 From: "Andrey Oleynik (GitHub)" Date: Tue, 5 Dec 2017 12:59:36 +0200 Subject: [PATCH 294/681] Updates tests according to switching flow changes Now switching is being triggered externally so new signals handling has been addes and tests have been changed accordingly. --- .../iAP2TransportSwitch/001_happy_path.lua | 33 +++++++++--- .../002_resume_failed_simple_case.lua | 32 +++++++++--- .../003_resume_failed_remove_data_check.lua | 35 +++++++++---- .../004_commands_hold_while_switching.lua | 50 ++++++++++++++++--- test_scripts/iAP2TransportSwitch/common.lua | 25 +++++++++- 5 files changed, 143 insertions(+), 32 deletions(-) diff --git a/test_scripts/iAP2TransportSwitch/001_happy_path.lua b/test_scripts/iAP2TransportSwitch/001_happy_path.lua index 691a2b91f0..12c323b36a 100644 --- a/test_scripts/iAP2TransportSwitch/001_happy_path.lua +++ b/test_scripts/iAP2TransportSwitch/001_happy_path.lua @@ -35,6 +35,7 @@ local mobSession = require("mobile_session") --[[ Local Variables ]] local deviceBluetooth +local deviceBluetoothName = common.device.bluetooth.id..":"..common.device.bluetooth.port --[[ Local Functions ]] local function connectBluetoothDevice(self) @@ -45,7 +46,7 @@ local function connectBluetoothDevice(self) deviceList = { { id = config.deviceMAC, - name = common.device.bluetooth.id, + name = deviceBluetoothName, transportType = common.device.bluetooth.type } } @@ -73,24 +74,42 @@ local function connectUSBDevice(self) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Times(0) EXPECT_HMICALL("BasicCommunication.UpdateAppList"):Times(0) + local is_switching_done = false + EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { deviceList = { { id = config.deviceMAC, - name = common.device.bluetooth.id, - transportType = common.device.bluetooth.type + name = common.device.usb.uid, + transportType = common.device.usb.type }, { id = config.deviceMAC, - name = common.device.usb.id, + name = common.device.bluetooth.uid, + transportType = common.device.bluetooth.type + } + } + }, + { + deviceList = { + { + id = config.deviceMAC, + name = common.device.usb.uid, transportType = common.device.usb.type - } + } } }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) - deviceBluetooth:Close() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + + if not is_switching_done then + self:doTransportSwitch(deviceBluetooth) + is_switching_done = true + end + + return true end) + :Times(2) self:connectMobile(deviceUsb) :Do(function() diff --git a/test_scripts/iAP2TransportSwitch/002_resume_failed_simple_case.lua b/test_scripts/iAP2TransportSwitch/002_resume_failed_simple_case.lua index 449b31196f..7decf7e11d 100644 --- a/test_scripts/iAP2TransportSwitch/002_resume_failed_simple_case.lua +++ b/test_scripts/iAP2TransportSwitch/002_resume_failed_simple_case.lua @@ -52,7 +52,7 @@ local function connectBluetoothDevice(self) deviceList = { { id = config.deviceMAC, - name = common.device.bluetooth.id, + name = common.device.bluetooth.uid, transportType = common.device.bluetooth.type } } @@ -98,24 +98,42 @@ local function connectUSBDevice(self) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Times(0) EXPECT_HMICALL("BasicCommunication.UpdateAppList"):Times(0) + local is_switching_done = false + EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { deviceList = { { id = config.deviceMAC, - name = common.device.bluetooth.id, - transportType = common.device.bluetooth.type + name = common.device.usb.uid, + transportType = common.device.usb.type }, { id = config.deviceMAC, - name = common.device.usb.id, + name = common.device.bluetooth.uid, + transportType = common.device.bluetooth.type + } + } + }, + { + deviceList = { + { + id = config.deviceMAC, + name = common.device.usb.uid, transportType = common.device.usb.type - } + } } }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) - deviceBluetooth:Close() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + + if not is_switching_done then + self:doTransportSwitch(deviceBluetooth) + is_switching_done = true + end + + return true end) + :Times(2) self:connectMobile(deviceUsb) :Do(function() diff --git a/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua b/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua index a2b55f01f1..5e1be687f1 100644 --- a/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua +++ b/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua @@ -49,7 +49,7 @@ local iconFileName = "icon.png" --[[ Local Functions ]] local function isFileExisting(pFileName) - local device_id = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" + local device_id = "ac355aa5275c7388743f1bd27761ab5fa79ec876927347b97bd6e0361ae04699" return commonFunctions:File_exists(config.pathToSDL .. "storage/" .. common.appParams.appID .. "_" .. device_id .. "/" .. pFileName) end @@ -78,7 +78,7 @@ local function connectBluetoothDevice(self) deviceList = { { id = config.deviceMAC, - name = common.device.bluetooth.id, + name = common.device.bluetooth.uid, transportType = common.device.bluetooth.type } } @@ -274,24 +274,42 @@ local function connectUSBDevice(self) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Times(0) EXPECT_HMICALL("BasicCommunication.UpdateAppList"):Times(0) + local is_switching_done = false + EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { deviceList = { { id = config.deviceMAC, - name = common.device.bluetooth.id, - transportType = common.device.bluetooth.type + name = common.device.usb.uid, + transportType = common.device.usb.type }, { id = config.deviceMAC, - name = common.device.usb.id, + name = common.device.bluetooth.uid, + transportType = common.device.bluetooth.type + } + } + }, + { + deviceList = { + { + id = config.deviceMAC, + name = common.device.usb.uid, transportType = common.device.usb.type - } + } } }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) - deviceBluetooth:Close() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + + if not is_switching_done then + self:doTransportSwitch(deviceBluetooth) + is_switching_done = true + end + + return true end) + :Times(2) self:connectMobile(deviceUsb) :Do(function() @@ -369,7 +387,6 @@ local function connectUSBDevice(self) }) end) - -- Temporary disabled EXPECT_HMICALL("Navigation.UnsubscribeWayPoints") :Do(function(_, data) common.print("Unsubscribed from waypoints") diff --git a/test_scripts/iAP2TransportSwitch/004_commands_hold_while_switching.lua b/test_scripts/iAP2TransportSwitch/004_commands_hold_while_switching.lua index 36722fa017..a4b56c891d 100644 --- a/test_scripts/iAP2TransportSwitch/004_commands_hold_while_switching.lua +++ b/test_scripts/iAP2TransportSwitch/004_commands_hold_while_switching.lua @@ -39,6 +39,7 @@ local sessionBluetooth local sessionUsb local hmiAppId local hmiRequestId +local lastHashID --[[ Local Functions ]] local function connectBluetoothDevice(self) @@ -49,7 +50,7 @@ local function connectBluetoothDevice(self) deviceList = { { id = config.deviceMAC, - name = common.device.bluetooth.id, + name = common.device.bluetooth.uid, transportType = common.device.bluetooth.type } } @@ -73,6 +74,21 @@ local function connectBluetoothDevice(self) end) end + +local function addVehicleInfoSubscription(self) + local cid = sessionBluetooth:SendRPC("SubscribeVehicleData", { odometer = true }) + EXPECT_HMICALL("VehicleInfo.SubscribeVehicleData") + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + sessionBluetooth:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + sessionBluetooth:ExpectNotification("OnHashChange") + :Do(function(_, data) + lastHashID = data.payload.hashID + print("Last hash "..lastHashID) + end) +end + local function connectUSBDevice(self) local deviceUsb = self:createIAP2Device(common.device.usb.id, common.device.usb.port, common.device.usb.out) @@ -81,24 +97,42 @@ local function connectUSBDevice(self) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered"):Times(0) EXPECT_HMICALL("BasicCommunication.UpdateAppList"):Times(0) + local is_switching_done = false + EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { deviceList = { { id = config.deviceMAC, - name = common.device.bluetooth.id, - transportType = common.device.bluetooth.type + name = common.device.usb.uid, + transportType = common.device.usb.type }, { id = config.deviceMAC, - name = common.device.usb.id, + name = common.device.bluetooth.uid, + transportType = common.device.bluetooth.type + } + } + }, + { + deviceList = { + { + id = config.deviceMAC, + name = common.device.usb.uid, transportType = common.device.usb.type - } + } } }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) - deviceBluetooth:Close() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + + if not is_switching_done then + self:doTransportSwitch(deviceBluetooth) + is_switching_done = true + end + + return true end) + :Times(2) self:connectMobile(deviceUsb) :Do(function() @@ -124,6 +158,7 @@ local function sendResponseToHMI(self) local rpc_service_id = 7 sessionUsb:StartService(rpc_service_id) :Do(function() + common.appParams.hashID = lastHashID local correlationId = sessionUsb:SendRPC("RegisterAppInterface", common.appParams) sessionUsb:ExpectResponse(correlationId, { success = true, resultCode = "SUCCESS" }) end) @@ -139,6 +174,7 @@ runner.Step("Start SDL, HMI", common.start) runner.Title("Test") runner.Step("Connect Bluetooth Device", connectBluetoothDevice) +runner.Step("Add VehicleInfoSubscription", addVehicleInfoSubscription) runner.Step("Connect USB Device", connectUSBDevice) runner.Step("Sending request from HMI, command hold expected", sendRequestFromHMI) runner.Step("Sending notification from HMI, command hold expected", sendNotificationFromHMI) diff --git a/test_scripts/iAP2TransportSwitch/common.lua b/test_scripts/iAP2TransportSwitch/common.lua index 923d04004f..9d6a1f6cbf 100644 --- a/test_scripts/iAP2TransportSwitch/common.lua +++ b/test_scripts/iAP2TransportSwitch/common.lua @@ -27,13 +27,15 @@ m.device = { id = "127.0.0.1", port = 23456, out = "iap2bt.out", - type = "BLUETOOTH" + type = "BLUETOOTH", + uid = "127.0.0.1:23456" }, usb = { id = "127.0.0.1", port = 34567, out = "iap2usb.out", - type = "USB_IOS" + type = "USB_IOS", + uid = "127.0.0.1:34567" } } @@ -91,6 +93,25 @@ function module:connectMobile(pDevice) return module:expectEvent(events.connectedEvent, "Connected", pDevice) end +function module:doTransportSwitch(device) + input = io.open(config.pathToSDL.."/iap_signals_in", "w") + if not input then print("Input signals channel not opened") return end + input_signal = "SDL_TRANSPORT_SWITCH" + input:write(input_signal) + print("Signal "..input_signal.." sent") + input:close() + + output = io.open(config.pathToSDL.."/iap_signals_out", "r") + if not output then print("Output signals channel not opened") return end + print("Waiting for ACK") + out = output:read() + print("Got signal: "..out) + if out ~= "SDL_TRANSPORT_SWITCH_ACK" then print("Unexpected signal") return end + output:close() + + device:Close() +end + function m.preconditions() local ptFileName = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") local ptName = "files/jsons/sdl_preloaded_pt_all_allowed.json" From 56f843e2d78773fbcba4c99fb66cd4c7510c218f Mon Sep 17 00:00:00 2001 From: "Andrey Oleynik (GitHub)" Date: Wed, 6 Dec 2017 13:51:26 +0200 Subject: [PATCH 295/681] Minor changes because of review notes --- test_scripts/iAP2TransportSwitch/common.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test_scripts/iAP2TransportSwitch/common.lua b/test_scripts/iAP2TransportSwitch/common.lua index 9d6a1f6cbf..6fff333dc8 100644 --- a/test_scripts/iAP2TransportSwitch/common.lua +++ b/test_scripts/iAP2TransportSwitch/common.lua @@ -14,7 +14,6 @@ local file_connection = require("file_connection") local mobile = require("mobile_connection") local events = require("events") local expectations = require('expectations') -local hmi_values = require('user_modules/hmi_values') local module = require("user_modules/dummy_connecttest") --[[ Local Variables ]] @@ -94,14 +93,14 @@ function module:connectMobile(pDevice) end function module:doTransportSwitch(device) - input = io.open(config.pathToSDL.."/iap_signals_in", "w") + local input = io.open(config.pathToSDL.."/iap_signals_in", "w") if not input then print("Input signals channel not opened") return end input_signal = "SDL_TRANSPORT_SWITCH" input:write(input_signal) print("Signal "..input_signal.." sent") input:close() - output = io.open(config.pathToSDL.."/iap_signals_out", "r") + local output = io.open(config.pathToSDL.."/iap_signals_out", "r") if not output then print("Output signals channel not opened") return end print("Waiting for ACK") out = output:read() From 6f47d419a5ce5345569bf942df7b103d47b4a6f4 Mon Sep 17 00:00:00 2001 From: "Andrey Oleynik (GitHub)" Date: Wed, 6 Dec 2017 15:52:41 +0200 Subject: [PATCH 296/681] Makes variables local --- test_scripts/iAP2TransportSwitch/common.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_scripts/iAP2TransportSwitch/common.lua b/test_scripts/iAP2TransportSwitch/common.lua index 6fff333dc8..860594c4ed 100644 --- a/test_scripts/iAP2TransportSwitch/common.lua +++ b/test_scripts/iAP2TransportSwitch/common.lua @@ -95,7 +95,7 @@ end function module:doTransportSwitch(device) local input = io.open(config.pathToSDL.."/iap_signals_in", "w") if not input then print("Input signals channel not opened") return end - input_signal = "SDL_TRANSPORT_SWITCH" + local input_signal = "SDL_TRANSPORT_SWITCH" input:write(input_signal) print("Signal "..input_signal.." sent") input:close() @@ -103,7 +103,7 @@ function module:doTransportSwitch(device) local output = io.open(config.pathToSDL.."/iap_signals_out", "r") if not output then print("Output signals channel not opened") return end print("Waiting for ACK") - out = output:read() + local out = output:read() print("Got signal: "..out) if out ~= "SDL_TRANSPORT_SWITCH_ACK" then print("Unexpected signal") return end output:close() From 8801a1bc93905b92aa9820e1f1508af5d0883a43 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 11 Jan 2018 15:42:35 +0200 Subject: [PATCH 297/681] Add test set for iAPTransportSwitch --- .../003_resume_failed_remove_data_check.lua | 12 ++++++------ test_scripts/iAP2TransportSwitch/common.lua | 5 +++-- test_sets/iAP2TransportSwitch.txt | 4 ++++ 3 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 test_sets/iAP2TransportSwitch.txt diff --git a/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua b/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua index 5e1be687f1..4ea094c1c0 100644 --- a/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua +++ b/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua @@ -257,7 +257,7 @@ local function addRegularFile(self) end local function addApplicationIcon(self) - AddFileForApplication(sessionBluetooth, iconFileName, "GRAPHIC_PNG") + AddFileForApplication(sessionBluetooth, iconFileName, "GRAPHIC_PNG", self) local cid = sessionBluetooth:SendRPC("SetAppIcon", { syncFileName = iconFileName }) EXPECT_HMICALL("UI.SetAppIcon") :Do(function(_, data) @@ -275,7 +275,7 @@ local function connectUSBDevice(self) EXPECT_HMICALL("BasicCommunication.UpdateAppList"):Times(0) local is_switching_done = false - + EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { deviceList = { { @@ -287,20 +287,20 @@ local function connectUSBDevice(self) id = config.deviceMAC, name = common.device.bluetooth.uid, transportType = common.device.bluetooth.type - } + } } - }, + }, { deviceList = { { id = config.deviceMAC, name = common.device.usb.uid, transportType = common.device.usb.type - } + } } }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) if not is_switching_done then self:doTransportSwitch(deviceBluetooth) diff --git a/test_scripts/iAP2TransportSwitch/common.lua b/test_scripts/iAP2TransportSwitch/common.lua index 860594c4ed..d21642e006 100644 --- a/test_scripts/iAP2TransportSwitch/common.lua +++ b/test_scripts/iAP2TransportSwitch/common.lua @@ -3,6 +3,7 @@ --------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 +config.zeroOccurrenceTimeout = 1000 --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") @@ -98,8 +99,8 @@ function module:doTransportSwitch(device) local input_signal = "SDL_TRANSPORT_SWITCH" input:write(input_signal) print("Signal "..input_signal.." sent") - input:close() - + input:close() + local output = io.open(config.pathToSDL.."/iap_signals_out", "r") if not output then print("Output signals channel not opened") return end print("Waiting for ACK") diff --git a/test_sets/iAP2TransportSwitch.txt b/test_sets/iAP2TransportSwitch.txt new file mode 100644 index 0000000000..a7c015d859 --- /dev/null +++ b/test_sets/iAP2TransportSwitch.txt @@ -0,0 +1,4 @@ +./test_scripts/iAP2TransportSwitch/001_happy_path.lua +./test_scripts/iAP2TransportSwitch/002_resume_failed_simple_case.lua +./test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua +./test_scripts/iAP2TransportSwitch/004_commands_hold_while_switching.lua From 547d116607edfe7a41a9d5b8d461c000de57f09a Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 11 Jan 2018 19:27:13 +0200 Subject: [PATCH 298/681] Stabilize scripts --- .../iAP2TransportSwitch/001_happy_path.lua | 16 +++++----- .../002_resume_failed_simple_case.lua | 31 ++++++++++--------- .../003_resume_failed_remove_data_check.lua | 17 +++++----- .../004_commands_hold_while_switching.lua | 16 +++++----- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/test_scripts/iAP2TransportSwitch/001_happy_path.lua b/test_scripts/iAP2TransportSwitch/001_happy_path.lua index 12c323b36a..af42a40df9 100644 --- a/test_scripts/iAP2TransportSwitch/001_happy_path.lua +++ b/test_scripts/iAP2TransportSwitch/001_happy_path.lua @@ -87,24 +87,27 @@ local function connectUSBDevice(self) id = config.deviceMAC, name = common.device.bluetooth.uid, transportType = common.device.bluetooth.type - } + } } - }, + }, { deviceList = { { id = config.deviceMAC, name = common.device.usb.uid, transportType = common.device.usb.type - } + } } }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) if not is_switching_done then self:doTransportSwitch(deviceBluetooth) is_switching_done = true + else + local sessionUsb = mobSession.MobileSession(self, deviceUsb, common.appParams) + sessionUsb:Start() end return true @@ -112,10 +115,7 @@ local function connectUSBDevice(self) :Times(2) self:connectMobile(deviceUsb) - :Do(function() - local sessionUsb = mobSession.MobileSession(self, deviceUsb, common.appParams) - sessionUsb:Start() - end) + self:waitForAllEvents(2000) end diff --git a/test_scripts/iAP2TransportSwitch/002_resume_failed_simple_case.lua b/test_scripts/iAP2TransportSwitch/002_resume_failed_simple_case.lua index 7decf7e11d..f2cfd21e03 100644 --- a/test_scripts/iAP2TransportSwitch/002_resume_failed_simple_case.lua +++ b/test_scripts/iAP2TransportSwitch/002_resume_failed_simple_case.lua @@ -99,7 +99,7 @@ local function connectUSBDevice(self) EXPECT_HMICALL("BasicCommunication.UpdateAppList"):Times(0) local is_switching_done = false - + EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { deviceList = { { @@ -111,24 +111,32 @@ local function connectUSBDevice(self) id = config.deviceMAC, name = common.device.bluetooth.uid, transportType = common.device.bluetooth.type - } + } } - }, + }, { deviceList = { { id = config.deviceMAC, name = common.device.usb.uid, transportType = common.device.usb.type - } + } } }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) if not is_switching_done then self:doTransportSwitch(deviceBluetooth) is_switching_done = true + else + local sessionUsb = mobSession.MobileSession(self, deviceUsb, common.appParams) + sessionUsb:StartService(7) + :Do(function() + common.appParams.hashID = "some_wrong_hash_id" + local cid = sessionUsb:SendRPC("RegisterAppInterface", common.appParams) + sessionUsb:ExpectResponse(cid, { success = true, resultCode = "RESUME_FAILED" }) + end) end return true @@ -136,17 +144,10 @@ local function connectUSBDevice(self) :Times(2) self:connectMobile(deviceUsb) - :Do(function() - local sessionUsb = mobSession.MobileSession(self, deviceUsb, common.appParams) - sessionUsb:StartService(7) - :Do(function() - common.appParams.hashID = "some_wrong_hash_id" - local cid = sessionUsb:SendRPC("RegisterAppInterface", common.appParams) - sessionUsb:ExpectResponse(cid, { success = true, resultCode = "RESUME_FAILED" }) - end) - end) + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", { isSubscribed = false, name = "PRESET_0" }) - self:waitForAllEvents(2000, self) + + self:waitForAllEvents(2000) end --[[ Scenario ]] diff --git a/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua b/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua index 4ea094c1c0..8548e9c2eb 100644 --- a/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua +++ b/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua @@ -305,6 +305,14 @@ local function connectUSBDevice(self) if not is_switching_done then self:doTransportSwitch(deviceBluetooth) is_switching_done = true + else + local sessionUsb = mobSession.MobileSession(self, deviceUsb, common.appParams) + sessionUsb:StartService(7) + :Do(function() + common.appParams.hashID = "some_wrong_hash_id" + local cid = sessionUsb:SendRPC("RegisterAppInterface", common.appParams) + sessionUsb:ExpectResponse(cid, { success = true, resultCode = "RESUME_FAILED" }) + end) end return true @@ -312,15 +320,6 @@ local function connectUSBDevice(self) :Times(2) self:connectMobile(deviceUsb) - :Do(function() - local sessionUsb = mobSession.MobileSession(self, deviceUsb, common.appParams) - sessionUsb:StartService(7) - :Do(function() - common.appParams.hashID = "some_wrong_hash_id" - local cid = sessionUsb:SendRPC("RegisterAppInterface", common.appParams) - sessionUsb:ExpectResponse(cid, { success = true, resultCode = "RESUME_FAILED" }) - end) - end) EXPECT_HMICALL("UI.DeleteCommand", { cmdID = 1 }) :Do(function(_, data) diff --git a/test_scripts/iAP2TransportSwitch/004_commands_hold_while_switching.lua b/test_scripts/iAP2TransportSwitch/004_commands_hold_while_switching.lua index a4b56c891d..ea7fb22508 100644 --- a/test_scripts/iAP2TransportSwitch/004_commands_hold_while_switching.lua +++ b/test_scripts/iAP2TransportSwitch/004_commands_hold_while_switching.lua @@ -98,7 +98,7 @@ local function connectUSBDevice(self) EXPECT_HMICALL("BasicCommunication.UpdateAppList"):Times(0) local is_switching_done = false - + EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { deviceList = { { @@ -110,24 +110,26 @@ local function connectUSBDevice(self) id = config.deviceMAC, name = common.device.bluetooth.uid, transportType = common.device.bluetooth.type - } + } } - }, + }, { deviceList = { { id = config.deviceMAC, name = common.device.usb.uid, transportType = common.device.usb.type - } + } } }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) if not is_switching_done then self:doTransportSwitch(deviceBluetooth) is_switching_done = true + else + sessionUsb = mobSession.MobileSession(self, deviceUsb, common.appParams) end return true @@ -135,9 +137,7 @@ local function connectUSBDevice(self) :Times(2) self:connectMobile(deviceUsb) - :Do(function() - sessionUsb = mobSession.MobileSession(self, deviceUsb, common.appParams) - end) + self:waitForAllEvents(1000) end From 6140d70b7584d4db9e7a27aa2331f6e746fed45c Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 19 Jan 2018 14:00:50 +0200 Subject: [PATCH 299/681] Rename scripts --- ..._Alert_Non_Media_PositiveCase_SUCCESS.lua} | 0 ...action_Non_Media_PositiveCase_SUCCESS.lua} | 0 ...kTimer_Non_Media_PositiveCase_SUCCESS.lua} | 0 ..._Speak_Non_Media_PositiveCase_SUCCESS.lua} | 0 ...Button_Non_Media_PositiveCase_SUCCESS.lua} | 0 ...Button_Non_Media_PositiveCase_SUCCESS.lua} | 0 ...neuver_Non_Media_PositiveCase_SUCCESS.lua} | 0 ...ssThru_Non_Media_PositiveCase_SUCCESS.lua} | 0 ...does_not_send_HB_and_does_not_respond.lua} | 0 ...Beat_App_does_not_send_HB_but_respond.lua} | 0 ...d_HB.lua => 003_HeartBeat_App_send_HB.lua} | 0 ...04_HeartBeat_no_heartbeat_v2_protocol.lua} | 0 ...tion.lua => 001_Register_5_connection.lua} | 0 ...session.lua => 002_Register_5_session.lua} | 0 ..._Register_App.lua => 003_Register_App.lua} | 0 ...egister_App.lua => 004_Reregister_App.lua} | 0 ...> 005_Reregister_App_after_disconnect.lua} | 0 ...gister_App_if_two_apps_are_registered.lua} | 0 ... => 001_Resumption_3rd_ignition_cycle.lua} | 0 ...d_in_more_than_30sec_after_BC.OnReady.lua} | 0 ... 003_Resumption_App_Unregister_itself.lua} | 0 ...ua => 004_Resumption_BACKGROUND_level.lua} | 0 ... => 005_Resumption_big_amount_of_data.lua} | 0 ...sconnect_more_than_30s_before_SUSPEND.lua} | 0 ...a => 007_Resumption_FULL_IGNITION_OFF.lua} | 0 ...> 008_Resumption_heartbeat_disconnect.lua} | 0 ...> 009_Resumption_LIMITED_IGNITION_OFF.lua} | 0 ...l.lua => 010_Resumption_LIMITED_level.lua} | 0 ... 011_Resumption_unexpected_disconnect.lua} | 0 ..._OFF.lua => 001_ShutDown_IGNITION_OFF.lua} | 0 ...ESET.lua => 002_ShutDown_MASTER_RESET.lua} | 0 test_sets/smoke_tests.txt | 56 +++++++++++-------- test_sets/smoke_tests_non_media.txt | 9 --- 33 files changed, 32 insertions(+), 33 deletions(-) rename test_scripts/Smoke/API/{007_Alert_Non_Media_PositiveCase_SUCCESS.lua => 038_Alert_Non_Media_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{012_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua => 039_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{014_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua => 040_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{021_Speak_Non_Media_PositiveCase_SUCCESS.lua => 041_Speak_Non_Media_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{022_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua => 042_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{023_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua => 043_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{028_AlertManeuver_Non_Media_PositiveCase_SUCCESS.lua => 044_AlertManeuver_Non_Media_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/API/{031_PerformAudioPassThru_Non_Media_PositiveCase_SUCCESS.lua => 045_PerformAudioPassThru_Non_Media_PositiveCase_SUCCESS.lua} (100%) rename test_scripts/Smoke/HeartBeat/{ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua => 001_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua} (100%) rename test_scripts/Smoke/HeartBeat/{ATF_HeartBeat_App_does_not_send_HB_but_respond.lua => 002_HeartBeat_App_does_not_send_HB_but_respond.lua} (100%) rename test_scripts/Smoke/HeartBeat/{ATF_HeartBeat_App_send_HB.lua => 003_HeartBeat_App_send_HB.lua} (100%) rename test_scripts/Smoke/HeartBeat/{ATF_HeartBeat_no_heartbeat_v2_protocol.lua => 004_HeartBeat_no_heartbeat_v2_protocol.lua} (100%) rename test_scripts/Smoke/Registration/{ATF_Register_5_connection.lua => 001_Register_5_connection.lua} (100%) rename test_scripts/Smoke/Registration/{ATF_Register_5_session.lua => 002_Register_5_session.lua} (100%) rename test_scripts/Smoke/Registration/{ATF_Register_App.lua => 003_Register_App.lua} (100%) rename test_scripts/Smoke/Registration/{ATF_Reregister_App.lua => 004_Reregister_App.lua} (100%) rename test_scripts/Smoke/Registration/{ATF_Reregister_App_after_disconnect.lua => 005_Reregister_App_after_disconnect.lua} (100%) rename test_scripts/Smoke/Registration/{ATF_Reregister_App_if_two_apps_are_registered.lua => 006_Reregister_App_if_two_apps_are_registered.lua} (100%) rename test_scripts/Smoke/Resumption/{ATF_Resumption_3rd_ignition_cycle.lua => 001_Resumption_3rd_ignition_cycle.lua} (100%) rename test_scripts/Smoke/Resumption/{ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua => 002_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua} (100%) rename test_scripts/Smoke/Resumption/{ATF_Resumption_App_Unregister_itself.lua => 003_Resumption_App_Unregister_itself.lua} (100%) rename test_scripts/Smoke/Resumption/{ATF_Resumption_BACKGROUND_level.lua => 004_Resumption_BACKGROUND_level.lua} (100%) rename test_scripts/Smoke/Resumption/{ATF_Resumption_big_amount_of_data.lua => 005_Resumption_big_amount_of_data.lua} (100%) rename test_scripts/Smoke/Resumption/{ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua => 006_Resumption_disconnect_more_than_30s_before_SUSPEND.lua} (100%) rename test_scripts/Smoke/Resumption/{ATF_Resumption_FULL_IGNITION_OFF.lua => 007_Resumption_FULL_IGNITION_OFF.lua} (100%) rename test_scripts/Smoke/Resumption/{ATF_Resumption_heartbeat_disconnect.lua => 008_Resumption_heartbeat_disconnect.lua} (100%) rename test_scripts/Smoke/Resumption/{ATF_Resumption_LIMITED_IGNITION_OFF.lua => 009_Resumption_LIMITED_IGNITION_OFF.lua} (100%) rename test_scripts/Smoke/Resumption/{ATF_Resumption_LIMITED_level.lua => 010_Resumption_LIMITED_level.lua} (100%) rename test_scripts/Smoke/Resumption/{ATF_Resumption_unexpected_disconnect.lua => 011_Resumption_unexpected_disconnect.lua} (100%) rename test_scripts/Smoke/ShutDown/{ATF_ShutDown_IGNITION_OFF.lua => 001_ShutDown_IGNITION_OFF.lua} (100%) rename test_scripts/Smoke/ShutDown/{ATF_ShutDown_MASTER_RESET.lua => 002_ShutDown_MASTER_RESET.lua} (100%) delete mode 100644 test_sets/smoke_tests_non_media.txt diff --git a/test_scripts/Smoke/API/007_Alert_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/038_Alert_Non_Media_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/007_Alert_Non_Media_PositiveCase_SUCCESS.lua rename to test_scripts/Smoke/API/038_Alert_Non_Media_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/012_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/039_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/012_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua rename to test_scripts/Smoke/API/039_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/014_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/040_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/014_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua rename to test_scripts/Smoke/API/040_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/021_Speak_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/041_Speak_Non_Media_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/021_Speak_Non_Media_PositiveCase_SUCCESS.lua rename to test_scripts/Smoke/API/041_Speak_Non_Media_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/022_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/042_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/022_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua rename to test_scripts/Smoke/API/042_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/023_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/043_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/023_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua rename to test_scripts/Smoke/API/043_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/028_AlertManeuver_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/044_AlertManeuver_Non_Media_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/028_AlertManeuver_Non_Media_PositiveCase_SUCCESS.lua rename to test_scripts/Smoke/API/044_AlertManeuver_Non_Media_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/API/031_PerformAudioPassThru_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/045_PerformAudioPassThru_Non_Media_PositiveCase_SUCCESS.lua similarity index 100% rename from test_scripts/Smoke/API/031_PerformAudioPassThru_Non_Media_PositiveCase_SUCCESS.lua rename to test_scripts/Smoke/API/045_PerformAudioPassThru_Non_Media_PositiveCase_SUCCESS.lua diff --git a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua b/test_scripts/Smoke/HeartBeat/001_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua similarity index 100% rename from test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua rename to test_scripts/Smoke/HeartBeat/001_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua diff --git a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_but_respond.lua b/test_scripts/Smoke/HeartBeat/002_HeartBeat_App_does_not_send_HB_but_respond.lua similarity index 100% rename from test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_but_respond.lua rename to test_scripts/Smoke/HeartBeat/002_HeartBeat_App_does_not_send_HB_but_respond.lua diff --git a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_send_HB.lua b/test_scripts/Smoke/HeartBeat/003_HeartBeat_App_send_HB.lua similarity index 100% rename from test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_send_HB.lua rename to test_scripts/Smoke/HeartBeat/003_HeartBeat_App_send_HB.lua diff --git a/test_scripts/Smoke/HeartBeat/ATF_HeartBeat_no_heartbeat_v2_protocol.lua b/test_scripts/Smoke/HeartBeat/004_HeartBeat_no_heartbeat_v2_protocol.lua similarity index 100% rename from test_scripts/Smoke/HeartBeat/ATF_HeartBeat_no_heartbeat_v2_protocol.lua rename to test_scripts/Smoke/HeartBeat/004_HeartBeat_no_heartbeat_v2_protocol.lua diff --git a/test_scripts/Smoke/Registration/ATF_Register_5_connection.lua b/test_scripts/Smoke/Registration/001_Register_5_connection.lua similarity index 100% rename from test_scripts/Smoke/Registration/ATF_Register_5_connection.lua rename to test_scripts/Smoke/Registration/001_Register_5_connection.lua diff --git a/test_scripts/Smoke/Registration/ATF_Register_5_session.lua b/test_scripts/Smoke/Registration/002_Register_5_session.lua similarity index 100% rename from test_scripts/Smoke/Registration/ATF_Register_5_session.lua rename to test_scripts/Smoke/Registration/002_Register_5_session.lua diff --git a/test_scripts/Smoke/Registration/ATF_Register_App.lua b/test_scripts/Smoke/Registration/003_Register_App.lua similarity index 100% rename from test_scripts/Smoke/Registration/ATF_Register_App.lua rename to test_scripts/Smoke/Registration/003_Register_App.lua diff --git a/test_scripts/Smoke/Registration/ATF_Reregister_App.lua b/test_scripts/Smoke/Registration/004_Reregister_App.lua similarity index 100% rename from test_scripts/Smoke/Registration/ATF_Reregister_App.lua rename to test_scripts/Smoke/Registration/004_Reregister_App.lua diff --git a/test_scripts/Smoke/Registration/ATF_Reregister_App_after_disconnect.lua b/test_scripts/Smoke/Registration/005_Reregister_App_after_disconnect.lua similarity index 100% rename from test_scripts/Smoke/Registration/ATF_Reregister_App_after_disconnect.lua rename to test_scripts/Smoke/Registration/005_Reregister_App_after_disconnect.lua diff --git a/test_scripts/Smoke/Registration/ATF_Reregister_App_if_two_apps_are_registered.lua b/test_scripts/Smoke/Registration/006_Reregister_App_if_two_apps_are_registered.lua similarity index 100% rename from test_scripts/Smoke/Registration/ATF_Reregister_App_if_two_apps_are_registered.lua rename to test_scripts/Smoke/Registration/006_Reregister_App_if_two_apps_are_registered.lua diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua b/test_scripts/Smoke/Resumption/001_Resumption_3rd_ignition_cycle.lua similarity index 100% rename from test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua rename to test_scripts/Smoke/Resumption/001_Resumption_3rd_ignition_cycle.lua diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua b/test_scripts/Smoke/Resumption/002_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua similarity index 100% rename from test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua rename to test_scripts/Smoke/Resumption/002_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_App_Unregister_itself.lua b/test_scripts/Smoke/Resumption/003_Resumption_App_Unregister_itself.lua similarity index 100% rename from test_scripts/Smoke/Resumption/ATF_Resumption_App_Unregister_itself.lua rename to test_scripts/Smoke/Resumption/003_Resumption_App_Unregister_itself.lua diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_BACKGROUND_level.lua b/test_scripts/Smoke/Resumption/004_Resumption_BACKGROUND_level.lua similarity index 100% rename from test_scripts/Smoke/Resumption/ATF_Resumption_BACKGROUND_level.lua rename to test_scripts/Smoke/Resumption/004_Resumption_BACKGROUND_level.lua diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua b/test_scripts/Smoke/Resumption/005_Resumption_big_amount_of_data.lua similarity index 100% rename from test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua rename to test_scripts/Smoke/Resumption/005_Resumption_big_amount_of_data.lua diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua b/test_scripts/Smoke/Resumption/006_Resumption_disconnect_more_than_30s_before_SUSPEND.lua similarity index 100% rename from test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua rename to test_scripts/Smoke/Resumption/006_Resumption_disconnect_more_than_30s_before_SUSPEND.lua diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua b/test_scripts/Smoke/Resumption/007_Resumption_FULL_IGNITION_OFF.lua similarity index 100% rename from test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua rename to test_scripts/Smoke/Resumption/007_Resumption_FULL_IGNITION_OFF.lua diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua b/test_scripts/Smoke/Resumption/008_Resumption_heartbeat_disconnect.lua similarity index 100% rename from test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua rename to test_scripts/Smoke/Resumption/008_Resumption_heartbeat_disconnect.lua diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua b/test_scripts/Smoke/Resumption/009_Resumption_LIMITED_IGNITION_OFF.lua similarity index 100% rename from test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua rename to test_scripts/Smoke/Resumption/009_Resumption_LIMITED_IGNITION_OFF.lua diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_level.lua b/test_scripts/Smoke/Resumption/010_Resumption_LIMITED_level.lua similarity index 100% rename from test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_level.lua rename to test_scripts/Smoke/Resumption/010_Resumption_LIMITED_level.lua diff --git a/test_scripts/Smoke/Resumption/ATF_Resumption_unexpected_disconnect.lua b/test_scripts/Smoke/Resumption/011_Resumption_unexpected_disconnect.lua similarity index 100% rename from test_scripts/Smoke/Resumption/ATF_Resumption_unexpected_disconnect.lua rename to test_scripts/Smoke/Resumption/011_Resumption_unexpected_disconnect.lua diff --git a/test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua b/test_scripts/Smoke/ShutDown/001_ShutDown_IGNITION_OFF.lua similarity index 100% rename from test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua rename to test_scripts/Smoke/ShutDown/001_ShutDown_IGNITION_OFF.lua diff --git a/test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua b/test_scripts/Smoke/ShutDown/002_ShutDown_MASTER_RESET.lua similarity index 100% rename from test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua rename to test_scripts/Smoke/ShutDown/002_ShutDown_MASTER_RESET.lua diff --git a/test_sets/smoke_tests.txt b/test_sets/smoke_tests.txt index 072c92d558..a4b4c32232 100644 --- a/test_sets/smoke_tests.txt +++ b/test_sets/smoke_tests.txt @@ -1,27 +1,3 @@ -./test_scripts/Smoke/Policies/001_PTU_all_flows.lua -./test_scripts/Smoke/ShutDown/ATF_ShutDown_MASTER_RESET.lua -./test_scripts/Smoke/ShutDown/ATF_ShutDown_IGNITION_OFF.lua -./test_scripts/Smoke/Resumption/ATF_Resumption_3rd_ignition_cycle.lua -./test_scripts/Smoke/Resumption/ATF_Resumption_App_Unregister_itself.lua -./test_scripts/Smoke/Resumption/ATF_Resumption_BACKGROUND_level.lua -./test_scripts/Smoke/Resumption/ATF_Resumption_FULL_IGNITION_OFF.lua -./test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_IGNITION_OFF.lua -./test_scripts/Smoke/Resumption/ATF_Resumption_LIMITED_level.lua -./test_scripts/Smoke/Resumption/ATF_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua -./test_scripts/Smoke/Resumption/ATF_Resumption_big_amount_of_data.lua -./test_scripts/Smoke/Resumption/ATF_Resumption_disconnect_more_than_30s_before_SUSPEND.lua -./test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua -./test_scripts/Smoke/Resumption/ATF_Resumption_unexpected_disconnect.lua -./test_scripts/Smoke/Registration/ATF_Register_App.lua -./test_scripts/Smoke/Registration/ATF_Register_5_session.lua -./test_scripts/Smoke/Registration/ATF_Register_5_connection.lua -./test_scripts/Smoke/Registration/ATF_Reregister_App.lua -./test_scripts/Smoke/Registration/ATF_Reregister_App_after_disconnect.lua -./test_scripts/Smoke/Registration/ATF_Reregister_App_if_two_apps_are_registered.lua -./test_scripts/Smoke/HeartBeat/ATF_HeartBeat_no_heartbeat_v2_protocol.lua -./test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_send_HB.lua -./test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_but_respond.lua -./test_scripts/Smoke/HeartBeat/ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua ./test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua ./test_scripts/Smoke/API/002_ResetGlobalProperties_PositiveCase_SUCCESS.lua ./test_scripts/Smoke/API/003_AddCommand_PositiveCase_SUCCESS.lua @@ -59,3 +35,35 @@ ./test_scripts/Smoke/API/035_ChangeRegistration_SUCCESS.lua ./test_scripts/Smoke/API/036_UnregisterAppInterface_PositiveCase_SUCCESS.lua ./test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/038_Alert_Non_Media_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/039_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/040_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/041_Speak_Non_Media_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/042_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/043_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/044_AlertManeuver_Non_Media_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/045_PerformAudioPassThru_Non_Media_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/HeartBeat/001_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua +./test_scripts/Smoke/HeartBeat/002_HeartBeat_App_does_not_send_HB_but_respond.lua +./test_scripts/Smoke/HeartBeat/003_HeartBeat_App_send_HB.lua +./test_scripts/Smoke/HeartBeat/004_HeartBeat_no_heartbeat_v2_protocol.lua +./test_scripts/Smoke/Policies/001_PTU_all_flows.lua +./test_scripts/Smoke/Registration/001_Register_5_connection.lua +./test_scripts/Smoke/Registration/002_Register_5_session.lua +./test_scripts/Smoke/Registration/003_Register_App.lua +./test_scripts/Smoke/Registration/004_Reregister_App.lua +./test_scripts/Smoke/Registration/005_Reregister_App_after_disconnect.lua +./test_scripts/Smoke/Registration/006_Reregister_App_if_two_apps_are_registered.lua +./test_scripts/Smoke/Resumption/001_Resumption_3rd_ignition_cycle.lua +./test_scripts/Smoke/Resumption/002_Resumption_app_registered_in_more_than_30sec_after_BC.OnReady.lua +./test_scripts/Smoke/Resumption/003_Resumption_App_Unregister_itself.lua +./test_scripts/Smoke/Resumption/004_Resumption_BACKGROUND_level.lua +./test_scripts/Smoke/Resumption/005_Resumption_big_amount_of_data.lua +./test_scripts/Smoke/Resumption/006_Resumption_disconnect_more_than_30s_before_SUSPEND.lua +./test_scripts/Smoke/Resumption/007_Resumption_FULL_IGNITION_OFF.lua +./test_scripts/Smoke/Resumption/008_Resumption_heartbeat_disconnect.lua +./test_scripts/Smoke/Resumption/009_Resumption_LIMITED_IGNITION_OFF.lua +./test_scripts/Smoke/Resumption/010_Resumption_LIMITED_level.lua +./test_scripts/Smoke/Resumption/011_Resumption_unexpected_disconnect.lua +./test_scripts/Smoke/ShutDown/001_ShutDown_IGNITION_OFF.lua +./test_scripts/Smoke/ShutDown/002_ShutDown_MASTER_RESET.lua diff --git a/test_sets/smoke_tests_non_media.txt b/test_sets/smoke_tests_non_media.txt deleted file mode 100644 index 83bfcae209..0000000000 --- a/test_sets/smoke_tests_non_media.txt +++ /dev/null @@ -1,9 +0,0 @@ -./test_scripts/Smoke/Policies/001_PTU_all_flows.lua -./test_scripts/Smoke/API/007_Alert_Non_Media_PositiveCase_SUCCESS.lua -./test_scripts/Smoke/API/012_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua -./test_scripts/Smoke/API/014_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua -./test_scripts/Smoke/API/021_Speak_Non_Media_PositiveCase_SUCCESS.lua -./test_scripts/Smoke/API/022_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua -./test_scripts/Smoke/API/023_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua -./test_scripts/Smoke/API/028_AlertManeuver_Non_Media_PositiveCase_SUCCESS.lua -./test_scripts/Smoke/API/031_PerformAudioPassThru_Non_Media_PositiveCase_SUCCESS.lua From 792f1c356a7f6442493466afead590e5800127c4 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 23 Jan 2018 09:02:46 +0200 Subject: [PATCH 300/681] Update handling of Device Id and Name --- .../012_PerfomInteraction_PositiveCase_SUCCESS.lua | 2 +- ...7_RegisterAppInterface_PositiveCase_SUCCESS.lua | 4 ++-- test_scripts/Smoke/Policies/001_PTU_all_flows.lua | 7 ++----- test_scripts/Smoke/commonSmoke.lua | 14 +++++++++++--- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua index 770a575006..5dae576f79 100644 --- a/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua @@ -46,7 +46,7 @@ local putFileParams = { } local storagePath = commonPreconditions:GetPathToSDL() .. "storage/" .. -config.application1.registerAppInterfaceParams.appID .. "_" .. config.deviceMAC .. "/" +config.application1.registerAppInterfaceParams.appID .. "_" .. commonSmoke.getDeviceMAC() .. "/" local ImageValue = { value = storagePath .. "icon.png", diff --git a/test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua index 99aa2d93bd..20ffcd8372 100644 --- a/test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua @@ -72,8 +72,8 @@ local function SetNotificationParams() notificationParams.application.hmiDisplayLanguageDesired = requestParams.hmiDisplayLanguageDesired notificationParams.application.appType = requestParams.appHMIType notificationParams.application.deviceInfo = { - name = "127.0.0.1", - id = config.deviceMAC, + name = commonSmoke.getDeviceName(), + id = commonSmoke.getDeviceMAC(), transportType = "WIFI", isSDLAllowed = true } diff --git a/test_scripts/Smoke/Policies/001_PTU_all_flows.lua b/test_scripts/Smoke/Policies/001_PTU_all_flows.lua index d57ad1df72..b95d1bf67b 100644 --- a/test_scripts/Smoke/Policies/001_PTU_all_flows.lua +++ b/test_scripts/Smoke/Policies/001_PTU_all_flows.lua @@ -10,10 +10,7 @@ local json = require("modules/json") local atf_logger = require("atf_logger") local sdl = require("SDL") local commonSteps = require("user_modules/shared_testcases/commonSteps") - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" -config.defaultProtocolVersion = 2 +local commonSmoke = require('test_scripts/Smoke/commonSmoke') --[[ Local Variables ]] local flowType = { @@ -36,7 +33,7 @@ end local function allowSDL(self) -- sending notification OnAllowSDLFunctionality from HMI to allow connected device self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + { allowed = true, source = "GUI", device = { id = commonSmoke.getDeviceMAC(), name = commonSmoke.getDeviceName() }}) end -- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP diff --git a/test_scripts/Smoke/commonSmoke.lua b/test_scripts/Smoke/commonSmoke.lua index 6c22690eda..e042fd169c 100644 --- a/test_scripts/Smoke/commonSmoke.lua +++ b/test_scripts/Smoke/commonSmoke.lua @@ -3,7 +3,7 @@ --------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.mobileHost = "127.0.0.1" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] @@ -32,7 +32,7 @@ commonSmoke.minTimeout = 500 local function allowSDL(self) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + { allowed = true, source = "GUI", device = { id = commonSmoke.getDeviceMAC(), name = commonSmoke.getDeviceName() }}) end local function jsonFileToTable(pFileName) @@ -128,8 +128,16 @@ function commonSmoke.preconditions() commonSteps:DeleteLogsFiles() end +function commonSmoke.getDeviceName() + return config.mobileHost .. ":" .. config.mobilePort +end + function commonSmoke.getDeviceMAC() - return config.deviceMAC + local cmd = "echo -n " .. commonSmoke.getDeviceName() .. " | sha256sum | awk '{printf $1}'" + local handle = io.popen(cmd) + local result = handle:read("*a") + handle:close() + return result end function commonSmoke.getPathToSDL() From eb503b12db995492761c1fecb55d213828c7c994 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 24 Jan 2018 13:26:38 +0200 Subject: [PATCH 301/681] Move existing RC tests to separate folder --- ...001_success_flow_for_climate_and_radio.lua | 0 ...02_disallow_flow_by_policy_for_climate.lua | 0 .../003_disallow_flow_by_policy_for_radio.lua | 0 ..._processing_button_press_for_nonRC_App.lua | 0 ...e_and_moduleType_for_radio_and_climate.lua | 0 ..._check_rpc_parameters_for_button_press.lua | 0 ...n_press_allowed_if_moduleType_is_empty.lua | 0 ...ess_disallowed_if_moduleType_is_absent.lua | 0 ...f_moduleType_is_disallowed_by_policies.lua | 0 ..._generic_error_if_no_response_from_hmi.lua | 0 ...or_if_read_only_response_come_from_hmi.lua | 0 ...ric_error_if_invalid_response_from_hmi.lua | 0 ...ransfering_of_HMI_resultCode_to_mobile.lua | 0 .../001_All_modules_all_params.lua | 0 .../002_Only_CLIMATE_all_params.lua | 0 .../003_Only_RADIO_all_params.lua | 0 ..._supported_parameter_and_reject_others.lua | 0 .../005_Resend_only_supported_parameters.lua | 0 ...supported_and_not_supported_parameters.lua | 0 ...f_HMI_respond_to_RC_IsReady_with_false.lua | 0 ...nt_respond_to_RC_GetCapabilities_RADIO.lua | 0 ..._respond_to_RC_GetCapabilities_CLIMATE.lua | 0 ...nt_respond_to_RC_GetCapabilities_RADIO.lua | 0 ..._respond_to_RC_GetCapabilities_CLIMATE.lua | 0 ...d_responds_to_RC_GetCapabilities_RADIO.lua | 0 ...responds_to_RC_GetCapabilities_CLIMATE.lua | 0 .../001_Success_flow.lua | 0 .../002_Disallow_flow_by_policy_CLIMATE.lua | 0 .../003_Disallow_flow_by_policy_RADIO.lua | 0 ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 0 ...ransfering_of_HMI_resultCode_to_mobile.lua | 0 .../006_RPC_parameters_values.lua | 0 ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 0 ..._in_case_HMI_respond_with_invalid_data.lua | 0 ...se_moduleType_is_an_empty_array_in_LPT.lua | 0 ...ow_in_case_moduleType_is_absent_in_LPT.lua | 0 ...ROR_in_case_HMI_respond_with_READ_ONLY.lua | 0 ...response_from_HMI_without_isSubscribed.lua | 0 ...ut_response_from_HMI_with_isSubscribed.lua | 0 ...ase_of_2nd_Subscription_UnSubscription.lua | 0 .../001_Consent_true_SIVD.lua | 0 .../002_Consent_true_BP.lua | 0 .../003_Consent_false_SIVD.lua | 0 .../004_Consent_false_BP.lua | 0 .../005_TIMED_OUT_from_HMI_SIVD.lua | 0 .../006_TIMED_OUT_from_HMI_BP.lua | 0 .../007_HMI_no_response_SIVD.lua | 0 .../008_HMI_no_response_BP.lua | 0 .../009_HMI_invalid_response_SIVD.lua | 0 .../010_HMI_invalid_response_BP.lua | 0 .../011_TIMED_OUT_after_default_timeout.lua | 0 .../001_Success_flow.lua | 0 .../002_Disallow_flow_by_policy_CLIMATE.lua | 0 .../003_Disallow_flow_by_policy_RADIO.lua | 0 ...ribing_with_isSubscribe_false_from_HMI.lua | 0 ...bscribing_without_isSubscribe_from_HMI.lua | 0 ...ase_of_subscribing_with_error_from_HMI.lua | 0 ..._subscribing_with_no_response_from_HMI.lua | 0 ...cribing_with_invalid_response_from_HMI.lua | 0 ...cribing_with_isSubscribe_true_from_HMI.lua | 0 ...bscribing_without_isSubscribe_from_HMI.lua | 0 ...bscribing_without_isSubscribe_from_HMI.lua | 0 ...imate_and_without_one_for_module_Radio.lua | 0 ...dio_and_without_one_for_module_Climate.lua | 0 ...nd_after_unsubscribe_from_module_Radio.lua | 0 ..._after_unsubscribe_from_module_Climate.lua | 0 .../016_RPC_parameters_values.lua | 0 .../001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua | 0 .../002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua | 0 .../003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua | 0 .../004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua | 0 ...005_REJECTED_in_case_nonFULL_HMI_level.lua | 0 .../006_IN_USE_in_case_2_requests.lua | 0 .../007_IN_USE_in_case_AUTO_DENY.lua | 0 .../008_Allowed_false.lua | 0 ...009_Allowed_true_accessMode_AUTO_ALLOW.lua | 0 .../010_Allowed_true_accessMode_AUTO_DENY.lua | 0 ...011_Allowed_true_accessMode_ASK_DRIVER.lua | 0 .../012_Default_accessMode.lua | 0 .../013_sequence_switches_of_accessMode.lua | 0 .../014_Invalid_data_from_HMI.lua | 0 .../015_Empty_data_from_HMI.lua | 0 ...DENY_for_app_with_reject_in_ASK_DRIVER.lua | 0 ...017_Release_resource_on_unregister_app.lua | 0 ...low_for_rejected_app_on_unregister_app.lua | 0 .../019_Release_resource_on_RC_disable.lua | 0 ...20_Restore_accessMode_after_RC_disable.lua | 0 .../021_Release_resource_on_exit_app.lua | 0 ...e_resource_on_PTU_with_module_disallow.lua | 0 ...lease_resource_on_PTU_with_app_revoked.lua | 0 .../024_Allowed_false_no_PTU.lua | 0 .../001_Success_flow.lua | 0 .../002_Disallow_flow_by_policy_CLIMATE.lua | 0 .../003_Disallow_flow_by_policy_RADIO.lua | 0 ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 0 ...rams_does_not_correspond_to_moduleType.lua | 0 .../006_RPC_parameters_values.lua | 0 ...se_moduleType_is_an_empty_array_in_LPT.lua | 0 ...ow_in_case_moduleType_is_absent_in_LPT.lua | 0 ...09_Cut-off_of_fake_parameters_from_App.lua | 0 ...cle_data_if_read_only_params_requested.lua | 0 ...read-only_and_not_read-only_parameters.lua | 0 ...y_parameters_and_HMI_returns_READ_ONLY.lua | 0 ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 0 ..._in_case_HMI_respond_with_invalid_data.lua | 0 ...ransfering_of_HMI_resultCode_to_mobile.lua | 0 test_sets/rc_ButtonPress.txt | 13 --- test_sets/rc_CLIMATE_RADIO.txt | 106 ++++++++++++++++++ test_sets/rc_Capabilities.txt | 13 --- test_sets/rc_GetInteriorVehicleData.txt | 14 --- .../rc_GetInteriorVehicleDataConsent.txt | 11 -- test_sets/rc_OnInteriorVehicleData.txt | 16 --- test_sets/rc_OnRemoteControlSettings.txt | 24 ---- test_sets/rc_SetInteriorVehicleData.txt | 15 --- 114 files changed, 106 insertions(+), 106 deletions(-) rename test_scripts/RC/{ => CLIMATE_RADIO}/ButtonPress/001_success_flow_for_climate_and_radio.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/ButtonPress/002_disallow_flow_by_policy_for_climate.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/ButtonPress/003_disallow_flow_by_policy_for_radio.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/ButtonPress/006_check_rpc_parameters_for_button_press.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/ButtonPress/010_generic_error_if_no_response_from_hmi.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/Capabilities/001_All_modules_all_params.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/Capabilities/002_Only_CLIMATE_all_params.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/Capabilities/003_Only_RADIO_all_params.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/Capabilities/005_Resend_only_supported_parameters.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleData/001_Success_flow.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleData/006_RPC_parameters_values.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnInteriorVehicleData/001_Success_flow.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnInteriorVehicleData/016_RPC_parameters_values.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/008_Allowed_false.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/012_Default_accessMode.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/015_Empty_data_from_HMI.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/SetInteriorVehicleData/001_Success_flow.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/SetInteriorVehicleData/006_RPC_parameters_values.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua (100%) rename test_scripts/RC/{ => CLIMATE_RADIO}/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua (100%) delete mode 100644 test_sets/rc_ButtonPress.txt create mode 100644 test_sets/rc_CLIMATE_RADIO.txt delete mode 100644 test_sets/rc_Capabilities.txt delete mode 100644 test_sets/rc_GetInteriorVehicleData.txt delete mode 100644 test_sets/rc_GetInteriorVehicleDataConsent.txt delete mode 100644 test_sets/rc_OnInteriorVehicleData.txt delete mode 100644 test_sets/rc_OnRemoteControlSettings.txt delete mode 100644 test_sets/rc_SetInteriorVehicleData.txt diff --git a/test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/001_success_flow_for_climate_and_radio.lua similarity index 100% rename from test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua rename to test_scripts/RC/CLIMATE_RADIO/ButtonPress/001_success_flow_for_climate_and_radio.lua diff --git a/test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua similarity index 100% rename from test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua rename to test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua diff --git a/test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/003_disallow_flow_by_policy_for_radio.lua similarity index 100% rename from test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua rename to test_scripts/RC/CLIMATE_RADIO/ButtonPress/003_disallow_flow_by_policy_for_radio.lua diff --git a/test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua similarity index 100% rename from test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua rename to test_scripts/RC/CLIMATE_RADIO/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua diff --git a/test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua similarity index 100% rename from test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua rename to test_scripts/RC/CLIMATE_RADIO/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua diff --git a/test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/006_check_rpc_parameters_for_button_press.lua similarity index 100% rename from test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua rename to test_scripts/RC/CLIMATE_RADIO/ButtonPress/006_check_rpc_parameters_for_button_press.lua diff --git a/test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua similarity index 100% rename from test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua rename to test_scripts/RC/CLIMATE_RADIO/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua diff --git a/test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua similarity index 100% rename from test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua rename to test_scripts/RC/CLIMATE_RADIO/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua diff --git a/test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua similarity index 100% rename from test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua rename to test_scripts/RC/CLIMATE_RADIO/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua diff --git a/test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/010_generic_error_if_no_response_from_hmi.lua similarity index 100% rename from test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua rename to test_scripts/RC/CLIMATE_RADIO/ButtonPress/010_generic_error_if_no_response_from_hmi.lua diff --git a/test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua similarity index 100% rename from test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua rename to test_scripts/RC/CLIMATE_RADIO/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua diff --git a/test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua similarity index 100% rename from test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua rename to test_scripts/RC/CLIMATE_RADIO/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua diff --git a/test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua similarity index 100% rename from test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua rename to test_scripts/RC/CLIMATE_RADIO/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua diff --git a/test_scripts/RC/Capabilities/001_All_modules_all_params.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/001_All_modules_all_params.lua similarity index 100% rename from test_scripts/RC/Capabilities/001_All_modules_all_params.lua rename to test_scripts/RC/CLIMATE_RADIO/Capabilities/001_All_modules_all_params.lua diff --git a/test_scripts/RC/Capabilities/002_Only_CLIMATE_all_params.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/002_Only_CLIMATE_all_params.lua similarity index 100% rename from test_scripts/RC/Capabilities/002_Only_CLIMATE_all_params.lua rename to test_scripts/RC/CLIMATE_RADIO/Capabilities/002_Only_CLIMATE_all_params.lua diff --git a/test_scripts/RC/Capabilities/003_Only_RADIO_all_params.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/003_Only_RADIO_all_params.lua similarity index 100% rename from test_scripts/RC/Capabilities/003_Only_RADIO_all_params.lua rename to test_scripts/RC/CLIMATE_RADIO/Capabilities/003_Only_RADIO_all_params.lua diff --git a/test_scripts/RC/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua similarity index 100% rename from test_scripts/RC/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua rename to test_scripts/RC/CLIMATE_RADIO/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua diff --git a/test_scripts/RC/Capabilities/005_Resend_only_supported_parameters.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/005_Resend_only_supported_parameters.lua similarity index 100% rename from test_scripts/RC/Capabilities/005_Resend_only_supported_parameters.lua rename to test_scripts/RC/CLIMATE_RADIO/Capabilities/005_Resend_only_supported_parameters.lua diff --git a/test_scripts/RC/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua similarity index 100% rename from test_scripts/RC/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua rename to test_scripts/RC/CLIMATE_RADIO/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua diff --git a/test_scripts/RC/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua similarity index 100% rename from test_scripts/RC/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua rename to test_scripts/RC/CLIMATE_RADIO/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua diff --git a/test_scripts/RC/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua similarity index 100% rename from test_scripts/RC/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua rename to test_scripts/RC/CLIMATE_RADIO/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua diff --git a/test_scripts/RC/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua similarity index 100% rename from test_scripts/RC/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua rename to test_scripts/RC/CLIMATE_RADIO/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua diff --git a/test_scripts/RC/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua similarity index 100% rename from test_scripts/RC/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua rename to test_scripts/RC/CLIMATE_RADIO/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua diff --git a/test_scripts/RC/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua similarity index 100% rename from test_scripts/RC/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua rename to test_scripts/RC/CLIMATE_RADIO/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua diff --git a/test_scripts/RC/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua similarity index 100% rename from test_scripts/RC/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua rename to test_scripts/RC/CLIMATE_RADIO/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua diff --git a/test_scripts/RC/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua similarity index 100% rename from test_scripts/RC/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua rename to test_scripts/RC/CLIMATE_RADIO/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua diff --git a/test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/001_Success_flow.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/001_Success_flow.lua diff --git a/test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua diff --git a/test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua diff --git a/test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua diff --git a/test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua diff --git a/test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/006_RPC_parameters_values.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/006_RPC_parameters_values.lua diff --git a/test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua diff --git a/test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua diff --git a/test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua diff --git a/test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua diff --git a/test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua diff --git a/test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua diff --git a/test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua diff --git a/test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua diff --git a/test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua similarity index 100% rename from test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/001_Success_flow.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua rename to test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/001_Success_flow.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua rename to test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua rename to test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua rename to test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua rename to test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua rename to test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua rename to test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua rename to test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua rename to test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua rename to test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua rename to test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua rename to test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua rename to test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua rename to test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua rename to test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua diff --git a/test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/016_RPC_parameters_values.lua similarity index 100% rename from test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua rename to test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/016_RPC_parameters_values.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/012_Default_accessMode.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/012_Default_accessMode.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/012_Default_accessMode.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/012_Default_accessMode.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/015_Empty_data_from_HMI.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/015_Empty_data_from_HMI.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua diff --git a/test_scripts/RC/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua similarity index 100% rename from test_scripts/RC/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua rename to test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/001_Success_flow.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/001_Success_flow.lua rename to test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/001_Success_flow.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua rename to test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua rename to test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua rename to test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua rename to test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/006_RPC_parameters_values.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua rename to test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/006_RPC_parameters_values.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua rename to test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua rename to test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua rename to test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua rename to test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua rename to test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua rename to test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua rename to test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua rename to test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua diff --git a/test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua similarity index 100% rename from test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua rename to test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua diff --git a/test_sets/rc_ButtonPress.txt b/test_sets/rc_ButtonPress.txt deleted file mode 100644 index 2e1a807a83..0000000000 --- a/test_sets/rc_ButtonPress.txt +++ /dev/null @@ -1,13 +0,0 @@ -./test_scripts/RC/ButtonPress/001_success_flow_for_climate_and_radio.lua -./test_scripts/RC/ButtonPress/002_disallow_flow_by_policy_for_climate.lua -./test_scripts/RC/ButtonPress/003_disallow_flow_by_policy_for_radio.lua -./test_scripts/RC/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua -./test_scripts/RC/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua -./test_scripts/RC/ButtonPress/006_check_rpc_parameters_for_button_press.lua -./test_scripts/RC/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua -./test_scripts/RC/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua -./test_scripts/RC/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua -./test_scripts/RC/ButtonPress/010_generic_error_if_no_response_from_hmi.lua -./test_scripts/RC/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua -./test_scripts/RC/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua -./test_scripts/RC/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua diff --git a/test_sets/rc_CLIMATE_RADIO.txt b/test_sets/rc_CLIMATE_RADIO.txt new file mode 100644 index 0000000000..a40098b191 --- /dev/null +++ b/test_sets/rc_CLIMATE_RADIO.txt @@ -0,0 +1,106 @@ +./test_scripts/RC/CLIMATE_RADIO/Capabilities/001_All_modules_all_params.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/002_Only_CLIMATE_all_params.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/003_Only_RADIO_all_params.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/005_Resend_only_supported_parameters.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/006_RPC_parameters_values.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/001_success_flow_for_climate_and_radio.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/003_disallow_flow_by_policy_for_radio.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/006_check_rpc_parameters_for_button_press.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/010_generic_error_if_no_response_from_hmi.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/016_RPC_parameters_values.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/012_Default_accessMode.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/015_Empty_data_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/006_RPC_parameters_values.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua diff --git a/test_sets/rc_Capabilities.txt b/test_sets/rc_Capabilities.txt deleted file mode 100644 index d6739047fd..0000000000 --- a/test_sets/rc_Capabilities.txt +++ /dev/null @@ -1,13 +0,0 @@ -./test_scripts/RC/Capabilities/001_All_modules_all_params.lua -./test_scripts/RC/Capabilities/002_Only_CLIMATE_all_params.lua -./test_scripts/RC/Capabilities/003_Only_RADIO_all_params.lua -./test_scripts/RC/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua -./test_scripts/RC/Capabilities/005_Resend_only_supported_parameters.lua -./test_scripts/RC/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua -./test_scripts/RC/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua -./test_scripts/RC/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua -./test_scripts/RC/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua -./test_scripts/RC/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua -./test_scripts/RC/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua -./test_scripts/RC/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua -./test_scripts/RC/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua diff --git a/test_sets/rc_GetInteriorVehicleData.txt b/test_sets/rc_GetInteriorVehicleData.txt deleted file mode 100644 index ac3f7b97b7..0000000000 --- a/test_sets/rc_GetInteriorVehicleData.txt +++ /dev/null @@ -1,14 +0,0 @@ -./test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua -./test_scripts/RC/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua -./test_scripts/RC/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua -./test_scripts/RC/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua -./test_scripts/RC/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua -./test_scripts/RC/GetInteriorVehicleData/006_RPC_parameters_values.lua -./test_scripts/RC/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua -./test_scripts/RC/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua -./test_scripts/RC/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua -./test_scripts/RC/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua -./test_scripts/RC/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua -./test_scripts/RC/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua -./test_scripts/RC/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua -./test_scripts/RC/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua diff --git a/test_sets/rc_GetInteriorVehicleDataConsent.txt b/test_sets/rc_GetInteriorVehicleDataConsent.txt deleted file mode 100644 index 1f51852e04..0000000000 --- a/test_sets/rc_GetInteriorVehicleDataConsent.txt +++ /dev/null @@ -1,11 +0,0 @@ -./test_scripts/RC/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua -./test_scripts/RC/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua -./test_scripts/RC/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua -./test_scripts/RC/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua -./test_scripts/RC/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua -./test_scripts/RC/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua -./test_scripts/RC/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua -./test_scripts/RC/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua -./test_scripts/RC/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua -./test_scripts/RC/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua -./test_scripts/RC/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua diff --git a/test_sets/rc_OnInteriorVehicleData.txt b/test_sets/rc_OnInteriorVehicleData.txt deleted file mode 100644 index d3794dee8a..0000000000 --- a/test_sets/rc_OnInteriorVehicleData.txt +++ /dev/null @@ -1,16 +0,0 @@ -./test_scripts/RC/OnInteriorVehicleData/001_Success_flow.lua -./test_scripts/RC/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua -./test_scripts/RC/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua -./test_scripts/RC/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua -./test_scripts/RC/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua -./test_scripts/RC/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua -./test_scripts/RC/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua -./test_scripts/RC/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua -./test_scripts/RC/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua -./test_scripts/RC/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua -./test_scripts/RC/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua -./test_scripts/RC/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua -./test_scripts/RC/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua -./test_scripts/RC/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua -./test_scripts/RC/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua -./test_scripts/RC/OnInteriorVehicleData/016_RPC_parameters_values.lua diff --git a/test_sets/rc_OnRemoteControlSettings.txt b/test_sets/rc_OnRemoteControlSettings.txt deleted file mode 100644 index a0cac4d503..0000000000 --- a/test_sets/rc_OnRemoteControlSettings.txt +++ /dev/null @@ -1,24 +0,0 @@ -./test_scripts/RC/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua -./test_scripts/RC/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua -./test_scripts/RC/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua -./test_scripts/RC/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua -./test_scripts/RC/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua -./test_scripts/RC/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua -./test_scripts/RC/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua -./test_scripts/RC/OnRemoteControlSettings/008_Allowed_false.lua -./test_scripts/RC/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua -./test_scripts/RC/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua -./test_scripts/RC/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua -./test_scripts/RC/OnRemoteControlSettings/012_Default_accessMode.lua -./test_scripts/RC/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua -./test_scripts/RC/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua -./test_scripts/RC/OnRemoteControlSettings/015_Empty_data_from_HMI.lua -./test_scripts/RC/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua -./test_scripts/RC/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua -./test_scripts/RC/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua -./test_scripts/RC/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua -./test_scripts/RC/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua -./test_scripts/RC/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua -./test_scripts/RC/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua -./test_scripts/RC/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua -./test_scripts/RC/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua diff --git a/test_sets/rc_SetInteriorVehicleData.txt b/test_sets/rc_SetInteriorVehicleData.txt deleted file mode 100644 index 18dc430d95..0000000000 --- a/test_sets/rc_SetInteriorVehicleData.txt +++ /dev/null @@ -1,15 +0,0 @@ -./test_scripts/RC/GetInteriorVehicleData/001_Success_flow.lua -./test_scripts/RC/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua -./test_scripts/RC/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua -./test_scripts/RC/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua -./test_scripts/RC/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua -./test_scripts/RC/SetInteriorVehicleData/006_RPC_parameters_values.lua -./test_scripts/RC/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua -./test_scripts/RC/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua -./test_scripts/RC/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua -./test_scripts/RC/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua -./test_scripts/RC/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua -./test_scripts/RC/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua -./test_scripts/RC/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua -./test_scripts/RC/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua -./test_scripts/RC/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua From a8a5c4645e655ab2d3804eda690170ee512a3a13 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 24 Jan 2018 17:19:21 +0200 Subject: [PATCH 302/681] Stabilize RC scripts --- test_scripts/RC/commonRC.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index b2863e2739..f3aa412d3c 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -116,11 +116,11 @@ local function ptu(self, ptu_update_func) self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = policy_file_path .. "/" .. policy_file_name }) end) mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + :Do(function() os.remove(ptu_file_name) end) end) :Times(AtMost(1)) end end) - os.remove(ptu_file_name) end local function allow_sdl(self) @@ -184,6 +184,7 @@ function commonRC.rai_ptu_n(id, ptu_update_func, self) self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + :Times(2) end) end) end From 3ea3937c1672748a89bd63a4ef9a97f140415077 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 25 Jan 2018 12:07:10 +0200 Subject: [PATCH 303/681] Fix priority of events processing --- user_modules/dummy_connecttest.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_modules/dummy_connecttest.lua b/user_modules/dummy_connecttest.lua index 10667760c0..ab2e7dd084 100644 --- a/user_modules/dummy_connecttest.lua +++ b/user_modules/dummy_connecttest.lua @@ -366,7 +366,7 @@ function module:initHMI_onReady(hmi_table) return end local event = events.Event() - event.level = 2 + event.level = 1 event.matches = function(self, data) return data.method == name end From 6d001a1cd29254c12131b48308f744f5a2d39fe9 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 25 Jan 2018 13:44:24 +0200 Subject: [PATCH 304/681] Add events module as local --- .../Smoke/Registration/001_Register_5_connection.lua | 1 + .../Smoke/Resumption/008_Resumption_heartbeat_disconnect.lua | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/test_scripts/Smoke/Registration/001_Register_5_connection.lua b/test_scripts/Smoke/Registration/001_Register_5_connection.lua index ee92fcc433..f3c91e4e2c 100644 --- a/test_scripts/Smoke/Registration/001_Register_5_connection.lua +++ b/test_scripts/Smoke/Registration/001_Register_5_connection.lua @@ -37,6 +37,7 @@ local mobile_session = require('mobile_session') local mobile = require('mobile_connection') local tcp = require('tcp_connection') local file_connection = require('file_connection') +local events = require("events") --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') diff --git a/test_scripts/Smoke/Resumption/008_Resumption_heartbeat_disconnect.lua b/test_scripts/Smoke/Resumption/008_Resumption_heartbeat_disconnect.lua index b3784329a2..d281c514fe 100644 --- a/test_scripts/Smoke/Resumption/008_Resumption_heartbeat_disconnect.lua +++ b/test_scripts/Smoke/Resumption/008_Resumption_heartbeat_disconnect.lua @@ -27,6 +27,7 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonStepsResumption = require('user_modules/shared_testcases/commonStepsResumption') local mobile_session = require('mobile_session') +local events = require("events") --[[ General Settings for configuration ]] Test = require('user_modules/dummy_connecttest') @@ -89,7 +90,7 @@ function Test:Wait_20_sec() :Timeout(20000) EXPECT_EVENT(events.disconnectedEvent, "Disconnected") :Do(function() - print("Disconnected!!!") + print("Disconnected!!!") end) :Timeout(20000) end @@ -114,4 +115,4 @@ function Test.Stop_SDL() StopSDL() end -return Test \ No newline at end of file +return Test From 52a843335a393c26eb22f52f685b993e367db162 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 26 Jan 2018 10:36:08 +0200 Subject: [PATCH 305/681] Fix obtaining of MAC address --- .../039_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/Smoke/API/039_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/039_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua index 5f68c53a4f..6e7efdc2f2 100644 --- a/test_scripts/Smoke/API/039_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/039_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua @@ -49,7 +49,7 @@ local putFileParams = { } local storagePath = commonPreconditions:GetPathToSDL() .. "storage/" .. -config.application1.registerAppInterfaceParams.appID .. "_" .. config.deviceMAC .. "/" +config.application1.registerAppInterfaceParams.appID .. "_" .. commonSmoke.getDeviceMAC() .. "/" local ImageValue = { value = storagePath .. "icon.png", From 737195e6dcea3dd909e89dea5b5d4e46c19accfd Mon Sep 17 00:00:00 2001 From: Andriy Byzhynar Date: Fri, 29 Sep 2017 17:02:13 +0300 Subject: [PATCH 306/681] Added common module for VehicleData and test coverage --- .../GetVehicleData/001_Success_flow.lua | 49 +++ ..._parameter_DISALLOWED_by_policies_flow.lua | 74 +++++ .../OnVehicleData/001_Success_flow.lua | 69 +++++ ...onForUnsubsribedParameter_Ignored_flow.lua | 95 ++++++ .../SubscribeVehicleData/001_Success_flow.lua | 51 ++++ ..._parameter_DISALLOWED_by_policies_flow.lua | 54 ++++ ...already_subscribed_Result_IGNORED_flow.lua | 62 ++++ .../001_Success_flow.lua | 70 +++++ ...ameter_not_yet_subscribed_IGNORED_flow.lua | 47 +++ ...ready_unsubscribed_Result_IGNORED_flow.lua | 79 +++++ ...wed_by_policies_Result_DISALLOWED_flow.lua | 54 ++++ .../API/VehicleData/commonVehicleData.lua | 289 ++++++++++++++++++ 12 files changed, 993 insertions(+) create mode 100644 test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua create mode 100644 test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua create mode 100644 test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua create mode 100644 test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua create mode 100644 test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua create mode 100644 test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua create mode 100644 test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua create mode 100644 test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua create mode 100644 test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua create mode 100644 test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua create mode 100644 test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua create mode 100644 test_scripts/API/VehicleData/commonVehicleData.lua diff --git a/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua new file mode 100644 index 0000000000..3ee53dcf04 --- /dev/null +++ b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- Item: Use Case: request is NOT allowed by Policies +-- +-- Requirement summary: +-- [GetVehicleData] As a mobile app wants to send a request to get the details of the vehicle data +-- +-- Description: +-- In case: +-- 1) mobile application sends valid GetVehicleData to SDL and this request is allowed by Policies +-- SDL must: +-- Transfer this request to HMI and after successful response from hmi +-- Respond SUCCESS, success:true to mobile application + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') + +--[[ Local Variables ]] + +local rpc = { + name = "GetVehicleData", + params = { + engineOilLife = true + } +} + +local function processRPCSuccess(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc.name, rpc.params) + EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { engineOilLife = 52.3 }) + end) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +runner.Step("RPC " .. rpc.name, processRPCSuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua new file mode 100644 index 0000000000..db98c8a024 --- /dev/null +++ b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -0,0 +1,74 @@ +--------------------------------------------------------------------------------------------------- +-- Item: Use Case: request is allowed but parameter of this request is NOT allowed by Policies +-- +-- Requirement summary: +-- [GetVehicleData] As a mobile app wants to send a request to get the details of the vehicle data +-- +-- Description: +-- In case: +-- 1) mobile application sends valid GetVehicleData to SDL and this request is allowed by Policies but RPC parameter is not allowed +-- SDL must: +-- 1) SDL responds DISALLOWED, success:false to mobile application and doesn't transfer this request to HMI + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") + +--[[ Local Variables ]] + +local rpc = { + name = "GetVehicleData", + params = { + engineOilLife = true + } +} + +-- Function which removes engineOilLife parameter from specified func group and rpc +local function ptu_update_func(tbl) + local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["GetVehicleData"].parameters + for index, value in pairs(params) do + if ("engineOilLife" == value) then params[index] = nil end + end +end + +local function delayExp() + commonTestCases:DelayedExp(2000) +end + +local function processRPCSuccess(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc.name, rpc.params) + EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { engineOilLife = 52.3 }) + end) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function processRPCFailure(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc.name, rpc.params) + EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params):Times(0) + mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +runner.Step("RPC " .. rpc.name .. " 1st time" , processRPCSuccess) + +runner.Step("RAI 2nd app with PTU", common.registerAppWithPTU, {2, ptu_update_func}) + +--runner.Step("Delay..", delayExp) + +runner.Step("RPC " .. rpc.name .. " 2nd time", processRPCFailure) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) \ No newline at end of file diff --git a/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua new file mode 100644 index 0000000000..596d4912b2 --- /dev/null +++ b/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua @@ -0,0 +1,69 @@ +--------------------------------------------------------------------------------------------------- +-- Item: Use Case: request is allowed by Policies +-- +-- Requirement summary: +-- [SubscribeVehicleData] As a mobile app wants to send a request to subscribe for specified parameter +-- +-- Description: +-- In case: +-- 1) hmi application sends valid SubscribeVehicleData to SDL and this request is allowed by Policies +-- SDL must: +-- Transfer this request to HMI and after successful response from hmi +-- Respond SUCCESS, success:true to mobile application +-- After HMI sends notification about changes in subcribed parameter +-- SDL must: +-- Forward this notification to mobile application + + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') + +--[[ Local Variables ]] + +local rpc1 = { + name = "SubscribeVehicleData", + params = { + engineOilLife = true + } +} + +local rpc2 = { + name = "OnVehicleData", + params = { + engineOilLife = 50.3 + } +} + +local function processRPCSubscribeSuccess(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc1.name, rpc1.params) + EXPECT_HMICALL("VehicleInfo." .. rpc1.name, rpc1.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + end) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) +end + + +local function checkNotificationSuccess(self) + local mobileSession = common.getMobileSession(self, 1) + self.hmiConnection:SendNotification("VehicleInfo." .. rpc2.name, rpc2.params) + --mobile side: expected SubscribeVehicleData response + mobileSession:ExpectNotification("OnVehicleData", rpc2.params) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +runner.Step("RPC " .. rpc1.name, processRPCSubscribeSuccess) +runner.Step("RPC " .. rpc2.name, checkNotificationSuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua new file mode 100644 index 0000000000..131e86557b --- /dev/null +++ b/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua @@ -0,0 +1,95 @@ +--------------------------------------------------------------------------------------------------- +-- Item: Use Case: request is allowed by Policies +-- +-- Requirement summary: +-- [SubscribeVehicleData] As a mobile app wants to send a request to subscribe for specified parameter +-- +-- Description: +-- In case: +-- 1) hmi application sends valid SubscribeVehicleData to SDL and this request is allowed by Policies +-- SDL must: +-- Transfer this request to HMI and after successful response from hmi +-- Respond SUCCESS, success:true to mobile application +-- After HMI sends notification about changes in subcribed parameter +-- SDL must: +-- Forward this notification to mobile application + + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') + +--[[ Local Variables ]] + +local rpc1 = { + name = "SubscribeVehicleData", + params = { + engineOilLife = true + } +} + +local rpc2 = { + name = "OnVehicleData", + params = { + engineOilLife = 50.3 + } +} + +local rpc3 = { + name = "UnsubscribeVehicleData", + params = { + engineOilLife = true + } +} + +local function processRPCSubscribeSuccess(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc1.name, rpc1.params) + EXPECT_HMICALL("VehicleInfo." .. rpc1.name, rpc1.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + end) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) +end + +local function processRPCUnsubscribeSuccess(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc3.name, rpc3.params) + EXPECT_HMICALL("VehicleInfo." .. rpc3.name, rpc3.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + end) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) +end + + +local function checkNotificationSuccess(self) + local mobileSession = common.getMobileSession(self, 1) + self.hmiConnection:SendNotification("VehicleInfo." .. rpc2.name, rpc2.params) + --mobile side: expected SubscribeVehicleData response + mobileSession:ExpectNotification("OnVehicleData", rpc2.params) +end + +local function checkNotificationIgnored(self) + local mobileSession = common.getMobileSession(self, 1) + self.hmiConnection:SendNotification("VehicleInfo." .. rpc2.name, rpc2.params) + --mobile side: expected SubscribeVehicleData response + mobileSession:ExpectNotification("OnVehicleData", rpc2.params):Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +runner.Step("RPC " .. rpc1.name, processRPCSubscribeSuccess) +runner.Step("RPC " .. rpc2.name .. " forwarded to mobile", checkNotificationSuccess) +runner.Step("RPC " .. rpc3.name, processRPCUnsubscribeSuccess) +runner.Step("RPC " .. rpc2.name .. " not forwarded to mobile", checkNotificationIgnored) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua new file mode 100644 index 0000000000..2ddb926855 --- /dev/null +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua @@ -0,0 +1,51 @@ +--------------------------------------------------------------------------------------------------- +-- Item: Use Case: request is allowed by Policies +-- +-- Requirement summary: +-- [SubscribeVehicleData] As a mobile app wants to send a request to subscribe for specified parameter +-- +-- Description: +-- In case: +-- 1) mobile application sends valid SubscribeVehicleData to SDL and this request is allowed by Policies +-- SDL must: +-- Transfer this request to HMI and after successful response from hmi +-- Respond SUCCESS, success:true to mobile application + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') + +--[[ Local Variables ]] + +local rpc = { + name = "SubscribeVehicleData", + params = { + engineOilLife = true + } +} + +local function processRPCSuccess(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc.name, rpc.params) + EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + end) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) +end + + + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +runner.Step("RPC " .. rpc.name, processRPCSuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua new file mode 100644 index 0000000000..54cd30a28c --- /dev/null +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -0,0 +1,54 @@ +--------------------------------------------------------------------------------------------------- +-- Item: Use Case: request is allowed but parameter of this request is NOT allowed by Policies +-- +-- Requirement summary: +-- [SubscribeVehicleData] As a mobile app wants to send a request to get the details of the vehicle data +-- +-- Description: +-- In case: +-- 1) mobile application sends valid SubscribeVehicleData to SDL and this request is allowed by Policies but RPC parameter is not allowed +-- SDL must: +-- 1) SDL responds DISALLOWED, success:false to mobile application and doesn't transfer this request to HMI + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') +--[[ Local Variables ]] + +local rpc = { + name = "SubscribeVehicleData", + params = { + engineOilLife = true + } +} + +-- Function which removes engineOilLife parameter from specified func group and rpc +local function ptu_update_func(tbl) + local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["SubscribeVehicleData"].parameters + for index, value in pairs(params) do + if ("engineOilLife" == value) then params[index] = nil end + end +end + +local function processRPCFailure(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc.name, rpc.params) + EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params):Times(0) + mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED", + info = "'engineOilLife' disallowed by policies.", + engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DISALLOWED"} }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU, {1, ptu_update_func}) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +runner.Step("RPC " .. rpc.name , processRPCFailure) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) \ No newline at end of file diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua new file mode 100644 index 0000000000..3ca0a4e5d2 --- /dev/null +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua @@ -0,0 +1,62 @@ +--------------------------------------------------------------------------------------------------- +-- Item: Use Case: request is allowed by policies but app is already subscribed for specified parameter +-- +-- Requirement summary: +-- [SubscribeVehicleData] As a mobile app wants to send a request to subscribe for specified parameter +-- +-- Description: +-- In case: +-- 1) mobile application sends valid SubscribeVehicleData to SDL and this request +-- is allowed by Policies but app is already subscribed for specified parameter +-- SDL must: +-- 1) SDL responds IGNORED, success:true and info: "Already subscribed on some provided VehicleData." +-- to mobile application and doesn't transfer this request to HMI + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') +--[[ Local Variables ]] + +local rpc = { + name = "SubscribeVehicleData", + params = { + engineOilLife = true + } +} + +local function processRPCSuccess(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc.name, rpc.params) + EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + end) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) +end + + +local function processRPCIgnored(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc.name, rpc.params) + EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params):Times(0) + mobileSession:ExpectResponse(cid, { success = false, resultCode = "IGNORED", + info = "Already subscribed on some provided VehicleData.", + engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DATA_ALREADY_SUBSCRIBED"} }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +runner.Step("RPC " .. rpc.name .. " 1st time" , processRPCSuccess) +runner.Step("RPC " .. rpc.name .. " 2nd time" , processRPCIgnored) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) \ No newline at end of file diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua new file mode 100644 index 0000000000..bb8b4b01dc --- /dev/null +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- Item: Use Case: request is allowed by Policies +-- +-- Requirement summary: +-- [UnsubscribeVehicleData] As a mobile app wants to send a request to unsubscribe +-- for already subscribed specified parameter +-- +-- Description: +-- In case: +-- 1) mobile application sends valid UnsubscribeVehicleData to SDL and this request is allowed by Policies +-- SDL must: +-- Transfer this request to HMI and after successful response from hmi +-- Respond SUCCESS, success:true to mobile application + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') + +--[[ Local Variables ]] + +local rpc_subscribe = { + name = "SubscribeVehicleData", + params = { + engineOilLife = true + } +} + +local rpc_unsubscribe = { + name = "UnsubscribeVehicleData", + params = { + engineOilLife = true + } +} + +local function processRPCSubscribeSuccess(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc_subscribe.name, rpc_subscribe.params) + EXPECT_HMICALL("VehicleInfo." .. rpc_subscribe.name, rpc_subscribe.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + end) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) +end + +local function processRPCUnsubscribeSuccess(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc_unsubscribe.name, rpc_unsubscribe.params) + EXPECT_HMICALL("VehicleInfo." .. rpc_unsubscribe.name, rpc_unsubscribe.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + end) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) +end + + + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +runner.Step("RPC " .. rpc_subscribe.name, processRPCSubscribeSuccess) +runner.Step("RPC " .. rpc_unsubscribe.name, processRPCUnsubscribeSuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua new file mode 100644 index 0000000000..64471eb6a0 --- /dev/null +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua @@ -0,0 +1,47 @@ +--------------------------------------------------------------------------------------------------- +-- Item: Use Case: request is allowed but parameter of this request is NOT allowed by Policies +-- +-- Requirement summary: +-- [UnsubscribeVehicleData] As a mobile app wants to send a request to get the details of the vehicle data +-- +-- Description: +-- In case: +-- 1) mobile application sends valid UnsubscribeVehicleData to SDL and this request +-- is allowed by Policies for parameter not yet subscribed +-- SDL must: +-- 1) SDL responds IGNORED, success:false to mobile application and doesn't transfer this request to HMI + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') +--[[ Local Variables ]] + +local rpc = { + name = "UnsubscribeVehicleData", + params = { + engineOilLife = true + } +} + +local function processRPCFailure(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc.name, rpc.params) + EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params):Times(0) + mobileSession:ExpectResponse(cid, { success = false, resultCode = "IGNORED", + info = "Some provided VehicleData was not subscribed.", + engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DATA_NOT_SUBSCRIBED"} }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +runner.Step("RPC " .. rpc.name , processRPCFailure) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) \ No newline at end of file diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua new file mode 100644 index 0000000000..c5ca1d50cf --- /dev/null +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua @@ -0,0 +1,79 @@ +--------------------------------------------------------------------------------------------------- +-- Item: Use Case: request is allowed by Policies +-- +-- Requirement summary: +-- [UnsubscribeVehicleData] As a mobile app wants to send a request to unsubscribe +-- for already subscribed specified parameter +-- +-- Description: +-- In case: +-- 1) mobile application sends valid UnsubscribeVehicleData to SDL and this request is allowed by Policies +-- SDL must: +-- Transfer this request to HMI and after successful response from hmi +-- Respond SUCCESS, success:true to mobile application + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') + +--[[ Local Variables ]] + +local rpc_subscribe = { + name = "SubscribeVehicleData", + params = { + engineOilLife = true + } +} + +local rpc_unsubscribe = { + name = "UnsubscribeVehicleData", + params = { + engineOilLife = true + } +} + +local function processRPCSubscribeSuccess(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc_subscribe.name, rpc_subscribe.params) + EXPECT_HMICALL("VehicleInfo." .. rpc_subscribe.name, rpc_subscribe.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + end) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) +end + +local function processRPCUnsubscribeSuccess(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc_unsubscribe.name, rpc_unsubscribe.params) + EXPECT_HMICALL("VehicleInfo." .. rpc_unsubscribe.name, rpc_unsubscribe.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + end) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) +end + +local function processRPCUnsubscribeIgnored(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc_unsubscribe.name, rpc_unsubscribe.params) + EXPECT_HMICALL("VehicleInfo." .. rpc_unsubscribe.name, rpc_unsubscribe.params):Times(0) + mobileSession:ExpectResponse(cid, { success = false, resultCode = "IGNORED", + engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", + resultCode = "DATA_NOT_SUBSCRIBED"} }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +runner.Step("RPC " .. rpc_subscribe.name, processRPCSubscribeSuccess) +runner.Step("RPC " .. rpc_unsubscribe.name, processRPCUnsubscribeSuccess) +runner.Title("Trying to unsubscribe from already unsubscribed parameter...") +runner.Step("RPC " .. rpc_unsubscribe.name, processRPCUnsubscribeIgnored) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua new file mode 100644 index 0000000000..4e407029a1 --- /dev/null +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua @@ -0,0 +1,54 @@ +--------------------------------------------------------------------------------------------------- +-- Item: Use Case: request is allowed but parameter of this request is NOT allowed by Policies +-- +-- Requirement summary: +-- [UnsubscribeVehicleData] As a mobile app wants to send a request to get the details of the vehicle data +-- +-- Description: +-- In case: +-- 1) mobile application sends valid UnsubscribeVehicleData to SDL and this request is allowed by Policies but RPC parameter is not allowed +-- SDL must: +-- 1) SDL responds DISALLOWED, success:false to mobile application and doesn't transfer this request to HMI + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') +--[[ Local Variables ]] + +local rpc = { + name = "UnsubscribeVehicleData", + params = { + engineOilLife = true + } +} + +-- Function which removes engineOilLife parameter from specified func group and rpc +local function ptu_update_func(tbl) + local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["UnsubscribeVehicleData"].parameters + for index, value in pairs(params) do + if ("engineOilLife" == value) then params[index] = nil end + end +end + +local function processRPCFailure(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc.name, rpc.params) + EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params):Times(0) + mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED", + info = "'engineOilLife' disallowed by policies.", + engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DISALLOWED"} }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU, {1, ptu_update_func}) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +runner.Step("RPC " .. rpc.name , processRPCFailure) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) \ No newline at end of file diff --git a/test_scripts/API/VehicleData/commonVehicleData.lua b/test_scripts/API/VehicleData/commonVehicleData.lua new file mode 100644 index 0000000000..fb2ef07c9c --- /dev/null +++ b/test_scripts/API/VehicleData/commonVehicleData.lua @@ -0,0 +1,289 @@ +--------------------------------------------------------------------------------------------------- +-- VehicleData common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 + +--[[ Required Shared libraries ]] +local mobile_session = require("mobile_session") +local json = require("modules/json") + +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') + +--[[ Local Variables ]] +local ptu_table = {} +local hmiAppIds = {} + +local commonVehicleData = {} + +commonVehicleData.timeout = 2000 +commonVehicleData.minTimeout = 500 +commonVehicleData.DEFAULT = "Default" + +local function checkIfPTSIsSentAsBinary(bin_data) + if not (bin_data ~= nil and string.len(bin_data) > 0) then + commonFunctions:userPrint(31, "PTS was not sent to Mobile in payload of OnSystemRequest") + end +end + +function commonVehicleData.getGetVehicleDataConfig() + return { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + groups = { "Base-4", "Emergency-1" } + } +end + +local function getPTUFromPTS(tbl) + tbl.policy_table.consumer_friendly_messages.messages = nil + tbl.policy_table.device_data = nil + tbl.policy_table.module_meta = nil + tbl.policy_table.usage_and_error_counts = nil + tbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + tbl.policy_table.module_config.preloaded_pt = nil + tbl.policy_table.module_config.preloaded_date = nil +end + +local function jsonFileToTable(file_name) + local f = io.open(file_name, "r") + local content = f:read("*all") + f:close() + return json.decode(content) +end + + +local function addParamToRPC(tbl, functional_grouping, rpc, param) + local is_found = false + local params = tbl.policy_table.functional_groupings[functional_grouping].rpcs[rpc].parameters + for _, value in pairs(params) do + if (value == param) then is_found = true end + end + if not is_found then + table.insert(tbl.policy_table.functional_groupings[functional_grouping].rpcs[rpc].parameters, param) + end +end + +local function ptu(self, app_id, ptu_update_func) + local function getAppsCount() + local count = 0 + for _ in pairs(hmiAppIds) do + count = count + 1 + end + return count + end + + local policy_file_name = "PolicyTableUpdate" + local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + local ptu_file_name = os.tmpname() + local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) + EXPECT_HMIRESPONSE(requestId) + :Do(function() + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = pts_file_name }) + getPTUFromPTS(ptu_table) + local function updatePTU(tbl) + for rpc in pairs(tbl.policy_table.functional_groupings["Emergency-1"].rpcs) do + addParamToRPC(tbl, "Emergency-1", rpc, "engineOilLife") + end + tbl.policy_table.app_policies[commonVehicleData.getMobileAppId(app_id)] = commonVehicleData.getGetVehicleDataConfig() + end + updatePTU(ptu_table) + if ptu_update_func then + ptu_update_func(ptu_table) + end + local function tableToJsonFile(tbl, file_name) + local f = io.open(file_name, "w") + f:write(json.encode(tbl)) + f:close() + end + tableToJsonFile(ptu_table, ptu_file_name) + + local event = events.Event() + event.matches = function(self, e) return self == e end + EXPECT_EVENT(event, "PTU event") + :Timeout(11000) + + for id = 1, getAppsCount() do + local mobileSession = commonVehicleData.getMobileSession(self, id) + mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :Do(function(_, d2) + print("App ".. id .. " was used for PTU") + RAISE_EVENT(event, event, "PTU event") + checkIfPTSIsSentAsBinary(d2.binaryData) + local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, d3) + self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = policy_file_path .. "/" .. policy_file_name }) + end) + mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + end) + :Times(AtMost(1)) + end + end) + os.remove(ptu_file_name) +end + +function commonVehicleData.preconditions() + commonFunctions:SDLForceStop() + commonSteps:DeletePolicyTable() + commonSteps:DeleteLogsFiles() +end + +--[[Module functions]] + +function commonVehicleData.activateApp(pAppId, self) + self, pAppId = commonVehicleData.getSelfAndParams(pAppId, self) + if not pAppId then pAppId = 1 end + local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + local mobSession = commonVehicleData.getMobileSession(self, pAppId) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + EXPECT_HMIRESPONSE(requestId) + mobSession:ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + commonTestCases:DelayedExp(commonVehicleData.minTimeout) +end + + +function commonVehicleData.getSelfAndParams(...) + local out = { } + local selfIdx = nil + for i,v in pairs({...}) do + if type(v) == "table" and v.isTest then + table.insert(out, v) + selfIdx = i + break + end + end + local idx = 2 + for i = 1, table.maxn({...}) do + if i ~= selfIdx then + out[idx] = ({...})[i] + idx = idx + 1 + end + end + return table.unpack(out, 1, table.maxn(out)) +end + +function commonVehicleData.getHMIAppId(pAppId) + if not pAppId then pAppId = 1 end + return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] +end + +function commonVehicleData.getMobileSession(self, pAppId) + if not pAppId then pAppId = 1 end + return self["mobileSession" .. pAppId] +end + +function commonVehicleData.getMobileAppId(pAppId) + if not pAppId then pAppId = 1 end + return config["application" .. pAppId].registerAppInterfaceParams.appID +end + +function commonVehicleData.getPathToSDL() + return config.pathToSDL +end + +function commonVehicleData.postconditions() + StopSDL() +end + +function commonVehicleData.registerAppWithPTU(id, ptu_update_func, self) + self, id, ptu_update_func = commonVehicleData.getSelfAndParams(id, ptu_update_func, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :Do(function(_, d2) + self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptu_table = jsonFileToTable(d2.params.file) + ptu(self, id, ptu_update_func) + end) + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(1) + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange"):Times(2) + EXPECT_HMICALL("VehicleInfo.GetVehicleData", { odometer = true}) + end) + end) +end + +function commonVehicleData.raiN(id, self) + self, id = commonVehicleData.getSelfAndParams(id, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(1) + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + end) + end) +end + +local function allowSDL(self) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", + { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) +end + +function commonVehicleData.start(pHMIParams, self) + self, pHMIParams = commonVehicleData.getSelfAndParams(pHMIParams, self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady(pHMIParams) + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + self:connectMobile() + :Do(function() + commonFunctions:userPrint(35, "Mobile connected") + allowSDL(self) + end) + end) + end) + end) +end + +function commonVehicleData.unregisterApp(pAppId, self) + local mobSession = commonVehicleData.getMobileSession(self, pAppId) + local hmiAppId = commonVehicleData.getHMIAppId(pAppId) + local cid = mobSession:SendRPC("UnregisterAppInterface",{}) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = hmiAppId, unexpectedDisconnect = false }) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +function commonVehicleData.backupHMICapabilities() + local hmiCapabilitiesFile = commonFunctions:read_parameter_from_smart_device_link_ini("HMICapabilities") + commonPreconditions:BackupFile(hmiCapabilitiesFile) +end + +function commonVehicleData.restoreHMICapabilities() + local hmiCapabilitiesFile = commonFunctions:read_parameter_from_smart_device_link_ini("HMICapabilities") + commonPreconditions:RestoreFile(hmiCapabilitiesFile) +end + +return commonVehicleData From e6bd464009b4b833b0ee7ec3c829aa472edc71b5 Mon Sep 17 00:00:00 2001 From: Andriy Byzhynar Date: Mon, 2 Oct 2017 18:42:42 +0300 Subject: [PATCH 307/681] Add parameter check and remove unused function --- .../API/VehicleData/GetVehicleData/001_Success_flow.lua | 4 ++-- .../002_RPC_parameter_DISALLOWED_by_policies_flow.lua | 4 ---- .../002_NotificationForUnsubsribedParameter_Ignored_flow.lua | 4 ++-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua index 3ee53dcf04..a1ed778165 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua @@ -29,9 +29,9 @@ local function processRPCSuccess(self) local cid = mobileSession:SendRPC(rpc.name, rpc.params) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { engineOilLife = 52.3 }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = 50.30}) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = 50.30}) end --[[ Scenario ]] diff --git a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index db98c8a024..b38ddef010 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -32,10 +32,6 @@ local function ptu_update_func(tbl) end end -local function delayExp() - commonTestCases:DelayedExp(2000) -end - local function processRPCSuccess(self) local mobileSession = common.getMobileSession(self, 1) local cid = mobileSession:SendRPC(rpc.name, rpc.params) diff --git a/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua index 131e86557b..f00846743d 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua @@ -66,14 +66,14 @@ end local function checkNotificationSuccess(self) local mobileSession = common.getMobileSession(self, 1) self.hmiConnection:SendNotification("VehicleInfo." .. rpc2.name, rpc2.params) - --mobile side: expected SubscribeVehicleData response + --mobile side: expected OnVehicleData notification mobileSession:ExpectNotification("OnVehicleData", rpc2.params) end local function checkNotificationIgnored(self) local mobileSession = common.getMobileSession(self, 1) self.hmiConnection:SendNotification("VehicleInfo." .. rpc2.name, rpc2.params) - --mobile side: expected SubscribeVehicleData response + --mobile side: OnVehicleData notification not expected mobileSession:ExpectNotification("OnVehicleData", rpc2.params):Times(0) end From 3171428714ba1ed696e23c3a8ea4418d640a4e8d Mon Sep 17 00:00:00 2001 From: Andriy Byzhynar Date: Tue, 3 Oct 2017 17:26:20 +0300 Subject: [PATCH 308/681] Add delays to times(0) expectations and fix coding style --- .../GetVehicleData/001_Success_flow.lua | 19 ++++--- ..._parameter_DISALLOWED_by_policies_flow.lua | 22 ++++---- .../OnVehicleData/001_Success_flow.lua | 27 +++++----- ...onForUnsubsribedParameter_Ignored_flow.lua | 37 +++++++------ .../SubscribeVehicleData/001_Success_flow.lua | 14 ++--- ..._parameter_DISALLOWED_by_policies_flow.lua | 17 +++--- ...already_subscribed_Result_IGNORED_flow.lua | 18 ++++--- .../001_Success_flow.lua | 26 +++++---- ...ameter_not_yet_subscribed_IGNORED_flow.lua | 22 +++++--- ...ready_unsubscribed_Result_IGNORED_flow.lua | 27 ++++++---- ...wed_by_policies_Result_DISALLOWED_flow.lua | 19 ++++--- .../API/VehicleData/commonVehicleData.lua | 53 ++++++++----------- 12 files changed, 165 insertions(+), 136 deletions(-) diff --git a/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua index a1ed778165..65ab5fd84d 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua @@ -1,22 +1,25 @@ --------------------------------------------------------------------------------------------------- --- Item: Use Case: request is NOT allowed by Policies +-- User story: TO ADD !!! +-- Use case: TO ADD !!! +-- Item: Use Case 1: Main Flow -- -- Requirement summary: -- [GetVehicleData] As a mobile app wants to send a request to get the details of the vehicle data -- -- Description: -- In case: --- 1) mobile application sends valid GetVehicleData to SDL and this request is allowed by Policies +-- mobile application sends valid GetVehicleData to SDL and this request is allowed by Policies -- SDL must: --- Transfer this request to HMI and after successful response from hmi --- Respond SUCCESS, success:true to mobile application +-- 1) Transfer this request to HMI +-- 2) After successful response from hmi +-- respond SUCCESS, success:true and parameter value received from HMI to mobile application +--------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/API/VehicleData/commonVehicleData') --[[ Local Variables ]] - local rpc = { name = "GetVehicleData", params = { @@ -24,14 +27,15 @@ local rpc = { } } +--[[ Local Functions ]] local function processRPCSuccess(self) local mobileSession = common.getMobileSession(self, 1) local cid = mobileSession:SendRPC(rpc.name, rpc.params) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = 50.30}) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { engineOilLife = 50.30 } ) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = 50.30}) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = 50.30 } ) end --[[ Scenario ]] @@ -42,7 +46,6 @@ runner.Step("RAI with PTU", common.registerAppWithPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") - runner.Step("RPC " .. rpc.name, processRPCSuccess) runner.Title("Postconditions") diff --git a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index b38ddef010..346fe4f073 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -1,4 +1,6 @@ --------------------------------------------------------------------------------------------------- +-- User story: TO ADD !!! +-- Use case: TO ADD !!! -- Item: Use Case: request is allowed but parameter of this request is NOT allowed by Policies -- -- Requirement summary: @@ -6,17 +8,19 @@ -- -- Description: -- In case: --- 1) mobile application sends valid GetVehicleData to SDL and this request is allowed by Policies but RPC parameter is not allowed +-- 1) mobile application sends valid GetVehicleData to SDL and this request is allowed +-- by Policies but RPC parameter is not allowed -- SDL must: --- 1) SDL responds DISALLOWED, success:false to mobile application and doesn't transfer this request to HMI +-- SDL responds DISALLOWED, success:false to mobile application +-- and doesn't transfer this request to HMI +--------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/API/VehicleData/commonVehicleData') -local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ Local Variables ]] - local rpc = { name = "GetVehicleData", params = { @@ -24,7 +28,7 @@ local rpc = { } } --- Function which removes engineOilLife parameter from specified func group and rpc +--[[ Local Functions ]] local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["GetVehicleData"].parameters for index, value in pairs(params) do @@ -46,6 +50,7 @@ local function processRPCFailure(self) local mobileSession = common.getMobileSession(self, 1) local cid = mobileSession:SendRPC(rpc.name, rpc.params) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params):Times(0) + commonTestCases:DelayedExp(common.timeout) mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) end @@ -57,14 +62,9 @@ runner.Step("RAI with PTU", common.registerAppWithPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") - runner.Step("RPC " .. rpc.name .. " 1st time" , processRPCSuccess) - runner.Step("RAI 2nd app with PTU", common.registerAppWithPTU, {2, ptu_update_func}) - ---runner.Step("Delay..", delayExp) - runner.Step("RPC " .. rpc.name .. " 2nd time", processRPCFailure) runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) \ No newline at end of file +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua index 596d4912b2..80d3094609 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua @@ -1,26 +1,25 @@ --------------------------------------------------------------------------------------------------- --- Item: Use Case: request is allowed by Policies +-- User story: TO ADD !!! +-- Use case: TO ADD !!! +-- Item: Use Case 1: TO ADD!!! -- -- Requirement summary: --- [SubscribeVehicleData] As a mobile app wants to send a request to subscribe for specified parameter +-- [OnVehicleData] As a mobile app is subscribed for VI parameter +-- and received notification about this parameter change from hmi -- -- Description: -- In case: --- 1) hmi application sends valid SubscribeVehicleData to SDL and this request is allowed by Policies --- SDL must: --- Transfer this request to HMI and after successful response from hmi --- Respond SUCCESS, success:true to mobile application --- After HMI sends notification about changes in subcribed parameter +-- 1) If application is subscribed to get vehicle data with 'engineOilLife' parameter +-- 2) Notification about changes in subscribed parameter is received from hmi -- SDL must: -- Forward this notification to mobile application - +--------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/API/VehicleData/commonVehicleData') --[[ Local Variables ]] - local rpc1 = { name = "SubscribeVehicleData", params = { @@ -35,21 +34,22 @@ local rpc2 = { } } +--[[ Local Functions ]] local function processRPCSubscribeSuccess(self) local mobileSession = common.getMobileSession(self, 1) local cid = mobileSession:SendRPC(rpc1.name, rpc1.params) EXPECT_HMICALL("VehicleInfo." .. rpc1.name, rpc1.params) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = + {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) end - local function checkNotificationSuccess(self) local mobileSession = common.getMobileSession(self, 1) self.hmiConnection:SendNotification("VehicleInfo." .. rpc2.name, rpc2.params) - --mobile side: expected SubscribeVehicleData response mobileSession:ExpectNotification("OnVehicleData", rpc2.params) end @@ -61,7 +61,6 @@ runner.Step("RAI with PTU", common.registerAppWithPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") - runner.Step("RPC " .. rpc1.name, processRPCSubscribeSuccess) runner.Step("RPC " .. rpc2.name, checkNotificationSuccess) diff --git a/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua index f00846743d..ad456cf168 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua @@ -1,26 +1,27 @@ --------------------------------------------------------------------------------------------------- +-- User story: TO ADD !!! +-- Use case: TO ADD !!! +-- Item: Use Case 1: Main Flow -- Item: Use Case: request is allowed by Policies -- -- Requirement summary: --- [SubscribeVehicleData] As a mobile app wants to send a request to subscribe for specified parameter +-- [OnVehicleData] As a hmi sends notificarion about VI paramter change +-- but mobile app is not subscribed for this parameter -- -- Description: -- In case: --- 1) hmi application sends valid SubscribeVehicleData to SDL and this request is allowed by Policies +-- 1) Hmi sends valid OnVehicleData notification to SDL +-- but mobile app is not subscribed for this parameter -- SDL must: --- Transfer this request to HMI and after successful response from hmi --- Respond SUCCESS, success:true to mobile application --- After HMI sends notification about changes in subcribed parameter --- SDL must: --- Forward this notification to mobile application - +-- Ignore this request and do not forward it to mobile app +--------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/API/VehicleData/commonVehicleData') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ Local Variables ]] - local rpc1 = { name = "SubscribeVehicleData", params = { @@ -42,14 +43,17 @@ local rpc3 = { } } +--[[ Local Functions ]] local function processRPCSubscribeSuccess(self) local mobileSession = common.getMobileSession(self, 1) local cid = mobileSession:SendRPC(rpc1.name, rpc1.params) EXPECT_HMICALL("VehicleInfo." .. rpc1.name, rpc1.params) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) end local function processRPCUnsubscribeSuccess(self) @@ -57,24 +61,24 @@ local function processRPCUnsubscribeSuccess(self) local cid = mobileSession:SendRPC(rpc3.name, rpc3.params) EXPECT_HMICALL("VehicleInfo." .. rpc3.name, rpc3.params) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) end - local function checkNotificationSuccess(self) local mobileSession = common.getMobileSession(self, 1) self.hmiConnection:SendNotification("VehicleInfo." .. rpc2.name, rpc2.params) - --mobile side: expected OnVehicleData notification mobileSession:ExpectNotification("OnVehicleData", rpc2.params) end local function checkNotificationIgnored(self) local mobileSession = common.getMobileSession(self, 1) self.hmiConnection:SendNotification("VehicleInfo." .. rpc2.name, rpc2.params) - --mobile side: OnVehicleData notification not expected mobileSession:ExpectNotification("OnVehicleData", rpc2.params):Times(0) + commonTestCases:DelayedExp(common.timeout) end --[[ Scenario ]] @@ -85,7 +89,6 @@ runner.Step("RAI with PTU", common.registerAppWithPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") - runner.Step("RPC " .. rpc1.name, processRPCSubscribeSuccess) runner.Step("RPC " .. rpc2.name .. " forwarded to mobile", checkNotificationSuccess) runner.Step("RPC " .. rpc3.name, processRPCUnsubscribeSuccess) diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua index 2ddb926855..7ecf79478b 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua @@ -1,4 +1,6 @@ --------------------------------------------------------------------------------------------------- +-- User story: TO ADD !!! +-- Use case: TO ADD !!! -- Item: Use Case: request is allowed by Policies -- -- Requirement summary: @@ -10,13 +12,13 @@ -- SDL must: -- Transfer this request to HMI and after successful response from hmi -- Respond SUCCESS, success:true to mobile application +--------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/API/VehicleData/commonVehicleData') --[[ Local Variables ]] - local rpc = { name = "SubscribeVehicleData", params = { @@ -24,18 +26,19 @@ local rpc = { } } +--[[ Local Functions ]] local function processRPCSuccess(self) local mobileSession = common.getMobileSession(self, 1) local cid = mobileSession:SendRPC(rpc.name, rpc.params) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) end - - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) @@ -44,7 +47,6 @@ runner.Step("RAI with PTU", common.registerAppWithPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") - runner.Step("RPC " .. rpc.name, processRPCSuccess) runner.Title("Postconditions") diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index 54cd30a28c..7177b3bc9c 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -1,4 +1,6 @@ --------------------------------------------------------------------------------------------------- +-- User story: TO ADD !!! +-- Use case: TO ADD !!! -- Item: Use Case: request is allowed but parameter of this request is NOT allowed by Policies -- -- Requirement summary: @@ -6,15 +8,18 @@ -- -- Description: -- In case: --- 1) mobile application sends valid SubscribeVehicleData to SDL and this request is allowed by Policies but RPC parameter is not allowed +-- Mobile application sends valid SubscribeVehicleData to SDL and this request is +-- allowed by Policies but RPC parameter is not allowed -- SDL must: --- 1) SDL responds DISALLOWED, success:false to mobile application and doesn't transfer this request to HMI +-- Respond DISALLOWED, success:false to mobile application and not transfer this request to HMI +--------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/API/VehicleData/commonVehicleData') ---[[ Local Variables ]] +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +--[[ Local Variables ]] local rpc = { name = "SubscribeVehicleData", params = { @@ -22,7 +27,7 @@ local rpc = { } } --- Function which removes engineOilLife parameter from specified func group and rpc +--[[ Local Functions ]] local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["SubscribeVehicleData"].parameters for index, value in pairs(params) do @@ -34,6 +39,7 @@ local function processRPCFailure(self) local mobileSession = common.getMobileSession(self, 1) local cid = mobileSession:SendRPC(rpc.name, rpc.params) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params):Times(0) + commonTestCases:DelayedExp(common.timeout) mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED", info = "'engineOilLife' disallowed by policies.", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DISALLOWED"} }) @@ -47,8 +53,7 @@ runner.Step("RAI with PTU", common.registerAppWithPTU, {1, ptu_update_func}) runner.Step("Activate App", common.activateApp) runner.Title("Test") - runner.Step("RPC " .. rpc.name , processRPCFailure) runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) \ No newline at end of file +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua index 3ca0a4e5d2..d90bb4c3eb 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua @@ -6,17 +6,19 @@ -- -- Description: -- In case: --- 1) mobile application sends valid SubscribeVehicleData to SDL and this request --- is allowed by Policies but app is already subscribed for specified parameter +-- Mobile application sends valid SubscribeVehicleData to SDL and this request +-- is allowed by Policies but app is already subscribed for specified parameter -- SDL must: --- 1) SDL responds IGNORED, success:true and info: "Already subscribed on some provided VehicleData." --- to mobile application and doesn't transfer this request to HMI +-- SDL responds IGNORED, success:false and info: "Already subscribed on some provided VehicleData." +-- to mobile application and doesn't transfer this request to HMI +--------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/API/VehicleData/commonVehicleData') ---[[ Local Variables ]] +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +--[[ Local Variables ]] local rpc = { name = "SubscribeVehicleData", params = { @@ -24,6 +26,7 @@ local rpc = { } } +--[[ Local Functions ]] local function processRPCSuccess(self) local mobileSession = common.getMobileSession(self, 1) local cid = mobileSession:SendRPC(rpc.name, rpc.params) @@ -36,11 +39,11 @@ local function processRPCSuccess(self) engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) end - local function processRPCIgnored(self) local mobileSession = common.getMobileSession(self, 1) local cid = mobileSession:SendRPC(rpc.name, rpc.params) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params):Times(0) + commonTestCases:DelayedExp(common.timeout) mobileSession:ExpectResponse(cid, { success = false, resultCode = "IGNORED", info = "Already subscribed on some provided VehicleData.", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DATA_ALREADY_SUBSCRIBED"} }) @@ -54,9 +57,8 @@ runner.Step("RAI with PTU", common.registerAppWithPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") - runner.Step("RPC " .. rpc.name .. " 1st time" , processRPCSuccess) runner.Step("RPC " .. rpc.name .. " 2nd time" , processRPCIgnored) runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) \ No newline at end of file +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua index bb8b4b01dc..365c365369 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua @@ -1,23 +1,25 @@ --------------------------------------------------------------------------------------------------- +-- User story: TO ADD !!! +-- Use case: TO ADD !!! -- Item: Use Case: request is allowed by Policies -- -- Requirement summary: --- [UnsubscribeVehicleData] As a mobile app wants to send a request to unsubscribe +-- [UnsubscribeVehicleData] Mobile app wants to send a request to unsubscribe -- for already subscribed specified parameter -- -- Description: -- In case: --- 1) mobile application sends valid UnsubscribeVehicleData to SDL and this request is allowed by Policies +-- Mobile application sends valid UnsubscribeVehicleData to SDL +-- This request is allowed by Policies and mobile app is subscribed for this parameter -- SDL must: -- Transfer this request to HMI and after successful response from hmi -- Respond SUCCESS, success:true to mobile application - +--------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/API/VehicleData/commonVehicleData') --[[ Local Variables ]] - local rpc_subscribe = { name = "SubscribeVehicleData", params = { @@ -32,14 +34,17 @@ local rpc_unsubscribe = { } } +--[[ Local Functions ]] local function processRPCSubscribeSuccess(self) local mobileSession = common.getMobileSession(self, 1) local cid = mobileSession:SendRPC(rpc_subscribe.name, rpc_subscribe.params) EXPECT_HMICALL("VehicleInfo." .. rpc_subscribe.name, rpc_subscribe.params) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) end local function processRPCUnsubscribeSuccess(self) @@ -47,13 +52,13 @@ local function processRPCUnsubscribeSuccess(self) local cid = mobileSession:SendRPC(rpc_unsubscribe.name, rpc_unsubscribe.params) EXPECT_HMICALL("VehicleInfo." .. rpc_unsubscribe.name, rpc_unsubscribe.params) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) end - - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) @@ -62,7 +67,6 @@ runner.Step("RAI with PTU", common.registerAppWithPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") - runner.Step("RPC " .. rpc_subscribe.name, processRPCSubscribeSuccess) runner.Step("RPC " .. rpc_unsubscribe.name, processRPCUnsubscribeSuccess) diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua index 64471eb6a0..1503a5a9c9 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua @@ -1,21 +1,26 @@ --------------------------------------------------------------------------------------------------- --- Item: Use Case: request is allowed but parameter of this request is NOT allowed by Policies +-- User story: TO ADD !!! +-- Use case: TO ADD !!! +-- Item: Use Case: request is allowed by Policies -- -- Requirement summary: --- [UnsubscribeVehicleData] As a mobile app wants to send a request to get the details of the vehicle data +-- [UnsubscribeVehicleData] Mobile app wants to send a request to unsubscribe +-- for not yet subscribed specified parameter -- -- Description: -- In case: --- 1) mobile application sends valid UnsubscribeVehicleData to SDL and this request --- is allowed by Policies for parameter not yet subscribed +-- Mobile application sends valid UnsubscribeVehicleData to SDL and this request +-- is allowed by Policies but app is not yet subscribed for this parameter -- SDL must: --- 1) SDL responds IGNORED, success:false to mobile application and doesn't transfer this request to HMI +-- Respond IGNORED, success:false to mobile application and not transfer this request to HMI +--------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/API/VehicleData/commonVehicleData') ---[[ Local Variables ]] +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +--[[ Local Variables ]] local rpc = { name = "UnsubscribeVehicleData", params = { @@ -23,10 +28,12 @@ local rpc = { } } +--[[ Local Functions ]] local function processRPCFailure(self) local mobileSession = common.getMobileSession(self, 1) local cid = mobileSession:SendRPC(rpc.name, rpc.params) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params):Times(0) + commonTestCases:DelayedExp(common.timeout) mobileSession:ExpectResponse(cid, { success = false, resultCode = "IGNORED", info = "Some provided VehicleData was not subscribed.", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DATA_NOT_SUBSCRIBED"} }) @@ -40,8 +47,7 @@ runner.Step("RAI with PTU", common.registerAppWithPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") - runner.Step("RPC " .. rpc.name , processRPCFailure) runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) \ No newline at end of file +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua index c5ca1d50cf..408797c88a 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua @@ -1,23 +1,27 @@ --------------------------------------------------------------------------------------------------- +-- User story: TO ADD !!! +-- Use case: TO ADD !!! -- Item: Use Case: request is allowed by Policies -- -- Requirement summary: --- [UnsubscribeVehicleData] As a mobile app wants to send a request to unsubscribe --- for already subscribed specified parameter +-- [UnsubscribeVehicleData] Mobile app wants to send a request to unsubscribe +-- for already unsubscribed specified parameter -- -- Description: -- In case: --- 1) mobile application sends valid UnsubscribeVehicleData to SDL and this request is allowed by Policies +-- 1) Mobile application sends valid UnsubscribeVehicleData to SDL and this request is allowed by Policies +-- 2) Mobile app is already unsubscribed from this parameter -- SDL must: -- Transfer this request to HMI and after successful response from hmi -- Respond SUCCESS, success:true to mobile application +--------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/API/VehicleData/commonVehicleData') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ Local Variables ]] - local rpc_subscribe = { name = "SubscribeVehicleData", params = { @@ -32,14 +36,17 @@ local rpc_unsubscribe = { } } +--[[ Local Functions ]] local function processRPCSubscribeSuccess(self) local mobileSession = common.getMobileSession(self, 1) local cid = mobileSession:SendRPC(rpc_subscribe.name, rpc_subscribe.params) EXPECT_HMICALL("VehicleInfo." .. rpc_subscribe.name, rpc_subscribe.params) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + { engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS" } }) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS" } }) end local function processRPCUnsubscribeSuccess(self) @@ -47,15 +54,18 @@ local function processRPCUnsubscribeSuccess(self) local cid = mobileSession:SendRPC(rpc_unsubscribe.name, rpc_unsubscribe.params) EXPECT_HMICALL("VehicleInfo." .. rpc_unsubscribe.name, rpc_unsubscribe.params) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + { engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS" } }) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) end local function processRPCUnsubscribeIgnored(self) local mobileSession = common.getMobileSession(self, 1) local cid = mobileSession:SendRPC(rpc_unsubscribe.name, rpc_unsubscribe.params) EXPECT_HMICALL("VehicleInfo." .. rpc_unsubscribe.name, rpc_unsubscribe.params):Times(0) + commonTestCases:DelayedExp(common.timeout) mobileSession:ExpectResponse(cid, { success = false, resultCode = "IGNORED", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DATA_NOT_SUBSCRIBED"} }) @@ -69,7 +79,6 @@ runner.Step("RAI with PTU", common.registerAppWithPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") - runner.Step("RPC " .. rpc_subscribe.name, processRPCSubscribeSuccess) runner.Step("RPC " .. rpc_unsubscribe.name, processRPCUnsubscribeSuccess) runner.Title("Trying to unsubscribe from already unsubscribed parameter...") diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua index 4e407029a1..d0a0773ba4 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua @@ -1,20 +1,25 @@ --------------------------------------------------------------------------------------------------- +-- User story: TO ADD !!! +-- Use case: TO ADD !!! -- Item: Use Case: request is allowed but parameter of this request is NOT allowed by Policies -- -- Requirement summary: --- [UnsubscribeVehicleData] As a mobile app wants to send a request to get the details of the vehicle data --- +-- [UnsubscribeVehicleData] Mobile app wants to send a request to unsubscribe +-- from specified parameter but parameter is disallowed by Policies -- Description: -- In case: --- 1) mobile application sends valid UnsubscribeVehicleData to SDL and this request is allowed by Policies but RPC parameter is not allowed +-- 1) mobile application sends valid UnsubscribeVehicleData to SDL and this request is +-- allowed by Policies but RPC parameter is not allowed -- SDL must: -- 1) SDL responds DISALLOWED, success:false to mobile application and doesn't transfer this request to HMI +--------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/API/VehicleData/commonVehicleData') ---[[ Local Variables ]] +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +--[[ Local Variables ]] local rpc = { name = "UnsubscribeVehicleData", params = { @@ -22,7 +27,7 @@ local rpc = { } } --- Function which removes engineOilLife parameter from specified func group and rpc +--[[ Local Functions ]] local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["UnsubscribeVehicleData"].parameters for index, value in pairs(params) do @@ -34,6 +39,7 @@ local function processRPCFailure(self) local mobileSession = common.getMobileSession(self, 1) local cid = mobileSession:SendRPC(rpc.name, rpc.params) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params):Times(0) + commonTestCases:DelayedExp(common.timeout) mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED", info = "'engineOilLife' disallowed by policies.", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DISALLOWED"} }) @@ -47,8 +53,7 @@ runner.Step("RAI with PTU", common.registerAppWithPTU, {1, ptu_update_func}) runner.Step("Activate App", common.activateApp) runner.Title("Test") - runner.Step("RPC " .. rpc.name , processRPCFailure) runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) \ No newline at end of file +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/VehicleData/commonVehicleData.lua b/test_scripts/API/VehicleData/commonVehicleData.lua index fb2ef07c9c..cd1b03180b 100644 --- a/test_scripts/API/VehicleData/commonVehicleData.lua +++ b/test_scripts/API/VehicleData/commonVehicleData.lua @@ -85,7 +85,8 @@ local function ptu(self, app_id, ptu_update_func) local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) EXPECT_HMIRESPONSE(requestId) :Do(function() - self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = pts_file_name }) + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + { requestType = "PROPRIETARY", fileName = pts_file_name }) getPTUFromPTS(ptu_table) local function updatePTU(tbl) for rpc in pairs(tbl.policy_table.functional_groupings["Emergency-1"].rpcs) do @@ -116,11 +117,13 @@ local function ptu(self, app_id, ptu_update_func) print("App ".. id .. " was used for PTU") RAISE_EVENT(event, event, "PTU event") checkIfPTSIsSentAsBinary(d2.binaryData) - local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) + local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", + { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) EXPECT_HMICALL("BasicCommunication.SystemRequest") :Do(function(_, d3) self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) - self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = policy_file_path .. "/" .. policy_file_name }) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", + { policyfile = policy_file_path .. "/" .. policy_file_name }) end) mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) end) @@ -137,7 +140,6 @@ function commonVehicleData.preconditions() end --[[Module functions]] - function commonVehicleData.activateApp(pAppId, self) self, pAppId = commonVehicleData.getSelfAndParams(pAppId, self) if not pAppId then pAppId = 1 end @@ -145,11 +147,11 @@ function commonVehicleData.activateApp(pAppId, self) local mobSession = commonVehicleData.getMobileSession(self, pAppId) local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) EXPECT_HMIRESPONSE(requestId) - mobSession:ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) commonTestCases:DelayedExp(commonVehicleData.minTimeout) end - function commonVehicleData.getSelfAndParams(...) local out = { } local selfIdx = nil @@ -199,11 +201,14 @@ function commonVehicleData.registerAppWithPTU(id, ptu_update_func, self) self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) self["mobileSession" .. id]:StartService(7) :Do(function() - local corId = self["mobileSession" .. id]:SendRPC("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + local corId = self["mobileSession" .. id]:SendRPC("RegisterAppInterface", + config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) :Do(function(_, d1) hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) :Times(3) EXPECT_HMICALL("BasicCommunication.PolicyUpdate") :Do(function(_, d2) @@ -214,7 +219,8 @@ function commonVehicleData.registerAppWithPTU(id, ptu_update_func, self) end) self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() - self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) :Times(1) self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange"):Times(2) EXPECT_HMICALL("VehicleInfo.GetVehicleData", { odometer = true}) @@ -228,14 +234,17 @@ function commonVehicleData.raiN(id, self) self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) self["mobileSession" .. id]:StartService(7) :Do(function() - local corId = self["mobileSession" .. id]:SendRPC("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + local corId = self["mobileSession" .. id]:SendRPC("RegisterAppInterface", + config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) :Do(function(_, d1) hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID end) self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() - self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) :Times(1) self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") end) @@ -268,22 +277,4 @@ function commonVehicleData.start(pHMIParams, self) end) end -function commonVehicleData.unregisterApp(pAppId, self) - local mobSession = commonVehicleData.getMobileSession(self, pAppId) - local hmiAppId = commonVehicleData.getHMIAppId(pAppId) - local cid = mobSession:SendRPC("UnregisterAppInterface",{}) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = hmiAppId, unexpectedDisconnect = false }) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) -end - -function commonVehicleData.backupHMICapabilities() - local hmiCapabilitiesFile = commonFunctions:read_parameter_from_smart_device_link_ini("HMICapabilities") - commonPreconditions:BackupFile(hmiCapabilitiesFile) -end - -function commonVehicleData.restoreHMICapabilities() - local hmiCapabilitiesFile = commonFunctions:read_parameter_from_smart_device_link_ini("HMICapabilities") - commonPreconditions:RestoreFile(hmiCapabilitiesFile) -end - return commonVehicleData From b0dee77b037847fa67fa20105ca28561e31a9fc3 Mon Sep 17 00:00:00 2001 From: Andriy Byzhynar Date: Tue, 3 Oct 2017 18:49:20 +0300 Subject: [PATCH 309/681] Remove unused code --- ...RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua | 4 ++-- test_scripts/API/VehicleData/commonVehicleData.lua | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua index 408797c88a..a21444b40c 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua @@ -12,8 +12,8 @@ -- 1) Mobile application sends valid UnsubscribeVehicleData to SDL and this request is allowed by Policies -- 2) Mobile app is already unsubscribed from this parameter -- SDL must: --- Transfer this request to HMI and after successful response from hmi --- Respond SUCCESS, success:true to mobile application +-- Respond IGNORED, success:false {dataType = "VEHICLEDATA_ENGINEOILLIFE", +-- resultCode = "DATA_NOT_SUBSCRIBED"} to mobile application --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] diff --git a/test_scripts/API/VehicleData/commonVehicleData.lua b/test_scripts/API/VehicleData/commonVehicleData.lua index cd1b03180b..a303f5f8be 100644 --- a/test_scripts/API/VehicleData/commonVehicleData.lua +++ b/test_scripts/API/VehicleData/commonVehicleData.lua @@ -12,7 +12,6 @@ local json = require("modules/json") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") -local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') --[[ Local Variables ]] local ptu_table = {} From d8ea02fc2a2188fee9049b6f08db500819108979 Mon Sep 17 00:00:00 2001 From: Andriy Byzhynar Date: Wed, 4 Oct 2017 12:28:55 +0300 Subject: [PATCH 310/681] Add missed test case for OnVehicleData notification --- ...meterDisallowedByPolicies_Ignored_flow.lua | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua diff --git a/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua new file mode 100644 index 0000000000..5c38c8c4ed --- /dev/null +++ b/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua @@ -0,0 +1,79 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TO ADD !!! +-- Use case: TO ADD !!! +-- Item: Use Case 1: TO ADD!!! +-- +-- Requirement summary: +-- [OnVehicleData] As a mobile app is subscribed for VI parameter +-- and received notification about this parameter change from hmi +-- +-- Description: +-- In case: +-- 1) If application is subscribed to get vehicle data with 'engineOilLife' parameter +-- 2) Parameter is disallowed by Policies in this notification +-- 3) Notification about changes in subscribed parameter is received from hmi +-- SDL must: +-- Ignore this notification and not send to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Local Variables ]] +local rpc1 = { + name = "SubscribeVehicleData", + params = { + engineOilLife = true + } +} + +local rpc2 = { + name = "OnVehicleData", + params = { + engineOilLife = 50.3 + } +} + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["OnVehicleData"].parameters + for index, value in pairs(params) do + if ("engineOilLife" == value) then params[index] = nil end + end +end + +local function processRPCSubscribeSuccess(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc1.name, rpc1.params) + EXPECT_HMICALL("VehicleInfo." .. rpc1.name, rpc1.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + end) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = + {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) +end + +local function checkNotificationIgnored(self) + local mobileSession = common.getMobileSession(self, 1) + self.hmiConnection:SendNotification("VehicleInfo." .. rpc2.name, rpc2.params) + mobileSession:ExpectNotification("OnVehicleData", rpc2.params):Times(0) + commonTestCases:DelayedExp(common.timeout) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("RPC " .. rpc1.name, processRPCSubscribeSuccess) +runner.Step("RAI 2nd app with PTU", common.registerAppWithPTU, {2, ptu_update_func}) +runner.Step("RPC " .. rpc2.name, checkNotificationIgnored) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From 77413a110be942c65569013a76289f2d2274b65c Mon Sep 17 00:00:00 2001 From: Andriy Byzhynar Date: Mon, 9 Oct 2017 13:44:43 +0300 Subject: [PATCH 311/681] Fix parameters removal --- .../002_RPC_parameter_DISALLOWED_by_policies_flow.lua | 2 +- ...3_NotificationParameterDisallowedByPolicies_Ignored_flow.lua | 2 +- .../002_RPC_parameter_DISALLOWED_by_policies_flow.lua | 2 +- ..._parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index 346fe4f073..9439671d11 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -32,7 +32,7 @@ local rpc = { local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["GetVehicleData"].parameters for index, value in pairs(params) do - if ("engineOilLife" == value) then params[index] = nil end + if ("engineOilLife" == value) then table.remove(params, index) end end end diff --git a/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua index 5c38c8c4ed..c71a005c96 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua @@ -40,7 +40,7 @@ local rpc2 = { local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["OnVehicleData"].parameters for index, value in pairs(params) do - if ("engineOilLife" == value) then params[index] = nil end + if ("engineOilLife" == value) then table.remove(params, index) end end end diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index 7177b3bc9c..3d8713872f 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -31,7 +31,7 @@ local rpc = { local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["SubscribeVehicleData"].parameters for index, value in pairs(params) do - if ("engineOilLife" == value) then params[index] = nil end + if ("engineOilLife" == value) then table.remove(params, index) end end end diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua index d0a0773ba4..b0c005785c 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua @@ -31,7 +31,7 @@ local rpc = { local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["UnsubscribeVehicleData"].parameters for index, value in pairs(params) do - if ("engineOilLife" == value) then params[index] = nil end + if ("engineOilLife" == value) then table.remove(params, index) end end end From 2b6c2823d6739c7ff58a494e04223c526a7d87f0 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 11 Oct 2017 14:08:27 +0300 Subject: [PATCH 312/681] Fix endless PTU loop --- test_scripts/API/VehicleData/commonVehicleData.lua | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test_scripts/API/VehicleData/commonVehicleData.lua b/test_scripts/API/VehicleData/commonVehicleData.lua index a303f5f8be..048d038e0d 100644 --- a/test_scripts/API/VehicleData/commonVehicleData.lua +++ b/test_scripts/API/VehicleData/commonVehicleData.lua @@ -210,10 +210,14 @@ function commonVehicleData.registerAppWithPTU(id, ptu_update_func, self) { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) :Times(3) EXPECT_HMICALL("BasicCommunication.PolicyUpdate") - :Do(function(_, d2) - self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) - ptu_table = jsonFileToTable(d2.params.file) - ptu(self, id, ptu_update_func) + :Do(function(e, d2) + if e.occurences == 1 then + self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptu_table = jsonFileToTable(d2.params.file) + ptu(self, id, ptu_update_func) + else + self:FailTestCase("BC.PolicyUpdate was sent more than once (PTU update was incorrect)") + end end) end) self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) From 366001d8129413bd83a8ed7f1fcfacc7d93c6778 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 12 Oct 2017 15:37:44 +0300 Subject: [PATCH 313/681] Add test set --- test_sets/EngineOilLife.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 test_sets/EngineOilLife.txt diff --git a/test_sets/EngineOilLife.txt b/test_sets/EngineOilLife.txt new file mode 100644 index 0000000000..2d6c710f89 --- /dev/null +++ b/test_sets/EngineOilLife.txt @@ -0,0 +1,12 @@ +./test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua +./test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +./test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua +./test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua +./test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua +./test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua +./test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +./test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua +./test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua +./test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua +./test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua +./test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua From 66d427d9e24468aa76a275a6ff944ffaf45ae1b6 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Sat, 4 Nov 2017 17:18:42 +0200 Subject: [PATCH 314/681] EngineOilLife: Stabilize scripts --- .../002_RPC_parameter_DISALLOWED_by_policies_flow.lua | 2 +- ..._parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index 3d8713872f..9fced65100 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -41,7 +41,7 @@ local function processRPCFailure(self) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params):Times(0) commonTestCases:DelayedExp(common.timeout) mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED", - info = "'engineOilLife' disallowed by policies.", + info = "'engineOilLife' parameter is disallowed by Policies", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DISALLOWED"} }) end diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua index b0c005785c..f18964f3ce 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua @@ -41,7 +41,7 @@ local function processRPCFailure(self) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params):Times(0) commonTestCases:DelayedExp(common.timeout) mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED", - info = "'engineOilLife' disallowed by policies.", + info = "'engineOilLife' parameter is disallowed by Policies", engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DISALLOWED"} }) end From 11dfa3e88debe771823409a5e127baac1e6019f3 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 26 Jan 2018 13:35:58 +0200 Subject: [PATCH 315/681] Fix obtaining of MAC address and device Id --- .../API/VehicleData/commonVehicleData.lua | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/test_scripts/API/VehicleData/commonVehicleData.lua b/test_scripts/API/VehicleData/commonVehicleData.lua index 048d038e0d..4833acbd75 100644 --- a/test_scripts/API/VehicleData/commonVehicleData.lua +++ b/test_scripts/API/VehicleData/commonVehicleData.lua @@ -2,7 +2,7 @@ -- VehicleData common module --------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.mobileHost = "127.0.0.1" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] @@ -255,8 +255,14 @@ function commonVehicleData.raiN(id, self) end local function allowSDL(self) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { + allowed = true, + source = "GUI", + device = { + id = commonVehicleData.getDeviceMAC(), + name = commonVehicleData.getDeviceName() + } + }) end function commonVehicleData.start(pHMIParams, self) @@ -280,4 +286,16 @@ function commonVehicleData.start(pHMIParams, self) end) end +function commonVehicleData.getDeviceName() + return config.mobileHost .. ":" .. config.mobilePort +end + +function commonVehicleData.getDeviceMAC() + local cmd = "echo -n " .. commonVehicleData.getDeviceName() .. " | sha256sum | awk '{printf $1}'" + local handle = io.popen(cmd) + local result = handle:read("*a") + handle:close() + return result +end + return commonVehicleData From 3be8fe2f5321ece8bc5f4e94f086d39c2ef85577 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 26 Jan 2018 13:55:58 +0200 Subject: [PATCH 316/681] Fix obtaining of MAC address and device Id --- test_scripts/RC/commonRC.lua | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index f3aa412d3c..10b48f159d 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -2,7 +2,7 @@ -- RC common module --------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.mobileHost = "127.0.0.1" config.defaultProtocolVersion = 2 config.ValidateSchema = false config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } @@ -124,8 +124,26 @@ local function ptu(self, ptu_update_func) end local function allow_sdl(self) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { + allowed = true, + source = "GUI", + device = { + id = commonRC.getDeviceMAC(), + name = commonRC.getDeviceName() + } + }) +end + +function commonRC.getDeviceName() + return config.mobileHost .. ":" .. config.mobilePort +end + +function commonRC.getDeviceMAC() + local cmd = "echo -n " .. commonRC.getDeviceName() .. " | sha256sum | awk '{printf $1}'" + local handle = io.popen(cmd) + local result = handle:read("*a") + handle:close() + return result end function commonRC.preconditions() From 44d79ac9607efe0700c2628635648380248c4eb4 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 1 Feb 2018 10:55:45 +0200 Subject: [PATCH 317/681] Improve stability of the scripts on security --- test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua index 8931c93b45..4b77b7260e 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua @@ -400,6 +400,7 @@ function m.policyTableUpdate(pPTUpdateFunc, pExpNotificationFunc, pAppId) if not pAppId then pAppId = 1 end if not pExpNotificationFunc then test.hmiConnection:ExpectNotification("SDL.OnStatusUpdate", { status = "UP_TO_DATE" }) + test.hmiConnection:ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) else pExpNotificationFunc() end From 7fe7464c2fc644d3acd05568460edbfdcc11487f Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 5 Feb 2018 18:08:25 +0200 Subject: [PATCH 318/681] Add test sets for Release 4.5 issues --- test_sets/Defects/4_5/1206.txt | 1 + test_sets/Defects/4_5/1211.txt | 1 + test_sets/Defects/4_5/1225.txt | 1 + test_sets/Defects/4_5/1376.txt | 1 + test_sets/Defects/4_5/1395.txt | 1 + test_sets/Defects/4_5/1772.txt | 1 + test_sets/Defects/4_5/1873.txt | 1 + test_sets/Defects/4_5/1881.txt | 1 + test_sets/Defects/4_5/1888.txt | 6 ++++++ test_sets/Defects/4_5/1891.txt | 4 ++++ test_sets/Defects/4_5/1892.txt | 1 + test_sets/Defects/4_5/1893.txt | 1 + test_sets/Defects/4_5/1894.txt | 4 ++++ test_sets/Defects/4_5/1912.txt | 1 + test_sets/Defects/4_5/1921.txt | 1 + test_sets/Defects/4_5/1922.txt | 2 ++ test_sets/Defects/4_5/1923.txt | 2 ++ test_sets/Defects/4_5/1924.txt | 2 ++ test_sets/Defects/4_5/1925.txt | 7 +++++++ 19 files changed, 39 insertions(+) create mode 100644 test_sets/Defects/4_5/1206.txt create mode 100644 test_sets/Defects/4_5/1211.txt create mode 100644 test_sets/Defects/4_5/1225.txt create mode 100644 test_sets/Defects/4_5/1376.txt create mode 100644 test_sets/Defects/4_5/1395.txt create mode 100644 test_sets/Defects/4_5/1772.txt create mode 100644 test_sets/Defects/4_5/1873.txt create mode 100644 test_sets/Defects/4_5/1881.txt create mode 100644 test_sets/Defects/4_5/1888.txt create mode 100644 test_sets/Defects/4_5/1891.txt create mode 100644 test_sets/Defects/4_5/1892.txt create mode 100644 test_sets/Defects/4_5/1893.txt create mode 100644 test_sets/Defects/4_5/1894.txt create mode 100644 test_sets/Defects/4_5/1912.txt create mode 100644 test_sets/Defects/4_5/1921.txt create mode 100644 test_sets/Defects/4_5/1922.txt create mode 100644 test_sets/Defects/4_5/1923.txt create mode 100644 test_sets/Defects/4_5/1924.txt create mode 100644 test_sets/Defects/4_5/1925.txt diff --git a/test_sets/Defects/4_5/1206.txt b/test_sets/Defects/4_5/1206.txt new file mode 100644 index 0000000000..0856370c86 --- /dev/null +++ b/test_sets/Defects/4_5/1206.txt @@ -0,0 +1 @@ +./test_scripts/Defects/4_5/1206_REQUEST_PTU_Trigger_PTU_failed_previous_IGN_ON.lua diff --git a/test_sets/Defects/4_5/1211.txt b/test_sets/Defects/4_5/1211.txt new file mode 100644 index 0000000000..863be6622a --- /dev/null +++ b/test_sets/Defects/4_5/1211.txt @@ -0,0 +1 @@ +./test_scripts/Defects/4_5/1211_ATF_Check_count_of_removals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua diff --git a/test_sets/Defects/4_5/1225.txt b/test_sets/Defects/4_5/1225.txt new file mode 100644 index 0000000000..93dcf47269 --- /dev/null +++ b/test_sets/Defects/4_5/1225.txt @@ -0,0 +1 @@ +./test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua diff --git a/test_sets/Defects/4_5/1376.txt b/test_sets/Defects/4_5/1376.txt new file mode 100644 index 0000000000..223dc60ed4 --- /dev/null +++ b/test_sets/Defects/4_5/1376.txt @@ -0,0 +1 @@ +./test_scripts/Defects/4_5/1376_PTU_all_flows.lua diff --git a/test_sets/Defects/4_5/1395.txt b/test_sets/Defects/4_5/1395.txt new file mode 100644 index 0000000000..1cc644ccab --- /dev/null +++ b/test_sets/Defects/4_5/1395.txt @@ -0,0 +1 @@ +./test_scripts/Defects/4_5/1395_Resumption_data_IGN_OFF.lua diff --git a/test_sets/Defects/4_5/1772.txt b/test_sets/Defects/4_5/1772.txt new file mode 100644 index 0000000000..61200271c7 --- /dev/null +++ b/test_sets/Defects/4_5/1772.txt @@ -0,0 +1 @@ +./test_scripts/Defects/4_5/1772_update_default_section.lua diff --git a/test_sets/Defects/4_5/1873.txt b/test_sets/Defects/4_5/1873.txt new file mode 100644 index 0000000000..86ab6b61eb --- /dev/null +++ b/test_sets/Defects/4_5/1873.txt @@ -0,0 +1 @@ +./test_scripts/Defects/4_5/1873_Parameters_empty_in_policy_table.lua diff --git a/test_sets/Defects/4_5/1881.txt b/test_sets/Defects/4_5/1881.txt new file mode 100644 index 0000000000..699188cfb9 --- /dev/null +++ b/test_sets/Defects/4_5/1881.txt @@ -0,0 +1 @@ +./test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua diff --git a/test_sets/Defects/4_5/1888.txt b/test_sets/Defects/4_5/1888.txt new file mode 100644 index 0000000000..29e7a8d790 --- /dev/null +++ b/test_sets/Defects/4_5/1888.txt @@ -0,0 +1,6 @@ +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_1_navi.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua diff --git a/test_sets/Defects/4_5/1891.txt b/test_sets/Defects/4_5/1891.txt new file mode 100644 index 0000000000..8e3ed29a89 --- /dev/null +++ b/test_sets/Defects/4_5/1891.txt @@ -0,0 +1,4 @@ +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_1_navi.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua diff --git a/test_sets/Defects/4_5/1892.txt b/test_sets/Defects/4_5/1892.txt new file mode 100644 index 0000000000..8972d7a1be --- /dev/null +++ b/test_sets/Defects/4_5/1892.txt @@ -0,0 +1 @@ +./test_scripts/Defects/4_5/1892_HB_from_SDL_after_receiving_HB_from_mobile.lua diff --git a/test_sets/Defects/4_5/1893.txt b/test_sets/Defects/4_5/1893.txt new file mode 100644 index 0000000000..ec150d4cca --- /dev/null +++ b/test_sets/Defects/4_5/1893.txt @@ -0,0 +1 @@ +./test_scripts/Defects/4_5/1893_ATF_HeartBeat_App_does_not_send_HB_and_does_not_respond.lua diff --git a/test_sets/Defects/4_5/1894.txt b/test_sets/Defects/4_5/1894.txt new file mode 100644 index 0000000000..e3816b8435 --- /dev/null +++ b/test_sets/Defects/4_5/1894.txt @@ -0,0 +1,4 @@ +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_1_navi.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua diff --git a/test_sets/Defects/4_5/1912.txt b/test_sets/Defects/4_5/1912.txt new file mode 100644 index 0000000000..54baf1ab3e --- /dev/null +++ b/test_sets/Defects/4_5/1912.txt @@ -0,0 +1 @@ +./test_scripts/Defects/4_5/1912_Video_service_start_via_2_protocol.lua diff --git a/test_sets/Defects/4_5/1921.txt b/test_sets/Defects/4_5/1921.txt new file mode 100644 index 0000000000..465c1d44ee --- /dev/null +++ b/test_sets/Defects/4_5/1921.txt @@ -0,0 +1 @@ +./test_scripts/Defects/4_5/1921_Invalid_PT_after_cutting_unknow_values.lua diff --git a/test_sets/Defects/4_5/1922.txt b/test_sets/Defects/4_5/1922.txt new file mode 100644 index 0000000000..63fb569e6a --- /dev/null +++ b/test_sets/Defects/4_5/1922.txt @@ -0,0 +1,2 @@ +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_2_navi_video-navi.lua diff --git a/test_sets/Defects/4_5/1923.txt b/test_sets/Defects/4_5/1923.txt new file mode 100644 index 0000000000..4e2a0af4d5 --- /dev/null +++ b/test_sets/Defects/4_5/1923.txt @@ -0,0 +1,2 @@ +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_2_navi_video-navi.lua diff --git a/test_sets/Defects/4_5/1924.txt b/test_sets/Defects/4_5/1924.txt new file mode 100644 index 0000000000..6121278f51 --- /dev/null +++ b/test_sets/Defects/4_5/1924.txt @@ -0,0 +1,2 @@ +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1924_2_navi.lua diff --git a/test_sets/Defects/4_5/1925.txt b/test_sets/Defects/4_5/1925.txt new file mode 100644 index 0000000000..2012dcba5d --- /dev/null +++ b/test_sets/Defects/4_5/1925.txt @@ -0,0 +1,7 @@ +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua From 000ce13939676593a1f7a96f0c70725900ad0ba9 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 9 Feb 2018 15:36:56 +0200 Subject: [PATCH 319/681] Fix cast to string in common module for Resumption --- user_modules/shared_testcases/commonStepsResumption.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user_modules/shared_testcases/commonStepsResumption.lua b/user_modules/shared_testcases/commonStepsResumption.lua index 882d5471b3..2ceb439571 100644 --- a/user_modules/shared_testcases/commonStepsResumption.lua +++ b/user_modules/shared_testcases/commonStepsResumption.lua @@ -90,7 +90,7 @@ function commonStepsResumption:RegisterApp(app, additional_expectations , resume return true end end - return false, "The value of " .. pA .. " (".. tostring(pA) .. ") is not as expected (" .. pE .. ")" + return false, "The value of " .. pA .. " (".. tostring(pA) .. ") is not as expected (" .. tostring(pE) .. ")" end) Test.mobileSession:ExpectResponse(correlation_id, { success = true}) local exp = additional_expectations(Test, app) @@ -188,4 +188,4 @@ function commonStepsResumption:Expect_Resumption_Data(app) Test.mobileSession:ExpectNotification("OnHashChange") end -return commonStepsResumption \ No newline at end of file +return commonStepsResumption From 435bb310b58ddd364a1368cf4c1f535bedcf377e Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 13 Feb 2018 12:59:01 +0200 Subject: [PATCH 320/681] Fix obtaining of MAC address and Device Id --- .../Defects/4_5/1225_FACTORY_DEFAULTS.lua | 16 ++------ .../Defects/4_5/1376_PTU_all_flows.lua | 22 ++++++++-- ...912_Video_service_start_via_2_protocol.lua | 1 - .../4_5/Trigger_PTU_NO_Certificate/common.lua | 25 ++++++++++-- test_scripts/Defects/4_5/commonDefects.lua | 40 ++++++++++++++++--- 5 files changed, 78 insertions(+), 26 deletions(-) diff --git a/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua b/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua index 85ad93828a..0a7145a191 100644 --- a/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua +++ b/test_scripts/Defects/4_5/1225_FACTORY_DEFAULTS.lua @@ -58,14 +58,6 @@ local function start(self) end) end --- Allow device from HMI -local function allowSDL(self) - -- sending notification OnAllowSDLFunctionality from HMI to allow connected device - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { - allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } - }) -end - -- Delay without expectation -- @tparam number pTime time to wait local function delayedExp(pTime, self) @@ -176,7 +168,7 @@ local function Check_user_consent_records_in_Snapshot(self) else -- Check presence of consented group for registered appID local pts = ptsToTable(pathToPTS) - local ucr = pts.policy_table.device_data[config.deviceMAC].user_consent_records + local ucr = pts.policy_table.device_data[commonDefects.getDeviceMAC()].user_consent_records if not (ucr[config.application1.registerAppInterfaceParams.appID]) then commonFunctions:printError("Error: user_consent_records.consent_groups.Location is not present in Snapshot") is_test_fail = true @@ -240,7 +232,7 @@ local function Check_no_user_consent_records_in_Snapshot(self) else -- Check absence of consented group for registered appID local pts = ptsToTable(pathToPTS) - local ucr = pts.policy_table.device_data[config.deviceMAC].user_consent_records + local ucr = pts.policy_table.device_data[commonDefects.getDeviceMAC()].user_consent_records if (ucr[config.application1.registerAppInterfaceParams.appID]) then commonFunctions:printError("Error: user_consent_records.consent_groups.Location was not reset in Snapshot") is_test_fail = true @@ -258,7 +250,7 @@ runner.Step("Clean environment", commonDefects.preconditions) -- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP runner.Step("Start SDL, HMI, connect Mobile", start) -- Allow connected device on HMI -runner.Step("Allow SDL for device", allowSDL) +runner.Step("Allow SDL for device", commonDefects.allow_sdl) -- create mobile session, register application, perform PTU wit PT from ptUpdateFunc -- with "Location" group for registered application runner.Step("RAI, PTU", commonDefects.rai_ptu, { ptUpdateFunc}) @@ -280,7 +272,7 @@ runner.Step("Start SDL, HMI, connect Mobile", start) -- Check absence of records related to consent group and device in LPT after FACTORY_DEFAULTS runner.Step("Check_absence_of_user_consent_records_in_LPT", Check_no_user_consent_records_in_LPT) -- Make device consent -runner.Step("Allow SDL for device", allowSDL) +runner.Step("Allow SDL for device", commonDefects.allow_sdl) -- Create session, register application runner.Step("RAI", commonDefects.rai_n) -- Remove snapshot to make sure that SDL creates new one during PTU, trigger PTU to initiation of snapshot creation diff --git a/test_scripts/Defects/4_5/1376_PTU_all_flows.lua b/test_scripts/Defects/4_5/1376_PTU_all_flows.lua index d57ad1df72..d32051bc98 100644 --- a/test_scripts/Defects/4_5/1376_PTU_all_flows.lua +++ b/test_scripts/Defects/4_5/1376_PTU_all_flows.lua @@ -12,7 +12,7 @@ local sdl = require("SDL") local commonSteps = require("user_modules/shared_testcases/commonSteps") --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.mobileHost = "127.0.0.1" config.defaultProtocolVersion = 2 --[[ Local Variables ]] @@ -34,9 +34,25 @@ end -- Allow device from HMI local function allowSDL(self) + local function getDeviceName() + return config.mobileHost .. ":" .. config.mobilePort + end + local function getDeviceMAC() + local cmd = "echo -n " .. getDeviceName() .. " | sha256sum | awk '{printf $1}'" + local handle = io.popen(cmd) + local result = handle:read("*a") + handle:close() + return result + end -- sending notification OnAllowSDLFunctionality from HMI to allow connected device - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { + allowed = true, + source = "GUI", + device = { + id = getDeviceMAC(), + name = getDeviceName() + } + }) end -- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP diff --git a/test_scripts/Defects/4_5/1912_Video_service_start_via_2_protocol.lua b/test_scripts/Defects/4_5/1912_Video_service_start_via_2_protocol.lua index 6485b340bc..04dc0eb469 100644 --- a/test_scripts/Defects/4_5/1912_Video_service_start_via_2_protocol.lua +++ b/test_scripts/Defects/4_5/1912_Video_service_start_via_2_protocol.lua @@ -18,7 +18,6 @@ local commonDefects = require('test_scripts/Defects/4_5/commonDefects') local events = require('events') --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.appHMIType = {"NAVIGATION"} diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua index 4b77b7260e..cea6bbc133 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua @@ -2,7 +2,7 @@ -- Navigation common module --------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.mobileHost = "127.0.0.1" config.defaultProtocolVersion = 3 config.serverCertificatePath = "./files/Security/spt_credential.pem" @@ -150,9 +150,26 @@ end --[[ @allowSDL: sequence that allows SDL functionality --! @parameters: none --]] -local function allowSDL() - test.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) +local function allowSDL(self) + local function getDeviceName() + return config.mobileHost .. ":" .. config.mobilePort + end + local function getDeviceMAC() + local cmd = "echo -n " .. getDeviceName() .. " | sha256sum | awk '{printf $1}'" + local handle = io.popen(cmd) + local result = handle:read("*a") + handle:close() + return result + end + -- sending notification OnAllowSDLFunctionality from HMI to allow connected device + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { + allowed = true, + source = "GUI", + device = { + id = getDeviceMAC(), + name = getDeviceName() + } + }) end --[[ @registerStartSecureServiceFunc: register function to start secure service diff --git a/test_scripts/Defects/4_5/commonDefects.lua b/test_scripts/Defects/4_5/commonDefects.lua index 32c069d1e2..2fb70092d5 100644 --- a/test_scripts/Defects/4_5/commonDefects.lua +++ b/test_scripts/Defects/4_5/commonDefects.lua @@ -3,7 +3,7 @@ --------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -- define MAC address mobile device -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.mobileHost = "127.0.0.1" -- define 2nd version of SDL protocol by default config.defaultProtocolVersion = 2 -- switch off schema validation for output messages against APIs @@ -155,14 +155,41 @@ local function ptu(self, ptu_update_func) end) end +--[[ @getDeviceName: provides device name +--! @parameters: none +--! @return: device name +--]] +function commonDefect.getDeviceName() + return config.mobileHost .. ":" .. config.mobilePort +end + +--[[ @getDeviceMAC: provides device MAC address +--! @parameters: none +--! @return: device MAC address +--]] +function commonDefect.getDeviceMAC() + local cmd = "echo -n " .. commonDefect.getDeviceName() .. " | sha256sum | awk '{printf $1}'" + local handle = io.popen(cmd) + local result = handle:read("*a") + handle:close() + return result +end + --[[ @allow_sdl: sequence that allows SDL functionality --! @parameters: --! self - test object --! @return: none --]] -local function allow_sdl(self) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) +function commonDefect.allow_sdl(self) + -- sending notification OnAllowSDLFunctionality from HMI to allow connected device + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { + allowed = true, + source = "GUI", + device = { + id = commonDefect.getDeviceMAC(), + name = commonDefect.getDeviceName() + } + }) end --[[ @preconditions: precondition steps @@ -193,7 +220,7 @@ function commonDefect.start(self) self:connectMobile() :Do(function() commonFunctions:userPrint(35, "Mobile connected") - allow_sdl(self) + commonDefect.allow_sdl(self) end) end) end) @@ -246,12 +273,12 @@ function commonDefect.ignitionOff(self) self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete") :Do(function() + sdl:DeleteFile() self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) self.mobileSession1:ExpectNotification("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") :Do(function() - sdl:DeleteFile() sdl:StopSDL() end) end) @@ -319,6 +346,7 @@ function commonDefect.rai_ptu_n(id, ptu_update_func, self) { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) :Times(AtLeast(1)) self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + :Times(AtLeast(1)) end) end) end From 07d5a7d08c4a320f8a0b8cd289d1a769ef1bc5e1 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 13 Feb 2018 13:55:36 +0200 Subject: [PATCH 321/681] Fix file names --- test_sets/Defects/4_5/1922.txt | 2 +- test_sets/Defects/4_5/1923.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test_sets/Defects/4_5/1922.txt b/test_sets/Defects/4_5/1922.txt index 63fb569e6a..1bd6ca1e47 100644 --- a/test_sets/Defects/4_5/1922.txt +++ b/test_sets/Defects/4_5/1922.txt @@ -1,2 +1,2 @@ ./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua -./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_2_navi_video-navi.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua diff --git a/test_sets/Defects/4_5/1923.txt b/test_sets/Defects/4_5/1923.txt index 4e2a0af4d5..0f719177aa 100644 --- a/test_sets/Defects/4_5/1923.txt +++ b/test_sets/Defects/4_5/1923.txt @@ -1,2 +1,2 @@ ./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua -./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_2_navi_video-navi.lua +./test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua From fa8d3bad7df4314b619e5dd6e0e22a14061f1944 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 13 Feb 2018 14:08:54 +0200 Subject: [PATCH 322/681] Add additional expectation for PTU sequence --- test_scripts/Defects/4_5/commonDefects.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test_scripts/Defects/4_5/commonDefects.lua b/test_scripts/Defects/4_5/commonDefects.lua index 2fb70092d5..9b106fd952 100644 --- a/test_scripts/Defects/4_5/commonDefects.lua +++ b/test_scripts/Defects/4_5/commonDefects.lua @@ -347,6 +347,7 @@ function commonDefect.rai_ptu_n(id, ptu_update_func, self) :Times(AtLeast(1)) self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") :Times(AtLeast(1)) + EXPECT_HMICALL("VehicleInfo.GetVehicleData", { odometer = true }) end) end) end @@ -386,6 +387,7 @@ function commonDefect.rai_ptu_n_without_OnPermissionsChange(id, ptu_update_func, self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) :Times(AtLeast(1)) + EXPECT_HMICALL("VehicleInfo.GetVehicleData", { odometer = true }) end) end) end From 127a8f0bc3dbe06388c4daf8532ea3aa877b325c Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 26 Feb 2018 18:22:05 +0200 Subject: [PATCH 323/681] Create common module for security --- .../4_5/Trigger_PTU_NO_Certificate/common.lua | 566 +----------------- user_modules/sequences/actions.lua | 448 ++++++++++++++ user_modules/sequences/security.lua | 146 +++++ user_modules/utils.lua | 222 ++++--- 4 files changed, 737 insertions(+), 645 deletions(-) create mode 100644 user_modules/sequences/actions.lua create mode 100644 user_modules/sequences/security.lua diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua index cea6bbc133..6d7dff8f48 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua @@ -1,569 +1,31 @@ --------------------------------------------------------------------------------------------------- --- Navigation common module +-- Common module --------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.mobileHost = "127.0.0.1" config.defaultProtocolVersion = 3 -config.serverCertificatePath = "./files/Security/spt_credential.pem" -config.serverPrivateKeyPath = "./files/Security/spt_credential.pem" -config.serverCAChainCertPath = "./files/Security/spt_credential.pem" - --[[ Required Shared libraries ]] -local mobile_session = require("mobile_session") -local json = require("modules/json") -local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local commonSteps = require("user_modules/shared_testcases/commonSteps") -local commonTestCases = require("user_modules/shared_testcases/commonTestCases") -local events = require("events") -local test = require("user_modules/dummy_connecttest") -local expectations = require('expectations') -local Expectation = expectations.Expectation -local constants = require('protocol_handler/ford_protocol_constants') -local reporter = require("reporter") +local actions = require("user_modules/sequences/actions") +local security = require("user_modules/sequences/security") +local utils = require("user_modules/utils") +--[[ Module ]] local m = {} ---[[ Constants ]] -m.timeout = 2000 -m.minTimeout = 500 -m.appId1 = 1 -m.appId2 = 2 -m.frameInfo = constants.FRAME_INFO - ---[[ Variables ]] -local ptuTable = {} -local hmiAppIds = {} - ---[[ Functions ]] - ---[[ @getPTUFromPTS: create policy table update table (PTU) ---! @parameters: ---! pTbl - table with policy table snapshot (PTS) ---! @return: table with PTU ---]] -local function getPTUFromPTS(pTbl) - pTbl.policy_table.consumer_friendly_messages.messages = nil - pTbl.policy_table.device_data = nil - pTbl.policy_table.module_meta = nil - pTbl.policy_table.usage_and_error_counts = nil - pTbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null - pTbl.policy_table.module_config.preloaded_pt = nil - pTbl.policy_table.module_config.preloaded_date = nil -end - ---[[ @jsonFileToTable: convert .json file to table ---! @parameters: ---! pFileName - file name ---! @return: table ---]] -local function jsonFileToTable(pFileName) - local f = io.open(pFileName, "r") - local content = f:read("*all") - f:close() - return json.decode(content) -end - ---[[ @tableToJsonFile: convert table to .json file ---! @parameters: ---! pTbl - table ---! pFileName - file name ---]] -local function tableToJsonFile(pTbl, pFileName) - local f = io.open(pFileName, "w") - f:write(json.encode(pTbl)) - f:close() -end - ---[[ @updatePTU: update PTU table with additional functional group for Navigation RPCs ---! @parameters: ---! pTbl - PTU table ---! pAppId - application number (1, 2, etc.) ---]] -function m.updatePTU(pTbl, pAppId) - pTbl.policy_table.app_policies[m.getAppID(pAppId)] = { - keep_context = false, - steal_focus = false, - priority = "NONE", - default_hmi = "NONE", - groups = { "Base-4", "Location-1" } - } -end - ---[[ @ptu: perform policy table update ---! @parameters: ---! pPTUpdateFunc - additional function for update ---! pAppId - application number (1, 2, etc.) ---]] -local function ptu(pPTUpdateFunc, pAppId) - if not pAppId then pAppId = 1 end - local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" - .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") - local ptu_file_name = os.tmpname() - local requestId = test.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(requestId) - :Do(function() - test.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", - { requestType = "PROPRIETARY", fileName = pts_file_name }) - getPTUFromPTS(ptuTable) - - m.updatePTU(ptuTable, pAppId) - - if pPTUpdateFunc then - pPTUpdateFunc(ptuTable) - end +-- Proxies for the inherited objects +utils.inheritObjects(m, actions) +utils.inheritObjects(m, security) - tableToJsonFile(ptuTable, ptu_file_name) - - local event = events.Event() - event.matches = function(e1, e2) return e1 == e2 end - EXPECT_EVENT(event, "PTU event") - - local function getAppsCount() - local count = 0 - for _ in pairs(hmiAppIds) do - count = count + 1 - end - return count - end - for id = 1, getAppsCount() do - local mobileSession = m.getMobileSession(id) - mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) - :Do(function() - print("App ".. id .. " was used for PTU") - RAISE_EVENT(event, event, "PTU event") - local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", - { requestType = "PROPRIETARY" }, ptu_file_name) - EXPECT_HMICALL("BasicCommunication.SystemRequest") - :Do(function(_, d3) - test.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) - test.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = d3.params.fileName }) - end) - mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) - :Do(function() os.remove(ptu_file_name) end) - end) - :Times(AtMost(1)) - end - end) -end - ---[[ @allowSDL: sequence that allows SDL functionality ---! @parameters: none ---]] -local function allowSDL(self) - local function getDeviceName() - return config.mobileHost .. ":" .. config.mobilePort - end - local function getDeviceMAC() - local cmd = "echo -n " .. getDeviceName() .. " | sha256sum | awk '{printf $1}'" - local handle = io.popen(cmd) - local result = handle:read("*a") - handle:close() - return result - end - -- sending notification OnAllowSDLFunctionality from HMI to allow connected device - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { - allowed = true, - source = "GUI", - device = { - id = getDeviceMAC(), - name = getDeviceName() - } - }) -end - ---[[ @registerStartSecureServiceFunc: register function to start secure service ---! @parameters: ---! pMobSession - mobile session ---]] -local function registerStartSecureServiceFunc(pMobSession) - function pMobSession.mobile_session_impl.control_services:StartSecureService(pServiceId) - local msg = { - serviceType = pServiceId, - frameInfo = constants.FRAME_INFO.START_SERVICE, - sessionId = self.session.sessionId.get(), - encryption = true - } - self:Send(msg) - end - function pMobSession.mobile_session_impl:StartSecureService(pServiceId) - if not self.isSecuredSession then - self.security:registerSessionSecurity() - self.security:prepareToHandshake() - end - return self.control_services:StartSecureService(pServiceId) - end -end - ---[[ @registerExpectServiceEventFunc: register functions for expectations of control messages: ---! Service Start ACK/NACK and Handshake ---! @parameters: ---! pMobSession - mobile session ---]] -local function registerExpectServiceEventFunc(pMobSession) - function pMobSession:ExpectControlMessage(pServiceId, pData) - local session = self.mobile_session_impl.control_services.session - local event = events.Event() - event.matches = function(_, data) - return data.frameType == constants.FRAME_TYPE.CONTROL_FRAME and - data.serviceType == pServiceId and - (pServiceId == constants.SERVICE_TYPE.RPC or data.sessionId == session.sessionId.get()) and - (data.frameInfo == constants.FRAME_INFO.START_SERVICE_ACK or - data.frameInfo == constants.FRAME_INFO.START_SERVICE_NACK) - end - local ret = session:ExpectEvent(event, "StartService") - :Do(function(_, data) - if data.encryption == true and data.frameInfo == constants.FRAME_INFO.START_SERVICE_ACK then - session.security:registerSecureService(pServiceId) - end - end) - :ValidIf(function(_, data) - if data.encryption ~= pData.encryption then - return false, "Expected 'encryption' flag is '" .. tostring(pData.encryption) - .. "', actual is '" .. tostring(data.encryption) .. "'" - end - return true - end) - :ValidIf(function(_, data) - if data.frameInfo ~= pData.frameInfo then - return false, "Expected 'frameInfo' is '" .. tostring(pData.frameInfo) - .. "', actual is '" .. tostring(data.frameInfo) .. "'" - end - return true - end) - return ret - end - - function pMobSession:ExpectHandshakeMessage() - local session = self.mobile_session_impl.control_services.session - local event = events.Event() - event.matches = function(e1, e2) return e1 == e2 end - local ret = pMobSession:ExpectEvent(event, "Handshake") - local handshakeEvent = events.Event() - handshakeEvent.matches = function(_, data) - return data.frameType ~= constants.FRAME_TYPE.CONTROL_FRAME - and data.serviceType == constants.SERVICE_TYPE.CONTROL - and data.sessionId == session.sessionId.get() - and data.rpcType == constants.BINARY_RPC_TYPE.NOTIFICATION - and data.rpcFunctionId == constants.BINARY_RPC_FUNCTION_ID.HANDSHAKE - end - session:ExpectEvent(handshakeEvent, "Handshake internal") - :Do(function(_, data) - local binData = data.binaryData - local dataToSend = session.security:performHandshake(binData) - if dataToSend then - local handshakeMessage = { - frameInfo = 0, - serviceType = constants.SERVICE_TYPE.CONTROL, - encryption = false, - rpcType = constants.BINARY_RPC_TYPE.NOTIFICATION, - rpcFunctionId = constants.BINARY_RPC_FUNCTION_ID.HANDSHAKE, - rpcCorrelationId = data.rpcCorrelationId, - binaryData = dataToSend - } - session:Send(handshakeMessage) - end - end) - :Do(function() - if session.security:isHandshakeFinished() then - event_dispatcher:RaiseEvent(test.mobileConnection, event) - end - end) - :Times(AnyNumber()) - return ret - end -end - ---[[ @getAppID: return 'appID' from configuration file ---! @parameters: ---! pAppId - application number (1, 2, etc.) ---! @return: application identifier from configuration file ---]] -function m.getAppID(pAppId) - if not pAppId then pAppId = 1 end - return config["application" .. pAppId].registerAppInterfaceParams.appID -end - ---[[ @preconditions: precondition steps ---! @parameters: none ---]] -function m.preconditions() - commonFunctions:SDLForceStop() - commonSteps:DeletePolicyTable() - commonSteps:DeleteLogsFiles() -end - ---[[ @postconditions: postcondition steps ---! @parameters: none ---]] -function m.postconditions() - StopSDL() -end - ---[[ @activateApp: activate application ---! @parameters: ---! pAppId - application number (1, 2, etc.) ---]] -function m.activateApp(pAppId) - if not pAppId then pAppId = 1 end - local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] - local mobSession = m.getMobileSession(pAppId) - local requestId = test.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) - EXPECT_HMIRESPONSE(requestId) - mobSession:ExpectNotification("OnHMIStatus", - { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) - commonTestCases:DelayedExp(m.minTimeout) -end - ---[[ @getHMIAppId: get HMI application identifier ---! @parameters: ---! pAppId - application number (1, 2, etc.) ---! @return: application identifier ---]] -function m.getHMIAppId(pAppId) - if not pAppId then pAppId = 1 end - return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] -end - ---[[ @getMobileSession: get mobile session ---! @parameters: ---! pAppId - application number (1, 2, etc.) ---! @return: mobile session ---]] -function m.getMobileSession(pAppId) - if not pAppId then pAppId = 1 end - local session - if not test["mobileSession" .. pAppId] then - session = mobile_session.MobileSession(test, test.mobileConnection) - test["mobileSession" .. pAppId] = session - registerStartSecureServiceFunc(session) - registerExpectServiceEventFunc(session) - if config.defaultProtocolVersion > 2 then - session.activateHeartbeat = true - session.sendHeartbeatToSDL = true - session.answerHeartbeatFromSDL = true - session.ignoreSDLHeartBeatACK = true - end - else - session = test["mobileSession" .. pAppId] - end - return session -end - ---[[ @registerApp: register mobile application ---! @parameters: ---! pAppId - application number (1, 2, etc.) ---]] -function m.registerApp(pAppId) - if not pAppId then pAppId = 1 end - local mobSession = m.getMobileSession(pAppId) - mobSession:StartService(7) - :Do(function() - local corId = mobSession:SendRPC("RegisterAppInterface", - config["application" .. pAppId].registerAppInterfaceParams) - test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", - { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) - :Do(function(_, d1) - hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = d1.params.application.appID - test.hmiConnection:ExpectNotification("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) - :Times(2) - test.hmiConnection:ExpectRequest("BasicCommunication.PolicyUpdate") - :Do(function(_, d2) - test.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) - ptuTable = jsonFileToTable(d2.params.file) - end) - end) - mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) - :Do(function() - mobSession:ExpectNotification("OnHMIStatus", - { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - mobSession:ExpectNotification("OnPermissionsChange") - end) - end) -end - ---[[ @registerAppWOPTU: register mobile application and do not perform PTU ---! @parameters: ---! pAppId - application number (1, 2, etc.) ---]] -function m.registerAppWOPTU(pAppId) - if not pAppId then pAppId = 1 end - local mobSession = m.getMobileSession(pAppId) - mobSession:StartService(7) - :Do(function() - local corId = mobSession:SendRPC("RegisterAppInterface", - config["application" .. pAppId].registerAppInterfaceParams) - test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", - { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) - :Do(function(_, d1) - hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = d1.params.application.appID - end) - mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) - :Do(function() - mobSession:ExpectNotification("OnHMIStatus", - { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - mobSession:ExpectNotification("OnPermissionsChange") - end) - end) -end - ---[[ @policyTableUpdate: perform PTU ---! @parameters: ---! pPTUpdateFunc - function with additional updates ---! pExpNotificationFunc - function with specific expectations which needs to be done during PTU ---! pAppId - application number (1, 2, etc.) ---]] -function m.policyTableUpdate(pPTUpdateFunc, pExpNotificationFunc, pAppId) - if not pAppId then pAppId = 1 end - if not pExpNotificationFunc then - test.hmiConnection:ExpectNotification("SDL.OnStatusUpdate", { status = "UP_TO_DATE" }) - test.hmiConnection:ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) - else - pExpNotificationFunc() - end - ptu(pPTUpdateFunc, pAppId) -end - ---[[ @start: starting sequence: starting of SDL, initialization of HMI, connect mobile ---! @parameters: ---! pHMIParams - table with parameters for HMI initialization ---]] -function m.start(pHMIParams) - test:runSDL() - commonFunctions:waitForSDLStart(test) - :Do(function() - test:initHMI() - :Do(function() - commonFunctions:userPrint(35, "HMI initialized") - test:initHMI_onReady(pHMIParams) - :Do(function() - commonFunctions:userPrint(35, "HMI is ready") - test:connectMobile() - :Do(function() - commonFunctions:userPrint(35, "Mobile connected") - allowSDL(test) - end) - end) - end) - end) +function m.setForceProtectedServiceParam(pParamValue) + m.setSDLIniParameter("ForceProtectedService", pParamValue) end ---[[ @delayedExp: delay test step for specific timeout ---! @parameters: none ---]] function m.delayedExp(pTimeOut) - if not pTimeOut then pTimeOut = m.timeout end - commonTestCases:DelayedExp(pTimeOut) -end - ---[[ @readFile: read data from file ---! @parameters: ---! pPath - path to file --- @return: content of the file ---]] -function m.readFile(pPath) - local open = io.open - local file = open(pPath, "rb") - if not file then return nil end - local content = file:read "*a" - file:close() - return content -end - ---[[ @ExpectRequest: register expectation for request on HMI connection ---! @parameters: ---! pName - name of the request ---! ... - expected data ---]] -function test.hmiConnection:ExpectRequest(pName, ...) - local event = events.Event() - event.matches = function(_, data) return data.method == pName end - local args = table.pack(...) - local ret = Expectation("HMI call " .. pName, self) - if #args > 0 then - ret:ValidIf(function(e, data) - local arguments - if e.occurences > #args then - arguments = args[#args] - else - arguments = args[e.occurences] - end - reporter.AddMessage("EXPECT_HMICALL", - { ["Id"] = data.id, ["name"] = tostring(pName),["Type"] = "EXPECTED_RESULT" }, arguments) - reporter.AddMessage("EXPECT_HMICALL", - { ["Id"] = data.id, ["name"] = tostring(pName),["Type"] = "AVAILABLE_RESULT" }, data.params) - return compareValues(arguments, data.params, "params") - end) - end - ret.event = event - event_dispatcher:AddEvent(self, event, ret) - test:AddExpectation(ret) - return ret -end - ---[[ @ExpectNotification: register expectation for notification on HMI connection ---! @parameters: ---! pName - name of the notification ---! ... - expected data ---]] -function test.hmiConnection:ExpectNotification(pName, ...) - local event = events.Event() - event.matches = function(_, data) return data.method == pName end - local args = table.pack(...) - local ret = Expectation("HMI notification " .. pName, self) - if #args > 0 then - ret:ValidIf(function(e, data) - local arguments - if e.occurences > #args then - arguments = args[#args] - else - arguments = args[e.occurences] - end - local cid = test.notification_counter - test.notification_counter = test.notification_counter + 1 - reporter.AddMessage("EXPECT_HMINOTIFICATION", - { ["Id"] = cid, ["name"] = tostring(pName), ["Type"] = "EXPECTED_RESULT" }, arguments) - reporter.AddMessage("EXPECT_HMINOTIFICATION", - { ["Id"] = cid, ["name"] = tostring(pName), ["Type"] = "AVAILABLE_RESULT" }, data.params) - return compareValues(arguments, data.params, "params") - end) - end - ret.event = event - event_dispatcher:AddEvent(self, event, ret) - test:AddExpectation(ret) - return ret -end - ---[[ @getHMIConnection: return HMI connection object ---! @parameters: none ---! @return: HMI connection object ---]] -function m.getHMIConnection() - return test.hmiConnection -end - ---[[ @setForceProtectedServiceParam: set value of 'ForceProtectedService' parameter in SDL .ini file ---! @parameters: ---! pParamValue - value of the paramter ---]] -function m.setForceProtectedServiceParam(pParamValue) - local paramName = "ForceProtectedService" - commonFunctions:SetValuesInIniFile(paramName .. "%s-=%s-[%d,A-Z,a-z]-%s-\n", paramName, pParamValue) + utils.wait(pTimeOut) end ---[[ @protect: make table immutable ---! @parameters: ---! pTbl - mutable table ---! @return: immutable table ---]] -local function protect(pTbl) - local mt = { - __index = pTbl, - __newindex = function(_, k, v) - error("Attempting to change item " .. tostring(k) .. " to " .. tostring(v), 2) - end - } - return setmetatable({}, mt) +function m.readFile(pFilePath) + return utils.readFile(pFilePath) end -return protect(m) +return m diff --git a/user_modules/sequences/actions.lua b/user_modules/sequences/actions.lua new file mode 100644 index 0000000000..2dee196e31 --- /dev/null +++ b/user_modules/sequences/actions.lua @@ -0,0 +1,448 @@ +--------------------------------------------------------------------------------------------------- +-- Common actions module +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local mobileSession = require("mobile_session") +local json = require("modules/json") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +local events = require("events") +local test = require("user_modules/dummy_connecttest") +local expectations = require('expectations') +local reporter = require("reporter") +local utils = require("user_modules/utils") + +--[[ Module ]] +local m = {} + +--[[ Constants ]] +m.minTimeout = 500 + +--[[ Variables ]] +local ptuTable = {} +local hmiAppIds = {} +local originalValuesInSDLIni = {} + +test.mobileSession = {} + +--[[ Functions ]] + +--[[ @getPTUFromPTS: create policy table update table (PTU) +--! @parameters: +--! pTbl - table with policy table snapshot (PTS) +--! @return: table with PTU +--]] +local function getPTUFromPTS(pTbl) + pTbl.policy_table.consumer_friendly_messages.messages = nil + pTbl.policy_table.device_data = nil + pTbl.policy_table.module_meta = nil + pTbl.policy_table.usage_and_error_counts = nil + pTbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + pTbl.policy_table.module_config.preloaded_pt = nil + pTbl.policy_table.module_config.preloaded_date = nil +end + +--[[ @updatePTU: update PTU table with additional functional group for Navigation RPCs +--! @parameters: +--! pTbl - PTU table +--! pAppId - application number (1, 2, etc.) +--! @return: none +--]] +function m.updatePTU(pTbl, pAppId) + pTbl.policy_table.app_policies[m.getAppID(pAppId)] = { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + groups = { "Base-4", "Location-1" } + } +end + +--[[ @ptu: perform policy table update +--! @parameters: +--! pPTUpdateFunc - additional function for update +--! pAppId - application number (1, 2, etc.) +--! @return: none +--]] +local function ptu(pPTUpdateFunc, pAppId) + if not pAppId then pAppId = 1 end + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" + .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + local ptu_file_name = os.tmpname() + local requestId = test.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) + test.hmiConnection:ExpectResponse(requestId) + :Do(function() + test.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + { requestType = "PROPRIETARY", fileName = pts_file_name }) + getPTUFromPTS(ptuTable) + + m.updatePTU(ptuTable, pAppId) + + if pPTUpdateFunc then + pPTUpdateFunc(ptuTable) + end + + utils.tableToJsonFile(ptuTable, ptu_file_name) + + local event = events.Event() + event.matches = function(e1, e2) return e1 == e2 end + EXPECT_EVENT(event, "PTU event") + + local function getAppsCount() + local count = 0 + for _ in pairs(hmiAppIds) do + count = count + 1 + end + return count + end + for id = 1, getAppsCount() do + local session = m.getMobileSession(id) + session:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :Do(function() + print("App ".. id .. " was used for PTU") + RAISE_EVENT(event, event, "PTU event") + local corIdSystemRequest = session:SendRPC("SystemRequest", + { requestType = "PROPRIETARY" }, ptu_file_name) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, d3) + test.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + test.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = d3.params.fileName }) + end) + session:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + :Do(function() os.remove(ptu_file_name) end) + end) + :Times(AtMost(1)) + end + end) +end + +--[[ @allowSDL: allow SDL functionality for default device +--! @parameters: none +--! @return: none +--]] +local function allowSDL(self) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { + allowed = true, + source = "GUI", + device = { + id = utils.getDeviceMAC(), + name = utils.getDeviceName() + } + }) +end + +--[[ @getAppID: return 'appID' from configuration file +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: application identifier from configuration file +--]] +function m.getAppID(pAppId) + if not pAppId then pAppId = 1 end + return config["application" .. pAppId].registerAppInterfaceParams.appID +end + +--[[ @preconditions: precondition steps +--! @parameters: none +--! @return: none +--]] +function m.preconditions() + commonFunctions:SDLForceStop() + commonSteps:DeletePolicyTable() + commonSteps:DeleteLogsFiles() +end + +--[[ @activateApp: activate application +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: none +--]] +function m.activateApp(pAppId) + if not pAppId then pAppId = 1 end + local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + local mobSession = m.getMobileSession(pAppId) + local requestId = test.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + test.hmiConnection:ExpectResponse(requestId) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + commonTestCases:DelayedExp(m.minTimeout) +end + +--[[ @getHMIAppId: get HMI application identifier +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: application identifier +--]] +function m.getHMIAppId(pAppId) + if not pAppId then pAppId = 1 end + return hmiAppIds[m.getAppID(pAppId)] +end + +--[[ @getMobileSession: get mobile session +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: mobile session object +--]] +function m.getMobileSession(pAppId) + if not pAppId then pAppId = 1 end + local session + if not test.mobileSession[pAppId] then + session = mobileSession.MobileSession(test, test.mobileConnection) + test.mobileSession[pAppId] = session + if config.defaultProtocolVersion > 2 then + session.activateHeartbeat = true + session.sendHeartbeatToSDL = true + session.answerHeartbeatFromSDL = true + session.ignoreSDLHeartBeatACK = true + end + else + session = test.mobileSession[pAppId] + end + return session +end + +--[[ @registerApp: register mobile application +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: none +--]] +function m.registerApp(pAppId) + if not pAppId then pAppId = 1 end + local mobSession = m.getMobileSession(pAppId) + mobSession:StartService(7) + :Do(function() + local corId = mobSession:SendRPC("RegisterAppInterface", + config["application" .. pAppId].registerAppInterfaceParams) + test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[m.getAppID(pAppId)] = d1.params.application.appID + test.hmiConnection:ExpectNotification("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(2) + test.hmiConnection:ExpectRequest("BasicCommunication.PolicyUpdate") + :Do(function(_, d2) + test.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptuTable = utils.jsonFileToTable(d2.params.file) + end) + end) + mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + mobSession:ExpectNotification("OnPermissionsChange") + end) + end) +end + +--[[ @registerAppWOPTU: register mobile application and do not perform PTU +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: none +--]] +function m.registerAppWOPTU(pAppId) + if not pAppId then pAppId = 1 end + local mobSession = m.getMobileSession(pAppId) + mobSession:StartService(7) + :Do(function() + local corId = mobSession:SendRPC("RegisterAppInterface", + config["application" .. pAppId].registerAppInterfaceParams) + test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[m.getAppID(pAppId)] = d1.params.application.appID + end) + mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + mobSession:ExpectNotification("OnPermissionsChange") + end) + end) +end + +--[[ @policyTableUpdate: perform PTU +--! @parameters: +--! pPTUpdateFunc - function with additional updates +--! pExpNotificationFunc - function with specific expectations which needs to be done during PTU +--! pAppId - application number (1, 2, etc.) +--! @return: none +--]] +function m.policyTableUpdate(pPTUpdateFunc, pExpNotificationFunc, pAppId) + if not pAppId then pAppId = 1 end + if not pExpNotificationFunc then + test.hmiConnection:ExpectNotification("SDL.OnStatusUpdate", { status = "UP_TO_DATE" }) + test.hmiConnection:ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) + else + pExpNotificationFunc() + end + ptu(pPTUpdateFunc, pAppId) +end + +--[[ @start: starting sequence: starting of SDL, initialization of HMI, connect mobile +--! @parameters: +--! pHMIParams - table with parameters for HMI initialization +--! @return: none +--]] +function m.start(pHMIParams) + test:runSDL() + commonFunctions:waitForSDLStart(test) + :Do(function() + test:initHMI() + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + test:initHMI_onReady(pHMIParams) + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + test:connectMobile() + :Do(function() + commonFunctions:userPrint(35, "Mobile connected") + allowSDL(test) + end) + end) + end) + end) +end + +--[[ @ExpectRequest: register expectation for request on HMI connection +--! @parameters: +--! pName - name of the request +--! ... - expected data +--! @return: Expectation object +--]] +function test.hmiConnection:ExpectRequest(pName, ...) + local event = events.Event() + event.matches = function(_, data) return data.method == pName end + local args = table.pack(...) + local ret = expectations.Expectation("HMI call " .. pName, self) + if #args > 0 then + ret:ValidIf(function(e, data) + local arguments + if e.occurences > #args then + arguments = args[#args] + else + arguments = args[e.occurences] + end + reporter.AddMessage("EXPECT_HMICALL", + { ["Id"] = data.id, ["name"] = tostring(pName),["Type"] = "EXPECTED_RESULT" }, arguments) + reporter.AddMessage("EXPECT_HMICALL", + { ["Id"] = data.id, ["name"] = tostring(pName),["Type"] = "AVAILABLE_RESULT" }, data.params) + return compareValues(arguments, data.params, "params") + end) + end + ret.event = event + event_dispatcher:AddEvent(self, event, ret) + test:AddExpectation(ret) + return ret +end + +--[[ @ExpectNotification: register expectation for notification on HMI connection +--! @parameters: +--! pName - name of the notification +--! ... - expected data +--! @return: Expectation object +--]] +function test.hmiConnection:ExpectNotification(pName, ...) + local event = events.Event() + event.matches = function(_, data) return data.method == pName end + local args = table.pack(...) + local ret = expectations.Expectation("HMI notification " .. pName, self) + if #args > 0 then + ret:ValidIf(function(e, data) + local arguments + if e.occurences > #args then + arguments = args[#args] + else + arguments = args[e.occurences] + end + local cid = test.notification_counter + test.notification_counter = test.notification_counter + 1 + reporter.AddMessage("EXPECT_HMINOTIFICATION", + { ["Id"] = cid, ["name"] = tostring(pName), ["Type"] = "EXPECTED_RESULT" }, arguments) + reporter.AddMessage("EXPECT_HMINOTIFICATION", + { ["Id"] = cid, ["name"] = tostring(pName), ["Type"] = "AVAILABLE_RESULT" }, data.params) + return compareValues(arguments, data.params, "params") + end) + end + ret.event = event + event_dispatcher:AddEvent(self, event, ret) + test:AddExpectation(ret) + return ret +end + +--[[ @ExpectResponse: register expectation for notification on HMI connection +--! @parameters: +--! pName - name of the notification +--! ... - expected data +--! @return: Expectation object +--]] +function test.hmiConnection:ExpectResponse(pId, ...) + local event = events.Event() + event.matches = function(_, data) return data.id == pId end + local args = table.pack(...) + local ret = expectations.Expectation("HMI response " .. pId, self) + if #args > 0 then + ret:ValidIf(function(e, data) + local arguments + if e.occurences > #args then + arguments = args[#args] + else + arguments = args[e.occurences] + end + reporter.AddMessage("EXPECT_HMIRESPONSE", { ["Id"] = data.id, ["Type"] = "EXPECTED_RESULT" }, arguments) + reporter.AddMessage("EXPECT_HMIRESPONSE", { ["Id"] = data.id, ["Type"] = "AVAILABLE_RESULT" }, data.result) + return compareValues(arguments, data.result, "result") + end) + end + ret.event = event + event_dispatcher:AddEvent(self, event, ret) + test:AddExpectation(ret) + return ret +end + +--[[ @getMobileConnection: return Mobile connection object +--! @parameters: none +--! @return: Mobile connection object +--]] +function m.getMobileConnection() + return test.mobileConnection +end + +--[[ @getHMIConnection: return HMI connection object +--! @parameters: none +--! @return: HMI connection object +--]] +function m.getHMIConnection() + return test.hmiConnection +end + +--[[ @setSDLConfigParameter: change original value of parameter in SDL .ini file +--! @parameters: +--! pParamName - name of the parameter +--! pParamValue - value to be set +--! @return: none +--]] +function m.setSDLIniParameter(pParamName, pParamValue) + originalValuesInSDLIni[pParamName] = commonFunctions:read_parameter_from_smart_device_link_ini(pParamName) + commonFunctions:write_parameter_to_smart_device_link_ini(pParamName, pParamValue) +end + +--[[ @restoreSDLConfigParameters: restore original values of parameters in SDL .ini file +--! @parameters: none +--! @return: none +--]] +local function restoreSDLIniParameters() + for pParamName, pParamValue in pairs(originalValuesInSDLIni) do + commonFunctions:write_parameter_to_smart_device_link_ini(pParamName, pParamValue) + end +end + +--[[ @postconditions: postcondition steps +--! @parameters: none +--! @return: none +--]] +function m.postconditions() + StopSDL() + restoreSDLIniParameters() +end + +return m diff --git a/user_modules/sequences/security.lua b/user_modules/sequences/security.lua new file mode 100644 index 0000000000..d1df643496 --- /dev/null +++ b/user_modules/sequences/security.lua @@ -0,0 +1,146 @@ +--------------------------------------------------------------------------------------------------- +-- Security common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/spt_credential.pem" +config.serverPrivateKeyPath = "./files/Security/spt_credential.pem" +config.serverCAChainCertPath = "./files/Security/spt_credential.pem" + +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") +local events = require("events") +local test = require("user_modules/dummy_connecttest") +local constants = require("protocol_handler/ford_protocol_constants") + +--[[ Module ]] +local m = {} + +--[[ Constants ]] +m.frameInfo = constants.FRAME_INFO + +--[[ Variables ]] +local origGetMobileSession = actions.getMobileSession + +--[[ Functions ]] + +--[[ @registerStartSecureServiceFunc: register function to start secure service +--! @parameters: +--! pMobSession - mobile session +--! @return: none +--]] +local function registerStartSecureServiceFunc(pMobSession) + function pMobSession.mobile_session_impl.control_services:StartSecureService(pServiceId) + local msg = { + serviceType = pServiceId, + frameInfo = constants.FRAME_INFO.START_SERVICE, + sessionId = self.session.sessionId.get(), + encryption = true + } + self:Send(msg) + end + function pMobSession.mobile_session_impl:StartSecureService(pServiceId) + if not self.isSecuredSession then + self.security:registerSessionSecurity() + self.security:prepareToHandshake() + end + return self.control_services:StartSecureService(pServiceId) + end +end + +--[[ @registerExpectServiceEventFunc: register functions for expectations of control messages: +--! Service Start ACK/NACK and Handshake +--! @parameters: +--! pMobSession - mobile session +--! @return: none +--]] +local function registerExpectServiceEventFunc(pMobSession) + function pMobSession:ExpectControlMessage(pServiceId, pData) + local session = self.mobile_session_impl.control_services.session + local event = events.Event() + event.matches = function(_, data) + return data.frameType == constants.FRAME_TYPE.CONTROL_FRAME and + data.serviceType == pServiceId and + (pServiceId == constants.SERVICE_TYPE.RPC or data.sessionId == session.sessionId.get()) and + (data.frameInfo == constants.FRAME_INFO.START_SERVICE_ACK or + data.frameInfo == constants.FRAME_INFO.START_SERVICE_NACK) + end + local ret = session:ExpectEvent(event, "StartService") + :Do(function(_, data) + if data.encryption == true and data.frameInfo == constants.FRAME_INFO.START_SERVICE_ACK then + session.security:registerSecureService(pServiceId) + end + end) + :ValidIf(function(_, data) + if data.encryption ~= pData.encryption then + return false, "Expected 'encryption' flag is '" .. tostring(pData.encryption) + .. "', actual is '" .. tostring(data.encryption) .. "'" + end + return true + end) + :ValidIf(function(_, data) + if data.frameInfo ~= pData.frameInfo then + return false, "Expected 'frameInfo' is '" .. tostring(pData.frameInfo) + .. "', actual is '" .. tostring(data.frameInfo) .. "'" + end + return true + end) + return ret + end + + function pMobSession:ExpectHandshakeMessage() + local session = self.mobile_session_impl.control_services.session + local event = events.Event() + event.matches = function(e1, e2) return e1 == e2 end + local ret = pMobSession:ExpectEvent(event, "Handshake") + local handshakeEvent = events.Event() + handshakeEvent.matches = function(_, data) + return data.frameType ~= constants.FRAME_TYPE.CONTROL_FRAME + and data.serviceType == constants.SERVICE_TYPE.CONTROL + and data.sessionId == session.sessionId.get() + and data.rpcType == constants.BINARY_RPC_TYPE.NOTIFICATION + and data.rpcFunctionId == constants.BINARY_RPC_FUNCTION_ID.HANDSHAKE + end + session:ExpectEvent(handshakeEvent, "Handshake internal") + :Do(function(_, data) + local binData = data.binaryData + local dataToSend = session.security:performHandshake(binData) + if dataToSend then + local handshakeMessage = { + frameInfo = 0, + serviceType = constants.SERVICE_TYPE.CONTROL, + encryption = false, + rpcType = constants.BINARY_RPC_TYPE.NOTIFICATION, + rpcFunctionId = constants.BINARY_RPC_FUNCTION_ID.HANDSHAKE, + rpcCorrelationId = data.rpcCorrelationId, + binaryData = dataToSend + } + session:Send(handshakeMessage) + end + end) + :Do(function() + if session.security:isHandshakeFinished() then + event_dispatcher:RaiseEvent(test.mobileConnection, event) + end + end) + :Times(AnyNumber()) + return ret + end +end + +--[[ @getMobileSession: override original getMobileSession function +-- and add additional functions to the mobile session object +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: mobile session object +--]] +function actions.getMobileSession(pAppId) + if not pAppId then pAppId = 1 end + if not test.mobileSession[pAppId] then + local session = origGetMobileSession(pAppId) + registerStartSecureServiceFunc(session) + registerExpectServiceEventFunc(session) + end + return origGetMobileSession(pAppId) +end + +return m diff --git a/user_modules/utils.lua b/user_modules/utils.lua index 4a8320a079..78c9b74c08 100644 --- a/user_modules/utils.lua +++ b/user_modules/utils.lua @@ -1,111 +1,147 @@ -local module = {} +--------------------------------------------------------------------------------------------------- +-- Utils +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.mobileHost = "127.0.0.1" -local common_functions = require("user_modules/common_functions") -local api_loader = require("modules/api_loader") -local mobile_api = api_loader.init("data/MOBILE_API.xml") -local interface_schema = mobile_api.interface["SmartDeviceLink RAPI"] +--[[ Required Shared libraries ]] +local json = require("modules/json") +local events = require('events') ---! @brief Function which returns unordered key set from any table ---! @param table - table from which we are going to get the keys -function module.GetUnorderedTableKeyset(source_table) - local keyset = {} +--[[ Module ]] +local m = {} - for k in pairs(source_table) do - table.insert(keyset, k) - end - return keyset +--[[ Constants ]] +m.timeout = 2000 + +--[[ Functions ]] + +--[[ @jsonFileToTable: convert .json file to table +--! @parameters: +--! pFileName - file name +--! @return: table +--]] +function m.jsonFileToTable(pFileName) + local f = io.open(pFileName, "r") + local content = f:read("*all") + f:close() + return json.decode(content) end ---! @brief Function converts time in TZ format to epoch seconds ---! @param tz_date - date in TZ format ---! @return value - value in epoch seconds ---! @usage Function usage example: epoch_seconds = module.ConvertTZDateToEpochSeconds("2017-02-13T19:28:19Z") -function module.ConvertTZDateToEpochSeconds(tz_date) - local tz_table = {year = 0, month = 0, day = 0, hour = 0, min = 0, sec = 0} - local keyset = {"year", "month", "day", "hour", "min", "sec"} - local count = 1 - for element in string.gmatch(tz_date,'%d+') do - tz_table[keyset[count]] = element - count = count + 1 - end - return os.time(tz_table) +--[[ @tableToJsonFile: convert table to .json file +--! @parameters: +--! pTbl - table +--! pFileName - file name +--! @return: none +--]] +function m.tableToJsonFile(pTbl, pFileName) + local f = io.open(pFileName, "w") + f:write(json.encode(pTbl)) + f:close() end ---! @brief Allows to get struct value from any mobile api struct ---! @param struct_name - name of needed struct ---! @param param_name - struct parameter ---! @param value_to_read - value which is needed to be read ---! @usage Function usage example: maxvalueMenuParams = module.GetStructValueFromMobileApi( "MenuParams", "parentID", "maxvalue") -function module.GetStructValueFromMobileApi(struct_name, param_name, value_to_read) - if not interface_schema.struct[struct_name] then - common_functions:UserPrint(31, "Struct with name:", " ") - common_functions:UserPrint(0, struct_name, " ") - common_functions:UserPrint(31, "does not exist") - return nil +--[[ @readFile: read data from file +--! @parameters: +--! pPath - path to file +-- @return: content of the file +--]] +function m.readFile(pPath) + local open = io.open + local file = open(pPath, "rb") + if not file then return nil end + local content = file:read "*a" + file:close() + return content +end + +--[[ @cloneTable: clone table +--! @parameters: +--! pTbl - table to clone +--! @return: cloned table +--]] +function m.cloneTable(pTbl) + if pTbl == nil then + return {} end - if not interface_schema.struct[struct_name].param[param_name] then - common_functions:UserPrint(31, "Param with name:", " ") - common_functions:UserPrint(0, param_name, " ") - common_functions:UserPrint(31, "does not exist in structure:", " ") - common_functions:UserPrint(0, struct_name) - return nil + local copy = {} + for k, v in pairs(pTbl) do + if type(v) == 'table' then + v = m:cloneTable(v) + end + copy[k] = v end - return interface_schema.struct[struct_name].param[param_name][value_to_read] + return copy end ---! @brief Function allows to get an enum from mobile api ---! @param enum_name - enum name which we are going to get ---! @param Function usage example: local sampling_rates = utils.GetEnumFromMobileApi("SamplingRate") -function module.GetEnumFromMobileApi(enum_name) - if not interface_schema.enum[enum_name] then - common_functions:UserPrint(31, "Enum with name:", " ") - common_functions:UserPrint(0, enum_name, " ") - common_functions:UserPrint(31, "does not exist") - return nil - end - return module.GetUnorderedTableKeyset(interface_schema.enum[enum_name]) +--[[ @wait: delay test step for specific timeout +--! @parameters: +--! pTimeOut - time to wait in ms +--! @return: none +--]] +function m.wait(pTimeOut) + if not pTimeOut then pTimeOut = m.timeout end + local event = events.Event() + event.matches = function(event1, event2) return event1 == event2 end + EXPECT_EVENT(event, "Delayed event") + :Timeout(pTimeOut + 60000) + RUN_AFTER(function() RAISE_EVENT(event, event) end, pTimeOut) end ---! @brief Function allows to get any enum size(number of elements) from mobile api ---! @param enum_name - enum name which size we are going to get ---! @param Function usage example: maxlength = enum_size = module.GetEnumSizeFromMobileApi("AppInterfaceUnregisteredReason") -function module.GetEnumSizeFromMobileApi(enum_name) - if not interface_schema.enum[enum_name] then - common_functions:UserPrint(31, "Enum with name:", " ") - common_functions:UserPrint(0, enum_name, " ") - common_functions:UserPrint(31, "does not exist") - return nil - end - return #module.GetUnorderedTableKeyset(interface_schema.enum[enum_name]) +--[[ @getDeviceName: provide device name +--! @parameters: none +--! @return: name of the device +--]] +function m.getDeviceName() + return config.mobileHost .. ":" .. config.mobilePort end ---! @brief Function allows to get value from any mobile api function ---! @param function_type - request, response or notification ---! @param function_name - name of the function ---! @param param_name - function parameter ---! @param value_to_read - value which is needed to be read ---! @param Function usage example: maxlength = module.GetFunctionValueFromMobileApi("request", "Show", "mainField2", "maxlength") -function module.GetFunctionValueFromMobileApi(function_type, function_name, param_name, value_to_read) - if not interface_schema.type[function_type] then - common_functions:UserPrint(31, "Function with type:", " ") - common_functions:UserPrint(0, function_type, " ") - common_functions:UserPrint(31, "does not exist") - return nil - end - if not interface_schema.type[function_type].functions[function_name] then - common_functions:UserPrint(31, "Function with name:", " ") - common_functions:UserPrint(0, function_name, " ") - common_functions:UserPrint(31, "does not exist") - return nil - end - if not interface_schema.type[function_type].functions[function_name].param[param_name] then - common_functions:UserPrint(31, "Parameter with name:", " ") - common_functions:UserPrint(0, param_name, " ") - common_functions:UserPrint(31, "does not exist") - return nil - end - return interface_schema.type[function_type].functions[function_name].param[param_name][value_to_read] +--[[ @getDeviceMAC: provide device MAC address +--! @parameters: none +--! @return: MAC address of the device +--]] +function m.getDeviceMAC() + local cmd = "echo -n " .. m.getDeviceName() .. " | sha256sum | awk '{printf $1}'" + local handle = io.popen(cmd) + local result = handle:read("*a") + handle:close() + return result end -return module +--[[ @protect: make table immutable +--! @parameters: +--! pTbl - mutable table +--! @return: immutable table +--]] +function m.protect(pTbl) + local mt = { + __index = pTbl, + __newindex = function(_, k, v) + error("Attempting to change item " .. tostring(k) .. " to " .. tostring(v), 2) + end + } + return setmetatable({}, mt) +end + +--[[ @inheritObjects: copy objects from source module to target +-- 'objects' means: tables, functions, fields +-- Function is useful for 'inheriting' data of one module to another +--! @parameters: +--! pTargetObject - target module +--! pSourceObject - source module +--! @return: none +--]] +function m.inheritObjects(pTargetObject, pSourceObject) + for k, v in pairs(pSourceObject) do + if type(v) == "table" then + pTargetObject[k] = m.cloneTable(v) + elseif type(v) == "function" then + pTargetObject[k] = function(...) + return v(...) + end + else + pTargetObject[k] = v + end + end +end +return m From bbe940b9cf5498e59b080f166958d5c5fab9ce90 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 27 Feb 2018 09:21:40 +0200 Subject: [PATCH 324/681] Correct parameter name --- ...request_with_both_supported_and_not_supported_parameters.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/RC/CLIMATE_RADIO/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua index 42e4540f3d..facede9853 100644 --- a/test_scripts/RC/CLIMATE_RADIO/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua +++ b/test_scripts/RC/CLIMATE_RADIO/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua @@ -33,7 +33,7 @@ local climate_params = fanSpeed = 30, acEnable = true, acMaxEnable = true, - circulateAirEnableAvailable = true -- unsupported parameter + circulateAirEnable = true -- unsupported parameter } } From 9002653528c0a94b6ba8ade930d210de3b706001 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 27 Feb 2018 15:48:10 +0200 Subject: [PATCH 325/681] Refactoring test scripts for Security --- .../1888_1_navi.lua | 1 - .../1888_2_non-navi.lua | 1 - .../1888_3_navi_audio_force_off.lua | 1 - .../1888_4_navi_video_force_off.lua | 1 - .../1888_5_navi_audio_force_on.lua | 1 - .../1888_6_navi_video_force_on.lua | 1 - .../1891_1_navi.lua | 1 - .../1891_2_non-navi.lua | 2 - .../1891_3_navi_audio.lua | 1 - .../1891_4_navi_video.lua | 1 - .../1894_1_navi.lua | 1 - .../1894_2_non-navi.lua | 1 - .../1894_3_navi_audio.lua | 1 - .../1894_4_navi_video.lua | 1 - .../1922_1_navi_audio.lua | 1 - .../1922_2_navi_video.lua | 1 - .../1923_1_navi_audio.lua | 1 - .../1923_2_navi_video.lua | 1 - .../1924_1_non-navi.lua | 1 - .../1924_2_navi.lua | 1 - .../1925_1_navi_no_cert_new_app.lua | 1 - .../1925_2_navi_no_cert_existing_app.lua | 4 +- .../1925_3_navi_cert_new_app.lua | 1 - .../1925_4_navi_cert_existing_app.lua | 4 +- .../1925_5_non-navi_no_cert_new_app.lua | 1 - .../1925_6_non-navi_no_cert_existing_app.lua | 4 +- .../1925_7_non-navi_cert_new_app.lua | 1 - .../1925_8_non-navi_cert_existing_app.lua | 4 +- .../4_5/Trigger_PTU_NO_Certificate/common.lua | 4 + user_modules/sequences/actions.lua | 83 +++++++++---------- 30 files changed, 49 insertions(+), 79 deletions(-) diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_1_navi.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_1_navi.lua index 98eac05c46..50d1607975 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_1_navi.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_1_navi.lua @@ -22,7 +22,6 @@ local function ptUpdate(pTbl) local filePath = "./files/Security/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end local function startServiceSecured(pData) diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua index 34ff3608bd..e701804700 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_2_non-navi.lua @@ -20,7 +20,6 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) pTbl.policy_table.module_config.certificate = nil - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end local function startServiceSecured(pData) diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua index 41c726f208..8258cf2334 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_3_navi_audio_force_off.lua @@ -22,7 +22,6 @@ local function ptUpdate(pTbl) local filePath = "./files/Security/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end local function startServiceSecured(pData) diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua index d715b8ac5f..a13799ec66 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_4_navi_video_force_off.lua @@ -22,7 +22,6 @@ local function ptUpdate(pTbl) local filePath = "./files/Security/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end local function startServiceSecured(pData) diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua index 6f259f1b16..bf9aecfb51 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_5_navi_audio_force_on.lua @@ -22,7 +22,6 @@ local function ptUpdate(pTbl) local filePath = "./files/Security/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end local function startServiceSecured(pData) diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua index 1eef37afbf..adbb37437a 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1888_6_navi_video_force_on.lua @@ -22,7 +22,6 @@ local function ptUpdate(pTbl) local filePath = "./files/Security/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end local function startServiceSecured(pData) diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_1_navi.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_1_navi.lua index adf0a6f0b2..ebfebd71d6 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_1_navi.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_1_navi.lua @@ -17,7 +17,6 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } pTbl.policy_table.module_config.seconds_between_retries = nil end diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua index 7abe903165..fccbf36b02 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_2_non-navi.lua @@ -18,11 +18,9 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdateSuccess(pTbl) pTbl.policy_table.module_config.certificate = nil - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end local function ptUpdateUnssucess(pTbl) - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } pTbl.policy_table.module_config.seconds_between_retries = nil end diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua index 37af0eec96..9fb98e56b6 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_3_navi_audio.lua @@ -17,7 +17,6 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } pTbl.policy_table.module_config.seconds_between_retries = nil end diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua index 8e1bd82230..070d6d05ae 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1891_4_navi_video.lua @@ -17,7 +17,6 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } pTbl.policy_table.module_config.seconds_between_retries = nil end diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_1_navi.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_1_navi.lua index 1c47142849..5659b655ef 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_1_navi.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_1_navi.lua @@ -18,7 +18,6 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) pTbl.policy_table.module_config.certificate = nil - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end local function startServiceSecured() diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua index c29e64a6b7..3458f0a57c 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_2_non-navi.lua @@ -18,7 +18,6 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) pTbl.policy_table.module_config.certificate = nil - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end local function startServiceSecured() diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua index a857a7d08a..0311bb8caa 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_3_navi_audio.lua @@ -18,7 +18,6 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) pTbl.policy_table.module_config.certificate = nil - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end local function startServiceSecured() diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua index cdb233ccd9..ebe5c82901 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1894_4_navi_video.lua @@ -18,7 +18,6 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) pTbl.policy_table.module_config.certificate = nil - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end local function startServiceSecured() diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua index 93425e08bd..c90960ae93 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_1_navi_audio.lua @@ -18,7 +18,6 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) pTbl.policy_table.module_config.certificate = nil - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end local function startServiceSecured() diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua index ef8631d651..8cb9199a57 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1922_2_navi_video.lua @@ -18,7 +18,6 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) pTbl.policy_table.module_config.certificate = nil - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end local function startServiceSecured() diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua index 92d37bade3..f2748c30c8 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_1_navi_audio.lua @@ -17,7 +17,6 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } pTbl.policy_table.module_config.seconds_between_retries = nil end diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua index 99ee1a1829..13c912094d 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1923_2_navi_video.lua @@ -17,7 +17,6 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } pTbl.policy_table.module_config.seconds_between_retries = nil end diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua index 65c08ae593..ba410c9b22 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1924_1_non-navi.lua @@ -18,7 +18,6 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) pTbl.policy_table.module_config.certificate = nil - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end local function startServiceSecured() diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1924_2_navi.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1924_2_navi.lua index 112cdb1d4b..ffce7517af 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1924_2_navi.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1924_2_navi.lua @@ -18,7 +18,6 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) pTbl.policy_table.module_config.certificate = nil - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { appHMIType } end local function startServiceSecured() diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua index 62b367fc45..927335055d 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_1_navi_no_cert_new_app.lua @@ -21,7 +21,6 @@ config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } --[[ Local Functions ]] local function ptUpdate(pTbl) pTbl.policy_table.module_config.certificate = nil - pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } end local function registerApp(pAppId) diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua index 8293893881..0304aca686 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_2_navi_no_cert_existing_app.lua @@ -21,9 +21,7 @@ config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } --[[ Local Functions ]] local function ptUpdate(pTbl) pTbl.policy_table.module_config.certificate = nil - pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } - common.updatePTU(pTbl, 2) - pTbl.policy_table.app_policies[common.getAppID(2)].AppHMIType = { appHMIType[2] } + pTbl.policy_table.app_policies[common.getAppID(2)] = common.getAppDataForPTU(2) end local function registerApp(pAppId) diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua index 2ba5a572e5..b1d8314317 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_3_navi_cert_new_app.lua @@ -20,7 +20,6 @@ config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } local filePath = "./files/Security/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua index 7f8a80d78e..3beddb54b7 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_4_navi_cert_existing_app.lua @@ -20,12 +20,10 @@ config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } local filePath = "./files/Security/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - common.updatePTU(pTbl, 2) - pTbl.policy_table.app_policies[common.getAppID(2)].AppHMIType = { appHMIType[2] } + pTbl.policy_table.app_policies[common.getAppID(2)] = common.getAppDataForPTU(2) end local function registerApp(pAppId) diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua index 554d02ec7a..ebc675c560 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_5_non-navi_no_cert_new_app.lua @@ -21,7 +21,6 @@ config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } --[[ Local Functions ]] local function ptUpdate(pTbl) pTbl.policy_table.module_config.certificate = nil - pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } end local function registerApp(pAppId) diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua index 84da86156a..1677bbf65f 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_6_non-navi_no_cert_existing_app.lua @@ -21,9 +21,7 @@ config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } --[[ Local Functions ]] local function ptUpdate(pTbl) pTbl.policy_table.module_config.certificate = nil - pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } - common.updatePTU(pTbl, 2) - pTbl.policy_table.app_policies[common.getAppID(2)].AppHMIType = { appHMIType[2] } + pTbl.policy_table.app_policies[common.getAppID(2)] = common.getAppDataForPTU(2) end local function registerApp(pAppId) diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua index 1e002fbcf8..a4e114d4fb 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_7_non-navi_cert_new_app.lua @@ -20,7 +20,6 @@ config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } local filePath = "./files/Security/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua index 45967a1e87..6f6f1d9b8b 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/1925_8_non-navi_cert_existing_app.lua @@ -20,12 +20,10 @@ config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getAppID(1)].AppHMIType = { appHMIType[1] } local filePath = "./files/Security/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - common.updatePTU(pTbl, 2) - pTbl.policy_table.app_policies[common.getAppID(2)].AppHMIType = { appHMIType[2] } + pTbl.policy_table.app_policies[common.getAppID(2)] = common.getAppDataForPTU(2) end local function registerApp(pAppId) diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua index 6d7dff8f48..aaced0218f 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua @@ -28,4 +28,8 @@ function m.readFile(pFilePath) return utils.readFile(pFilePath) end +function m.getAppID(pAppId) + return m.getConfigAppParams(pAppId).appID +end + return m diff --git a/user_modules/sequences/actions.lua b/user_modules/sequences/actions.lua index 2dee196e31..6bc144cb74 100644 --- a/user_modules/sequences/actions.lua +++ b/user_modules/sequences/actions.lua @@ -43,30 +43,40 @@ local function getPTUFromPTS(pTbl) pTbl.policy_table.module_config.preloaded_date = nil end ---[[ @updatePTU: update PTU table with additional functional group for Navigation RPCs +--[[ @getAppDataForPTU: provide application data for PTU --! @parameters: ---! pTbl - PTU table --! pAppId - application number (1, 2, etc.) --! @return: none --]] -function m.updatePTU(pTbl, pAppId) - pTbl.policy_table.app_policies[m.getAppID(pAppId)] = { +function m.getAppDataForPTU(pAppId) + return { keep_context = false, steal_focus = false, priority = "NONE", default_hmi = "NONE", - groups = { "Base-4", "Location-1" } + groups = { "Base-4", "Location-1" }, + AppHMIType = m.getConfigAppParams(pAppId).appHMIType } end +--[[ @updatePTU: update PTU table with application data +--! @parameters: +--! pTbl - PTU table +--! @return: none +--]] +function m.updatePTU(pTbl) + for i = 1, m.getAppsCount() do + pTbl.policy_table.app_policies[m.getConfigAppParams(i).appID] = m.getAppDataForPTU(i) + end +end + --[[ @ptu: perform policy table update --! @parameters: --! pPTUpdateFunc - additional function for update --! pAppId - application number (1, 2, etc.) --! @return: none --]] -local function ptu(pPTUpdateFunc, pAppId) - if not pAppId then pAppId = 1 end +local function ptu(pPTUpdateFunc) local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") local ptu_file_name = os.tmpname() @@ -77,7 +87,7 @@ local function ptu(pPTUpdateFunc, pAppId) { requestType = "PROPRIETARY", fileName = pts_file_name }) getPTUFromPTS(ptuTable) - m.updatePTU(ptuTable, pAppId) + m.updatePTU(ptuTable) if pPTUpdateFunc then pPTUpdateFunc(ptuTable) @@ -88,15 +98,7 @@ local function ptu(pPTUpdateFunc, pAppId) local event = events.Event() event.matches = function(e1, e2) return e1 == e2 end EXPECT_EVENT(event, "PTU event") - - local function getAppsCount() - local count = 0 - for _ in pairs(hmiAppIds) do - count = count + 1 - end - return count - end - for id = 1, getAppsCount() do + for id = 1, m.getAppsCount() do local session = m.getMobileSession(id) session:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) :Do(function() @@ -132,14 +134,14 @@ local function allowSDL(self) }) end ---[[ @getAppID: return 'appID' from configuration file +--[[ @getConfigAppParams: return app's configuration from defined in config file --! @parameters: --! pAppId - application number (1, 2, etc.) --! @return: application identifier from configuration file --]] -function m.getAppID(pAppId) +function m.getConfigAppParams(pAppId) if not pAppId then pAppId = 1 end - return config["application" .. pAppId].registerAppInterfaceParams.appID + return config["application" .. pAppId].registerAppInterfaceParams end --[[ @preconditions: precondition steps @@ -159,13 +161,11 @@ end --]] function m.activateApp(pAppId) if not pAppId then pAppId = 1 end - local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] - local mobSession = m.getMobileSession(pAppId) - local requestId = test.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + local requestId = test.hmiConnection:SendRequest("SDL.ActivateApp", { appID = m.getHMIAppId(pAppId) }) test.hmiConnection:ExpectResponse(requestId) - mobSession:ExpectNotification("OnHMIStatus", + m.getMobileSession(pAppId):ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) - commonTestCases:DelayedExp(m.minTimeout) + utils.wait() end --[[ @getHMIAppId: get HMI application identifier @@ -175,7 +175,7 @@ end --]] function m.getHMIAppId(pAppId) if not pAppId then pAppId = 1 end - return hmiAppIds[m.getAppID(pAppId)] + return hmiAppIds[m.getConfigAppParams(pAppId).appID] end --[[ @getMobileSession: get mobile session @@ -211,12 +211,11 @@ function m.registerApp(pAppId) local mobSession = m.getMobileSession(pAppId) mobSession:StartService(7) :Do(function() - local corId = mobSession:SendRPC("RegisterAppInterface", - config["application" .. pAppId].registerAppInterfaceParams) + local corId = mobSession:SendRPC("RegisterAppInterface", m.getConfigAppParams(pAppId)) test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", - { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) + { application = { appName = m.getConfigAppParams(pAppId).appName } }) :Do(function(_, d1) - hmiAppIds[m.getAppID(pAppId)] = d1.params.application.appID + hmiAppIds[m.getConfigAppParams(pAppId).appID] = d1.params.application.appID test.hmiConnection:ExpectNotification("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) :Times(2) test.hmiConnection:ExpectRequest("BasicCommunication.PolicyUpdate") @@ -244,12 +243,11 @@ function m.registerAppWOPTU(pAppId) local mobSession = m.getMobileSession(pAppId) mobSession:StartService(7) :Do(function() - local corId = mobSession:SendRPC("RegisterAppInterface", - config["application" .. pAppId].registerAppInterfaceParams) + local corId = mobSession:SendRPC("RegisterAppInterface", m.getConfigAppParams(pAppId)) test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", - { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) + { application = { appName = m.getConfigAppParams(pAppId).appName } }) :Do(function(_, d1) - hmiAppIds[m.getAppID(pAppId)] = d1.params.application.appID + hmiAppIds[m.getConfigAppParams(pAppId).appID] = d1.params.application.appID end) mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() @@ -263,19 +261,16 @@ end --[[ @policyTableUpdate: perform PTU --! @parameters: --! pPTUpdateFunc - function with additional updates ---! pExpNotificationFunc - function with specific expectations which needs to be done during PTU ---! pAppId - application number (1, 2, etc.) --! @return: none --]] -function m.policyTableUpdate(pPTUpdateFunc, pExpNotificationFunc, pAppId) - if not pAppId then pAppId = 1 end - if not pExpNotificationFunc then +function m.policyTableUpdate(pPTUpdateFunc, pExpNotificationFunc) + if pExpNotificationFunc then + pExpNotificationFunc() + else test.hmiConnection:ExpectNotification("SDL.OnStatusUpdate", { status = "UP_TO_DATE" }) test.hmiConnection:ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) - else - pExpNotificationFunc() end - ptu(pPTUpdateFunc, pAppId) + ptu(pPTUpdateFunc) end --[[ @start: starting sequence: starting of SDL, initialization of HMI, connect mobile @@ -445,4 +440,8 @@ function m.postconditions() restoreSDLIniParameters() end +function m.getAppsCount() + return #test.mobileSession +end + return m From 9d47d2402515a790eec05469f294646bbe9b3138 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 27 Feb 2018 22:49:51 +0200 Subject: [PATCH 326/681] Remove unused code --- user_modules/sequences/actions.lua | 71 +++++++++++------------------- user_modules/utils.lua | 9 ++++ 2 files changed, 35 insertions(+), 45 deletions(-) diff --git a/user_modules/sequences/actions.lua b/user_modules/sequences/actions.lua index 6bc144cb74..5be21e543c 100644 --- a/user_modules/sequences/actions.lua +++ b/user_modules/sequences/actions.lua @@ -6,7 +6,6 @@ local mobileSession = require("mobile_session") local json = require("modules/json") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") -local commonTestCases = require("user_modules/shared_testcases/commonTestCases") local events = require("events") local test = require("user_modules/dummy_connecttest") local expectations = require('expectations') @@ -59,42 +58,35 @@ function m.getAppDataForPTU(pAppId) } end ---[[ @updatePTU: update PTU table with application data +--[[ @policyTableUpdate: perform PTU --! @parameters: ---! pTbl - PTU table +--! pPTUpdateFunc - function with additional updates (optional) +--! pExpNotificationFunc - function with specific expectations (optional) --! @return: none --]] -function m.updatePTU(pTbl) - for i = 1, m.getAppsCount() do - pTbl.policy_table.app_policies[m.getConfigAppParams(i).appID] = m.getAppDataForPTU(i) +function m.policyTableUpdate(pPTUpdateFunc, pExpNotificationFunc) + if pExpNotificationFunc then + pExpNotificationFunc() + else + test.hmiConnection:ExpectNotification("SDL.OnStatusUpdate", { status = "UP_TO_DATE" }) + test.hmiConnection:ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) end -end - ---[[ @ptu: perform policy table update ---! @parameters: ---! pPTUpdateFunc - additional function for update ---! pAppId - application number (1, 2, etc.) ---! @return: none ---]] -local function ptu(pPTUpdateFunc) - local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" + local ptsFileName = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") - local ptu_file_name = os.tmpname() + local ptuFileName = os.tmpname() local requestId = test.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) test.hmiConnection:ExpectResponse(requestId) :Do(function() test.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", - { requestType = "PROPRIETARY", fileName = pts_file_name }) + { requestType = "PROPRIETARY", fileName = ptsFileName }) getPTUFromPTS(ptuTable) - - m.updatePTU(ptuTable) - + for i = 1, m.getAppsCount() do + ptuTable.policy_table.app_policies[m.getConfigAppParams(i).appID] = m.getAppDataForPTU(i) + end if pPTUpdateFunc then pPTUpdateFunc(ptuTable) end - - utils.tableToJsonFile(ptuTable, ptu_file_name) - + utils.tableToJsonFile(ptuTable, ptuFileName) local event = events.Event() event.matches = function(e1, e2) return e1 == e2 end EXPECT_EVENT(event, "PTU event") @@ -102,17 +94,17 @@ local function ptu(pPTUpdateFunc) local session = m.getMobileSession(id) session:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) :Do(function() - print("App ".. id .. " was used for PTU") + utils.cprint(35, "App ".. id .. " was used for PTU") RAISE_EVENT(event, event, "PTU event") local corIdSystemRequest = session:SendRPC("SystemRequest", - { requestType = "PROPRIETARY" }, ptu_file_name) + { requestType = "PROPRIETARY" }, ptuFileName) EXPECT_HMICALL("BasicCommunication.SystemRequest") :Do(function(_, d3) test.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) test.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = d3.params.fileName }) end) session:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) - :Do(function() os.remove(ptu_file_name) end) + :Do(function() os.remove(ptuFileName) end) end) :Times(AtMost(1)) end @@ -258,21 +250,6 @@ function m.registerAppWOPTU(pAppId) end) end ---[[ @policyTableUpdate: perform PTU ---! @parameters: ---! pPTUpdateFunc - function with additional updates ---! @return: none ---]] -function m.policyTableUpdate(pPTUpdateFunc, pExpNotificationFunc) - if pExpNotificationFunc then - pExpNotificationFunc() - else - test.hmiConnection:ExpectNotification("SDL.OnStatusUpdate", { status = "UP_TO_DATE" }) - test.hmiConnection:ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) - end - ptu(pPTUpdateFunc) -end - --[[ @start: starting sequence: starting of SDL, initialization of HMI, connect mobile --! @parameters: --! pHMIParams - table with parameters for HMI initialization @@ -284,13 +261,13 @@ function m.start(pHMIParams) :Do(function() test:initHMI() :Do(function() - commonFunctions:userPrint(35, "HMI initialized") + utils.cprint(35, "HMI initialized") test:initHMI_onReady(pHMIParams) :Do(function() - commonFunctions:userPrint(35, "HMI is ready") + utils.cprint(35, "HMI is ready") test:connectMobile() :Do(function() - commonFunctions:userPrint(35, "Mobile connected") + utils.cprint(35, "Mobile connected") allowSDL(test) end) end) @@ -440,6 +417,10 @@ function m.postconditions() restoreSDLIniParameters() end +--[[ @getAppsCount: provide count of registered applications +--! @parameters: none +--! @return: count of apps +--]] function m.getAppsCount() return #test.mobileSession end diff --git a/user_modules/utils.lua b/user_modules/utils.lua index 78c9b74c08..e15afb8931 100644 --- a/user_modules/utils.lua +++ b/user_modules/utils.lua @@ -144,4 +144,13 @@ function m.inheritObjects(pTargetObject, pSourceObject) end end +--[[ @cprint: print color message to console +--! @parameters: +--! pColor - color code +--! pMsg - message +--]] +function m.cprint(pColor, pMsg) + print("\27[" .. tostring(pColor) .. "m" .. tostring(pMsg) .. "\27[0m") +end + return m From 479b6caa027a7f75d176bd7fa7b36fc32ef297cb Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 28 Feb 2018 17:18:12 +0200 Subject: [PATCH 327/681] Decrease priority of internal ATF expectations --- user_modules/connecttest_resumption.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user_modules/connecttest_resumption.lua b/user_modules/connecttest_resumption.lua index 3ea6e55bf4..cff55d9d12 100644 --- a/user_modules/connecttest_resumption.lua +++ b/user_modules/connecttest_resumption.lua @@ -363,7 +363,7 @@ end function module:initHMI_onReady() local function ExpectRequest(name, mandatory, params) local event = events.Event() - event.level = 2 + event.level = 1 event.matches = function(self, data) return data.method == name end return EXPECT_HMIEVENT(event, name) @@ -382,7 +382,7 @@ function module:initHMI_onReady() local function ExpectNotification(name, mandatory) xmlReporter.AddMessage(debug.getinfo(1, "n").name, tostring(name)) local event = events.Event() - event.level = 2 + event.level = 1 event.matches = function(self, data) return data.method == name end return EXPECT_HMIEVENT(event, name) From 2619d6dc3806cc4b5924ed361bd1f0d2a5ae0aeb Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 28 Feb 2018 17:58:30 +0200 Subject: [PATCH 328/681] Change SDL protocol version to 2 --- ...ATF_P_Policies_Performance_Requirement.lua | 1 + ...6_ATF_OnPolicyUpdate_initiation_of_PTU.lua | 1 + ..._Application_Which_Appid_Exists_In_LPT.lua | 1 + .../194_ATF_ActivateApp_isSDLAllowed_true.lua | 1 + .../197_ATF_ActivateApp_isSDLAllowed_true.lua | 1 + ...13_ATF_No_user_consent_prompt_in_group.lua | 6 +- .../214_ATF_User_consent_prompt_persists.lua | 7 ++- .../shared_testcases/commonPreconditions.lua | 10 +-- .../testCasesForPolicyAppIdManagament.lua | 61 +++++++++---------- .../testCasesForPolicyTable.lua | 2 + 10 files changed, 48 insertions(+), 43 deletions(-) diff --git a/test_scripts/Policies/Policies_Security/119_ATF_P_Policies_Performance_Requirement.lua b/test_scripts/Policies/Policies_Security/119_ATF_P_Policies_Performance_Requirement.lua index 6eafbc6e23..d29f4fc35e 100644 --- a/test_scripts/Policies/Policies_Security/119_ATF_P_Policies_Performance_Requirement.lua +++ b/test_scripts/Policies/Policies_Security/119_ATF_P_Policies_Performance_Requirement.lua @@ -16,6 +16,7 @@ --[[ General configuration parameters ]] config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local mobile_session = require("mobile_session") diff --git a/test_scripts/Policies/Related_HMI_API/186_ATF_OnPolicyUpdate_initiation_of_PTU.lua b/test_scripts/Policies/Related_HMI_API/186_ATF_OnPolicyUpdate_initiation_of_PTU.lua index 97f33f072b..0ce420c61a 100644 --- a/test_scripts/Policies/Related_HMI_API/186_ATF_OnPolicyUpdate_initiation_of_PTU.lua +++ b/test_scripts/Policies/Related_HMI_API/186_ATF_OnPolicyUpdate_initiation_of_PTU.lua @@ -13,6 +13,7 @@ --[[ General configuration parameters ]] config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua b/test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua index 2fc5f5e483..ffe027dd9c 100644 --- a/test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua +++ b/test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua @@ -20,6 +20,7 @@ --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") diff --git a/test_scripts/Policies/user_consent_of_Policies/194_ATF_ActivateApp_isSDLAllowed_true.lua b/test_scripts/Policies/user_consent_of_Policies/194_ATF_ActivateApp_isSDLAllowed_true.lua index a373fd8ea1..1b13d968c6 100644 --- a/test_scripts/Policies/user_consent_of_Policies/194_ATF_ActivateApp_isSDLAllowed_true.lua +++ b/test_scripts/Policies/user_consent_of_Policies/194_ATF_ActivateApp_isSDLAllowed_true.lua @@ -21,6 +21,7 @@ --[[ General configuration parameters ]] config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/user_consent_of_Policies/197_ATF_ActivateApp_isSDLAllowed_true.lua b/test_scripts/Policies/user_consent_of_Policies/197_ATF_ActivateApp_isSDLAllowed_true.lua index 20f559c28b..33c408e9db 100644 --- a/test_scripts/Policies/user_consent_of_Policies/197_ATF_ActivateApp_isSDLAllowed_true.lua +++ b/test_scripts/Policies/user_consent_of_Policies/197_ATF_ActivateApp_isSDLAllowed_true.lua @@ -24,6 +24,7 @@ --[[ General configuration parameters ]] config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/user_consent_of_Policies/213_ATF_No_user_consent_prompt_in_group.lua b/test_scripts/Policies/user_consent_of_Policies/213_ATF_No_user_consent_prompt_in_group.lua index 8ae7cb6cf7..93b010162e 100644 --- a/test_scripts/Policies/user_consent_of_Policies/213_ATF_No_user_consent_prompt_in_group.lua +++ b/test_scripts/Policies/user_consent_of_Policies/213_ATF_No_user_consent_prompt_in_group.lua @@ -22,6 +22,7 @@ --[[ General configuration parameters ]] config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') @@ -31,9 +32,6 @@ local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/t --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() ---testCasesForPolicyTable:Precondition_updatePolicy_By_overwriting_preloaded_pt("files/DeviceGroupInPreconsented_preloadedPT.json") ---TODO(istoimenova): shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed -config.defaultProtocolVersion = 2 --[[ General Settings for configuration ]] Test = require('connecttest') @@ -68,7 +66,7 @@ end function Test:TestStep_app_no_consent() local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records."..config.application1.registerAppInterfaceParams.appID) - if(app_permission ~= 0) then + if(app_permission ~= nil) then self:FailTestCase("Consented gropus are assigned to application") end end diff --git a/test_scripts/Policies/user_consent_of_Policies/214_ATF_User_consent_prompt_persists.lua b/test_scripts/Policies/user_consent_of_Policies/214_ATF_User_consent_prompt_persists.lua index 7b48c010e1..0e03ec8d9e 100644 --- a/test_scripts/Policies/user_consent_of_Policies/214_ATF_User_consent_prompt_persists.lua +++ b/test_scripts/Policies/user_consent_of_Policies/214_ATF_User_consent_prompt_persists.lua @@ -21,6 +21,7 @@ --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') @@ -133,8 +134,8 @@ end --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() ---TODO(istoimenova): shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed -config.defaultProtocolVersion = 2 + + testCasesForPolicyTable.Delete_Policy_table_snapshot() testCasesForPolicyTable:Precondition_updatePolicy_By_overwriting_preloaded_pt("files/sdl_preloaded_pt_AlertOnlyNotifications_1.json") @@ -176,7 +177,7 @@ function Test:Precondition_IsPermissionsConsentNeeded_false_on_app_activation() EXPECT_HMICALL("BasicCommunication.PolicyUpdate", {file = "/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json"}) :Do(function() local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records."..config.application1.registerAppInterfaceParams.appID) - if(app_permission ~= 0) then + if(app_permission ~= nil) then self:FailTestCase("Consented gropus are assigned to application") end end) diff --git a/user_modules/shared_testcases/commonPreconditions.lua b/user_modules/shared_testcases/commonPreconditions.lua index 653f98ca26..8871b0f1cb 100644 --- a/user_modules/shared_testcases/commonPreconditions.lua +++ b/user_modules/shared_testcases/commonPreconditions.lua @@ -173,8 +173,8 @@ function Preconditions:Connecttest_without_ExitBySDLDisconnect_WithoutOpenConnec local fileContent = f:read("*all") f:close() - local pattertConnectMobileCall = "function .?module%:ConnectMobile.-connectMobile.-end" - local patternStartSessionCall = "function .?module%:StartSession.-startSession.-end" + local pattertConnectMobileCall = "function .?Test%:ConnectMobile.-connectMobile.-end" + local patternStartSessionCall = "function .?Test%:StartSession.-startSession.-end" local connectMobileCall = fileContent:match(pattertConnectMobileCall) local startSessionCall = fileContent:match(patternStartSessionCall) @@ -209,7 +209,7 @@ function Preconditions:Connecttest_without_ExitBySDLDisconnect_OpenConnection(Fi local fileContent = f:read("*all") f:close() - local patternStartSessionCall = "function .?module%:StartSession.-startSession.-end" + local patternStartSessionCall = "function .?Test%:StartSession.-startSession.-end" local startSessionCall = fileContent:match(patternStartSessionCall) if startSessionCall == nil then @@ -461,7 +461,7 @@ function Preconditions:Connecttest_InitHMI_onReady_call(FileName, createFile) fileContent = f:read("*all") f:close() - local pattern1 = "function .?module%:InitHMI_onReady.-initHMI_onReady.-end" + local pattern1 = "function .?Test%:InitHMI_onReady.-initHMI_onReady.-end" local pattern1Result = fileContent:match(pattern1) if pattern1Result == nil then @@ -476,4 +476,4 @@ function Preconditions:Connecttest_InitHMI_onReady_call(FileName, createFile) end -return Preconditions \ No newline at end of file +return Preconditions diff --git a/user_modules/shared_testcases/testCasesForPolicyAppIdManagament.lua b/user_modules/shared_testcases/testCasesForPolicyAppIdManagament.lua index e559c12b6c..5e7e37353c 100644 --- a/user_modules/shared_testcases/testCasesForPolicyAppIdManagament.lua +++ b/user_modules/shared_testcases/testCasesForPolicyAppIdManagament.lua @@ -1,54 +1,53 @@ --------------------------------------------------------------------------------------------- -- Policy: AppID Management common module --------------------------------------------------------------------------------------------- +config.defaultProtocolVersion = 2 local common = {} - local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") -local policy_file_name = "PolicyTableUpdate" - ----------------------------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------------------------ -- The function is used only in case when PTU PROPRIETARY should have as result: UP_TO_DATE -- The funcion will be used when PTU is triggered. --- 1. It is assumed that notification is recevied: EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATE_NEEDED"}) +-- 1. It is assumed that notification is recevied: +-- EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATE_NEEDED"}) -- 2. It is assumed that request/response is received: EXPECT_HMICALL("BasicCommunication.PolicyUpdate", -- 3. Function will use default endpoints --- Difference with PROPRIETARY flow is clarified in "Can you clarify is PTU flows for External_Proprietary and Proprietary have differences?" +-- Difference with PROPRIETARY flow is clarified in "Can you clarify is PTU flows for External_Proprietary +-- and Proprietary have differences?" -- But this should be checked in appropriate scripts --TODO(istoimenova): functions with External_Proprietary should be merged at review of common functions. function common:updatePolicyTable(test, file) EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATING" }, { status = "UP_TO_DATE" }):Times(2) local requestId = test.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(requestId, {result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) - :Do(function(_, _) - test.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }) - + EXPECT_HMIRESPONSE(requestId, { + result = { + code = 0, + method = "SDL.GetURLS", + urls = { + { + url = "http://policies.telematics.ford.com/api/policies" + } + } + } + }) + :Do(function() + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" + .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + test.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { + requestType = "PROPRIETARY", + fileName = pts_file_name + }) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) - :Do(function(_, _) - - local corIdSystemRequest = test.mobileSession:SendRPC("SystemRequest", - { - requestType = "PROPRIETARY", - fileName = policy_file_name - }, - file) - EXPECT_HMICALL("BasicCommunication.SystemRequest",{requestType = "PROPRIETARY", fileName = policy_file_path.."/"..policy_file_name },file) + :Do(function() + local corIdSystemRequest = test.mobileSession:SendRPC("SystemRequest", { requestType = "PROPRIETARY" }, file) + EXPECT_HMICALL("BasicCommunication.SystemRequest",{ requestType = "PROPRIETARY" }, file) :Do(function(_, data) - test.hmiConnection:SendResponse(data.id, "BasicCommunication.SystemRequest", "SUCCESS", {}) - test.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", - { - policyfile = policy_file_path.."/"..policy_file_name - } - ) + test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + test.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = data.params.fileName } ) end) - EXPECT_RESPONSE(corIdSystemRequest, { success = true, resultCode = "SUCCESS"}) - :Do(function(_, _) - -- requestId = test.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"StatusUpToDate"}}) - -- EXPECT_HMIRESPONSE(requestId) - end) + EXPECT_HMICALL("VehicleInfo.GetVehicleData", { odometer = true }) end) end) diff --git a/user_modules/shared_testcases/testCasesForPolicyTable.lua b/user_modules/shared_testcases/testCasesForPolicyTable.lua index 034be71792..d963347be5 100644 --- a/user_modules/shared_testcases/testCasesForPolicyTable.lua +++ b/user_modules/shared_testcases/testCasesForPolicyTable.lua @@ -3,6 +3,7 @@ --1. local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') --2. testCasesForPolicyTable:createPolicyTableWithoutAPI() --------------------------------------------------------------------------------------------- +config.defaultProtocolVersion = 2 local testCasesForPolicyTable = {} local commonFunctions = require('user_modules/shared_testcases/commonFunctions') @@ -939,6 +940,7 @@ function testCasesForPolicyTable:flow_SUCCEESS_EXTERNAL_PROPRIETARY(self, app_id self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = SystemFilesPath..ptu_file_name}) end) EXPECT_RESPONSE(CorIdSystemRequest, { success = true, resultCode = "SUCCESS"}) + EXPECT_HMICALL("VehicleInfo.GetVehicleData", { odometer = true }) end) end) end From 8acc0970859f13158c97b9f83494df1d14539c9d Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 28 Feb 2018 18:04:42 +0200 Subject: [PATCH 329/681] Stabilize scripts --- ...007_ATF_StealFocus_validation_true_PTU.lua | 32 +++------ ..._ATF_Sending_PTS_to_mobile_application.lua | 6 +- .../145_ATF_PTU_Merge_Into_LPT.lua | 46 ++++++------- ...TU_Merge_Of_Consumer_Friendly_Messages.lua | 19 ++---- ...ot_From_Sync_After_Getting_The_Updates.lua | 38 ++--------- ...F_OnAppPermissionConsent_without_appID.lua | 17 ++--- ...Applying_Heart_Beat_Timeout_Ms_From_PT.lua | 53 ++++++--------- ...plying_Heart_Beat_Timeout_Ms_After_PTU.lua | 67 ++++++------------- ...App_Interface_Assign_Existing_Policies.lua | 19 +----- ..._ATF_HP_Device_Data_Section_Validation.lua | 1 - ...207_ATF_HMILevel_before_data_consented.lua | 2 +- 11 files changed, 99 insertions(+), 201 deletions(-) diff --git a/test_scripts/Policies/App_Permissions/007_ATF_StealFocus_validation_true_PTU.lua b/test_scripts/Policies/App_Permissions/007_ATF_StealFocus_validation_true_PTU.lua index 28f7e19f88..3de843ae31 100644 --- a/test_scripts/Policies/App_Permissions/007_ATF_StealFocus_validation_true_PTU.lua +++ b/test_scripts/Policies/App_Permissions/007_ATF_StealFocus_validation_true_PTU.lua @@ -94,37 +94,27 @@ function Test:Precondition_DeactivateApp() end function Test:Preconditions_Update_Policy_With_Steal_Focus_FalseValue_for_Current_App() + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" + .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATING" }, { status = "UP_TO_DATE" }):Times(2) local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) :Do(function() - self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", - { + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", - fileName = "filename" + fileName = pts_file_name } ) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) :Do(function() - local CorIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", - { - fileName = "PolicyTableUpdate", - requestType = "PROPRIETARY" - }, "files/ptu_general_steal_focus_true.json") - local systemRequestId + local CorIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", { + requestType = "PROPRIETARY" }, "files/ptu_general_steal_focus_true.json") EXPECT_HMICALL("BasicCommunication.SystemRequest") - :Do(function(_,data) - systemRequestId = data.id - self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", - { - policyfile = "/tmp/fs/mp/images/ivsu_cache/PolicyTableUpdate" - }) - local function to_run() - self.hmiConnection:SendResponse(systemRequestId,"BasicCommunication.SystemRequest", "SUCCESS", {}) - end - RUN_AFTER(to_run, 800) - self.mobileSession:ExpectResponse(CorIdSystemRequest, {success = true, resultCode = "SUCCESS"}) - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UP_TO_DATE"}) + :Do(function(_, data) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = data.params.fileName }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) + self.mobileSession:ExpectResponse(CorIdSystemRequest, { success = true, resultCode = "SUCCESS" }) end) end) end diff --git a/test_scripts/Policies/Policy_Table_Update/137_ATF_Sending_PTS_to_mobile_application.lua b/test_scripts/Policies/Policy_Table_Update/137_ATF_Sending_PTS_to_mobile_application.lua index 960782d3db..8fa77b7d2c 100644 --- a/test_scripts/Policies/Policy_Table_Update/137_ATF_Sending_PTS_to_mobile_application.lua +++ b/test_scripts/Policies/Policy_Table_Update/137_ATF_Sending_PTS_to_mobile_application.lua @@ -39,6 +39,8 @@ Test = require("user_modules/connecttest_resumption") require('cardinalities') require('user_modules/AppTypes') +local HMIAppID + --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") @@ -59,7 +61,7 @@ function Test:RAI() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config.application1.registerAppInterfaceParams.appName } }) :Do( function(_, d1) - self.applications[config.application1.registerAppInterfaceParams.appID] = d1.params.application.appID + HMIAppID = d1.params.application.appID end) self.mobileSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do( @@ -74,7 +76,7 @@ end commonFunctions:newTestCasesGroup("Test") function Test:Trigger_getting_device_consent() - local requestId1 = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appID] }) + local requestId1 = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = HMIAppID }) EXPECT_HMIRESPONSE(requestId1) :Do( function(_, d1) diff --git a/test_scripts/Policies/Policy_Table_Update/145_ATF_PTU_Merge_Into_LPT.lua b/test_scripts/Policies/Policy_Table_Update/145_ATF_PTU_Merge_Into_LPT.lua index a902233c9c..97da3c8321 100644 --- a/test_scripts/Policies/Policy_Table_Update/145_ATF_PTU_Merge_Into_LPT.lua +++ b/test_scripts/Policies/Policy_Table_Update/145_ATF_PTU_Merge_Into_LPT.lua @@ -156,32 +156,26 @@ function Test:TestStep_RegisterNewApp() end function Test:TestStep_ValidateResult() - self.mobileSession:ExpectAny() - :ValidIf(function(_, _) - local pts = json_to_table(policy_file_path .. "/sdl_snapshot.json") - local ptu = json_to_table(ptu_file) - -- Reconcile expected vs actual - ptu.policy_table.module_config.preloaded_pt = false - ptu.policy_table.app_policies["0000002"] = "default" - - -- Compare - if not is_table_equal(ptu.policy_table.functional_groupings, pts.policy_table.functional_groupings) then - return false, "Diffs in functional_groupings\nExpected:\n" .. commonFunctions:convertTableToString(ptu.policy_table.functional_groupings, 1) .. "\nActual:\n" .. commonFunctions:convertTableToString(pts.policy_table.functional_groupings, 1) - end - if not is_table_equal(ptu.policy_table.module_config, pts.policy_table.module_config) then - return false, "Diffs in module_config\nExpected:\n" .. commonFunctions:convertTableToString(ptu.policy_table.module_config, 1) .. "\nActual:\n" .. commonFunctions:convertTableToString(pts.policy_table.module_config, 1) - end - -- Section app_policies verified for '0000001' app only - if not is_table_equal(ptu.policy_table.app_policies["0000001"], pts.policy_table.app_policies["0000001"]) then - return false, "Diffs in app_policies\nExpected:\n" .. commonFunctions:convertTableToString(ptu.policy_table.app_policies["0000001"], 1) .. "\nActual:\n" .. commonFunctions:convertTableToString(pts.policy_table.app_policies["0000001"], 1) - end - -- Section app_policies verified for '0000002' app only - if not is_table_equal(ptu.policy_table.app_policies["0000002"], pts.policy_table.app_policies["0000002"]) then - return false, "Diffs in app_policies\nExpected:\n" .. commonFunctions:convertTableToString(ptu.policy_table.app_policies["0000002"], 1) .. "\nActual:\n" .. commonFunctions:convertTableToString(pts.policy_table.app_policies["0000002"], 1) - end - return true - end) - :Times(1) + local pts = json_to_table(policy_file_path .. "/sdl_snapshot.json") + local ptu = json_to_table(ptu_file) + -- Reconcile expected vs actual + ptu.policy_table.module_config.preloaded_pt = false + ptu.policy_table.app_policies["0000002"] = "default" + -- Compare + if not is_table_equal(ptu.policy_table.functional_groupings, pts.policy_table.functional_groupings) then + self:FailTestCase("Diffs in functional_groupings\nExpected:\n" .. commonFunctions:convertTableToString(ptu.policy_table.functional_groupings, 1) .. "\nActual:\n" .. commonFunctions:convertTableToString(pts.policy_table.functional_groupings, 1)) + end + if not is_table_equal(ptu.policy_table.module_config, pts.policy_table.module_config) then + self:FailTestCase("Diffs in module_config\nExpected:\n" .. commonFunctions:convertTableToString(ptu.policy_table.module_config, 1) .. "\nActual:\n" .. commonFunctions:convertTableToString(pts.policy_table.module_config, 1)) + end + -- Section app_policies verified for '0000001' app only + if not is_table_equal(ptu.policy_table.app_policies["0000001"], pts.policy_table.app_policies["0000001"]) then + self:FailTestCase("Diffs in app_policies\nExpected:\n" .. commonFunctions:convertTableToString(ptu.policy_table.app_policies["0000001"], 1) .. "\nActual:\n" .. commonFunctions:convertTableToString(pts.policy_table.app_policies["0000001"], 1)) + end + -- Section app_policies verified for '0000002' app only + if not is_table_equal(ptu.policy_table.app_policies["0000002"], pts.policy_table.app_policies["0000002"]) then + self:FailTestCase("Diffs in app_policies\nExpected:\n" .. commonFunctions:convertTableToString(ptu.policy_table.app_policies["0000002"], 1) .. "\nActual:\n" .. commonFunctions:convertTableToString(pts.policy_table.app_policies["0000002"], 1)) + end end --[[ Postconditions ]] diff --git a/test_scripts/Policies/Policy_Table_Update/152_ATF_PTU_Merge_Of_Consumer_Friendly_Messages.lua b/test_scripts/Policies/Policy_Table_Update/152_ATF_PTU_Merge_Of_Consumer_Friendly_Messages.lua index cfd5898c56..db62a28063 100644 --- a/test_scripts/Policies/Policy_Table_Update/152_ATF_PTU_Merge_Of_Consumer_Friendly_Messages.lua +++ b/test_scripts/Policies/Policy_Table_Update/152_ATF_PTU_Merge_Of_Consumer_Friendly_Messages.lua @@ -127,18 +127,13 @@ function Test:TestStep_RegisterNewApp() self.mobileSession2:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) end -function Test.TestStep_ValidateResultAfterPTU() - EXPECT_ANY() - :ValidIf(function(_, _) - local r_expected = { "1|TTS1|LABEL|LINE1|LINE2|TEXTBODY|en-us|AppPermissions", "2|TTS2|||||en-us|AppPermissionsHelp" } - local query = "select id, tts, label, line1, line2, textBody, language_code, message_type_name from message" - local r_actual = commonFunctions:get_data_policy_sql(config.pathToSDL.."/storage/policy.sqlite", query) - if not is_table_equal(r_expected, r_actual) then - return false, "\nExpected:\n" .. commonFunctions:convertTableToString(r_expected, 1) .. "\nActual:\n" .. commonFunctions:convertTableToString(r_actual, 1) - end - return true - end) - :Times(1) +function Test:TestStep_ValidateResultAfterPTU() + local r_expected = { "1|TTS1|LABEL|LINE1|LINE2|TEXTBODY|en-us|AppPermissions", "2|TTS2|||||en-us|AppPermissionsHelp" } + local query = "select id, tts, label, line1, line2, textBody, language_code, message_type_name from message" + local r_actual = commonFunctions:get_data_policy_sql(config.pathToSDL.."/storage/policy.sqlite", query) + if not is_table_equal(r_expected, r_actual) then + self:FailTestCase("\nExpected:\n" .. commonFunctions:convertTableToString(r_expected, 1) .. "\nActual:\n" .. commonFunctions:convertTableToString(r_actual, 1)) + end end --[[ Postconditions ]] diff --git a/test_scripts/Policies/Policy_Table_Update/154_ATF_PTU_SDL_Must_Remove_PTU_File_Got_From_Sync_After_Getting_The_Updates.lua b/test_scripts/Policies/Policy_Table_Update/154_ATF_PTU_SDL_Must_Remove_PTU_File_Got_From_Sync_After_Getting_The_Updates.lua index ed1eb4ccae..6defb13cc3 100644 --- a/test_scripts/Policies/Policy_Table_Update/154_ATF_PTU_SDL_Must_Remove_PTU_File_Got_From_Sync_After_Getting_The_Updates.lua +++ b/test_scripts/Policies/Policy_Table_Update/154_ATF_PTU_SDL_Must_Remove_PTU_File_Got_From_Sync_After_Getting_The_Updates.lua @@ -28,29 +28,12 @@ local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") --[[ Local Variables ]] --- local r_expected = { true, false } -- Expected file is created and then afterwards is deleted --- local r_actual = { } -local policy_file_name = "PolicyTableUpdate" +local policy_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" + .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") local ptu_file = "files/jsons/Policies/Policy_Table_Update/ptu_19168.json" --[[ Local Functions ]] --- local function is_table_equal(t1, t2) --- local ty1 = type(t1) --- local ty2 = type(t2) --- if ty1 ~= ty2 then return false end --- if ty1 ~= 'table' and ty2 ~= 'table' then return t1 == t2 end --- for k1, v1 in pairs(t1) do --- local v2 = t2[k1] --- if v2 == nil or not is_table_equal(v1, v2) then return false end --- end --- for k2, v2 in pairs(t2) do --- local v1 = t1[k2] --- if v1 == nil or not is_table_equal(v1, v2) then return false end --- end --- return true --- end - local function check_file_exists(name) local f = io.open(name, "r") if f ~= nil then @@ -103,23 +86,16 @@ function Test:TestStep_PTU_Success_PTUfile_removed() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) :Do(function(_, _) - local corIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file) + local corIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", { requestType = "PROPRIETARY" }, ptu_file) EXPECT_HMICALL("BasicCommunication.SystemRequest") :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) - --table.insert(r_actual, check_file_exists(policy_file_path .. "/" .. policy_file_name)) - self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = policy_file_path .. "/" .. policy_file_name }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = data.params.fileName }) end) EXPECT_RESPONSE(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) - :Do(function(_, _) - --table.insert(r_actual, check_file_exists(policy_file_path .. "/" .. policy_file_name)) - requestId = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", { language = "EN-US", messageCodes = { "StatusUpToDate" } }) - EXPECT_HMIRESPONSE(requestId) - end) end) end) - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", - {status = "UPDATING"}, {status = "UP_TO_DATE"}):Times(2) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATING"}, {status = "UP_TO_DATE"}):Times(2) :Do(function(_,data) if(data.params.status == "UP_TO_DATE") then local result = check_file_exists(policy_file_path .. "/" .. policy_file_name) @@ -136,4 +112,4 @@ function Test.Postcondition_StopSDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Related_HMI_API/178_ATF_OnAppPermissionConsent_without_appID.lua b/test_scripts/Policies/Related_HMI_API/178_ATF_OnAppPermissionConsent_without_appID.lua index 840f3ecd28..19a135d269 100644 --- a/test_scripts/Policies/Related_HMI_API/178_ATF_OnAppPermissionConsent_without_appID.lua +++ b/test_scripts/Policies/Related_HMI_API/178_ATF_OnAppPermissionConsent_without_appID.lua @@ -72,17 +72,19 @@ function Test:TestStep_User_consent_on_activate_app() local groups = {} if #data.result.allowedFunctions > 0 then for i = 1, #data.result.allowedFunctions do + print(data.result.allowedFunctions[i].name) groups[i] = { name = data.result.allowedFunctions[i].name, id = data.result.allowedFunctions[i].id, allowed = true} end end - self.hmiConnection:SendNotification("SDL.OnAppPermissionConsent", { consentedFunctions = groups, source = "GUI"}) + self.hmiConnection:SendNotification("SDL.OnAppPermissionConsent", { + consentedFunctions = groups, + source = "GUI", + appID = self.applications[config.application1.registerAppInterfaceParams.appName] + }) EXPECT_NOTIFICATION("OnPermissionsChange") - :Do(function(_,_) - - end) end) end) @@ -92,13 +94,12 @@ function Test:TestStep_User_consent_on_activate_app() end function Test:TestStep_check_LocalPT_for_updates() - local is_test_fail = false - self.hmiConnection:SendRequest("SDL.UpdateSDL", {} ) - - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATE_NEEDED"}) + local RequestId = self.hmiConnection:SendRequest("SDL.UpdateSDL", {} ) + EXPECT_HMIRESPONSE(RequestId, { result = { result = "UPDATE_NEEDED" }}) EXPECT_HMICALL("BasicCommunication.PolicyUpdate",{}) :Do(function(_,data) + local is_test_fail = false local app_consent_location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Location-1") local app_consent_notifications = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Notifications") diff --git a/test_scripts/Policies/Validation_of_PolicyTables/300_ATF_HP_Applying_Heart_Beat_Timeout_Ms_From_PT.lua b/test_scripts/Policies/Validation_of_PolicyTables/300_ATF_HP_Applying_Heart_Beat_Timeout_Ms_From_PT.lua index 93942d4af6..80af820cdd 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/300_ATF_HP_Applying_Heart_Beat_Timeout_Ms_From_PT.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/300_ATF_HP_Applying_Heart_Beat_Timeout_Ms_From_PT.lua @@ -20,8 +20,6 @@ --[[ General configuration parameters ]] config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" ---Heartbeat is supported after protocolversion 3 ---config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') @@ -29,10 +27,12 @@ local commonSteps = require ('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') +--Heartbeat is supported after protocolversion 3 +config.defaultProtocolVersion = 3 + --[[ Local Variables ]] local HBTime_max = 0 local HBTime_min = 0 -local eventHB --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -67,25 +67,9 @@ end function Test:Precondition_StartSession() self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) self.mobileSession.sendHeartbeatToSDL = false - self.mobileSession.answerHeartbeatFromSDL = true - - eventHB = events.Event() - eventHB.matches = function(_, data) - return data.frameType == 0 and - (data.serviceType == 0) and - (data.frameInfo == 0) --HeartBeat - end - self.mobileSession:StartRPC(function () - self.mobileSession:ExpectEvent(eventHB, "Heartbeat") - :Do(function() - - self.mobileSession:Send( - { frameType = constants.FRAME_TYPE.CONTROL_FRAME, - serviceType = constants.SERVICE_TYPE.CONTROL, - frameInfo = constants.FRAME_INFO.HEARTBEAT_ACK } ) - end):Times(AnyNumber()) - end) - end + self.mobileSession.ignoreSDLHeartBeatACK = true + self.mobileSession:StartRPC() +end function Test:Precondition_Register_App_With_heart_beat_timeout_ms_Param() local correlationId = self.mobileSession:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) @@ -102,6 +86,14 @@ function Test:TestStep_Get_HeartBeat_Time() local time_prev = 0 local time_now = 0 + local eventHB = events.Event() + eventHB.level = 3 + eventHB.matches = function(_, data) + return data.frameType == 0 and + (data.serviceType == 0) and + (data.frameInfo == 0) --HeartBeat + end + self.mobileSession:ExpectEvent(eventHB, "Heartbeat") :ValidIf(function() print("HeartBeat received in "..atf_logger.formated_time(true)) @@ -133,18 +125,11 @@ function Test:TestStep_Get_HeartBeat_Time() end function Test:TestStep_Check_HB_Time() - -- Send request to bind ValidIf for HB time validation - self.mobileSession:SendRPC("UnregisterAppInterface", {}) - EXPECT_RESPONSE("UnregisterAppInterface", {success = true , resultCode = "SUCCESS"}) - :ValidIf(function() - if ( (HBTime_min < 3850) or (HBTime_max > 4150) ) then - print("Wrong HearBeat time! Expected: 4000ms, Actual: ["..HBTime_min.." ; "..HBTime_max.."]ms ") - return false - else - print(" HearBeat is in range ["..HBTime_min.." ; "..HBTime_max.."]ms ") - return true - end - end) + if ( (HBTime_min < 3850) or (HBTime_max > 4150) ) then + self:FailTestCase("Wrong HearBeat time! Expected: 4000ms, Actual: ["..HBTime_min.." ; "..HBTime_max.."]ms ") + else + print("HearBeat is in range ["..HBTime_min.." ; "..HBTime_max.."]ms ") + end end --[[ Postconditions ]] diff --git a/test_scripts/Policies/Validation_of_PolicyTables/302_ATF_HP_Applying_Heart_Beat_Timeout_Ms_After_PTU.lua b/test_scripts/Policies/Validation_of_PolicyTables/302_ATF_HP_Applying_Heart_Beat_Timeout_Ms_After_PTU.lua index f79db4991d..f03fda6e25 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/302_ATF_HP_Applying_Heart_Beat_Timeout_Ms_After_PTU.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/302_ATF_HP_Applying_Heart_Beat_Timeout_Ms_After_PTU.lua @@ -21,8 +21,6 @@ --[[ General configuration parameters ]] config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" ---Heartbeat is supported after protocolversion 3 ---config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') @@ -30,12 +28,13 @@ local commonSteps = require ('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') +--Heartbeat is supported after protocolversion 3 +config.defaultProtocolVersion = 3 + --[[ Local Variables ]] local HBTime_max = 0 local HBTime_min = 0 -local eventHB - --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() commonPreconditions:Connecttest_without_ExitBySDLDisconnect_WithoutOpenConnectionRegisterApp("connecttest_ConnectMobile.lua") @@ -68,24 +67,8 @@ end function Test:Precondition_StartSession() self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) self.mobileSession.sendHeartbeatToSDL = false - self.mobileSession.answerHeartbeatFromSDL = true - - eventHB = events.Event() - eventHB.matches = function(_, data) - return data.frameType == 0 and - (data.serviceType == 0) and - (data.frameInfo == 0) --HeartBeat - end - - self.mobileSession:StartRPC(function () - self.mobileSession:ExpectEvent(eventHB, "Heartbeat") - :Do(function() - self.mobileSession:Send( - { frameType = constants.FRAME_TYPE.CONTROL_FRAME, - serviceType = constants.SERVICE_TYPE.CONTROL, - frameInfo = constants.FRAME_INFO.HEARTBEAT_ACK } ) - end):Times(AnyNumber()) - end) + self.mobileSession.ignoreSDLHeartBeatACK = true + self.mobileSession:StartRPC() end function Test:Precondition_RegisterApp() @@ -100,12 +83,6 @@ function Test:Precondition_RegisterApp() end function Test:Precondition_Activate_Consent_App() - self.mobileSession:ExpectEvent(eventHB, "Heartbeat"):Do(function() - self.mobileSession:Send( - { frameType = constants.FRAME_TYPE.CONTROL_FRAME, - serviceType = constants.SERVICE_TYPE.CONTROL, - frameInfo = constants.FRAME_INFO.HEARTBEAT_ACK } ) - end):Times(AnyNumber()) testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) end @@ -116,17 +93,10 @@ end function Test:Precondition_HMI_sends_OnAllowSDLFunctionality() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = false, source = "GUI"}) - self.mobileSession:ExpectNotification("OnPermissionsChange") + -- self.mobileSession:ExpectNotification("OnPermissionsChange") -- not allowed by Policies end function Test:Precondition_Check_App_PreDataConsent() - self.mobileSession:ExpectEvent(eventHB, "Heartbeat"):Do(function() - self.mobileSession:Send( - { frameType = constants.FRAME_TYPE.CONTROL_FRAME, - serviceType = constants.SERVICE_TYPE.CONTROL, - frameInfo = constants.FRAME_INFO.HEARTBEAT_ACK } ) - end):Times(AnyNumber()) - local cid = self.mobileSession:SendRPC("AddCommand", { cmdID = 1, menuParams = { parentID = 0, position = 0, menuName ="Commandpositive1" }, @@ -144,6 +114,14 @@ function Test:TestStep_Get_HeartBeat_Time() local time_prev = 0 local time_now = 0 + local eventHB = events.Event() + eventHB.level = 3 + eventHB.matches = function(_, data) + return data.frameType == 0 and + (data.serviceType == 0) and + (data.frameInfo == 0) --HeartBeat + end + self.mobileSession:ExpectEvent(eventHB, "Heartbeat") :ValidIf(function() print("HeartBeat received in "..atf_logger.formated_time(true)) @@ -173,18 +151,11 @@ function Test:TestStep_Get_HeartBeat_Time() end function Test:TestStep_Check_HB_Time() - -- Send request to bind ValidIf for HB time validation - self.mobileSession:SendRPC("UnregisterAppInterface", {}) - EXPECT_RESPONSE("UnregisterAppInterface", {success = true , resultCode = "SUCCESS"}) - :ValidIf(function() - if ( (HBTime_min < 3850) or (HBTime_max > 4150) ) then - print("Wrong HearBeat time! Expected: 4000ms, Actual: ["..HBTime_min.." ; "..HBTime_max.."]ms ") - return false - else - print(" HearBeat is in range ["..HBTime_min.." ; "..HBTime_max.."]ms ") - return true - end - end) + if ( (HBTime_min < 3850) or (HBTime_max > 4150) ) then + self:FailTestCase("Wrong HearBeat time! Expected: 4000ms, Actual: ["..HBTime_min.." ; "..HBTime_max.."]ms ") + else + print("HearBeat is in range ["..HBTime_min.." ; "..HBTime_max.."]ms ") + end end --[[ Postconditions ]] diff --git a/test_scripts/Policies/appID_Management/037_ATF_Register_App_Interface_Assign_Existing_Policies.lua b/test_scripts/Policies/appID_Management/037_ATF_Register_App_Interface_Assign_Existing_Policies.lua index c6c57c3f05..c8ae092178 100644 --- a/test_scripts/Policies/appID_Management/037_ATF_Register_App_Interface_Assign_Existing_Policies.lua +++ b/test_scripts/Policies/appID_Management/037_ATF_Register_App_Interface_Assign_Existing_Policies.lua @@ -66,6 +66,7 @@ function Test:RegisterNewApp() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = "ABC Application" }}) self.mobileSession2:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) self.mobileSession2:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE" }) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") end function Test:CheckPermissions() @@ -79,23 +80,7 @@ function Test:CheckPermissions() end function Test:UpdatePolicy() - local timeout_after_x_seconds = testCasesForPolicyTableSnapshot:get_data_from_Preloaded_PT("module_config.timeout_after_x_seconds") - local seconds_between_retries = {} - for i = 1, #testCasesForPolicyTableSnapshot.seconds_between_retries do - seconds_between_retries[i] = testCasesForPolicyTableSnapshot.seconds_between_retries[i].value - end - - EXPECT_HMICALL("BasicCommunication.PolicyUpdate", - { - file = "/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json", - timeout = timeout_after_x_seconds, - retry = seconds_between_retries - }) - :Do(function(_,data1) - self.hmiConnection:SendResponse(data1.id, data1.method, "SUCCESS", {}) - testCasesForPolicyAppIdManagament:updatePolicyTable(self, "files/jsons/Policies/appID_Management/ptu_01.json") - end) - --testCasesForPolicyAppIdManagament:updatePolicyTable(self, "files/jsons/Policies/appID_Management/ptu_01.json") + testCasesForPolicyAppIdManagament:updatePolicyTable(self, "files/jsons/Policies/appID_Management/ptu_01.json") end function Test:CheckPermissions() diff --git a/test_scripts/Policies/user_consent_of_Policies/188_ATF_HP_Device_Data_Section_Validation.lua b/test_scripts/Policies/user_consent_of_Policies/188_ATF_HP_Device_Data_Section_Validation.lua index 21dd9d24d0..7637d1dcd4 100644 --- a/test_scripts/Policies/user_consent_of_Policies/188_ATF_HP_Device_Data_Section_Validation.lua +++ b/test_scripts/Policies/user_consent_of_Policies/188_ATF_HP_Device_Data_Section_Validation.lua @@ -163,7 +163,6 @@ function Test:Precondition_Activate_App_Consent_Device_Make_PTU_Consent_Group() end) end) end) - EXPECT_NOTIFICATION("OnPermissionsChange", {}) end ) :Timeout(500) diff --git a/test_scripts/Policies/user_consent_of_Policies/207_ATF_HMILevel_before_data_consented.lua b/test_scripts/Policies/user_consent_of_Policies/207_ATF_HMILevel_before_data_consented.lua index e82272e6fa..17dcf32412 100644 --- a/test_scripts/Policies/user_consent_of_Policies/207_ATF_HMILevel_before_data_consented.lua +++ b/test_scripts/Policies/user_consent_of_Policies/207_ATF_HMILevel_before_data_consented.lua @@ -74,7 +74,7 @@ function Test:ActivateApp_on_unconsented_device() end) end end) - EXPECT_HMICALL("BasicCommunication.ActivateApp",{}) :Times(0) + EXPECT_HMICALL("BasicCommunication.ActivateApp",{ level = "NONE" }):Times(1) EXPECT_NOTIFICATION("OnHMIStatus", {}):Times(0) end From 2785ed3340cbeeddfd847902ee926554e1d8e11f Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 2 Mar 2018 11:44:02 +0200 Subject: [PATCH 330/681] Correct expectation function and common module for certificates --- .../4_5/Trigger_PTU_NO_Certificate/common.lua | 16 ++++------------ user_modules/sequences/actions.lua | 2 +- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua index aaced0218f..e4698b5e8a 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua @@ -10,24 +10,16 @@ local security = require("user_modules/sequences/security") local utils = require("user_modules/utils") --[[ Module ]] -local m = {} +local m = actions --- Proxies for the inherited objects -utils.inheritObjects(m, actions) -utils.inheritObjects(m, security) +m.frameInfo = security.frameInfo +m.delayedExp = utils.wait +m.readFile = utils.readFile function m.setForceProtectedServiceParam(pParamValue) m.setSDLIniParameter("ForceProtectedService", pParamValue) end -function m.delayedExp(pTimeOut) - utils.wait(pTimeOut) -end - -function m.readFile(pFilePath) - return utils.readFile(pFilePath) -end - function m.getAppID(pAppId) return m.getConfigAppParams(pAppId).appID end diff --git a/user_modules/sequences/actions.lua b/user_modules/sequences/actions.lua index 5be21e543c..23687cf56f 100644 --- a/user_modules/sequences/actions.lua +++ b/user_modules/sequences/actions.lua @@ -362,7 +362,7 @@ function test.hmiConnection:ExpectResponse(pId, ...) end reporter.AddMessage("EXPECT_HMIRESPONSE", { ["Id"] = data.id, ["Type"] = "EXPECTED_RESULT" }, arguments) reporter.AddMessage("EXPECT_HMIRESPONSE", { ["Id"] = data.id, ["Type"] = "AVAILABLE_RESULT" }, data.result) - return compareValues(arguments, data.result, "result") + return compareValues(arguments, data, "data") end) end ret.event = event From 554f9ef9aacd224b8cef3124a0a5709b0a79e935 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 14 Mar 2018 13:49:45 +0200 Subject: [PATCH 331/681] Remove defaulting of 2nd version of SDL protocol --- user_modules/shared_testcases/commonTestCases.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/user_modules/shared_testcases/commonTestCases.lua b/user_modules/shared_testcases/commonTestCases.lua index 20c61d34ab..d0094fa533 100644 --- a/user_modules/shared_testcases/commonTestCases.lua +++ b/user_modules/shared_testcases/commonTestCases.lua @@ -7,7 +7,6 @@ local commonTestCases = {} local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') -local policyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local mobile_session = require('mobile_session') local events = require('events') From 3aa173a20bf9a888ab64dd9de13ec86611fb1549 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 16 Mar 2018 09:38:08 +0200 Subject: [PATCH 332/681] Update Policy scripts regarding Device Id and Device Name calculation logic --- .../Policies/ATF_Preloaded_PT_validation.lua | 219 +++++++++--------- ...sponse_Notification_On_Registering_App.lua | 11 +- ...Assigned_Policy_After_App_Registration.lua | 11 +- .../003_ATF_HP_User_Consent_Yes.lua | 12 +- .../004_ATF_HP_User_Consent_NO.lua | 12 +- ...Id_policies_And_RequestType_Validation.lua | 14 +- ...6_ATF_Steal_focus_validation_false_PTU.lua | 9 +- ...007_ATF_StealFocus_validation_true_PTU.lua | 9 +- ...lt_policies_And_RequestType_Validation.lua | 5 +- .../009_ATF_Steal_Focus_Validation_False.lua | 4 +- ..._ATF_StealFocus_validation_true_app_id.lua | 4 +- .../011_ATF_KeepContext_Validation_false.lua | 4 +- .../012_ATF_KeepContext_Validation_true.lua | 4 +- ...tted_In_The_Policy_Table_Default_Group.lua | 7 +- ...t_Of_Parameters_Disallowed_By_Policies.lua | 7 +- ...ameters_Are_Not_Allowed_In_The_Request.lua | 7 +- ...t_Of_Parameters_Disallowed_By_Policies.lua | 7 +- ...ot-allowed_Parameters_By_Policies_Only.lua | 7 +- ...And_Not-allowed_By_Policies_Parameters.lua | 7 +- ...wed_Rpc_Is_Omitted_In_The_Policy_Table.lua | 6 +- ...vel_Is_Not_Listed_In_Assigned_Policies.lua | 7 +- ...fication_Is_Allowed_To_Be_Processed_In.lua | 7 +- ...ation_To_HMI_In_First_App_Registration.lua | 7 +- ...Default_Priority_Value_Assigned_To_App.lua | 5 +- ...f_Failed_Nickname_Validation_After_PTU.lua | 9 +- ...n_With_AppName_Not_Listed_In_NickNames.lua | 19 +- ...ame_Does_Not_Match_With_Nickname_In_PT.lua | 3 +- .../027_ATF_NickName_Case_Insensitivity.lua | 7 +- ...ation_Before_Duplicate_Name_Validation.lua | 13 +- .../029_ATF_OnPermissionsChange_After_PTU.lua | 5 +- ...030_ATF_Successful_Nickname_Validation.lua | 17 +- ..._external_consent_status_groups_struct.lua | 9 +- ..._external_consent_status_groups_struct.lua | 5 +- ...y_external_consent_entities_off_struct.lua | 2 - ...y_external_consent_entities_off_struct.lua | 2 - ...by_external_consent_entities_on_struct.lua | 2 - ...by_external_consent_entities_on_struct.lua | 2 - ...off_struct_with_invalid_type_of_params.lua | 2 - ..._on_struct_with_invalid_type_of_params.lua | 2 - ..._external_consent_status_groups_struct.lua | 11 +- ..._external_consent_status_groups_struct.lua | 11 +- ...y_external_consent_entities_off_struct.lua | 2 - ...y_external_consent_entities_off_struct.lua | 2 - ...by_external_consent_entities_on_struct.lua | 2 - ...by_external_consent_entities_on_struct.lua | 2 - ..._external_consent_status_groups_struct.lua | 2 - ..._external_consent_status_groups_struct.lua | 13 +- ...y_external_consent_entities_off_struct.lua | 2 - ...y_external_consent_entities_off_struct.lua | 2 - ...by_external_consent_entities_on_struct.lua | 2 - ...by_external_consent_entities_on_struct.lua | 2 - ...off_struct_with_invalid_type_of_params.lua | 2 - ..._on_struct_with_invalid_type_of_params.lua | 2 - ..._external_consent_status_groups_struct.lua | 9 +- ..._external_consent_status_groups_struct.lua | 5 +- ...y_external_consent_entities_off_struct.lua | 2 - ...y_external_consent_entities_off_struct.lua | 2 - ...by_external_consent_entities_on_struct.lua | 2 - ...by_external_consent_entities_on_struct.lua | 2 - ...off_struct_with_invalid_type_of_params.lua | 2 - ..._on_struct_with_invalid_type_of_params.lua | 2 - ...tities_omitted_data_consent_disallowed.lua | 5 +- ..._entities_omitted_user_consent_allowed.lua | 5 +- ...tities_omitted_user_consent_disallowed.lua | 5 +- ...tities_omitted_data_consent_disallowed.lua | 5 +- ..._entities_omitted_user_consent_allowed.lua | 5 +- ...tities_omitted_user_consent_disallowed.lua | 5 +- ..._entities_omitted_user_consent_omitted.lua | 5 +- ..._appID_all_ecs_in_bound_EntitySatus_ON.lua | 7 +- ...pID_all_ecs_upper_bound_EntitySatus_ON.lua | 8 +- ...th_appID_fake_param_cut_EntitySatus_ON.lua | 7 +- ...appID_all_ecs_in_bound_EntitySatus_OFF.lua | 7 +- ...ID_all_ecs_lower_bound_EntitySatus_OFF.lua | 7 +- ...ID_all_ecs_upper_bound_EntitySatus_OFF.lua | 7 +- ...h_appID_fake_param_cut_EntitySatus_OFF.lua | 7 +- ...fPermissions_with_appID_not_stored_ecs.lua | 7 +- ...ermissions_no_appID_stored_ecs_present.lua | 7 +- ...tofPermissions_no_appID_not_stored_ecs.lua | 7 +- ..._no_appID_no_app_registered_stored_ecs.lua | 7 +- ...appID_no_app_registered_not_stored_ecs.lua | 7 +- ...s_no_appID_app_unregistered_stored_ecs.lua | 7 +- ..._appID_app_unregistered_not_stored_ecs.lua | 7 +- ...sing_entity_type_OnAppPermissionChange.lua | 5 +- ...missing_entityID_OnAppPermissionChange.lua | 5 +- ...o_missing_status_OnAppPermissionChange.lua | 8 +- ...param_entityType_OnAppPermissionChange.lua | 5 +- ...d_param_entityID_OnAppPermissionChange.lua | 5 +- ...lid_param_status_OnAppPermissionChange.lua | 5 +- ...PermissionConsent_not_sent_when_no_PTU.lua | 7 +- ...ATF_P_Policies_Performance_Requirement.lua | 5 +- ...TF_PolicyTable_Certificate_EMPTY_value.lua | 9 +- ...NotListed_PT_DeviceConsented_SecondApp.lua | 9 +- ...tSuccessful_AppID_ListedPT_NewIgnCycle.lua | 11 +- .../123_ATF_PTU_DeviceConsent_from_User.lua | 7 +- .../124_ATF_User_requests_PTU.lua | 9 +- .../125_ATF_User_PressButton_HMI_PTU.lua | 9 +- ...usUpdate_UPDATE_NEEDED_new_PTU_request.lua | 7 +- .../127_ATF_PTS_Creation_rule.lua | 10 +- .../128_ATF_PTU_GetURLs.lua | 7 +- ...F_HMI_sends_GetURLs_one_app_registered.lua | 7 +- ...TF_HMI_sends_GetURLs_no_app_registered.lua | 7 +- .../131_ATF_PTS_storage_on_file_system.lua | 8 +- .../132_ATF_Timeout_to_wait_response_PTU.lua | 12 +- .../133_ATF_PTU_retry_timeout_definition.lua | 12 +- ...34_ATF_WiFi_one_application_registered.lua | 9 +- .../135_ATF_PM_sends_PTS_to_HMI.lua | 12 +- .../136_ATF_Define_urls_PTS_will_sent_hmi.lua | 9 +- ..._ATF_Sending_PTS_to_mobile_application.lua | 5 +- ...S_to_app_OnSystemRequest_appID_default.lua | 7 +- ...oliciesManager_changes_status_UPDATING.lua | 7 +- .../140_ATF_timeout_countdown_start.lua | 7 +- ...41_ATF_Got_PTU_from_mobile_application.lua | 7 +- ...esManager_changes_status_to_UP_TO_DATE.lua | 7 +- .../143_ATF_PTU_validation_rules.lua | 11 +- .../144_ATF_PTU_validation_failure.lua | 7 +- .../145_ATF_PTU_Merge_Into_LPT.lua | 6 +- ...Lvl_on_PTU_affected_in_FULL_or_LIMITED.lua | 4 +- ...able_Update_Trigger_After_N_Kilometers.lua | 5 +- ..._on_PTU_affected_in_BACKGROUND_or_NONE.lua | 4 +- ...licy_Table_Update_Trigger_After_N_Days.lua | 5 +- ...tifying_HMI_via_OnAppPermissionChanged.lua | 4 +- ...pply_PTU_and_OnPermissionChange_notify.lua | 6 +- ...TU_Merge_Of_Consumer_Friendly_Messages.lua | 7 +- ...PTU_Omit_Of_Consumer_Friendly_Messages.lua | 6 +- ...ot_From_Sync_After_Getting_The_Updates.lua | 6 +- ...anager_Changes_Status_To_UPDATE_NEEDED.lua | 9 +- .../156_ATF_PTU_OnStatusUpdate_Trigger.lua | 7 +- ...ies_Manager_Changes_Status_To_UPDATING.lua | 8 +- ...s_Manager_Changes_Status_To_UP_TO_DATE.lua | 6 +- ...plication_Taking_Part_In_Policy_Update.lua | 4 +- ...F_Default_Policy_For_The_App_After_PTU.lua | 5 +- ...igger_PTU_While_Another_Is_In_Progress.lua | 5 +- .../162_ATF_Policies_UTF-8_Encoding.lua | 6 +- ...egister_NewApp_not_exist_inLocalPT_PTU.lua | 4 +- ...r_NewApp_not_exist_inLocalPT_FinishPTU.lua | 4 +- ...t_exist_inLocalPT_start_PTU_for_NewApp.lua | 4 +- ...tURLs_one_app_registered_urls_3default.lua | 7 +- ...egistered_urls_3default_not_registered.lua | 7 +- ...pp_registered_urls_3default_registered.lua | 7 +- ..._HMILvl_on_PTU_affected_app_in_LIMITED.lua | 4 +- ...vi_App_Registration_And_No_Certificate.lua | 5 +- ...ATF_Policies_Memory_Allocation_For_PTU.lua | 9 +- ...TF_PTU_request_after_N_ignition_cycles.lua | 4 +- ...unctionality_allowed_false_with_device.lua | 12 +- ...tionality_allowed_false_without_device.lua | 7 +- ...ctionality_allowed_true_without_device.lua | 6 +- ...unctionality_allowed_false_with_device.lua | 17 +- ...Functionality_allowed_true_with_device.lua | 13 +- ...F_OnAppPermissionConsent_without_appID.lua | 10 +- ..._ATF_OnAppPermissionConsent_with_appID.lua | 10 +- ..._language_section_is_absent_in_LocalPT.lua | 6 +- ...yMessage_Language_not_found_in_localPT.lua | 3 - ...F_GetUserFriendlyMessage_with_Language.lua | 3 - ...des_data_consent_prompt_on_HMI_request.lua | 9 +- ...ATF_GetListOfPermissions_without_appID.lua | 9 +- ...85_ATF_GetListOfPermissions_with_appID.lua | 9 +- ...6_ATF_OnPolicyUpdate_initiation_of_PTU.lua | 9 +- ...ATF_Get_Status_Update_Request_from_HMI.lua | 7 +- ...ation_rules_request_type_array_omitted.lua | 5 +- ...quest_type_array_has_one_invalid_value.lua | 5 +- ...pe_array_has_only_one_value_is_invalid.lua | 5 +- ...counts_update_count_sync_out_of_memory.lua | 1 - ...or_counts_update_count_of_sync_reboots.lua | 2 - ...counts_update_count_of_iap_buffer_full.lua | 1 - ...rror_counts_update_minutes_in_hmi_none.lua | 5 +- ...r_counts_update_minutes_in_hmi_limited.lua | 4 +- ...rror_counts_update_minutes_in_hmi_full.lua | 4 +- ...ounts_update_minutes_in_hmi_background.lua | 5 +- ...tion_rules_for_omited_parameters_exist.lua | 1 - ...lidation_rules_for_required_parameters.lua | 3 - ...loaded_pt_exists_with_read_permissions.lua | 4 - .../243_ATF_preloaded_pt_exists.lua | 3 - ...oaded_pt_parameter_trigger_in_local_pt.lua | 9 +- ...requesttype_parameters_all_are_invalid.lua | 2 - ...al_pt_consumer_frendly_messages_exists.lua | 1 - ...onsumer_frendly_messages_do_not_exists.lua | 1 - ...nsumer_frendly_messages_exists_in_both.lua | 1 - ...reloaded_pt_into_local_pt_app_policies.lua | 1 - ...o_local_pt_functional_groupings_exists.lua | 3 +- ...pt_functional_groupings_does_not_exist.lua | 1 - ...t_into_local_pt_usage_and_error_counts.lua | 4 - ...preloaded_pt_into_local_pt_device_data.lua | 10 +- ...erge_preloaded_pt_into_local_pt_launch.lua | 4 - ..._into_local_pt_launch_does_not_changed.lua | 6 +- ...eloaded_pt_into_local_pt_module_config.lua | 3 - .../258_ATF_pt_snapshot_path_is_correct.lua | 6 +- .../259_ATF_pt_snapshot_path_is_incorrect.lua | 1 - ...ocal_pt_from_preloaded_pt_master_reset.lua | 3 - ...lidation_rules_for_optional_parameters.lua | 11 +- ...alidation_rules_for_omitted_parameters.lua | 11 +- ...lidation_rules_for_required_parameters.lua | 11 +- .../264_ATF_pt_snapshot_creation_rule.lua | 9 +- ...ATF_pt_snapshot_storage_on_file_system.lua | 9 +- ...idation_rules_optional_parameters_type.lua | 5 +- ...idation_rules_required_parameters_type.lua | 5 +- ...ATF_pt_update_validation_rules_general.lua | 1 - ...dation_rules_consumer_friendly_message.lua | 7 +- ..._Validate_default_hmi_default_policies.lua | 9 +- ...e_preconsented_groups_default_policies.lua | 9 +- ...2_ATF_Validate_groups_default_policies.lua | 6 +- ...TF_Validate_default_hmi_appId_policies.lua | 7 +- ...F_Validate_appID_and_steal_focus_false.lua | 6 +- ...TF_Validate_appID_and_steal_focus_true.lua | 6 +- ...F_Validate_appID_and_keep_context_true.lua | 6 +- ..._Validate_appID_and_keep_context_false.lua | 6 +- ...278_ATF_Validate_groups_appID_policies.lua | 7 +- ...TF_Store_vin_from_GetVehicleData_in_PT.lua | 1 - ...ition_cycles_since_last_exchange_in_PT.lua | 4 +- ...ition_cycles_since_last_exchange_in_PT.lua | 1 - ...PT_Exchanged_X_Days_After_Epoch_In_PTS.lua | 7 +- ...Store_pt_exchanged_at_odometer_x_in_PT.lua | 4 +- .../284_ATF_Store_wers_country_code_in_PT.lua | 1 - .../285_ATF_Store_language_in_PT.lua | 1 - ...ATF_RAI_ccpu_version_via_GetSystemInfo.lua | 1 - ...ATF_Validate_appHMIType_appID_policies.lua | 6 +- ...ray_preconsented_groups_preDataConsent.lua | 1 - ...lue_preconsented_groups_preDataConsent.lua | 1 - ...nal_preconsented_groups_preDataConsent.lua | 1 - ...lid_preconsented_groups_preDataConsent.lua | 1 - ...2_ATF_Valid_default_hmi_preDataConsent.lua | 1 - ...lidate_default_priority_preDataConsent.lua | 9 +- ...ate_nondefault_priority_preDataConsent.lua | 8 +- ...te_preDataConsent_and_stealFocus_false.lua | 5 +- ...ate_preDataConsent_and_stealFocus_true.lua | 5 +- ...e_preDataConsent_and_keepContext_false.lua | 5 +- ...te_preDataConsent_and_keepContext_true.lua | 5 +- ...299_ATF_Memory_Kb_Constraints_Ignoring.lua | 5 +- ...Applying_Heart_Beat_Timeout_Ms_From_PT.lua | 4 - ...s_update_app_registration_language_vui.lua | 5 +- ...plying_Heart_Beat_Timeout_Ms_After_PTU.lua | 9 +- ...TF_HP_Usage_And_Error_Counts_For_AppID.lua | 6 +- ...HP_Validation_Count_Of_User_Selections.lua | 4 +- ...nt_of_run_attempts_while_revoked_in_PT.lua | 4 +- ..._preDataConsent_RequestType_disallowed.lua | 3 +- ...TF_Check_app_registration_language_gui.lua | 2 - ...ATF_Check_count_of_rejected_rpcs_calls.lua | 3 - ...havior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua | 4 +- ...bad_behavior_too_many_pending_requests.lua | 5 +- ...als_for_bad_behavior_too_many_requests.lua | 4 +- ...F_Check_count_of_rpcs_sent_in_hmi_none.lua | 7 +- ...314_ATF_Check_count_of_user_selections.lua | 1 - ...egister_App_Interface_App_Unauthorized.lua | 7 +- ...terface_Successful_Nickname_Validation.lua | 7 +- ...Interface_Order_Of_Nickname_Validation.lua | 7 +- ..._ATF_Register_App_Interface_Disallowed.lua | 7 +- ...nterface_Case-insensitivity_Of_AppName.lua | 9 +- ...036_ATF_Change_Registration_Disallowed.lua | 7 +- ...App_Interface_Assign_Existing_Policies.lua | 7 +- ...onsent_Assign_pre_DataConsent_Policies.lua | 5 +- ...h_Data_Consent_Assign_Default_Policies.lua | 5 +- ..._Interface_Case-insensitivity_Of_AppId.lua | 7 +- ...OnAppPermissionChanged_appRevoked_true.lua | 5 +- ...RAI_with_NULL_policies_RPCs_DISALLOWED.lua | 5 +- ..._Status_Appid_Gets_Null_In_Case_Of_PTU.lua | 5 +- ...MI_Status_Value_Of_AppId_In_PT_Is_Null.lua | 5 +- ...tion_Which_Appid_Does_Not_Exist_In_LPT.lua | 6 +- ..._Application_Which_Appid_Exists_In_LPT.lua | 4 +- ..._DEXTENDED_POLICY_EXTERNAL_PROPRIETARY.lua | 9 +- ...uild_Flag_DEXTENDED_POLICY_PROPRIETARY.lua | 3 +- ...rigger_PTU_failed_previous_IGN_ON_HTTP.lua | 2 - ...Update_Trigger_After_N_Kilometers_HTTP.lua | 5 +- .../052_ATF_PTU_Trigger_IGN_Cycles_HTTP.lua | 2 - ...Table_Update_Trigger_After_N_Days_HTTP.lua | 2 - ...PTU_UPDATE_NEEDED_new_PTU_Request_HTTP.lua | 4 - ...TF_Policy_Table_Snapshot_Creation_HTTP.lua | 4 - ...Several_Apps_Different_HMI_Levels_HTTP.lua | 1 - ...57_ATF_PTS_Define_URL_to_send_PTS_HTTP.lua | 4 - ...I_sends_GetURLs_no_app_registered_HTTP.lua | 7 +- ..._sends_GetURLs_one_app_registered_HTTP.lua | 4 - ..._ATF_Timeout_to_wait_response_PTU_HTTP.lua | 2 - ...Sending_PTS_to_Mobile_Application_HTTP.lua | 4 - ...eout_Countdown_Start_PTU_Response_HTTP.lua | 4 - ...iciesManager_Sets_Status_UPDATING_HTTP.lua | 4 - ...eived_PTU_From_Mobile_Application_HTTP.lua | 1 - .../066_ATF_PTU_Validation_Failure_HTTP.lua | 3 +- ...Manager_Sets_Status_to_UP_TO_DATE_HTTP.lua | 4 - .../068_ATF_PTU_Merge_Into_Local_PT_HTTP.lua | 10 +- ...Local_PT_ConsumerFriendlyMessages_HTTP.lua | 8 +- ..._ConsumerFriendlyMessages_Omitted_HTTP.lua | 27 +-- ...PTU_Local_PT_Start_Retry_Sequence_HTTP.lua | 3 - ..._PTU_PM_Sets_Status_UPDATE_NEEDED_HTTP.lua | 2 - ...equence_Retry_Timeout_Computation_HTTP.lua | 2 - ..._Restarting_Policy_Table_Exchange_HTTP.lua | 78 +++---- ...Sequence_Retry_Timeout_Expiration_HTTP.lua | 2 - ...PermissionChange_Notification_App_HTTP.lua | 4 +- ...PermissionChange_Notification_HMI_HTTP.lua | 1 - ..._Level_Affected_Apps_FULL_LIMITED_HTTP.lua | 1 - ...vel_Affected_Apps_NONE_BACKGROUND_HTTP.lua | 1 - ...atsusUpdate_Trigger_UPDATE_NEEDED_HTTP.lua | 3 - ..._OnStatsusUpdate_Trigger_UPDATING_HTTP.lua | 3 - ...nStatsusUpdate_Trigger_UP_TO_DATE_HTTP.lua | 6 +- .../083_ATF_PTU_UTF8_Encoding_Check_HTTP.lua | 3 - ...ault_Policy_For_The_App_After_PTU_HTTP.lua | 1 - ...PTU_In_Progress_New_App_Registers_HTTP.lua | 2 - .../086_ATF_PTU_Merging_wtih_LPT_HTTP.lua | 4 - ...quence_AppRegistered_PTU_Progress_HTTP.lua | 9 +- ...eivedPolicyUpdate_from_HMI_PROPRIETARY.lua | 3 +- ...nd_GetURLs_Request_fromHMI_PROPRIETARY.lua | 8 +- ..._ATF_For_PTU_use_consented_device_only.lua | 14 +- ...Check_STATUS_UPDATE_NEEDED_PROPRIETARY.lua | 8 +- ...ck_STATUS_vai_USER_Request_PROPRIETARY.lua | 5 +- ...ATF_OnStatusUpdate_Trigger_PROPRIETARY.lua | 2 +- .../094_ATF_PTS_creation_rule_PROPRIETARY.lua | 7 +- ..._exist_inLocalPT_FinishPTU_PROPRIETARY.lua | 1 - ...I_In_Case_PTU_Is_Triggered_PROPRIETARY.lua | 2 - ...gh_The_URLs_During_Retry_Sequence_HTTP.lua | 3 - ...cessful_Even_After_Retry_Strategy_HTTP.lua | 2 - ...I_In_Case_PTU_Is_Triggered_PROPRIETARY.lua | 3 - ..._Apps_Different_HMI_Levels_PROPRIETARY.lua | 2 +- ...101_ATF_SDL_Build_EXTENDED_POLICY_HTTP.lua | 2 - ...TF_Timeout_countdown_start_PROPRIETARY.lua | 4 - ..._Timeout_wait_response_PTU_PROPRIETARY.lua | 4 - ...sfer_OnSystemRequest_toApp_PROPRIETARY.lua | 4 - ...EDED_after_timeout_expired_PROPRIETARY.lua | 2 - ...changes_status_to_UPDATING_PROPRIETARY.lua | 2 +- ...egy_during_previous_IGN_ON_PROPRIETARY.lua | 2 - .../108_ATF_PTU_Trigger_days_PROPRIETARY.lua | 4 +- ...ATF_PTU_Trigger_IGN_cycles_PROPRIETARY.lua | 2 - ...ATF_PTU_Trigger_kilometers_PROPRIETARY.lua | 5 +- ...F_Start_PTU_retry_sequence_PROPRIETARY.lua | 1 - ...temRequest_from_app_to_HMI_PROPRIETARY.lua | 4 - ...temRequest_from_HMI_to_app_PROPRIETARY.lua | 4 - ..._exist_inLocalPT_FinishPTU_PROPRIETARY.lua | 3 +- ...calPT_start_PTU_for_NewApp_PROPRIETARY.lua | 1 - .../116_ATF_DEXTENDED_POLICY_OFF_HTTP.lua | 4 - .../117_ATF_DEXTENDED_POLICY_No_Flag_HTTP.lua | 4 - ...quest_PTU_Trigger_App_Excluded_PT_HTTP.lua | 4 - ..._ATF_HP_Device_Data_Section_Validation.lua | 5 +- .../189_ATF_isAppPermissionsRevoked_true.lua | 6 +- .../190_ATF_Device_treated_as_consented.lua | 3 - ...ATF_UpdateDeviceList_on_device_connect.lua | 12 +- ...2_ATF_isPermissionsConsentNeeded_false.lua | 4 - ...93_ATF_isPermissionsConsentNeeded_true.lua | 6 +- .../194_ATF_ActivateApp_isSDLAllowed_true.lua | 5 +- ...195_ATF_ActivateApp_isSDLAllowed_false.lua | 12 +- ...TF_UpdateDeviceList_isSDLAllowed_false.lua | 11 +- .../197_ATF_ActivateApp_isSDLAllowed_true.lua | 5 +- ...GetUserFriendlyMessage_language_missed.lua | 8 +- ...9_ATF_appPermissionsConsentNeeded_true.lua | 7 +- .../200_ATF_Data_consent_prompt.lua | 10 +- .../201_ATF_User_consents_permissions.lua | 10 +- .../202_ATF_No_OnSDLConsentNeeded.lua | 1 - .../203_ATF_Master_reset.lua | 10 +- .../204_ATF_App_group_order_preconsented.lua | 8 +- .../205_ATF_Consent_timestamp.lua | 9 +- ...TF_Permissions_before_device_consented.lua | 13 +- ...207_ATF_HMILevel_before_data_consented.lua | 12 +- ...08_ATF_No_consent_for_default_policies.lua | 6 +- ...F_Device_user_disallowed_after_consent.lua | 10 +- ...TF_User_consent_initing_after_PTU_FULL.lua | 8 +- ...User_consent_initing_after_PTU_LIMITED.lua | 8 +- ...212_ATF_Data_consent_device_not_in_LPT.lua | 10 +- ...13_ATF_No_user_consent_prompt_in_group.lua | 8 +- .../214_ATF_User_consent_prompt_persists.lua | 11 +- .../215_ATF_User_clears_all_applications.lua | 13 +- .../216_ATF_User_consent_storage_in_LPT.lua | 13 +- ...nsent_status_allowed_on_device_connect.lua | 8 +- ...t_status_not_allowed_on_device_connect.lua | 14 +- ...entifier_creation_upon_connect_no_apps.lua | 8 +- ...tifier_creation_upon_connect_with_apps.lua | 16 +- .../221_ATF_Factory_reset.lua | 12 +- .../222_ATF_Device_HashID_In_LPT.lua | 10 +- user_modules/common_steps.lua | 3 +- user_modules/shared_testcases/commonSteps.lua | 5 +- .../testCasesForExternalUCS.lua | 61 ++--- .../testCasesForPolicyTable.lua | 12 +- 366 files changed, 868 insertions(+), 1600 deletions(-) diff --git a/test_scripts/Policies/ATF_Preloaded_PT_validation.lua b/test_scripts/Policies/ATF_Preloaded_PT_validation.lua index cea5bef280..0b19caf1d3 100644 --- a/test_scripts/Policies/ATF_Preloaded_PT_validation.lua +++ b/test_scripts/Policies/ATF_Preloaded_PT_validation.lua @@ -23,7 +23,7 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local SDLConfig = require('user_modules/shared_testcases/SmartDeviceLinkConfigurations') - +local utils = require ('user_modules/utils') --------------------------------------------------------------------------------------------- ------------------------------------Common Variables----------------------------------------- --------------------------------------------------------------------------------------------- @@ -31,8 +31,7 @@ local SDLConfig = require('user_modules/shared_testcases/SmartDeviceLinkConfigur --Set 2 protocol as default for script: config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" -local storagePath = config.pathToSDL .. SDLConfig:GetValue("AppStorageFolder") .. "/" .. tostring(config.application1.registerAppInterfaceParams.appID .. "_" .. tostring(config.deviceMAC) .. "/") +local storagePath = config.pathToSDL .. SDLConfig:GetValue("AppStorageFolder") .. "/" .. tostring(config.application1.registerAppInterfaceParams.appID .. "_" .. tostring(utils.getDeviceMAC()) .. "/") --------------------------------------------------------------------------------------------- -------------------------------------Common functions----------------------------------------- @@ -65,7 +64,7 @@ local function WaitForStopSDL(self) if status == SDL.RUNNING then self:FailTestCase("SDL didn't finish correctly") StopSDL() - else + else userPrint(34, "After correct sdl_preloaded_pt.json restored, SDL stops successfully") end end @@ -107,14 +106,14 @@ commonSteps:ActivationApp() --------------------------------------------------------------------------------------------- --Start Positive cases check. -- Start positive case1. - --Description: PTU of registered App is performed using correct file. + --Description: PTU of registered App is performed using correct file. --Verification criteria: Policy update is successfull. - + commonFunctions:newTestCasesGroup("TC01_Case when for PTU is used correct file") - - + + function Test:PTUSuccessIfPTWithDeviceAndPreDataConsent() - + local CorIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", { fileName = "PolicyTableUpdate", @@ -122,14 +121,14 @@ commonSteps:ActivationApp() appID = iappID }, "files/ptu_general.json") - + local systemRequestId --hmi side: expect SystemRequest request EXPECT_HMICALL("BasicCommunication.SystemRequest") :Do(function(_,data) systemRequestId = data.id --print("BasicCommunication.SystemRequest is received") - + --hmi side: sending BasicCommunication.OnSystemRequest request to SDL self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { @@ -140,14 +139,14 @@ commonSteps:ActivationApp() --hmi side: sending SystemRequest response self.hmiConnection:SendResponse(systemRequestId,"BasicCommunication.SystemRequest", "SUCCESS", {}) end - + RUN_AFTER(to_run, 500) end) --hmi side: expect SDL.OnStatusUpdate EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate") :ValidIf(function(exp,data) - if + if exp.occurences == 1 and data.params.status == "UP_TO_DATE" then return true @@ -165,8 +164,8 @@ commonSteps:ActivationApp() exp.occurences == 3) and data.params.status == "UP_TO_DATE" then return true - else - if + else + if exp.occurences == 1 then print ("\27[31m SDL.OnStatusUpdate came with wrong values. Expected in first occurrences status 'UP_TO_DATE' or 'UPDATING', 'UPDATE_NEEDED', got '" .. tostring(data.params.status) .. "' \27[0m") elseif exp.occurences == 2 then @@ -179,17 +178,17 @@ commonSteps:ActivationApp() end end) :Times(Between(1,3)) - + --mobile side: expect SystemRequest response EXPECT_RESPONSE(CorIdSystemRequest, { success = true, resultCode = "SUCCESS"}) :Do(function(_,data) --hmi side: sending SDL.GetUserFriendlyMessage request to SDL local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"StatusUpToDate"}}) - + --hmi side: expect SDL.GetUserFriendlyMessage response - EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage", messages = {{messageCode = "StatusUpToDate"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage", messages = {{messageCode = "StatusUpToDate"}}}}) end) - + end -- End Positive case1. --End Positive cases check. @@ -202,7 +201,7 @@ commonSteps:ActivationApp() ------------------------------------------------------------------------------------------------------- -- Start Negative case1. - --Description:SDL starts with valid preloaded_pt. PTU of registered App is performed with omitted "device" section. + --Description:SDL starts with valid preloaded_pt. PTU of registered App is performed with omitted "device" section. --Verification criteria: SDL fails validation of PTU file, policy update is not successfull. commonFunctions:newTestCasesGroup("TC02_Case when in PTU file device section omitted:") @@ -216,13 +215,13 @@ commonSteps:ActivationApp() appID = iappID }, "files/PTU_DeviceSectionMissed.json") - + local systemRequestId --hmi side: expect SystemRequest request EXPECT_HMICALL("BasicCommunication.SystemRequest") :Do(function(_,data) systemRequestId = data.id - + --hmi side: sending BasicCommunication.OnSystemRequest request to SDL self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { @@ -233,14 +232,14 @@ commonSteps:ActivationApp() --hmi side: sending SystemRequest response self.hmiConnection:SendResponse(systemRequestId,"BasicCommunication.SystemRequest", "SUCCESS", {}) end - + RUN_AFTER(to_run, 500) end) --hmi side: expect SDL.OnStatusUpdate EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATE_NEEDED"}) :ValidIf(function(exp,data) - if + if exp.occurences == 1 and data.params.status == "UPDATE_NEEDED" then print ("\27[31m SDL.OnStatusUpdate came with wrong values. PTU file validation failed. Exchange wasn't successful") @@ -256,20 +255,20 @@ commonSteps:ActivationApp() print ("\27[31m SDL.OnStatusUpdate came with wrong values. Exchange should not be successful.Expected in second occurrences status 'UPDATE_NEEDED', got '" .. tostring(data.params.status) .. "' \27[0m") return false end - + end) :Times(Between(1,2)) - + --mobile side: expect SystemRequest response EXPECT_RESPONSE(CorIdSystemRequest, { success = true, resultCode = "SUCCESS"}) :Times(0) - + end -- End Negative case1. ------------------------------------------- -- Start Negative case2. - --Description:SDL starts with valid preloaded_pt. PTU of registered App is performed with incorrect "device" section - uppercase. + --Description:SDL starts with valid preloaded_pt. PTU of registered App is performed with incorrect "device" section - uppercase. --Verification criteria: SDL fails validation of PTU file, policy update is not successfull. commonFunctions:newTestCasesGroup("TC03_Case when in PTU file device section incorrect:") @@ -283,13 +282,13 @@ commonSteps:ActivationApp() appID = iappID }, "files/PTU_DeviceSectionUppercase.json") - + local systemRequestId --hmi side: expect SystemRequest request EXPECT_HMICALL("BasicCommunication.SystemRequest") :Do(function(_,data) systemRequestId = data.id - + --hmi side: sending BasicCommunication.OnSystemRequest request to SDL self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { @@ -300,14 +299,14 @@ commonSteps:ActivationApp() --hmi side: sending SystemRequest response self.hmiConnection:SendResponse(systemRequestId,"BasicCommunication.SystemRequest", "SUCCESS", {}) end - + RUN_AFTER(to_run, 500) end) --hmi side: expect SDL.OnStatusUpdate EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATE_NEEDED"}) :ValidIf(function(exp,data) - if + if exp.occurences == 1 and data.params.status == "UPDATE_NEEDED" then print ("\27[31m SDL.OnStatusUpdate came with wrong values. PTU file validation failed. Exchange wasn't successful") @@ -323,22 +322,22 @@ commonSteps:ActivationApp() print ("\27[31m SDL.OnStatusUpdate came with wrong values. Exchange should not be successful.Expected in second occurrences status 'UPDATE_NEEDED', got '" .. tostring(data.params.status) .. "' \27[0m") return false end - + end) :Times(Between(1,2)) - + --mobile side: expect SystemRequest response EXPECT_RESPONSE(CorIdSystemRequest, { success = true, resultCode = "SUCCESS"}) :Times(0) - + end -- End Negative case2. ------------------------------------------- -- Start Negative case3. - --Description:SDL starts with valid preloaded_pt. PTU of registered app is performed with omitted "pre_DataConsent" section. - --Verification criteria: SDL fails validation of PTU file, policy update is not successfull. - + --Description:SDL starts with valid preloaded_pt. PTU of registered app is performed with omitted "pre_DataConsent" section. + --Verification criteria: SDL fails validation of PTU file, policy update is not successfull. + commonFunctions:newTestCasesGroup("TC04_Case when in PTU file pre_DataConsent section omitted:") function Test:PTUFailNoPredataSection() @@ -350,13 +349,13 @@ commonSteps:ActivationApp() appID = iappID }, "files/PTU_PreDataConsentMissed.json") - + local systemRequestId --hmi side: expect SystemRequest request EXPECT_HMICALL("BasicCommunication.SystemRequest") :Do(function(_,data) systemRequestId = data.id - + --hmi side: sending BasicCommunication.OnSystemRequest request to SDL self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { @@ -367,14 +366,14 @@ commonSteps:ActivationApp() --hmi side: sending SystemRequest response self.hmiConnection:SendResponse(systemRequestId,"BasicCommunication.SystemRequest", "SUCCESS", {}) end - + RUN_AFTER(to_run, 500) end) --hmi side: expect SDL.OnStatusUpdate EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATE_NEEDED"}) :ValidIf(function(exp,data) - if + if exp.occurences == 1 and data.params.status == "UPDATE_NEEDED" then print ("\27[31m SDL.OnStatusUpdate came with wrong values. PTU file validation failed. Exchange wasn't successful") @@ -390,21 +389,21 @@ commonSteps:ActivationApp() print ("\27[31m SDL.OnStatusUpdate came with wrong values. Exchange should not be successful.Expected in second occurrences status 'UPDATE_NEEDED', got '" .. tostring(data.params.status) .. "' \27[0m") return false end - + end) :Times(Between(1,2)) - + --mobile side: expect SystemRequest response EXPECT_RESPONSE(CorIdSystemRequest, { success = true, resultCode = "SUCCESS"}) :Times(0) - + end -- End Negative case3. ------------------------------------------- -- Start Negative case4. - --Description:SDL starts with valid preloaded_pt. PTU of registered App is performed with incorrect "pre_DataConsent" section - uppercase. + --Description:SDL starts with valid preloaded_pt. PTU of registered App is performed with incorrect "pre_DataConsent" section - uppercase. --Verification criteria: SDL fails validation of PTU file, policy update is not successfull. commonFunctions:newTestCasesGroup("TC05_Case when in PTU file pre_DataConsent section incorrect:") @@ -418,13 +417,13 @@ commonSteps:ActivationApp() appID = iappID }, "files/PTU_PreDataSectionUppercase.json") - + local systemRequestId --hmi side: expect SystemRequest request EXPECT_HMICALL("BasicCommunication.SystemRequest") :Do(function(_,data) systemRequestId = data.id - + --hmi side: sending BasicCommunication.OnSystemRequest request to SDL self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { @@ -435,14 +434,14 @@ commonSteps:ActivationApp() --hmi side: sending SystemRequest response self.hmiConnection:SendResponse(systemRequestId,"BasicCommunication.SystemRequest", "SUCCESS", {}) end - + RUN_AFTER(to_run, 500) end) --hmi side: expect SDL.OnStatusUpdate EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATE_NEEDED"}) :ValidIf(function(exp,data) - if + if exp.occurences == 1 and data.params.status == "UPDATE_NEEDED" then print ("\27[31m SDL.OnStatusUpdate came with wrong values. PTU file validation failed. Exchange wasn't successful") @@ -458,21 +457,21 @@ commonSteps:ActivationApp() print ("\27[31m SDL.OnStatusUpdate came with wrong values. Exchange should not be successful.Expected in second occurrences status 'UPDATE_NEEDED', got '" .. tostring(data.params.status) .. "' \27[0m") return false end - + end) :Times(Between(1,2)) - + --mobile side: expect SystemRequest response EXPECT_RESPONSE(CorIdSystemRequest, { success = true, resultCode = "SUCCESS"}) :Times(0) - + end -- End Negative case4. ------------------------------------------- -- Start Negative case5. - --Description:SDL starts with valid preloaded_pt. PTU of registered app is performed with omitted "device" and "pre_DataConsent" sections. - --Verification criteria: SDL fails validation of PTU file, policy update is not successfull. + --Description:SDL starts with valid preloaded_pt. PTU of registered app is performed with omitted "device" and "pre_DataConsent" sections. + --Verification criteria: SDL fails validation of PTU file, policy update is not successfull. commonFunctions:newTestCasesGroup("TC06_Case when in PTU file device and pre_DataConsent sections omitted:") @@ -485,13 +484,13 @@ commonSteps:ActivationApp() appID = iappID }, "files/PTU_DeviceAndPreDataMissed.json") - + local systemRequestId --hmi side: expect SystemRequest request EXPECT_HMICALL("BasicCommunication.SystemRequest") :Do(function(_,data) systemRequestId = data.id - + --hmi side: sending BasicCommunication.OnSystemRequest request to SDL self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { @@ -502,14 +501,14 @@ commonSteps:ActivationApp() --hmi side: sending SystemRequest response self.hmiConnection:SendResponse(systemRequestId,"BasicCommunication.SystemRequest", "SUCCESS", {}) end - + RUN_AFTER(to_run, 500) end) --hmi side: expect SDL.OnStatusUpdate EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATE_NEEDED"}) :ValidIf(function(exp,data) - if + if exp.occurences == 1 and data.params.status == "UPDATE_NEEDED" then print ("\27[31m SDL.OnStatusUpdate came with wrong values. PTU file validation failed. Exchange wasn't successful") @@ -525,20 +524,20 @@ commonSteps:ActivationApp() print ("\27[31m SDL.OnStatusUpdate came with wrong values. Exchange should not be successful.Expected in second occurrences status 'UPDATE_NEEDED', got '" .. tostring(data.params.status) .. "' \27[0m") return false end - + end) :Times(Between(1,2)) - + --mobile side: expect SystemRequest response EXPECT_RESPONSE(CorIdSystemRequest, { success = true, resultCode = "SUCCESS"}) :Times(0) - + end -- End Negative case5. ------------------------------------------- -- Start Negative case6. - --Description:SDL starts with valid preloaded_pt. PTU of registered App is performed with incorrect "device" and "pre_DataConsent" sections - uppercase. + --Description:SDL starts with valid preloaded_pt. PTU of registered App is performed with incorrect "device" and "pre_DataConsent" sections - uppercase. --Verification criteria: SDL fails validation of PTU file, policy update is not successfull. commonFunctions:newTestCasesGroup("TC07_Case when in PTU device & pre_DataConsent sections incorrect:") @@ -552,13 +551,13 @@ commonSteps:ActivationApp() appID = iappID }, "files/PTU_DeviceAndPreDataUppercase.json") - + local systemRequestId --hmi side: expect SystemRequest request EXPECT_HMICALL("BasicCommunication.SystemRequest") :Do(function(_,data) systemRequestId = data.id - + --hmi side: sending BasicCommunication.OnSystemRequest request to SDL self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { @@ -569,14 +568,14 @@ commonSteps:ActivationApp() --hmi side: sending SystemRequest response self.hmiConnection:SendResponse(systemRequestId,"BasicCommunication.SystemRequest", "SUCCESS", {}) end - + RUN_AFTER(to_run, 500) end) --hmi side: expect SDL.OnStatusUpdate EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATE_NEEDED"}) :ValidIf(function(exp,data) - if + if exp.occurences == 1 and data.params.status == "UPDATE_NEEDED" then print ("\27[31m SDL.OnStatusUpdate came with wrong values. PTU file validation failed. Exchange wasn't successful") @@ -592,20 +591,20 @@ commonSteps:ActivationApp() print ("\27[31m SDL.OnStatusUpdate came with wrong values. Exchange should not be successful.Expected in second occurrences status 'UPDATE_NEEDED', got '" .. tostring(data.params.status) .. "' \27[0m") return false end - + end) :Times(Between(1,2)) - + --mobile side: expect SystemRequest response EXPECT_RESPONSE(CorIdSystemRequest, { success = true, resultCode = "SUCCESS"}) :Times(0) - + end -- End Negative case6. ------------------------------------------------------------------------------------------------------ ---"Device" and "pre_DataConsent" section are omitted in sdl_preloaded_pt.json file. +--"Device" and "pre_DataConsent" section are omitted in sdl_preloaded_pt.json file. ------------------------------------------------------------------------------------------------------ -- Start Negative case7. @@ -629,20 +628,20 @@ commonSteps:ActivationApp() file:close() local json = require("modules/json") - + local data = json.decode(json_data) - if data.policy_table.app_policies and + if data.policy_table.app_policies and data.policy_table.app_policies["device"] ~= nil then - data.policy_table.app_policies["device"] = nil + data.policy_table.app_policies["device"] = nil end - + data = json.encode(data) file = io.open(pathToFile, "w") file:write(data) file:close() end - + function Test:IgnitionOnWithEditedPT() StartSDL(config.pathToSDL, config.ExitOnCrash) userPrint(34, "After IGNON SDL stops since preloaded not valid(see above message)") @@ -658,7 +657,7 @@ commonSteps:ActivationApp() - function Test:StartSDLWithDeviceInPT() + function Test:StartSDLWithDeviceInPT() StartSDL(config.pathToSDL, config.ExitOnCrash) userPrint(34, "After correct sdl_preloaded_pt.json restored, SDL starts successfully") end @@ -688,26 +687,26 @@ commonSteps:ActivationApp() file:close() local json = require("modules/json") - + local data = json.decode(json_data) - if data.policy_table.app_policies and + if data.policy_table.app_policies and data.policy_table.app_policies["device"] ~= nil then - data.policy_table.app_policies["device"] = data.policy_table.app_policies["Device"] + data.policy_table.app_policies["device"] = data.policy_table.app_policies["Device"] end - + data = json.encode(data) file = io.open(pathToFile, "w") file:write(data) file:close() end - + function Test:IgnitionOnWithEditedPT() StartSDL(config.pathToSDL, config.ExitOnCrash) userPrint(34, "After IGNON SDL stops since preloaded not valid(see above message)") WaitForStopSDL(self) end - + --Start Postcondition to case8. commonFunctions:newTestCasesGroup("TC09_Postconditions") @@ -715,14 +714,14 @@ commonSteps:ActivationApp() RestorePreloadedPT() end - function Test:StartSDLWithDeviceInPT() + function Test:StartSDLWithDeviceInPT() StartSDL(config.pathToSDL, config.ExitOnCrash) userPrint(34, "After correct sdl_preloaded_pt.json restored, SDL starts successfully") end --end Postcondition to case8. -- End Negative case8. - ------------------------------------------------------------- + ------------------------------------------------------------- -- Start Negative case9. --Description: Mandatory section "pre_DataConsent" is not present in preloaded_pt @@ -745,14 +744,14 @@ commonSteps:ActivationApp() file:close() local json = require("modules/json") - + local data = json.decode(json_data) - if data.policy_table.app_policies and + if data.policy_table.app_policies and data.policy_table.app_policies["pre_DataConsent"] ~= nil then data.policy_table.app_policies["pre_DataConsent"] = nil - + end - + data = json.encode(data) file = io.open(pathToFile, "w") @@ -765,14 +764,14 @@ commonSteps:ActivationApp() userPrint(34, "After IGNON SDL stops since preloaded not valid(see above message)") WaitForStopSDL(self) end - + --Start Postcondition to case9. commonFunctions:newTestCasesGroup("TC10_Postconditions") function Test:RestorePreloadedJson() RestorePreloadedPT() - end + end - function Test:StartSDLWithPreDataInPT() + function Test:StartSDLWithPreDataInPT() StartSDL(config.pathToSDL, config.ExitOnCrash) userPrint(34, "After correct sdl_preloaded_pt.json restored, SDL starts successfully") end @@ -801,13 +800,13 @@ commonSteps:ActivationApp() file:close() local json = require("modules/json") - + local data = json.decode(json_data) - if data.policy_table.app_policies and + if data.policy_table.app_policies and data.policy_table.app_policies["pre_DataConsent"] ~= nil then - data.policy_table.app_policies["pre_DataConsent"] = data.policy_table.app_policies["Pre_DataConsent"] + data.policy_table.app_policies["pre_DataConsent"] = data.policy_table.app_policies["Pre_DataConsent"] end - + data = json.encode(data) file = io.open(pathToFile, "w") @@ -820,7 +819,7 @@ commonSteps:ActivationApp() userPrint(34, "After IGNON SDL stops since preloaded not valid(see above message)") WaitForStopSDL(self) end - + --Start Postcondition to case10. commonFunctions:newTestCasesGroup("TC11_Postconditions") function Test:RestorePreloadedJson() @@ -857,12 +856,12 @@ commonSteps:ActivationApp() file:close() local json = require("modules/json") - + local data = json.decode(json_data) - if data.policy_table.app_policies and + if data.policy_table.app_policies and data.policy_table.app_policies["pre_DataConsent"] ~= nil and data.policy_table.app_policies["device"] ~= nil then data.policy_table.app_policies["device"] = nil - data.policy_table.app_policies["pre_DataConsent"] = nil + data.policy_table.app_policies["pre_DataConsent"] = nil end data = json.encode(data) @@ -877,14 +876,14 @@ commonSteps:ActivationApp() userPrint(34, "After IGNON SDL stops since preloaded not valid(see above message)") WaitForStopSDL(self) end - + --Start Postcondition to case11. commonFunctions:newTestCasesGroup("TC12_Postconditions") function Test:RestorePreloadedJson() RestorePreloadedPT() - end + end - function Test:StartSDLWithDeviceAndPreDataInPT() + function Test:StartSDLWithDeviceAndPreDataInPT() StartSDL(config.pathToSDL, config.ExitOnCrash) userPrint(34, "After correct sdl_preloaded_pt.json restored, SDL starts successfully") end @@ -913,15 +912,15 @@ commonSteps:ActivationApp() file:close() local json = require("modules/json") - + local data = json.decode(json_data) - if data.policy_table.app_policies and + if data.policy_table.app_policies and data.policy_table.app_policies["pre_DataConsent"] ~= nil and data.policy_table.app_policies["device"] ~= nil then - data.policy_table.app_policies["pre_DataConsent"] = data.policy_table.app_policies["Pre_DataConsent"] - data.policy_table.app_policies["device"] = data.policy_table.app_policies["Device"] + data.policy_table.app_policies["pre_DataConsent"] = data.policy_table.app_policies["Pre_DataConsent"] + data.policy_table.app_policies["device"] = data.policy_table.app_policies["Device"] end - + data = json.encode(data) file = io.open(pathToFile, "w") @@ -934,14 +933,14 @@ commonSteps:ActivationApp() userPrint(34, "After IGNON SDL stops since preloaded not valid(see above message)") WaitForStopSDL(self) end - + --Start Postcondition to case12. commonFunctions:newTestCasesGroup("TC13_Postconditions") function Test:RestorePreloadedJson() RestorePreloadedPT() end - function Test:StartSDLWithDeviceInPT() + function Test:StartSDLWithDeviceInPT() StartSDL(config.pathToSDL, config.ExitOnCrash) userPrint(34, "After correct sdl_preloaded_pt.json restored, SDL starts successfully") end diff --git a/test_scripts/Policies/App_Permissions/001_ATF_HP_Order_Of_Request_Response_Notification_On_Registering_App.lua b/test_scripts/Policies/App_Permissions/001_ATF_HP_Order_Of_Request_Response_Notification_On_Registering_App.lua index 9f46d1907a..a4b8e37afd 100644 --- a/test_scripts/Policies/App_Permissions/001_ATF_HP_Order_Of_Request_Response_Notification_On_Registering_App.lua +++ b/test_scripts/Policies/App_Permissions/001_ATF_HP_Order_Of_Request_Response_Notification_On_Registering_App.lua @@ -27,15 +27,13 @@ -- 4. SDL assigns the appropriate policies and notifies application: -- SDL->app: OnPermissionsChange (params) - as specified in "pre_DataConsent" section. --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') local commonTestCases = require ('user_modules/shared_testcases/commonTestCases') local testCasesForPolicyTableSnapshot = require ('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -44,7 +42,6 @@ commonPreconditions:Connecttest_without_ExitBySDLDisconnect_WithoutOpenConnectio config.defaultProtocolVersion = 2 --[[ Local variables ]] -local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RPC_BaseBeforeDataConsent = {} --[[ Local functions ]] @@ -80,7 +77,7 @@ function Test:Precondition_Connect_device() commonTestCases:DelayedExp(2000) self:connectMobile() EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { - deviceList = { { id = config.deviceMAC, name = ServerAddress, transportType = "WIFI", isSDLAllowed = false} } }) + deviceList = { { id = utils.getDeviceMAC(), name = utils.getDeviceName(), transportType = "WIFI", isSDLAllowed = false} } }) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) @@ -110,8 +107,8 @@ function Test:Register_App_And_Check_Order_Of_Request_Response_Notiofications() hmiDisplayLanguageDesired = "EN-US", deviceInfo = { - name = ServerAddress, - id = config.deviceMAC, + name = utils.getDeviceName(), + id = utils.getDeviceMAC(), transportType = "WIFI", isSDLAllowed = false } } }) diff --git a/test_scripts/Policies/App_Permissions/002_ATF_HP_OnPermissionsChange_With_Assigned_Policy_After_App_Registration.lua b/test_scripts/Policies/App_Permissions/002_ATF_HP_OnPermissionsChange_With_Assigned_Policy_After_App_Registration.lua index ab87b15e23..835b14c8da 100644 --- a/test_scripts/Policies/App_Permissions/002_ATF_HP_OnPermissionsChange_With_Assigned_Policy_After_App_Registration.lua +++ b/test_scripts/Policies/App_Permissions/002_ATF_HP_OnPermissionsChange_With_Assigned_Policy_After_App_Registration.lua @@ -17,15 +17,13 @@ -- 1. SDL -> app: RegisterAppInterface_response -- 2. SDL -> app: OnPermissionsChange () --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') local commonTestCases = require ('user_modules/shared_testcases/commonTestCases') local testCasesForPolicyTableSnapshot = require ('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -34,7 +32,6 @@ commonPreconditions:Connecttest_without_ExitBySDLDisconnect_WithoutOpenConnectio config.defaultProtocolVersion = 2 --[[ Local variables ]] -local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RPC_BaseBeforeDataConsent = {} --[[ Local functions ]] @@ -74,7 +71,7 @@ function Test:Precondition_Connect_device() commonTestCases:DelayedExp(2000) self:connectMobile() EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { - deviceList = { { id = config.deviceMAC, name = ServerAddress, transportType = "WIFI", isSDLAllowed = false} } }) + deviceList = { { id = utils.getDeviceMAC(), name = utils.getDeviceName(), transportType = "WIFI", isSDLAllowed = false} } }) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) @@ -104,8 +101,8 @@ function Test:Step1_Register_App_And_Check_Its_Permissions_In_OnPermissionsChang hmiDisplayLanguageDesired = "EN-US", deviceInfo = { - name = ServerAddress, - id = config.deviceMAC, + name = utils.getDeviceName(), + id = utils.getDeviceMAC(), transportType = "WIFI", isSDLAllowed = false } } }) diff --git a/test_scripts/Policies/App_Permissions/003_ATF_HP_User_Consent_Yes.lua b/test_scripts/Policies/App_Permissions/003_ATF_HP_User_Consent_Yes.lua index 1addbc22fd..5d580e18e5 100644 --- a/test_scripts/Policies/App_Permissions/003_ATF_HP_User_Consent_Yes.lua +++ b/test_scripts/Policies/App_Permissions/003_ATF_HP_User_Consent_Yes.lua @@ -29,9 +29,7 @@ -- PoliciesManager: update "" subsection of "user_consent_records" subsection of "" section of "device_data" section in Local PT. -- c) SDL responds SUCCESS to allowed by USER RPC and DISALLOW to disallowed by Policy RPC. --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -42,6 +40,7 @@ local commonTestCases = require ('user_modules/shared_testcases/commonTestCases' local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') local testCasesForPolicyTableSnapshot = require ('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -83,11 +82,10 @@ local mobile_session = require('mobile_session') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_Connect_device() - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") commonTestCases:DelayedExp(2000) self:connectMobile() EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { - deviceList = { { id = config.deviceMAC, name = ServerAddress, transportType = "WIFI", isSDLAllowed = false} } }) + deviceList = { { id = utils.getDeviceMAC(), name = utils.getDeviceName(), transportType = "WIFI", isSDLAllowed = false} } }) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) @@ -133,8 +131,8 @@ function Test:Precondition_Activate_App_And_Consent_Device() hmiDisplayLanguageDesired = "EN-US", deviceInfo = { - name = "127.0.0.1", - id = config.deviceMAC, + name = utils.getDeviceName(), + id = utils.getDeviceMAC(), transportType = "WIFI", isSDLAllowed = false } @@ -152,7 +150,7 @@ function Test:Precondition_Activate_App_And_Consent_Device() local RequestId1 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestId1,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/App_Permissions/004_ATF_HP_User_Consent_NO.lua b/test_scripts/Policies/App_Permissions/004_ATF_HP_User_Consent_NO.lua index 35f5cf00a8..fa0f3d3e8b 100644 --- a/test_scripts/Policies/App_Permissions/004_ATF_HP_User_Consent_NO.lua +++ b/test_scripts/Policies/App_Permissions/004_ATF_HP_User_Consent_NO.lua @@ -29,9 +29,7 @@ -- SDL->HMI: GetListOfPermissions_response{} -- b) HMI->SDL: OnAppPermissionConsent {allowed = false} --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -41,6 +39,7 @@ local commonSteps = require ('user_modules/shared_testcases/commonSteps') local commonTestCases = require ('user_modules/shared_testcases/commonTestCases') local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -57,11 +56,10 @@ local mobile_session = require('mobile_session') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_Connect_device() - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") commonTestCases:DelayedExp(2000) self:connectMobile() EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { - deviceList = { { id = config.deviceMAC, name = ServerAddress, transportType = "WIFI", isSDLAllowed = false} } }) + deviceList = { { id = utils.getDeviceMAC(), name = utils.getDeviceName(), transportType = "WIFI", isSDLAllowed = false} } }) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) @@ -107,8 +105,8 @@ function Test:Precondition_Activate_App_And_Consent_Device() hmiDisplayLanguageDesired = "EN-US", deviceInfo = { - name = "127.0.0.1", - id = config.deviceMAC, + name = utils.getDeviceName(), + id = utils.getDeviceMAC(), transportType = "WIFI", isSDLAllowed = false } @@ -126,7 +124,7 @@ function Test:Precondition_Activate_App_And_Consent_Device() local RequestId1 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestId1,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/App_Permissions/005_ATF_DISALLOWED_app_Id_policies_And_RequestType_Validation.lua b/test_scripts/Policies/App_Permissions/005_ATF_DISALLOWED_app_Id_policies_And_RequestType_Validation.lua index cc954b9c8c..d2e9ae04a4 100644 --- a/test_scripts/Policies/App_Permissions/005_ATF_DISALLOWED_app_Id_policies_And_RequestType_Validation.lua +++ b/test_scripts/Policies/App_Permissions/005_ATF_DISALLOWED_app_Id_policies_And_RequestType_Validation.lua @@ -17,9 +17,7 @@ -- Expected result: -- SDL allow SystemRequest with requestType = "PROPRIETARY" and disallow SystemRequest with requestType = "HTTP" --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -30,9 +28,7 @@ local commonPreconditions = require ('user_modules/shared_testcases/commonPrecon local commonTestCases = require ('user_modules/shared_testcases/commonTestCases') local testCasesForPolicyTableSnapshot = require ('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') - ---[[ Local variables ]] -local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -51,7 +47,7 @@ function Test:Precondition_Connect_device() commonTestCases:DelayedExp(2000) self:connectMobile() EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { - deviceList = { { id = config.deviceMAC, name = ServerAddress, transportType = "WIFI", isSDLAllowed = false} } }) + deviceList = { { id = utils.getDeviceMAC(), name = utils.getDeviceName(), transportType = "WIFI", isSDLAllowed = false} } }) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) @@ -94,8 +90,8 @@ function Test:Precondition_Activate_App_And_Consent_Device() hmiDisplayLanguageDesired = "EN-US", deviceInfo = { - name = "127.0.0.1", - id = config.deviceMAC, + name = utils.getDeviceName(), + id = utils.getDeviceMAC(), transportType = "WIFI", isSDLAllowed = false } @@ -113,7 +109,7 @@ function Test:Precondition_Activate_App_And_Consent_Device() local RequestId1 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestId1,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/App_Permissions/006_ATF_Steal_focus_validation_false_PTU.lua b/test_scripts/Policies/App_Permissions/006_ATF_Steal_focus_validation_false_PTU.lua index 51c4b8932b..02c69778dd 100644 --- a/test_scripts/Policies/App_Permissions/006_ATF_Steal_focus_validation_false_PTU.lua +++ b/test_scripts/Policies/App_Permissions/006_ATF_Steal_focus_validation_false_PTU.lua @@ -15,7 +15,6 @@ -- SDL must response: success = false, resultCode = "DISALLOWED" ------------------------------------------------------------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -26,9 +25,7 @@ local commonTestCases = require ('user_modules/shared_testcases/commonTestCases' local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') local testCasesForPolicyTableSnapshot = require ('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') - ---[[ Local variables ]] -local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -45,7 +42,7 @@ function Test:Precondition_Connect_device() commonTestCases:DelayedExp(2000) self:connectMobile() EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { - deviceList = { { id = config.deviceMAC, name = ServerAddress, transportType = "WIFI", isSDLAllowed = false} } }) + deviceList = { { id = utils.getDeviceMAC(), name = utils.getDeviceName(), transportType = "WIFI", isSDLAllowed = false} } }) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) @@ -71,7 +68,7 @@ function Test:Precondition_ActivateApplication() local RequestId1 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestId1,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/App_Permissions/007_ATF_StealFocus_validation_true_PTU.lua b/test_scripts/Policies/App_Permissions/007_ATF_StealFocus_validation_true_PTU.lua index 3de843ae31..dfb9da6d3c 100644 --- a/test_scripts/Policies/App_Permissions/007_ATF_StealFocus_validation_true_PTU.lua +++ b/test_scripts/Policies/App_Permissions/007_ATF_StealFocus_validation_true_PTU.lua @@ -15,7 +15,6 @@ -- SDL must response: success = true, resultCode = "SUCCESS" -------------------------------------------------------------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -26,15 +25,13 @@ local commonTestCases = require ('user_modules/shared_testcases/commonTestCases' local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') local testCasesForPolicyTableSnapshot = require ('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local Functions ]] local function SendOnSystemContext(self, ctx) self.hmiConnection:SendNotification("UI.OnSystemContext",{ appID = self.applications[config.application1.registerAppInterfaceParams.appName], systemContext = ctx }) end ---[[ Local variables ]] -local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") - --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() commonPreconditions:Connecttest_without_ExitBySDLDisconnect_WithoutOpenConnectionRegisterApp("connecttest_connect_device.lua") @@ -50,7 +47,7 @@ function Test:Precondition_Connect_device() commonTestCases:DelayedExp(2000) self:connectMobile() EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { - deviceList = { { id = config.deviceMAC, name = ServerAddress, transportType = "WIFI", isSDLAllowed = false} } }) + deviceList = { { id = utils.getDeviceMAC(), name = utils.getDeviceName(), transportType = "WIFI", isSDLAllowed = false} } }) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) @@ -76,7 +73,7 @@ function Test:Precondition_ActivateApplication() local RequestId1 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestId1,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/App_Permissions/008_ATF_DISALLOWED_default_policies_And_RequestType_Validation.lua b/test_scripts/Policies/App_Permissions/008_ATF_DISALLOWED_default_policies_And_RequestType_Validation.lua index a392175075..07503cfe79 100644 --- a/test_scripts/Policies/App_Permissions/008_ATF_DISALLOWED_default_policies_And_RequestType_Validation.lua +++ b/test_scripts/Policies/App_Permissions/008_ATF_DISALLOWED_default_policies_And_RequestType_Validation.lua @@ -17,9 +17,7 @@ -- Expected result: -- SDL allow SystemRequest with requestType = "PROPRIETARY" and disallow SystemRequest with requestType = "HTTP" --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -29,6 +27,7 @@ local commonSteps = require ('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') local testCasesForPolicyTableSnapshot = require ('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ Local Functions ]] local function SetRequestTypeForDefaultGroup() @@ -74,7 +73,7 @@ function Test:Preconditions_Assign_To_App_Default_RequestType_PROPRIETARY_Via_Ac local RequestId1 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestId1,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data) self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/App_Permissions/009_ATF_Steal_Focus_Validation_False.lua b/test_scripts/Policies/App_Permissions/009_ATF_Steal_Focus_Validation_False.lua index 1b9f5b5137..46eead0838 100644 --- a/test_scripts/Policies/App_Permissions/009_ATF_Steal_Focus_Validation_False.lua +++ b/test_scripts/Policies/App_Permissions/009_ATF_Steal_Focus_Validation_False.lua @@ -16,13 +16,13 @@ --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -43,7 +43,7 @@ function Test:ActivateApplication() local RequestId1 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestId1,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data) self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/App_Permissions/010_ATF_StealFocus_validation_true_app_id.lua b/test_scripts/Policies/App_Permissions/010_ATF_StealFocus_validation_true_app_id.lua index a524b1dbcb..2dc0c3f5f3 100644 --- a/test_scripts/Policies/App_Permissions/010_ATF_StealFocus_validation_true_app_id.lua +++ b/test_scripts/Policies/App_Permissions/010_ATF_StealFocus_validation_true_app_id.lua @@ -16,13 +16,13 @@ --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ Local Functions ]] local function SendOnSystemContext(self, ctx) @@ -48,7 +48,7 @@ function Test:ActivateApplication() local RequestId1 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestId1,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data) self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/App_Permissions/011_ATF_KeepContext_Validation_false.lua b/test_scripts/Policies/App_Permissions/011_ATF_KeepContext_Validation_false.lua index b7345fbb23..355f0f2281 100644 --- a/test_scripts/Policies/App_Permissions/011_ATF_KeepContext_Validation_false.lua +++ b/test_scripts/Policies/App_Permissions/011_ATF_KeepContext_Validation_false.lua @@ -16,13 +16,13 @@ --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -43,7 +43,7 @@ function Test:Precondition_ActivateApplication() local RequestId1 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestId1,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data) self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/App_Permissions/012_ATF_KeepContext_Validation_true.lua b/test_scripts/Policies/App_Permissions/012_ATF_KeepContext_Validation_true.lua index 6356f1438a..35e247dd20 100644 --- a/test_scripts/Policies/App_Permissions/012_ATF_KeepContext_Validation_true.lua +++ b/test_scripts/Policies/App_Permissions/012_ATF_KeepContext_Validation_true.lua @@ -16,13 +16,13 @@ --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ Local Functions ]] local function SendOnSystemContext(self, ctx) @@ -48,7 +48,7 @@ function Test:Precondition_ActivateApplication() local RequestId1 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestId1,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data) self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/App_Permissions/013_ATF_General_Result_Codes_Disallowed_Rpc_Is_Omitted_In_The_Policy_Table_Default_Group.lua b/test_scripts/Policies/App_Permissions/013_ATF_General_Result_Codes_Disallowed_Rpc_Is_Omitted_In_The_Policy_Table_Default_Group.lua index 77cd6f991e..9bd23abda7 100644 --- a/test_scripts/Policies/App_Permissions/013_ATF_General_Result_Codes_Disallowed_Rpc_Is_Omitted_In_The_Policy_Table_Default_Group.lua +++ b/test_scripts/Policies/App_Permissions/013_ATF_General_Result_Codes_Disallowed_Rpc_Is_Omitted_In_The_Policy_Table_Default_Group.lua @@ -18,14 +18,11 @@ -- Expected result: -- SDL -> App: RPC (DISALLOWED, success: "false") --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") +local utils = require ('user_modules/utils') --[[ Local Variables ]] local rpc = {} @@ -47,7 +44,7 @@ require("user_modules/AppTypes") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_ActivateApplication() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end -- function Test:UpdatePolicy() diff --git a/test_scripts/Policies/App_Permissions/014_ATF_Unsubscribe_Vehicle_Data_General_Resultcode_And_The_Individual_Result_Codes_For_A_Part_Of_Parameters_Disallowed_By_Policies.lua b/test_scripts/Policies/App_Permissions/014_ATF_Unsubscribe_Vehicle_Data_General_Resultcode_And_The_Individual_Result_Codes_For_A_Part_Of_Parameters_Disallowed_By_Policies.lua index a8d253f4eb..c11794ba06 100644 --- a/test_scripts/Policies/App_Permissions/014_ATF_Unsubscribe_Vehicle_Data_General_Resultcode_And_The_Individual_Result_Codes_For_A_Part_Of_Parameters_Disallowed_By_Policies.lua +++ b/test_scripts/Policies/App_Permissions/014_ATF_Unsubscribe_Vehicle_Data_General_Resultcode_And_The_Individual_Result_Codes_For_A_Part_Of_Parameters_Disallowed_By_Policies.lua @@ -32,14 +32,11 @@ -- - for allowed: dataType: , resultCode: SUCCESS -- - for disallowed: dataType: , resultCode: DISALLOWED --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -82,7 +79,7 @@ require("user_modules/AppTypes") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end -- function Test:UpdatePolicy() diff --git a/test_scripts/Policies/App_Permissions/015_ATF_Subscribe_Vehicle_Data_Disallowed_Response_When_All_Parameters_Are_Not_Allowed_In_The_Request.lua b/test_scripts/Policies/App_Permissions/015_ATF_Subscribe_Vehicle_Data_Disallowed_Response_When_All_Parameters_Are_Not_Allowed_In_The_Request.lua index 5bf0c83935..8ee18dc6c8 100644 --- a/test_scripts/Policies/App_Permissions/015_ATF_Subscribe_Vehicle_Data_Disallowed_Response_When_All_Parameters_Are_Not_Allowed_In_The_Request.lua +++ b/test_scripts/Policies/App_Permissions/015_ATF_Subscribe_Vehicle_Data_Disallowed_Response_When_All_Parameters_Are_Not_Allowed_In_The_Request.lua @@ -24,14 +24,11 @@ -- General: success: false, resultCode: DISALLOWED -- Individual: dataType: , resultCode: DISALLOWED --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -73,7 +70,7 @@ require("user_modules/AppTypes") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/App_Permissions/016_ATF_Subscribe_Vehicle_Data_General_Resultcode_And_The_Individual_Result_Codes_For_A_Part_Of_Parameters_Disallowed_By_Policies.lua b/test_scripts/Policies/App_Permissions/016_ATF_Subscribe_Vehicle_Data_General_Resultcode_And_The_Individual_Result_Codes_For_A_Part_Of_Parameters_Disallowed_By_Policies.lua index 76b8005689..b34ffb17a3 100644 --- a/test_scripts/Policies/App_Permissions/016_ATF_Subscribe_Vehicle_Data_General_Resultcode_And_The_Individual_Result_Codes_For_A_Part_Of_Parameters_Disallowed_By_Policies.lua +++ b/test_scripts/Policies/App_Permissions/016_ATF_Subscribe_Vehicle_Data_General_Resultcode_And_The_Individual_Result_Codes_For_A_Part_Of_Parameters_Disallowed_By_Policies.lua @@ -31,14 +31,11 @@ -- - for allowed: dataType: , resultCode: SUCCESS -- - for disallowed: dataType: , resultCode: DISALLOWED --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local functions ]] local function UpdatePolicy() @@ -80,7 +77,7 @@ require("user_modules/AppTypes") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/App_Permissions/017_ATF_Get_Vehicle_Data_App_Sends_Not-allowed_Parameters_By_Policies_Only.lua b/test_scripts/Policies/App_Permissions/017_ATF_Get_Vehicle_Data_App_Sends_Not-allowed_Parameters_By_Policies_Only.lua index 591a2309dd..8d61b9a70c 100644 --- a/test_scripts/Policies/App_Permissions/017_ATF_Get_Vehicle_Data_App_Sends_Not-allowed_Parameters_By_Policies_Only.lua +++ b/test_scripts/Policies/App_Permissions/017_ATF_Get_Vehicle_Data_App_Sends_Not-allowed_Parameters_By_Policies_Only.lua @@ -21,14 +21,11 @@ -- Expected result: -- SDL -> App: success: false, resultCode: DISALLOWED --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local functions ]] local function UpdatePolicy() @@ -59,7 +56,7 @@ require("user_modules/AppTypes") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/App_Permissions/018_ATF_Get_Vehicle_Data_App_Sends_Allowed_Parameters_And_Not-allowed_By_Policies_Parameters.lua b/test_scripts/Policies/App_Permissions/018_ATF_Get_Vehicle_Data_App_Sends_Allowed_Parameters_And_Not-allowed_By_Policies_Parameters.lua index 14583a4956..2bf5fa07fe 100644 --- a/test_scripts/Policies/App_Permissions/018_ATF_Get_Vehicle_Data_App_Sends_Allowed_Parameters_And_Not-allowed_By_Policies_Parameters.lua +++ b/test_scripts/Policies/App_Permissions/018_ATF_Get_Vehicle_Data_App_Sends_Allowed_Parameters_And_Not-allowed_By_Policies_Parameters.lua @@ -24,14 +24,11 @@ -- SDL -> HMI: Only allowed parameters -- SDL -> App: "success: true, resultCode: SUCCESS, + "info" parameter listing the params disallowed by policies --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local functions ]] local function UpdatePolicy() @@ -62,7 +59,7 @@ require("user_modules/AppTypes") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/App_Permissions/019_ATF_General_Result_Codes_Disallowed_Rpc_Is_Omitted_In_The_Policy_Table.lua b/test_scripts/Policies/App_Permissions/019_ATF_General_Result_Codes_Disallowed_Rpc_Is_Omitted_In_The_Policy_Table.lua index c7fe74bb43..bc700024df 100644 --- a/test_scripts/Policies/App_Permissions/019_ATF_General_Result_Codes_Disallowed_Rpc_Is_Omitted_In_The_Policy_Table.lua +++ b/test_scripts/Policies/App_Permissions/019_ATF_General_Result_Codes_Disallowed_Rpc_Is_Omitted_In_The_Policy_Table.lua @@ -18,13 +18,11 @@ -- Expected result: -- SDL -> App: RPC (DISALLOWED, success: "false") --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local testCasesForPolicyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -37,7 +35,7 @@ require("user_modules/AppTypes") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/App_Permissions/020_ATF_General_Result_Codes_Disallowed_In_Case_App_Current_Hmi_Level_Is_Not_Listed_In_Assigned_Policies.lua b/test_scripts/Policies/App_Permissions/020_ATF_General_Result_Codes_Disallowed_In_Case_App_Current_Hmi_Level_Is_Not_Listed_In_Assigned_Policies.lua index c677bfa61e..e80d76065a 100644 --- a/test_scripts/Policies/App_Permissions/020_ATF_General_Result_Codes_Disallowed_In_Case_App_Current_Hmi_Level_Is_Not_Listed_In_Assigned_Policies.lua +++ b/test_scripts/Policies/App_Permissions/020_ATF_General_Result_Codes_Disallowed_In_Case_App_Current_Hmi_Level_Is_Not_Listed_In_Assigned_Policies.lua @@ -19,15 +19,12 @@ -- Expected result: -- SDL -> App: RPC (DISALLOWED, success: "false") --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local testCasesForPolicyAppIdManagament = require("user_modules/shared_testcases/testCasesForPolicyAppIdManagament") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() @@ -40,7 +37,7 @@ require("user_modules/AppTypes") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondtion_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:UpdatePolicy() diff --git a/test_scripts/Policies/App_Permissions/021_ATF_HMI_Levels_The_Notification_Is_Allowed_To_Be_Processed_In.lua b/test_scripts/Policies/App_Permissions/021_ATF_HMI_Levels_The_Notification_Is_Allowed_To_Be_Processed_In.lua index 8e4b542e2b..ef6b1e6eea 100644 --- a/test_scripts/Policies/App_Permissions/021_ATF_HMI_Levels_The_Notification_Is_Allowed_To_Be_Processed_In.lua +++ b/test_scripts/Policies/App_Permissions/021_ATF_HMI_Levels_The_Notification_Is_Allowed_To_Be_Processed_In.lua @@ -20,15 +20,12 @@ -- Expected result: -- SDL -> App: There is no notification --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +local utils = require ('user_modules/utils') --[[ Local functions ]] local function UpdatePolicy() @@ -73,7 +70,7 @@ require("user_modules/AppTypes") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/App_Permissions/022_ATF_No_Permission_Notification_To_HMI_In_First_App_Registration.lua b/test_scripts/Policies/App_Permissions/022_ATF_No_Permission_Notification_To_HMI_In_First_App_Registration.lua index 7f05d9e475..b6f4cd8990 100644 --- a/test_scripts/Policies/App_Permissions/022_ATF_No_Permission_Notification_To_HMI_In_First_App_Registration.lua +++ b/test_scripts/Policies/App_Permissions/022_ATF_No_Permission_Notification_To_HMI_In_First_App_Registration.lua @@ -14,9 +14,7 @@ -- No prompts or notification are observed on HMI -- Note: Requirement under clarification! Assumed that OnAppPermissionChanged and OnSDLConsentNeeded should not come --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -25,6 +23,7 @@ local commonFunctions = require ('user_modules/shared_testcases/commonFunctions' local commonSteps = require ('user_modules/shared_testcases/commonSteps') local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') local commonTestCases = require ('user_modules/shared_testcases/commonTestCases') +local utils = require ('user_modules/utils') --[[ General Preconditions before ATF starts ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -80,8 +79,8 @@ function Test:TestStep_Firs_Time_Register_App_And_Check_That_No_Permission_Notif hmiDisplayLanguageDesired = "EN-US", deviceInfo = { - name = "127.0.0.1", - id = config.deviceMAC, + name = utils.getDeviceName(), + id = utils.getDeviceMAC(), transportType = "WIFI", isSDLAllowed = false } diff --git a/test_scripts/Policies/App_Permissions/023_ATF_Default_Priority_Value_Assigned_To_App.lua b/test_scripts/Policies/App_Permissions/023_ATF_Default_Priority_Value_Assigned_To_App.lua index 3b13d3363b..dedcddaae9 100644 --- a/test_scripts/Policies/App_Permissions/023_ATF_Default_Priority_Value_Assigned_To_App.lua +++ b/test_scripts/Policies/App_Permissions/023_ATF_Default_Priority_Value_Assigned_To_App.lua @@ -17,9 +17,7 @@ -- SDL->HMI: SDL.ActivateApp_response {priority: NONE, params} -- SDL->HMI: SDL.OnAppPermissionsChanged {priority: NONE, params} --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -28,6 +26,7 @@ local commonFunctions = require ('user_modules/shared_testcases/commonFunctions' local commonSteps = require ('user_modules/shared_testcases/commonSteps') local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Preconditions before ATF starts ]] commonPreconditions:Connecttest_without_ExitBySDLDisconnect_WithoutOpenConnectionRegisterApp("connecttest_ConnectMobile.lua") @@ -98,7 +97,7 @@ function Test:TestStep_Activate_App_Consent_Device_And_Check_Priority_In_Activat local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMINOTIFICATION("SDL.OnAppPermissionChanged", {appID = self.applications["Test Application"], priority = "NONE"}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data) diff --git a/test_scripts/Policies/App_Permissions/024_ATF_APP_UNAUTHORIZED_If_Failed_Nickname_Validation_After_PTU.lua b/test_scripts/Policies/App_Permissions/024_ATF_APP_UNAUTHORIZED_If_Failed_Nickname_Validation_After_PTU.lua index 1ddf2d612e..1029fb2743 100644 --- a/test_scripts/Policies/App_Permissions/024_ATF_APP_UNAUTHORIZED_If_Failed_Nickname_Validation_After_PTU.lua +++ b/test_scripts/Policies/App_Permissions/024_ATF_APP_UNAUTHORIZED_If_Failed_Nickname_Validation_After_PTU.lua @@ -14,15 +14,14 @@ -- Expected result: -- a) SDL->app: OnAppInterfaceUnregistered (APP_UNAUTHORIZED) --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFiles() @@ -146,8 +145,8 @@ function Test:TestStep_Update_PT_With_Another_NickName_For_Current_App_And_Check hmiDisplayLanguageDesired = "EN-US", deviceInfo = { - name = "127.0.0.1", - id = config.deviceMAC, + name = utils.getDeviceName(), + id = utils.getDeviceMAC(), transportType = "WIFI", isSDLAllowed = false } @@ -160,7 +159,7 @@ function Test:TestStep_Update_PT_With_Another_NickName_For_Current_App_And_Check local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/App_Permissions/025_ATF_ChangeRegistration_With_AppName_Not_Listed_In_NickNames.lua b/test_scripts/Policies/App_Permissions/025_ATF_ChangeRegistration_With_AppName_Not_Listed_In_NickNames.lua index fbd794b0d3..990410c36e 100644 --- a/test_scripts/Policies/App_Permissions/025_ATF_ChangeRegistration_With_AppName_Not_Listed_In_NickNames.lua +++ b/test_scripts/Policies/App_Permissions/025_ATF_ChangeRegistration_With_AppName_Not_Listed_In_NickNames.lua @@ -14,15 +14,14 @@ -- Expected result: -- a) (DISALLOWED, success:false) to this application for ChangeRegistration (not unregister it) --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFiles() @@ -144,8 +143,8 @@ function Test:Precondition_Register_App_Activate_And_consent_Device() hmiDisplayLanguageDesired = "EN-US", deviceInfo = { - name = "127.0.0.1", - id = config.deviceMAC, + name = utils.getDeviceName(), + id = utils.getDeviceMAC(), transportType = "WIFI", isSDLAllowed = false } @@ -158,7 +157,7 @@ function Test:Precondition_Register_App_Activate_And_consent_Device() local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) @@ -167,19 +166,19 @@ function Test:Precondition_Register_App_Activate_And_consent_Device() end) end) end) - EXPECT_RESPONSE(CorIdRAI, { success = true, resultCode = "SUCCESS"}) + EXPECT_RESPONSE(CorIdRAI, { success = true, resultCode = "SUCCESS"}) end --[[ Test ]] -function Test:TestStep_Send_ChangeRegistration_WithApp_Name_Not_Listed_In_NickNames_DISALLOWED() +function Test:TestStep_Send_ChangeRegistration_WithApp_Name_Not_Listed_In_NickNames_DISALLOWED() local CorIdChangeRegistration = self.mobileSession:SendRPC("ChangeRegistration",{ language ="EN-US", hmiDisplayLanguage ="EN-US", appName ="NameNotListedInNickNames"}) - EXPECT_RESPONSE(CorIdChangeRegistration, { success = false, resultCode = "DISALLOWED" }) + EXPECT_RESPONSE(CorIdChangeRegistration, { success = false, resultCode = "DISALLOWED" }) end -function Test:TestStep_Ensure_App_Still_Registered_By_Sending_Show() +function Test:TestStep_Ensure_App_Still_Registered_By_Sending_Show() local CorIdRAI = self.mobileSession:SendRPC("Show", { mediaClock = "00:00:01", @@ -194,4 +193,4 @@ end --[[ Postcondition ]] function Test:Postcondition_StopSDL() StopSDL() -end \ No newline at end of file +end diff --git a/test_scripts/Policies/App_Permissions/026_ATF_DISALLOWED_App_Which_Name_Does_Not_Match_With_Nickname_In_PT.lua b/test_scripts/Policies/App_Permissions/026_ATF_DISALLOWED_App_Which_Name_Does_Not_Match_With_Nickname_In_PT.lua index 66c44e9d71..4355acf878 100644 --- a/test_scripts/Policies/App_Permissions/026_ATF_DISALLOWED_App_Which_Name_Does_Not_Match_With_Nickname_In_PT.lua +++ b/test_scripts/Policies/App_Permissions/026_ATF_DISALLOWED_App_Which_Name_Does_Not_Match_With_Nickname_In_PT.lua @@ -12,15 +12,14 @@ -- Expected result: -- a) SDL->app: RegisterAppInterface(DISALLOWED, success:false) --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() diff --git a/test_scripts/Policies/App_Permissions/027_ATF_NickName_Case_Insensitivity.lua b/test_scripts/Policies/App_Permissions/027_ATF_NickName_Case_Insensitivity.lua index d51f885ac9..e15ee9a7d2 100644 --- a/test_scripts/Policies/App_Permissions/027_ATF_NickName_Case_Insensitivity.lua +++ b/test_scripts/Policies/App_Permissions/027_ATF_NickName_Case_Insensitivity.lua @@ -13,9 +13,7 @@ -- Expected result: -- a) SDL->appID: SUCCESS: RegisterAppInterface() --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -23,6 +21,7 @@ config.defaultProtocolVersion = 2 local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFiles() @@ -101,7 +100,7 @@ end function Test.Postcondition_Restore_preloaded() commonPreconditions:RestoreFile("sdl_preloaded_pt.json") -end +end --[[ Test ]] commonFunctions:newTestCasesGroup("Test") @@ -134,4 +133,4 @@ end commonFunctions:newTestCasesGroup("Postconditions") function Test.Postcondition_SDLStop() StopSDL() -end \ No newline at end of file +end diff --git a/test_scripts/Policies/App_Permissions/028_ATF_Nickname_Validation_Before_Duplicate_Name_Validation.lua b/test_scripts/Policies/App_Permissions/028_ATF_Nickname_Validation_Before_Duplicate_Name_Validation.lua index f32289c606..a559d4bacd 100644 --- a/test_scripts/Policies/App_Permissions/028_ATF_Nickname_Validation_Before_Duplicate_Name_Validation.lua +++ b/test_scripts/Policies/App_Permissions/028_ATF_Nickname_Validation_Before_Duplicate_Name_Validation.lua @@ -3,9 +3,9 @@ -- [RegisterAppInterface] Nickname validation must be done before duplicate name validation -- -- Description: --- In case the application sends RegisterAppInterface request with the "appName" value that +-- In case the application sends RegisterAppInterface request with the "appName" value that -- - is not listed in this app's specific policies --- - is the same as another already-registered application hasSDL +-- - is the same as another already-registered application hasSDL -- must: return RegisterAppInterface_response (DISALLOWED, success: false) -- 1. Used preconditions: -- a) First SDL life cycle with loaded permissions for specific appId and nickname for it @@ -16,15 +16,14 @@ -- Expected result: -- a) SDL validate nicknames before duplicate name validation and respond for second app RegisterAppInterface_response (DISALLOWED, success: false) --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Settings for configuration ]] Test = require('connecttest') @@ -132,7 +131,7 @@ function Test:Precondition_Register_New_App_Not_Listad_In_PT() maxNumberRFCOMMPorts = 1 } }) - EXPECT_RESPONSE(CorIdRAI, { success = true, resultCode = "SUCCESS"}) + EXPECT_RESPONSE(CorIdRAI, { success = true, resultCode = "SUCCESS"}) end function Test:Precondition_StartSession_2() @@ -141,7 +140,7 @@ function Test:Precondition_StartSession_2() end --[[ Test ]] -function Test:TestStep_Register_DuplicateName_App_Listed_In_PT_But_With_Wrong_NickName_Check_DISALLOWED() +function Test:TestStep_Register_DuplicateName_App_Listed_In_PT_But_With_Wrong_NickName_Check_DISALLOWED() local CorIdRAI2 = self.mobileSession2:SendRPC("RegisterAppInterface", { syncMsgVersion = @@ -169,4 +168,4 @@ end --[[ Postcondition ]] function Test:Postcondition_StopSDL() StopSDL() -end \ No newline at end of file +end diff --git a/test_scripts/Policies/App_Permissions/029_ATF_OnPermissionsChange_After_PTU.lua b/test_scripts/Policies/App_Permissions/029_ATF_OnPermissionsChange_After_PTU.lua index c3c9c2b4b1..63620cb798 100644 --- a/test_scripts/Policies/App_Permissions/029_ATF_OnPermissionsChange_After_PTU.lua +++ b/test_scripts/Policies/App_Permissions/029_ATF_OnPermissionsChange_After_PTU.lua @@ -16,15 +16,14 @@ -- Expected result: -- SDL notify app with new changed permissions via OnPermissionsChange --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() @@ -45,7 +44,7 @@ function Test:TestStep_Assign_To_App_Default_Permissions_And_Check_Them_In_OnPer local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data) self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/App_Permissions/030_ATF_Successful_Nickname_Validation.lua b/test_scripts/Policies/App_Permissions/030_ATF_Successful_Nickname_Validation.lua index e8a523ff29..ad25f178f8 100644 --- a/test_scripts/Policies/App_Permissions/030_ATF_Successful_Nickname_Validation.lua +++ b/test_scripts/Policies/App_Permissions/030_ATF_Successful_Nickname_Validation.lua @@ -5,20 +5,18 @@ -- Note: SDL must build with EXTENDED_POLICY flag -- -- Description: --- In case the application sends RegisterAppInterface request with +-- In case the application sends RegisterAppInterface request with -- a) the "appName" value that is listed in this app's specific policies -- b) other valid parameters SDL must: successfully register such application: RegisterAppInterface_response (, success: true) -- 1. Used preconditions: -- a) First SDL life cycle with loaded permissions for specific appId and nickname -- 2. Performed steps -- a) Register app with name listed in policy table for this app --- +-- -- Expected result: -- a) RegisterAppInterface_response (, success: true) --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -27,6 +25,7 @@ config.defaultProtocolVersion = 2 local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFiles() @@ -62,7 +61,7 @@ local function SetNickNameForSpecificApp() file:write(data) file:close() end - + --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test.Precondition_StopSDL() @@ -136,14 +135,14 @@ function Test:TestStep_Register_App_With_Name_Listed_In_LPT() hmiDisplayLanguageDesired = "EN-US", deviceInfo = { - name = "127.0.0.1", - id = config.deviceMAC, + name = utils.getDeviceName(), + id = utils.getDeviceMAC(), transportType = "WIFI", isSDLAllowed = false } } }) - EXPECT_RESPONSE(CorIdRAI, {success = true, resultCode = "SUCCESS"}) + EXPECT_RESPONSE(CorIdRAI, {success = true, resultCode = "SUCCESS"}) end @@ -154,4 +153,4 @@ function Test.Postcondition_SDLStop() end function Test.Postcondition_Restore_preloaded() commonPreconditions:RestoreFile("sdl_preloaded_pt.json") -end +end diff --git a/test_scripts/Policies/External_UCS/001_ATF_P_TC_LPT_Creation_PreloadedPT_without_external_consent_status_groups_struct.lua b/test_scripts/Policies/External_UCS/001_ATF_P_TC_LPT_Creation_PreloadedPT_without_external_consent_status_groups_struct.lua index 63cc4bcebc..c2713e312a 100644 --- a/test_scripts/Policies/External_UCS/001_ATF_P_TC_LPT_Creation_PreloadedPT_without_external_consent_status_groups_struct.lua +++ b/test_scripts/Policies/External_UCS/001_ATF_P_TC_LPT_Creation_PreloadedPT_without_external_consent_status_groups_struct.lua @@ -24,9 +24,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] @@ -35,6 +33,7 @@ local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') local sdl = require('SDL') local testCasesForExternalUCS = require('user_modules/shared_testcases/testCasesForExternalUCS') +local utils = require ('user_modules/utils') --[[ Local variables ]] local checkedSection = "external_consent_status_groups" @@ -66,10 +65,10 @@ function Test:CheckPreloadedPT() if preloadedTable and preloadedTable.policy_table and preloadedTable.policy_table.device_data - and preloadedTable.policy_table.device_data[config.deviceMAC] - and preloadedTable.policy_table.device_data[config.deviceMAC].user_consent_records + and preloadedTable.policy_table.device_data[utils.getDeviceMAC()] + and preloadedTable.policy_table.device_data[utils.getDeviceMAC()].user_consent_records then - for _, v in pairs(preloadedTable.policy_table.device_data[config.deviceMAC].user_consent_records) do + for _, v in pairs(preloadedTable.policy_table.device_data[utils.getDeviceMAC()].user_consent_records) do if v[checkedSection] then result = false end diff --git a/test_scripts/Policies/External_UCS/002_ATF_N_TC_LPT_Creation_PreloadedPT_with_external_consent_status_groups_struct.lua b/test_scripts/Policies/External_UCS/002_ATF_N_TC_LPT_Creation_PreloadedPT_with_external_consent_status_groups_struct.lua index 8b40c4ffb3..2d4b0eecc0 100644 --- a/test_scripts/Policies/External_UCS/002_ATF_N_TC_LPT_Creation_PreloadedPT_with_external_consent_status_groups_struct.lua +++ b/test_scripts/Policies/External_UCS/002_ATF_N_TC_LPT_Creation_PreloadedPT_with_external_consent_status_groups_struct.lua @@ -29,9 +29,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 config.ExitOnCrash = false @@ -42,6 +40,7 @@ local commonPreconditions = require('user_modules/shared_testcases/commonPrecond local sdl = require('SDL') local testCasesForExternalUCS = require('user_modules/shared_testcases/testCasesForExternalUCS') local testCasesForPolicySDLErrorsStops = require('user_modules/shared_testcases/testCasesForPolicySDLErrorsStops') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() @@ -74,7 +73,7 @@ end function Test.UpdatePreloadedPT_Add_section() local updateFunc = function(preloadedTable) preloadedTable.policy_table.device_data = { - [config.deviceMAC] = { + [utils.getDeviceMAC()] = { user_consent_records = { [config.application1.registerAppInterfaceParams.appID] = { external_consent_status_groups = { diff --git a/test_scripts/Policies/External_UCS/003_ATF_P_TC_LPT_Creation_PreloadedPT_without_disallowed_by_external_consent_entities_off_struct.lua b/test_scripts/Policies/External_UCS/003_ATF_P_TC_LPT_Creation_PreloadedPT_without_disallowed_by_external_consent_entities_off_struct.lua index 0437f96b33..b322b68979 100644 --- a/test_scripts/Policies/External_UCS/003_ATF_P_TC_LPT_Creation_PreloadedPT_without_disallowed_by_external_consent_entities_off_struct.lua +++ b/test_scripts/Policies/External_UCS/003_ATF_P_TC_LPT_Creation_PreloadedPT_without_disallowed_by_external_consent_entities_off_struct.lua @@ -28,9 +28,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/004_ATF_P_TC_LPT_Creation_PreloadedPT_with_disallowed_by_external_consent_entities_off_struct.lua b/test_scripts/Policies/External_UCS/004_ATF_P_TC_LPT_Creation_PreloadedPT_with_disallowed_by_external_consent_entities_off_struct.lua index e72caa0c2f..5dce067ecb 100644 --- a/test_scripts/Policies/External_UCS/004_ATF_P_TC_LPT_Creation_PreloadedPT_with_disallowed_by_external_consent_entities_off_struct.lua +++ b/test_scripts/Policies/External_UCS/004_ATF_P_TC_LPT_Creation_PreloadedPT_with_disallowed_by_external_consent_entities_off_struct.lua @@ -28,9 +28,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/005_ATF_P_TC_LPT_Creation_PreloadedPT_without_disallowed_by_external_consent_entities_on_struct.lua b/test_scripts/Policies/External_UCS/005_ATF_P_TC_LPT_Creation_PreloadedPT_without_disallowed_by_external_consent_entities_on_struct.lua index 8fc90f888a..5c7fb93dcf 100644 --- a/test_scripts/Policies/External_UCS/005_ATF_P_TC_LPT_Creation_PreloadedPT_without_disallowed_by_external_consent_entities_on_struct.lua +++ b/test_scripts/Policies/External_UCS/005_ATF_P_TC_LPT_Creation_PreloadedPT_without_disallowed_by_external_consent_entities_on_struct.lua @@ -28,9 +28,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/006_ATF_P_TC_LPT_Creation_PreloadedPT_with_disallowed_by_external_consent_entities_on_struct.lua b/test_scripts/Policies/External_UCS/006_ATF_P_TC_LPT_Creation_PreloadedPT_with_disallowed_by_external_consent_entities_on_struct.lua index efe6b4930b..2be3f11a25 100644 --- a/test_scripts/Policies/External_UCS/006_ATF_P_TC_LPT_Creation_PreloadedPT_with_disallowed_by_external_consent_entities_on_struct.lua +++ b/test_scripts/Policies/External_UCS/006_ATF_P_TC_LPT_Creation_PreloadedPT_with_disallowed_by_external_consent_entities_on_struct.lua @@ -28,9 +28,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/007_ATF_N_TC_LPT_Creation_PreloadedPT_with_disallowed_by_external_consent_entities_off_struct_with_invalid_type_of_params.lua b/test_scripts/Policies/External_UCS/007_ATF_N_TC_LPT_Creation_PreloadedPT_with_disallowed_by_external_consent_entities_off_struct_with_invalid_type_of_params.lua index 5337e004fa..68b0c6847b 100644 --- a/test_scripts/Policies/External_UCS/007_ATF_N_TC_LPT_Creation_PreloadedPT_with_disallowed_by_external_consent_entities_off_struct_with_invalid_type_of_params.lua +++ b/test_scripts/Policies/External_UCS/007_ATF_N_TC_LPT_Creation_PreloadedPT_with_disallowed_by_external_consent_entities_off_struct_with_invalid_type_of_params.lua @@ -26,9 +26,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 config.ExitOnCrash = false diff --git a/test_scripts/Policies/External_UCS/008_ATF_N_TC_LPT_Creation_PreloadedPT_with_disallowed_by_external_consent_entities_on_struct_with_invalid_type_of_params.lua b/test_scripts/Policies/External_UCS/008_ATF_N_TC_LPT_Creation_PreloadedPT_with_disallowed_by_external_consent_entities_on_struct_with_invalid_type_of_params.lua index d988cf2aec..97b3c21887 100644 --- a/test_scripts/Policies/External_UCS/008_ATF_N_TC_LPT_Creation_PreloadedPT_with_disallowed_by_external_consent_entities_on_struct_with_invalid_type_of_params.lua +++ b/test_scripts/Policies/External_UCS/008_ATF_N_TC_LPT_Creation_PreloadedPT_with_disallowed_by_external_consent_entities_on_struct_with_invalid_type_of_params.lua @@ -26,9 +26,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 config.ExitOnCrash = false diff --git a/test_scripts/Policies/External_UCS/009_ATF_P_TC_SnapshotPT_without_external_consent_status_groups_struct.lua b/test_scripts/Policies/External_UCS/009_ATF_P_TC_SnapshotPT_without_external_consent_status_groups_struct.lua index d181cd5339..d6b3052032 100644 --- a/test_scripts/Policies/External_UCS/009_ATF_P_TC_SnapshotPT_without_external_consent_status_groups_struct.lua +++ b/test_scripts/Policies/External_UCS/009_ATF_P_TC_SnapshotPT_without_external_consent_status_groups_struct.lua @@ -26,15 +26,14 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForExternalUCS = require('user_modules/shared_testcases/testCasesForExternalUCS') +local utils = require ('user_modules/utils') --[[ Local variables ]] local appId = config.application1.registerAppInterfaceParams.appID @@ -76,10 +75,10 @@ function Test:CheckPTS() self:FailTestCase("PTS was not created") elseif testCasesForExternalUCS.pts.policy_table and testCasesForExternalUCS.pts.policy_table.device_data - and testCasesForExternalUCS.pts.policy_table.device_data[config.deviceMAC] - and testCasesForExternalUCS.pts.policy_table.device_data[config.deviceMAC].user_consent_records - and testCasesForExternalUCS.pts.policy_table.device_data[config.deviceMAC].user_consent_records[appId] - and testCasesForExternalUCS.pts.policy_table.device_data[config.deviceMAC].user_consent_records[appId][checkedSection] + and testCasesForExternalUCS.pts.policy_table.device_data[utils.getDeviceMAC()] + and testCasesForExternalUCS.pts.policy_table.device_data[utils.getDeviceMAC()].user_consent_records + and testCasesForExternalUCS.pts.policy_table.device_data[utils.getDeviceMAC()].user_consent_records[appId] + and testCasesForExternalUCS.pts.policy_table.device_data[utils.getDeviceMAC()].user_consent_records[appId][checkedSection] then self:FailTestCase("Section '" .. checkedSection .. "' was found in PTS") else diff --git a/test_scripts/Policies/External_UCS/010_ATF_P_TC_SnapshotPT_with_external_consent_status_groups_struct.lua b/test_scripts/Policies/External_UCS/010_ATF_P_TC_SnapshotPT_with_external_consent_status_groups_struct.lua index 35d3263578..2444502278 100644 --- a/test_scripts/Policies/External_UCS/010_ATF_P_TC_SnapshotPT_with_external_consent_status_groups_struct.lua +++ b/test_scripts/Policies/External_UCS/010_ATF_P_TC_SnapshotPT_with_external_consent_status_groups_struct.lua @@ -27,9 +27,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] @@ -38,6 +36,7 @@ local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') local json = require("modules/json") local testCasesForExternalUCS = require('user_modules/shared_testcases/testCasesForExternalUCS') +local utils = require ('user_modules/utils') --[[ Local variables ]] local appId = config.application1.registerAppInterfaceParams.appID @@ -128,10 +127,10 @@ function Test:CheckPTS() self:FailTestCase("PTS was not created") elseif testCasesForExternalUCS.pts.policy_table and testCasesForExternalUCS.pts.policy_table.device_data - and testCasesForExternalUCS.pts.policy_table.device_data[config.deviceMAC] - and testCasesForExternalUCS.pts.policy_table.device_data[config.deviceMAC].user_consent_records - and testCasesForExternalUCS.pts.policy_table.device_data[config.deviceMAC].user_consent_records[appId] - and testCasesForExternalUCS.pts.policy_table.device_data[config.deviceMAC].user_consent_records[appId][checkedSection] + and testCasesForExternalUCS.pts.policy_table.device_data[utils.getDeviceMAC()] + and testCasesForExternalUCS.pts.policy_table.device_data[utils.getDeviceMAC()].user_consent_records + and testCasesForExternalUCS.pts.policy_table.device_data[utils.getDeviceMAC()].user_consent_records[appId] + and testCasesForExternalUCS.pts.policy_table.device_data[utils.getDeviceMAC()].user_consent_records[appId][checkedSection] then print("Section '".. checkedSection .. "' exists in PTS") print(" => OK") diff --git a/test_scripts/Policies/External_UCS/011_ATF_P_TC_SnapshotPT_without_disallowed_by_external_consent_entities_off_struct.lua b/test_scripts/Policies/External_UCS/011_ATF_P_TC_SnapshotPT_without_disallowed_by_external_consent_entities_off_struct.lua index ef9da346f8..c25c903972 100644 --- a/test_scripts/Policies/External_UCS/011_ATF_P_TC_SnapshotPT_without_disallowed_by_external_consent_entities_off_struct.lua +++ b/test_scripts/Policies/External_UCS/011_ATF_P_TC_SnapshotPT_without_disallowed_by_external_consent_entities_off_struct.lua @@ -25,9 +25,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/012_ATF_P_TC_SnapshotPT_with_disallowed_by_external_consent_entities_off_struct.lua b/test_scripts/Policies/External_UCS/012_ATF_P_TC_SnapshotPT_with_disallowed_by_external_consent_entities_off_struct.lua index fa80af962c..695f256474 100644 --- a/test_scripts/Policies/External_UCS/012_ATF_P_TC_SnapshotPT_with_disallowed_by_external_consent_entities_off_struct.lua +++ b/test_scripts/Policies/External_UCS/012_ATF_P_TC_SnapshotPT_with_disallowed_by_external_consent_entities_off_struct.lua @@ -27,9 +27,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/013_ATF_P_TC_SnapshotPT_without_disallowed_by_external_consent_entities_on_struct.lua b/test_scripts/Policies/External_UCS/013_ATF_P_TC_SnapshotPT_without_disallowed_by_external_consent_entities_on_struct.lua index 9dcaa1aa33..af1e0250dc 100644 --- a/test_scripts/Policies/External_UCS/013_ATF_P_TC_SnapshotPT_without_disallowed_by_external_consent_entities_on_struct.lua +++ b/test_scripts/Policies/External_UCS/013_ATF_P_TC_SnapshotPT_without_disallowed_by_external_consent_entities_on_struct.lua @@ -25,9 +25,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/014_ATF_P_TC_SnapshotPT_with_disallowed_by_external_consent_entities_on_struct.lua b/test_scripts/Policies/External_UCS/014_ATF_P_TC_SnapshotPT_with_disallowed_by_external_consent_entities_on_struct.lua index 0a2ed84c52..6fec168313 100644 --- a/test_scripts/Policies/External_UCS/014_ATF_P_TC_SnapshotPT_with_disallowed_by_external_consent_entities_on_struct.lua +++ b/test_scripts/Policies/External_UCS/014_ATF_P_TC_SnapshotPT_with_disallowed_by_external_consent_entities_on_struct.lua @@ -27,9 +27,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/015_ATF_P_TC_PTU_without_external_consent_status_groups_struct.lua b/test_scripts/Policies/External_UCS/015_ATF_P_TC_PTU_without_external_consent_status_groups_struct.lua index 7d54253ef0..9f8b80a56b 100644 --- a/test_scripts/Policies/External_UCS/015_ATF_P_TC_PTU_without_external_consent_status_groups_struct.lua +++ b/test_scripts/Policies/External_UCS/015_ATF_P_TC_PTU_without_external_consent_status_groups_struct.lua @@ -27,9 +27,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/016_ATF_N_TC_PTU_with_external_consent_status_groups_struct.lua b/test_scripts/Policies/External_UCS/016_ATF_N_TC_PTU_with_external_consent_status_groups_struct.lua index d7d3de9bf9..ed3a5fb78a 100644 --- a/test_scripts/Policies/External_UCS/016_ATF_N_TC_PTU_with_external_consent_status_groups_struct.lua +++ b/test_scripts/Policies/External_UCS/016_ATF_N_TC_PTU_with_external_consent_status_groups_struct.lua @@ -24,15 +24,14 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForExternalUCS = require('user_modules/shared_testcases/testCasesForExternalUCS') +local utils = require ('user_modules/utils') --[[ Local variables ]] local appId = config.application1.registerAppInterfaceParams.appID @@ -70,7 +69,7 @@ end function Test:ActivateApp() local updateFunc = function(pts) pts.policy_table.device_data = { - [config.deviceMAC] = { + [utils.getDeviceMAC()] = { user_consent_records = { [appId] = { [checkedSection] = { @@ -108,10 +107,10 @@ function Test:CheckPTS() self:FailTestCase("PTS was not created") elseif testCasesForExternalUCS.pts.policy_table and testCasesForExternalUCS.pts.policy_table.device_data - and testCasesForExternalUCS.pts.policy_table.device_data[config.deviceMAC] - and testCasesForExternalUCS.pts.policy_table.device_data[config.deviceMAC].user_consent_records - and testCasesForExternalUCS.pts.policy_table.device_data[config.deviceMAC].user_consent_records[appId] - and testCasesForExternalUCS.pts.policy_table.device_data[config.deviceMAC].user_consent_records[appId][checkedSection] + and testCasesForExternalUCS.pts.policy_table.device_data[utils.getDeviceMAC()] + and testCasesForExternalUCS.pts.policy_table.device_data[utils.getDeviceMAC()].user_consent_records + and testCasesForExternalUCS.pts.policy_table.device_data[utils.getDeviceMAC()].user_consent_records[appId] + and testCasesForExternalUCS.pts.policy_table.device_data[utils.getDeviceMAC()].user_consent_records[appId][checkedSection] then self:FailTestCase("Section '" .. checkedSection .. "' was found in PTS") else diff --git a/test_scripts/Policies/External_UCS/017_ATF_P_TC_PTU_without_disallowed_by_external_consent_entities_off_struct.lua b/test_scripts/Policies/External_UCS/017_ATF_P_TC_PTU_without_disallowed_by_external_consent_entities_off_struct.lua index 4de0c31161..b9d4696cb6 100644 --- a/test_scripts/Policies/External_UCS/017_ATF_P_TC_PTU_without_disallowed_by_external_consent_entities_off_struct.lua +++ b/test_scripts/Policies/External_UCS/017_ATF_P_TC_PTU_without_disallowed_by_external_consent_entities_off_struct.lua @@ -30,9 +30,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/018_ATF_P_TC_PTU_with_disallowed_by_external_consent_entities_off_struct.lua b/test_scripts/Policies/External_UCS/018_ATF_P_TC_PTU_with_disallowed_by_external_consent_entities_off_struct.lua index 927ec34566..cbd7c9c774 100644 --- a/test_scripts/Policies/External_UCS/018_ATF_P_TC_PTU_with_disallowed_by_external_consent_entities_off_struct.lua +++ b/test_scripts/Policies/External_UCS/018_ATF_P_TC_PTU_with_disallowed_by_external_consent_entities_off_struct.lua @@ -31,9 +31,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/019_ATF_P_TC_PTU_without_disallowed_by_external_consent_entities_on_struct.lua b/test_scripts/Policies/External_UCS/019_ATF_P_TC_PTU_without_disallowed_by_external_consent_entities_on_struct.lua index db58a92941..1a4f4718a1 100644 --- a/test_scripts/Policies/External_UCS/019_ATF_P_TC_PTU_without_disallowed_by_external_consent_entities_on_struct.lua +++ b/test_scripts/Policies/External_UCS/019_ATF_P_TC_PTU_without_disallowed_by_external_consent_entities_on_struct.lua @@ -30,9 +30,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/020_ATF_P_TC_PTU_with_disallowed_by_external_consent_entities_on_struct.lua b/test_scripts/Policies/External_UCS/020_ATF_P_TC_PTU_with_disallowed_by_external_consent_entities_on_struct.lua index 7a7173d213..70910e5ab6 100644 --- a/test_scripts/Policies/External_UCS/020_ATF_P_TC_PTU_with_disallowed_by_external_consent_entities_on_struct.lua +++ b/test_scripts/Policies/External_UCS/020_ATF_P_TC_PTU_with_disallowed_by_external_consent_entities_on_struct.lua @@ -31,9 +31,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/021_ATF_N_TC_PTU_with_disallowed_by_external_consent_entities_off_struct_with_invalid_type_of_params.lua b/test_scripts/Policies/External_UCS/021_ATF_N_TC_PTU_with_disallowed_by_external_consent_entities_off_struct_with_invalid_type_of_params.lua index 2e63284e26..d5b8af354a 100644 --- a/test_scripts/Policies/External_UCS/021_ATF_N_TC_PTU_with_disallowed_by_external_consent_entities_off_struct_with_invalid_type_of_params.lua +++ b/test_scripts/Policies/External_UCS/021_ATF_N_TC_PTU_with_disallowed_by_external_consent_entities_off_struct_with_invalid_type_of_params.lua @@ -23,9 +23,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/022_ATF_N_TC_PTU_with_disallowed_by_external_consent_entities_on_struct_with_invalid_type_of_params.lua b/test_scripts/Policies/External_UCS/022_ATF_N_TC_PTU_with_disallowed_by_external_consent_entities_on_struct_with_invalid_type_of_params.lua index 070a1269ed..0835e0d4c6 100644 --- a/test_scripts/Policies/External_UCS/022_ATF_N_TC_PTU_with_disallowed_by_external_consent_entities_on_struct_with_invalid_type_of_params.lua +++ b/test_scripts/Policies/External_UCS/022_ATF_N_TC_PTU_with_disallowed_by_external_consent_entities_on_struct_with_invalid_type_of_params.lua @@ -23,9 +23,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/023_ATF_P_TC_LPT_Update_PreloadedPT_without_external_consent_status_groups_struct.lua b/test_scripts/Policies/External_UCS/023_ATF_P_TC_LPT_Update_PreloadedPT_without_external_consent_status_groups_struct.lua index 6de257b0e9..e7f1543896 100644 --- a/test_scripts/Policies/External_UCS/023_ATF_P_TC_LPT_Update_PreloadedPT_without_external_consent_status_groups_struct.lua +++ b/test_scripts/Policies/External_UCS/023_ATF_P_TC_LPT_Update_PreloadedPT_without_external_consent_status_groups_struct.lua @@ -25,9 +25,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] @@ -36,6 +34,7 @@ local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') local sdl = require('SDL') local testCasesForExternalUCS = require('user_modules/shared_testcases/testCasesForExternalUCS') +local utils = require ('user_modules/utils') --[[ Local variables ]] local checkedSection = "external_consent_status_groups" @@ -67,10 +66,10 @@ function Test:CheckPreloadedPT() if preloadedTable and preloadedTable.policy_table and preloadedTable.policy_table.device_data - and preloadedTable.policy_table.device_data[config.deviceMAC] - and preloadedTable.policy_table.device_data[config.deviceMAC].user_consent_records + and preloadedTable.policy_table.device_data[utils.getDeviceMAC()] + and preloadedTable.policy_table.device_data[utils.getDeviceMAC()].user_consent_records then - for _, v in pairs(preloadedTable.policy_table.device_data[config.deviceMAC].user_consent_records) do + for _, v in pairs(preloadedTable.policy_table.device_data[utils.getDeviceMAC()].user_consent_records) do if v[checkedSection] then result = false end diff --git a/test_scripts/Policies/External_UCS/024_ATF_N_TC_LPT_Update_PreloadedPT_with_external_consent_status_groups_struct.lua b/test_scripts/Policies/External_UCS/024_ATF_N_TC_LPT_Update_PreloadedPT_with_external_consent_status_groups_struct.lua index d1dbf54f12..7290a1305a 100644 --- a/test_scripts/Policies/External_UCS/024_ATF_N_TC_LPT_Update_PreloadedPT_with_external_consent_status_groups_struct.lua +++ b/test_scripts/Policies/External_UCS/024_ATF_N_TC_LPT_Update_PreloadedPT_with_external_consent_status_groups_struct.lua @@ -26,9 +26,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 config.ExitOnCrash = false @@ -39,6 +37,7 @@ local commonPreconditions = require('user_modules/shared_testcases/commonPrecond local sdl = require('SDL') local testCasesForExternalUCS = require('user_modules/shared_testcases/testCasesForExternalUCS') local testCasesForPolicySDLErrorsStops = require('user_modules/shared_testcases/testCasesForPolicySDLErrorsStops') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() @@ -80,7 +79,7 @@ function Test.UpdatePreloadedPT() local updateFunc = function(preloadedTable) preloadedTable.policy_table.module_config.preloaded_date = os.date("%Y-%m-%d") preloadedTable.policy_table.device_data = { - [config.deviceMAC] = { + [utils.getDeviceMAC()] = { user_consent_records = { [config.application1.registerAppInterfaceParams.appID] = { external_consent_status_groups = { diff --git a/test_scripts/Policies/External_UCS/025_ATF_P_TC_LPT_Update_PreloadedPT_without_disallowed_by_external_consent_entities_off_struct.lua b/test_scripts/Policies/External_UCS/025_ATF_P_TC_LPT_Update_PreloadedPT_without_disallowed_by_external_consent_entities_off_struct.lua index 875e191117..63a6156821 100644 --- a/test_scripts/Policies/External_UCS/025_ATF_P_TC_LPT_Update_PreloadedPT_without_disallowed_by_external_consent_entities_off_struct.lua +++ b/test_scripts/Policies/External_UCS/025_ATF_P_TC_LPT_Update_PreloadedPT_without_disallowed_by_external_consent_entities_off_struct.lua @@ -30,9 +30,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/026_ATF_P_TC_LPT_Update_PreloadedPT_with_disallowed_by_external_consent_entities_off_struct.lua b/test_scripts/Policies/External_UCS/026_ATF_P_TC_LPT_Update_PreloadedPT_with_disallowed_by_external_consent_entities_off_struct.lua index e0bfb19255..305569027e 100644 --- a/test_scripts/Policies/External_UCS/026_ATF_P_TC_LPT_Update_PreloadedPT_with_disallowed_by_external_consent_entities_off_struct.lua +++ b/test_scripts/Policies/External_UCS/026_ATF_P_TC_LPT_Update_PreloadedPT_with_disallowed_by_external_consent_entities_off_struct.lua @@ -29,9 +29,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/027_ATF_P_TC_LPT_Update_PreloadedPT_without_disallowed_by_external_consent_entities_on_struct.lua b/test_scripts/Policies/External_UCS/027_ATF_P_TC_LPT_Update_PreloadedPT_without_disallowed_by_external_consent_entities_on_struct.lua index c5f4f0b24b..bb9e115d75 100644 --- a/test_scripts/Policies/External_UCS/027_ATF_P_TC_LPT_Update_PreloadedPT_without_disallowed_by_external_consent_entities_on_struct.lua +++ b/test_scripts/Policies/External_UCS/027_ATF_P_TC_LPT_Update_PreloadedPT_without_disallowed_by_external_consent_entities_on_struct.lua @@ -30,9 +30,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/028_ATF_P_TC_LPT_Update_PreloadedPT_with_disallowed_by_external_consent_entities_on_struct.lua b/test_scripts/Policies/External_UCS/028_ATF_P_TC_LPT_Update_PreloadedPT_with_disallowed_by_external_consent_entities_on_struct.lua index 7ce9473bd7..d5c57ee2ce 100644 --- a/test_scripts/Policies/External_UCS/028_ATF_P_TC_LPT_Update_PreloadedPT_with_disallowed_by_external_consent_entities_on_struct.lua +++ b/test_scripts/Policies/External_UCS/028_ATF_P_TC_LPT_Update_PreloadedPT_with_disallowed_by_external_consent_entities_on_struct.lua @@ -29,9 +29,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared Libraries ]] diff --git a/test_scripts/Policies/External_UCS/029_ATF_N_TC_LPT_Update_PreloadedPT_with_disallowed_by_external_consent_entities_off_struct_with_invalid_type_of_params.lua b/test_scripts/Policies/External_UCS/029_ATF_N_TC_LPT_Update_PreloadedPT_with_disallowed_by_external_consent_entities_off_struct_with_invalid_type_of_params.lua index e5b93f1dcd..90c6572caa 100644 --- a/test_scripts/Policies/External_UCS/029_ATF_N_TC_LPT_Update_PreloadedPT_with_disallowed_by_external_consent_entities_off_struct_with_invalid_type_of_params.lua +++ b/test_scripts/Policies/External_UCS/029_ATF_N_TC_LPT_Update_PreloadedPT_with_disallowed_by_external_consent_entities_off_struct_with_invalid_type_of_params.lua @@ -27,9 +27,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 config.ExitOnCrash = false diff --git a/test_scripts/Policies/External_UCS/030_ATF_N_TC_LPT_Update_PreloadedPT_with_disallowed_by_external_consent_entities_on_struct_with_invalid_type_of_params.lua b/test_scripts/Policies/External_UCS/030_ATF_N_TC_LPT_Update_PreloadedPT_with_disallowed_by_external_consent_entities_on_struct_with_invalid_type_of_params.lua index 852e93e438..aa7083f2ff 100644 --- a/test_scripts/Policies/External_UCS/030_ATF_N_TC_LPT_Update_PreloadedPT_with_disallowed_by_external_consent_entities_on_struct_with_invalid_type_of_params.lua +++ b/test_scripts/Policies/External_UCS/030_ATF_N_TC_LPT_Update_PreloadedPT_with_disallowed_by_external_consent_entities_on_struct_with_invalid_type_of_params.lua @@ -27,9 +27,7 @@ -- -- Note: Script is designed for EXTERNAL_PROPRIETARY flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 config.ExitOnCrash = false diff --git a/test_scripts/Policies/External_UCS/External_Consent_OFF/007_ATF_Policies_External_Consent_OFF_disallowed_by_external_consent_entities_omitted_data_consent_disallowed.lua b/test_scripts/Policies/External_UCS/External_Consent_OFF/007_ATF_Policies_External_Consent_OFF_disallowed_by_external_consent_entities_omitted_data_consent_disallowed.lua index 5b804d9ce2..1324c01769 100644 --- a/test_scripts/Policies/External_UCS/External_Consent_OFF/007_ATF_Policies_External_Consent_OFF_disallowed_by_external_consent_entities_omitted_data_consent_disallowed.lua +++ b/test_scripts/Policies/External_UCS/External_Consent_OFF/007_ATF_Policies_External_Consent_OFF_disallowed_by_external_consent_entities_omitted_data_consent_disallowed.lua @@ -105,7 +105,10 @@ Test["TEST_NAME_OFF".."_Precondition_GetListOfPermissions"] = function(self) result = { code = 0, method = "SDL.GetListOfPermissions", - allowedFunctions = {{name = "ConsentGroup001", allowed = nil}}, + allowedFunctions = { + {name = "ConsentGroup001", allowed = nil}, + {name = "ConsentGroup002", allowed = nil} + }, externalConsentStatus = {} } }) diff --git a/test_scripts/Policies/External_UCS/External_Consent_OFF/008_ATF_Policies_External_Consent_OFF_disallowed_by_external_consent_entities_omitted_user_consent_allowed.lua b/test_scripts/Policies/External_UCS/External_Consent_OFF/008_ATF_Policies_External_Consent_OFF_disallowed_by_external_consent_entities_omitted_user_consent_allowed.lua index e0789e72b8..d22e6069b2 100644 --- a/test_scripts/Policies/External_UCS/External_Consent_OFF/008_ATF_Policies_External_Consent_OFF_disallowed_by_external_consent_entities_omitted_user_consent_allowed.lua +++ b/test_scripts/Policies/External_UCS/External_Consent_OFF/008_ATF_Policies_External_Consent_OFF_disallowed_by_external_consent_entities_omitted_user_consent_allowed.lua @@ -106,7 +106,10 @@ Test["TEST_NAME_OFF".."_Precondition_GetListOfPermissions"] = function(self) result = { code = 0, method = "SDL.GetListOfPermissions", - allowedFunctions = {{name = "ConsentGroup001", allowed = nil}}, + allowedFunctions = { + {name = "ConsentGroup001", allowed = nil}, + {name = "ConsentGroup002", allowed = nil} + }, externalConsentStatus = {} } }) diff --git a/test_scripts/Policies/External_UCS/External_Consent_OFF/009_ATF_Policies_External_Consent_OFF_disallowed_by_external_consent_entities_omitted_user_consent_disallowed.lua b/test_scripts/Policies/External_UCS/External_Consent_OFF/009_ATF_Policies_External_Consent_OFF_disallowed_by_external_consent_entities_omitted_user_consent_disallowed.lua index d887f90f1d..80dc9dda28 100644 --- a/test_scripts/Policies/External_UCS/External_Consent_OFF/009_ATF_Policies_External_Consent_OFF_disallowed_by_external_consent_entities_omitted_user_consent_disallowed.lua +++ b/test_scripts/Policies/External_UCS/External_Consent_OFF/009_ATF_Policies_External_Consent_OFF_disallowed_by_external_consent_entities_omitted_user_consent_disallowed.lua @@ -106,7 +106,10 @@ Test["TEST_NAME_OFF".."_Precondition_GetListOfPermissions"] = function(self) result = { code = 0, method = "SDL.GetListOfPermissions", - allowedFunctions = {{name = "ConsentGroup001", allowed = nil}}, + allowedFunctions = { + {name = "ConsentGroup001", allowed = nil}, + {name = "ConsentGroup002", allowed = nil} + }, externalConsentStatus = {} } }) diff --git a/test_scripts/Policies/External_UCS/External_Consent_ON/007_ATF_Policies_External_Consent_ON_disallowed_by_external_consent_entities_omitted_data_consent_disallowed.lua b/test_scripts/Policies/External_UCS/External_Consent_ON/007_ATF_Policies_External_Consent_ON_disallowed_by_external_consent_entities_omitted_data_consent_disallowed.lua index 63f53a329a..0fa29c52fd 100644 --- a/test_scripts/Policies/External_UCS/External_Consent_ON/007_ATF_Policies_External_Consent_ON_disallowed_by_external_consent_entities_omitted_data_consent_disallowed.lua +++ b/test_scripts/Policies/External_UCS/External_Consent_ON/007_ATF_Policies_External_Consent_ON_disallowed_by_external_consent_entities_omitted_data_consent_disallowed.lua @@ -105,7 +105,10 @@ Test[TEST_NAME_ON .. "Precondition_GetListOfPermissions"] = function(self) result = { code = 0, method = "SDL.GetListOfPermissions", - allowedFunctions = {{name = "ConsentGroup001", allowed = nil}}, + allowedFunctions = { + {name = "ConsentGroup001", allowed = nil}, + {name = "ConsentGroup002", allowed = nil} + }, externalConsentStatus = {} } }) diff --git a/test_scripts/Policies/External_UCS/External_Consent_ON/008_ATF_Policies_External_Consent_ON_disallowed_by_external_consent_entities_omitted_user_consent_allowed.lua b/test_scripts/Policies/External_UCS/External_Consent_ON/008_ATF_Policies_External_Consent_ON_disallowed_by_external_consent_entities_omitted_user_consent_allowed.lua index f5aa4421b1..9ac8ff1fe5 100644 --- a/test_scripts/Policies/External_UCS/External_Consent_ON/008_ATF_Policies_External_Consent_ON_disallowed_by_external_consent_entities_omitted_user_consent_allowed.lua +++ b/test_scripts/Policies/External_UCS/External_Consent_ON/008_ATF_Policies_External_Consent_ON_disallowed_by_external_consent_entities_omitted_user_consent_allowed.lua @@ -105,7 +105,10 @@ Test[TEST_NAME_ON .. "Precondition_GetListOfPermissions"] = function(self) result = { code = 0, method = "SDL.GetListOfPermissions", - allowedFunctions = {{name = "ConsentGroup001", allowed = nil}}, + allowedFunctions = { + {name = "ConsentGroup001", allowed = nil}, + {name = "ConsentGroup002", allowed = nil} + }, externalConsentStatus = {} } }) diff --git a/test_scripts/Policies/External_UCS/External_Consent_ON/009_ATF_Policies_External_Consent_ON_disallowed_by_external_consent_entities_omitted_user_consent_disallowed.lua b/test_scripts/Policies/External_UCS/External_Consent_ON/009_ATF_Policies_External_Consent_ON_disallowed_by_external_consent_entities_omitted_user_consent_disallowed.lua index 69e18c938c..4e3b0323b8 100644 --- a/test_scripts/Policies/External_UCS/External_Consent_ON/009_ATF_Policies_External_Consent_ON_disallowed_by_external_consent_entities_omitted_user_consent_disallowed.lua +++ b/test_scripts/Policies/External_UCS/External_Consent_ON/009_ATF_Policies_External_Consent_ON_disallowed_by_external_consent_entities_omitted_user_consent_disallowed.lua @@ -105,7 +105,10 @@ Test[TEST_NAME_ON .. "Precondition_GetListOfPermissions"] = function(self) result = { code = 0, method = "SDL.GetListOfPermissions", - allowedFunctions = {{name = "ConsentGroup001", allowed = nil}}, + allowedFunctions = { + {name = "ConsentGroup001", allowed = nil}, + {name = "ConsentGroup002", allowed = nil} + }, externalConsentStatus = {} } }) diff --git a/test_scripts/Policies/External_UCS/External_Consent_ON/010_ATF_Policies_External_Consent_ON_disallowed_by_external_consent_entities_omitted_user_consent_omitted.lua b/test_scripts/Policies/External_UCS/External_Consent_ON/010_ATF_Policies_External_Consent_ON_disallowed_by_external_consent_entities_omitted_user_consent_omitted.lua index b687da46e3..9897e0f8c0 100644 --- a/test_scripts/Policies/External_UCS/External_Consent_ON/010_ATF_Policies_External_Consent_ON_disallowed_by_external_consent_entities_omitted_user_consent_omitted.lua +++ b/test_scripts/Policies/External_UCS/External_Consent_ON/010_ATF_Policies_External_Consent_ON_disallowed_by_external_consent_entities_omitted_user_consent_omitted.lua @@ -105,7 +105,10 @@ Test[TEST_NAME_ON .. "Precondition_GetListOfPermissions"] = function(self) result = { code = 0, method = "SDL.GetListOfPermissions", - allowedFunctions = {{name = "ConsentGroup001", allowed = nil}}, + allowedFunctions = { + {name = "ConsentGroup001", allowed = nil}, + {name = "ConsentGroup002", allowed = nil} + }, externalConsentStatus = {} } }) diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/001_ATF_P_GetListofPermissions_with_appID_all_ecs_in_bound_EntitySatus_ON.lua b/test_scripts/Policies/External_UCS/Informing_HMI/001_ATF_P_GetListofPermissions_with_appID_all_ecs_in_bound_EntitySatus_ON.lua index d0a9ce7b1e..194880a01e 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/001_ATF_P_GetListofPermissions_with_appID_all_ecs_in_bound_EntitySatus_ON.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/001_ATF_P_GetListofPermissions_with_appID_all_ecs_in_bound_EntitySatus_ON.lua @@ -23,14 +23,11 @@ -- Expected result: -- SDL sends do HMI received from HMI --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -44,7 +41,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PTU_and_OnAppPermissionConsent_AllParams_Valid() diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/003_ATF_P_GetListofPermissions_with_appID_all_ecs_upper_bound_EntitySatus_ON.lua b/test_scripts/Policies/External_UCS/Informing_HMI/003_ATF_P_GetListofPermissions_with_appID_all_ecs_upper_bound_EntitySatus_ON.lua index 8860b41855..6bd3604d77 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/003_ATF_P_GetListofPermissions_with_appID_all_ecs_upper_bound_EntitySatus_ON.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/003_ATF_P_GetListofPermissions_with_appID_all_ecs_upper_bound_EntitySatus_ON.lua @@ -23,17 +23,13 @@ -- Expected result: -- SDL sends to HMI received from HMI --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local variables ]] - local external_consent_status = {} for i =1, 100 do @@ -52,7 +48,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PTU_and_OnAppPermissionConsent_AllParams_Upper() diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/004_ATF_P_GetListofPermissions_with_appID_fake_param_cut_EntitySatus_ON.lua b/test_scripts/Policies/External_UCS/Informing_HMI/004_ATF_P_GetListofPermissions_with_appID_fake_param_cut_EntitySatus_ON.lua index b1c0dd67d7..ebf992945b 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/004_ATF_P_GetListofPermissions_with_appID_fake_param_cut_EntitySatus_ON.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/004_ATF_P_GetListofPermissions_with_appID_fake_param_cut_EntitySatus_ON.lua @@ -24,14 +24,11 @@ -- Expected result: -- SDL sends to HMI --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -45,7 +42,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PTU_and_OnAppPermissionConsent_FakeParam() diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/005_ATF_P_GetListofPermissions_with_appID_all_ecs_in_bound_EntitySatus_OFF.lua b/test_scripts/Policies/External_UCS/Informing_HMI/005_ATF_P_GetListofPermissions_with_appID_all_ecs_in_bound_EntitySatus_OFF.lua index 8aebe6a4e4..48c7dd732f 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/005_ATF_P_GetListofPermissions_with_appID_all_ecs_in_bound_EntitySatus_OFF.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/005_ATF_P_GetListofPermissions_with_appID_all_ecs_in_bound_EntitySatus_OFF.lua @@ -23,14 +23,11 @@ -- Expected result: -- SDL sends to HMI received from HMI --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -44,7 +41,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PTU_and_OnAppPermissionConsent_AllParams_Valid() diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/006_ATF_P_GetListofPermissions_with_appID_all_ecs_lower_bound_EntitySatus_OFF.lua b/test_scripts/Policies/External_UCS/Informing_HMI/006_ATF_P_GetListofPermissions_with_appID_all_ecs_lower_bound_EntitySatus_OFF.lua index fdc552cb59..719089679d 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/006_ATF_P_GetListofPermissions_with_appID_all_ecs_lower_bound_EntitySatus_OFF.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/006_ATF_P_GetListofPermissions_with_appID_all_ecs_lower_bound_EntitySatus_OFF.lua @@ -23,14 +23,11 @@ -- Expected result: -- SDL sends to HMI received from HMI --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -44,7 +41,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PTU_and_OnAppPermissionConsent_AllParams_Lower() diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/007_ATF_P_GetListofPermissions_with_appID_all_ecs_upper_bound_EntitySatus_OFF.lua b/test_scripts/Policies/External_UCS/Informing_HMI/007_ATF_P_GetListofPermissions_with_appID_all_ecs_upper_bound_EntitySatus_OFF.lua index 1958552eb8..7422453cd1 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/007_ATF_P_GetListofPermissions_with_appID_all_ecs_upper_bound_EntitySatus_OFF.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/007_ATF_P_GetListofPermissions_with_appID_all_ecs_upper_bound_EntitySatus_OFF.lua @@ -23,14 +23,11 @@ -- Expected result: -- SDL sends to HMI received from HMI --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local variables ]] @@ -52,7 +49,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PTU_and_OnAppPermissionConsent_AllParams_Upper() diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/008_ATF_P_GetListofPermissions_with_appID_fake_param_cut_EntitySatus_OFF.lua b/test_scripts/Policies/External_UCS/Informing_HMI/008_ATF_P_GetListofPermissions_with_appID_fake_param_cut_EntitySatus_OFF.lua index 46734eb4ef..50cdb240e5 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/008_ATF_P_GetListofPermissions_with_appID_fake_param_cut_EntitySatus_OFF.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/008_ATF_P_GetListofPermissions_with_appID_fake_param_cut_EntitySatus_OFF.lua @@ -24,14 +24,11 @@ -- Expected result: -- SDL sends to HMI --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -45,7 +42,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PTU_and_OnAppPermissionConsent_FakeParam() diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/009_ATF_P_GetListofPermissions_with_appID_not_stored_ecs.lua b/test_scripts/Policies/External_UCS/Informing_HMI/009_ATF_P_GetListofPermissions_with_appID_not_stored_ecs.lua index bcab4d6c35..e466d4f081 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/009_ATF_P_GetListofPermissions_with_appID_not_stored_ecs.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/009_ATF_P_GetListofPermissions_with_appID_not_stored_ecs.lua @@ -22,14 +22,11 @@ -- Expected result: -- SDL sends to HMI empty array --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -43,7 +40,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PTU_and_OnAppPermissionConsent_Empty() diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/010_ATF_P_GetListofPermissions_no_appID_stored_ecs_present.lua b/test_scripts/Policies/External_UCS/Informing_HMI/010_ATF_P_GetListofPermissions_no_appID_stored_ecs_present.lua index 733db172a4..7d1b434aff 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/010_ATF_P_GetListofPermissions_no_appID_stored_ecs_present.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/010_ATF_P_GetListofPermissions_no_appID_stored_ecs_present.lua @@ -23,14 +23,11 @@ -- Expected result: -- SDL sends to HMI received from HMI --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -44,7 +41,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PTU_and_OnAppPermissionConsent_AllParams() diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/011_ATF_P_GetListofPermissions_no_appID_not_stored_ecs.lua b/test_scripts/Policies/External_UCS/Informing_HMI/011_ATF_P_GetListofPermissions_no_appID_not_stored_ecs.lua index 373ea9584d..0ddfe7f3ec 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/011_ATF_P_GetListofPermissions_no_appID_not_stored_ecs.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/011_ATF_P_GetListofPermissions_no_appID_not_stored_ecs.lua @@ -22,14 +22,11 @@ -- Expected result: -- SDL sends to HMI empty array --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -43,7 +40,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PTU_and_OnAppPermissionConsent_Empty() diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/012_ATF_N_GetListofPermissions_no_appID_no_app_registered_stored_ecs.lua b/test_scripts/Policies/External_UCS/Informing_HMI/012_ATF_N_GetListofPermissions_no_appID_no_app_registered_stored_ecs.lua index 6da31bacfb..e15dcc6364 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/012_ATF_N_GetListofPermissions_no_appID_no_app_registered_stored_ecs.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/012_ATF_N_GetListofPermissions_no_appID_no_app_registered_stored_ecs.lua @@ -24,14 +24,11 @@ -- SDL invalidates the appID and cuts it off, the GetListOfPermissions request is treated as if sent without appID -- SDL sends to HMI received from HMI --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -45,7 +42,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PTU_and_OnAppPermissionConsent_AllParams() diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/013_ATF_N_GetListofPermissions_no_appID_no_app_registered_not_stored_ecs.lua b/test_scripts/Policies/External_UCS/Informing_HMI/013_ATF_N_GetListofPermissions_no_appID_no_app_registered_not_stored_ecs.lua index a0a01d3567..6f3bace400 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/013_ATF_N_GetListofPermissions_no_appID_no_app_registered_not_stored_ecs.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/013_ATF_N_GetListofPermissions_no_appID_no_app_registered_not_stored_ecs.lua @@ -23,14 +23,11 @@ -- SDL invalidates the appID and cuts it off, the GetListOfPermissions request is treated as if sent without appID -- SDL sends to HMI empty array --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -44,7 +41,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PTU_and_OnAppPermissionConsent_Empty() diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/014_ATF_N_GetListofPermissions_no_appID_app_unregistered_stored_ecs.lua b/test_scripts/Policies/External_UCS/Informing_HMI/014_ATF_N_GetListofPermissions_no_appID_app_unregistered_stored_ecs.lua index 73c078cddc..ba59810abe 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/014_ATF_N_GetListofPermissions_no_appID_app_unregistered_stored_ecs.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/014_ATF_N_GetListofPermissions_no_appID_app_unregistered_stored_ecs.lua @@ -25,15 +25,12 @@ -- SDL invalidates the appID and cuts it off, the GetListOfPermissions request is treated as if sent without appID -- SDL sends to HMI received from HMI --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local mobile_session = require('mobile_session') +local utils = require ('user_modules/utils') local hmi_appid --[[ General Precondition before ATF start ]] @@ -48,7 +45,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PTU_and_OnAppPermissionConsent_AllParams_First_Application() diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/015_ATF_N_GetListofPermissions_no_appID_app_unregistered_not_stored_ecs.lua b/test_scripts/Policies/External_UCS/Informing_HMI/015_ATF_N_GetListofPermissions_no_appID_app_unregistered_not_stored_ecs.lua index 91c0c56bdd..669b7df92e 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/015_ATF_N_GetListofPermissions_no_appID_app_unregistered_not_stored_ecs.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/015_ATF_N_GetListofPermissions_no_appID_app_unregistered_not_stored_ecs.lua @@ -24,15 +24,12 @@ -- SDL invalidates the appID and cuts it off, the GetListOfPermissions request is treated as if sent without appID -- SDL sends to HMI empty array --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local mobile_session = require('mobile_session') +local utils = require ('user_modules/utils') local hmi_appid --[[ General Precondition before ATF start ]] @@ -47,7 +44,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PTU_and_OnAppPermissionConsent_Empty_First_Application() diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/016_ATF_N_GetListofPermissions_empty_due_to_missing_entity_type_OnAppPermissionChange.lua b/test_scripts/Policies/External_UCS/Informing_HMI/016_ATF_N_GetListofPermissions_empty_due_to_missing_entity_type_OnAppPermissionChange.lua index 61dcd66099..a146a313e6 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/016_ATF_N_GetListofPermissions_empty_due_to_missing_entity_type_OnAppPermissionChange.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/016_ATF_N_GetListofPermissions_empty_due_to_missing_entity_type_OnAppPermissionChange.lua @@ -23,9 +23,7 @@ -- Expected result: -- SDL sends to HMI empty array --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" -- ToDo (vvvakulenko): remove after issue "ATF does not stop HB timers by closing session and connection" is resolved config.defaultProtocolVersion = 2 @@ -34,6 +32,7 @@ local commonFunctions = require ('user_modules/shared_testcases/commonFunctions' local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() @@ -49,7 +48,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PTU_and_OnAppPermissionConsent_entityType_missing() diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/017_ATF_N_GetListofPermissions_empty_due_to_missing_entityID_OnAppPermissionChange.lua b/test_scripts/Policies/External_UCS/Informing_HMI/017_ATF_N_GetListofPermissions_empty_due_to_missing_entityID_OnAppPermissionChange.lua index 1cd23d64c5..99bac80da1 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/017_ATF_N_GetListofPermissions_empty_due_to_missing_entityID_OnAppPermissionChange.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/017_ATF_N_GetListofPermissions_empty_due_to_missing_entityID_OnAppPermissionChange.lua @@ -23,9 +23,7 @@ -- Expected result: -- SDL sends to HMI empty array --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" -- ToDo (vvvakulenko): remove after issue "ATF does not stop HB timers by closing session and connection" is resolved config.defaultProtocolVersion = 2 @@ -34,6 +32,7 @@ local commonFunctions = require ('user_modules/shared_testcases/commonFunctions' local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() @@ -49,7 +48,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PTU_and_OnAppPermissionConsent_entityID_missing() diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/018_ATF_N_GetListofPermissions_empty_due_to_missing_status_OnAppPermissionChange.lua b/test_scripts/Policies/External_UCS/Informing_HMI/018_ATF_N_GetListofPermissions_empty_due_to_missing_status_OnAppPermissionChange.lua index cfd20a4d9f..1f43d297be 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/018_ATF_N_GetListofPermissions_empty_due_to_missing_status_OnAppPermissionChange.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/018_ATF_N_GetListofPermissions_empty_due_to_missing_status_OnAppPermissionChange.lua @@ -22,10 +22,7 @@ -- -- Expected result: -- SDL sends to HMI empty array ---------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +-----------------------------------------------------------------------------------------------[[ General configuration parameters ]] -- ToDo (vvvakulenko): remove after issue "ATF does not stop HB timers by closing session and connection" is resolved config.defaultProtocolVersion = 2 @@ -34,6 +31,7 @@ local commonFunctions = require ('user_modules/shared_testcases/commonFunctions' local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() @@ -49,7 +47,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PTU_and_OnAppPermissionConsent_entityStatus_missing() diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/019_ATF_N_GetListofPermissions_empty_due_to_invalid_param_entityType_OnAppPermissionChange.lua b/test_scripts/Policies/External_UCS/Informing_HMI/019_ATF_N_GetListofPermissions_empty_due_to_invalid_param_entityType_OnAppPermissionChange.lua index 0c7a796529..dda91b0075 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/019_ATF_N_GetListofPermissions_empty_due_to_invalid_param_entityType_OnAppPermissionChange.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/019_ATF_N_GetListofPermissions_empty_due_to_invalid_param_entityType_OnAppPermissionChange.lua @@ -25,9 +25,7 @@ -- Expected result: -- SDL sends to HMI empty array --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" -- ToDo (vvvakulenko): remove after issue "ATF does not stop HB timers by closing session and connection" is resolved config.defaultProtocolVersion = 2 @@ -36,6 +34,7 @@ local commonFunctions = require ('user_modules/shared_testcases/commonFunctions' local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +local utils = require ('user_modules/utils') --[[Local Variables]] local params_invalid_data = @@ -65,7 +64,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end for i = 1, #params_invalid_data do diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/020_ATF_N_GetListofPermissions_empty_due_to_invalid_param_entityID_OnAppPermissionChange.lua b/test_scripts/Policies/External_UCS/Informing_HMI/020_ATF_N_GetListofPermissions_empty_due_to_invalid_param_entityID_OnAppPermissionChange.lua index 380c531da4..76f148206f 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/020_ATF_N_GetListofPermissions_empty_due_to_invalid_param_entityID_OnAppPermissionChange.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/020_ATF_N_GetListofPermissions_empty_due_to_invalid_param_entityID_OnAppPermissionChange.lua @@ -25,9 +25,7 @@ -- Expected result: -- SDL sends to HMI empty array --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" -- ToDo (vvvakulenko): remove after issue "ATF does not stop HB timers by closing session and connection" is resolved config.defaultProtocolVersion = 2 @@ -36,6 +34,7 @@ local commonFunctions = require ('user_modules/shared_testcases/commonFunctions' local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +local utils = require ('user_modules/utils') --[[Local Variables]] local params_invalid_data = @@ -65,7 +64,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end for i = 1, #params_invalid_data do diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/021_ATF_N_GetListofPermissions_empty_due_to_invalid_param_status_OnAppPermissionChange.lua b/test_scripts/Policies/External_UCS/Informing_HMI/021_ATF_N_GetListofPermissions_empty_due_to_invalid_param_status_OnAppPermissionChange.lua index 33d0f7de92..0506707797 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/021_ATF_N_GetListofPermissions_empty_due_to_invalid_param_status_OnAppPermissionChange.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/021_ATF_N_GetListofPermissions_empty_due_to_invalid_param_status_OnAppPermissionChange.lua @@ -25,9 +25,7 @@ -- Expected result: -- SDL sends to HMI empty array --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" -- ToDo (vvvakulenko): remove after issue "ATF does not stop HB timers by closing session and connection" is resolved config.defaultProtocolVersion = 2 @@ -36,6 +34,7 @@ local commonFunctions = require ('user_modules/shared_testcases/commonFunctions' local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +local utils = require ('user_modules/utils') --[[Local Variables]] local params_invalid_data = @@ -67,7 +66,7 @@ require('user_modules/AppTypes') function Test:Precondition_trigger_getting_device_consent() testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, - config.deviceMAC) + utils.getDeviceMAC()) end for i = 1, #params_invalid_data do diff --git a/test_scripts/Policies/External_UCS/Informing_HMI/022_ATF_N_OnAppPermissionConsent_not_sent_when_no_PTU.lua b/test_scripts/Policies/External_UCS/Informing_HMI/022_ATF_N_OnAppPermissionConsent_not_sent_when_no_PTU.lua index a448728aa0..f84f561f48 100644 --- a/test_scripts/Policies/External_UCS/Informing_HMI/022_ATF_N_OnAppPermissionConsent_not_sent_when_no_PTU.lua +++ b/test_scripts/Policies/External_UCS/Informing_HMI/022_ATF_N_OnAppPermissionConsent_not_sent_when_no_PTU.lua @@ -22,15 +22,12 @@ -- PTU is triggered -- HMI notification SDL.OnAppPermissionChanged is not sent --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -44,7 +41,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Test") function Test:TestStep_No_PTU_No_OnAppPermissionConsent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) EXPECT_HMINOTIFICATION("SDL.OnAppPermissionChanged"):Times(0) commonTestCases:DelayedExp(10000) end diff --git a/test_scripts/Policies/Policies_Security/119_ATF_P_Policies_Performance_Requirement.lua b/test_scripts/Policies/Policies_Security/119_ATF_P_Policies_Performance_Requirement.lua index d29f4fc35e..3a6830e63f 100644 --- a/test_scripts/Policies/Policies_Security/119_ATF_P_Policies_Performance_Requirement.lua +++ b/test_scripts/Policies/Policies_Security/119_ATF_P_Policies_Performance_Requirement.lua @@ -13,9 +13,7 @@ -- Expected result -- SDL must correctly finish the PTU --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] @@ -23,6 +21,7 @@ local mobile_session = require("mobile_session") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local json = require("modules/json") +local utils = require ('user_modules/utils') --[[ Local Variables ]] local app_id = config.application1.registerAppInterfaceParams.appID @@ -208,7 +207,7 @@ function Test:Activate_App() :Do( function() log("SDL->HMI: RS: SDL.GetUserFriendlyMessage") - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) log("HMI->SDL: N: SDL.OnAllowSDLFunctionality") EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do( diff --git a/test_scripts/Policies/Policies_Security/120_ATF_PolicyTable_Certificate_EMPTY_value.lua b/test_scripts/Policies/Policies_Security/120_ATF_PolicyTable_Certificate_EMPTY_value.lua index b7813f9a8b..629b75178b 100644 --- a/test_scripts/Policies/Policies_Security/120_ATF_PolicyTable_Certificate_EMPTY_value.lua +++ b/test_scripts/Policies/Policies_Security/120_ATF_PolicyTable_Certificate_EMPTY_value.lua @@ -1,12 +1,11 @@ ----- Name of requirement that is covered----- ----- [Security]: SDL behavior in case 'certificates' field is empty - ----- Description: + ----- Description: ----- Certificate have empty value in sdl_preloaded_pt JSON of module_config section ----- Expected result------ ----- SDL must continue working as assigned. ------------------------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 @@ -51,7 +50,7 @@ local function UpdatePreloadedJson_CertificateValue_Empty() if data.policy_table.functional_groupings["DataConsent-2"] then data.policy_table.functional_groupings["DataConsent-2"] = nil end - + data.policy_table.module_config.certificate = "" data = json.encode(data) @@ -126,6 +125,6 @@ function Test.Postcondition_SDLStop() end function Test.Postcondition_Restore_preloaded() commonPreconditions:RestoreFile("sdl_preloaded_pt.json") -end +end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Policy_Table_Update/121_ATF_PTU_AppID_NotListed_PT_DeviceConsented_SecondApp.lua b/test_scripts/Policies/Policy_Table_Update/121_ATF_PTU_AppID_NotListed_PT_DeviceConsented_SecondApp.lua index ff2f75802d..3b3b6b6188 100644 --- a/test_scripts/Policies/Policy_Table_Update/121_ATF_PTU_AppID_NotListed_PT_DeviceConsented_SecondApp.lua +++ b/test_scripts/Policies/Policy_Table_Update/121_ATF_PTU_AppID_NotListed_PT_DeviceConsented_SecondApp.lua @@ -18,15 +18,12 @@ -- SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) -- SDL->HMI: BasicCommunication.PolicyUpdate --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -46,7 +43,7 @@ local mobile_session = require('mobile_session') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_flow_SUCCEESS_EXTERNAL_PROPRIETARY() @@ -77,7 +74,7 @@ function Test:TestStep_PTU_AppID_SecondApp_NotListed_PT() config.application1.registerAppInterfaceParams.appID, config.application2.registerAppInterfaceParams.appID, }, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {hmi_app1_id, hmi_app2_id}) local timeout_after_x_seconds = testCasesForPolicyTableSnapshot:get_data_from_PTS("module_config.timeout_after_x_seconds") diff --git a/test_scripts/Policies/Policy_Table_Update/122_ATF_PTU_NotSuccessful_AppID_ListedPT_NewIgnCycle.lua b/test_scripts/Policies/Policy_Table_Update/122_ATF_PTU_NotSuccessful_AppID_ListedPT_NewIgnCycle.lua index d254085fa1..fd58af3c64 100644 --- a/test_scripts/Policies/Policy_Table_Update/122_ATF_PTU_NotSuccessful_AppID_ListedPT_NewIgnCycle.lua +++ b/test_scripts/Policies/Policy_Table_Update/122_ATF_PTU_NotSuccessful_AppID_ListedPT_NewIgnCycle.lua @@ -20,15 +20,12 @@ -- PTU is requested. PTS is created. -- SDL-> HMI: SDL.PolicyUpdate() --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ Local Variables ]] local hmi_app_id1, hmi_app_id2 @@ -49,7 +46,7 @@ local mobile_session = require('mobile_session') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_flow_SUCCEESS_EXTERNAL_PROPRIETARY() @@ -76,7 +73,7 @@ function Test:Precondition_RegisterNewApplication() :Do(function(_,_data3) testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID, config.application2.registerAppInterfaceParams.appID}, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {hmi_app_id1, hmi_app_id2}) local timeout_after_x_seconds = testCasesForPolicyTableSnapshot:get_data_from_PTS("module_config.timeout_after_x_seconds") @@ -147,7 +144,7 @@ function Test:TestStep_PTU_NotSuccessful_AppID_ListedPT_NewIgnCycle() :Do(function(_,_data4) testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID, config.application2.registerAppInterfaceParams.appID}, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {hmi_app_id1, hmi_app_id2}) local timeout_after_x_seconds = testCasesForPolicyTableSnapshot:get_data_from_PTS("module_config.timeout_after_x_seconds") diff --git a/test_scripts/Policies/Policy_Table_Update/123_ATF_PTU_DeviceConsent_from_User.lua b/test_scripts/Policies/Policy_Table_Update/123_ATF_PTU_DeviceConsent_from_User.lua index 1423a5ed2c..81df7d428b 100644 --- a/test_scripts/Policies/Policy_Table_Update/123_ATF_PTU_DeviceConsent_from_User.lua +++ b/test_scripts/Policies/Policy_Table_Update/123_ATF_PTU_DeviceConsent_from_User.lua @@ -16,14 +16,11 @@ -- PTU is requested. PTS is created. -- SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local Functions ]] local function check_file_exists(name) @@ -58,7 +55,7 @@ function Test:ActivateApp() EXPECT_HMIRESPONSE(requestId2) :Do(function(_, _) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_, data2) self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", { }) diff --git a/test_scripts/Policies/Policy_Table_Update/124_ATF_User_requests_PTU.lua b/test_scripts/Policies/Policy_Table_Update/124_ATF_User_requests_PTU.lua index a1179c6601..a1dfda4850 100644 --- a/test_scripts/Policies/Policy_Table_Update/124_ATF_User_requests_PTU.lua +++ b/test_scripts/Policies/Policy_Table_Update/124_ATF_User_requests_PTU.lua @@ -19,15 +19,12 @@ -- SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) -- SDL->HMI: BasicCommunication.PolicyUpdate --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -43,7 +40,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_trigger_getting_device_consent() @@ -69,7 +66,7 @@ function Test:TestStep_User_requests_PTU() :Do(function(_,data) testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID}, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {hmi_app1_id}) local timeout_after_x_seconds = testCasesForPolicyTableSnapshot:get_data_from_PTS("module_config.timeout_after_x_seconds") diff --git a/test_scripts/Policies/Policy_Table_Update/125_ATF_User_PressButton_HMI_PTU.lua b/test_scripts/Policies/Policy_Table_Update/125_ATF_User_PressButton_HMI_PTU.lua index 80fb9d6988..985a9a29cc 100644 --- a/test_scripts/Policies/Policy_Table_Update/125_ATF_User_PressButton_HMI_PTU.lua +++ b/test_scripts/Policies/Policy_Table_Update/125_ATF_User_PressButton_HMI_PTU.lua @@ -18,15 +18,12 @@ -- SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) -- SDL->HMI: BasicCommunication.PolicyUpdate --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local commonSteps = require('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed @@ -41,7 +38,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_flow_SUCCEESS_EXTERNAL_PROPRIETARY() @@ -68,7 +65,7 @@ function Test:TC_User_PressButton_HMI_PTU() :Do(function(_,data) testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID}, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {hmi_app1_id}) local timeout_after_x_seconds = testCasesForPolicyTableSnapshot:get_data_from_PTS("module_config.timeout_after_x_seconds") diff --git a/test_scripts/Policies/Policy_Table_Update/126_ATF_OnStatusUpdate_UPDATE_NEEDED_new_PTU_request.lua b/test_scripts/Policies/Policy_Table_Update/126_ATF_OnStatusUpdate_UPDATE_NEEDED_new_PTU_request.lua index e81cf17661..29edaed4f5 100644 --- a/test_scripts/Policies/Policy_Table_Update/126_ATF_OnStatusUpdate_UPDATE_NEEDED_new_PTU_request.lua +++ b/test_scripts/Policies/Policy_Table_Update/126_ATF_OnStatusUpdate_UPDATE_NEEDED_new_PTU_request.lua @@ -18,15 +18,12 @@ -- SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) -- SDL->HMI: BasicCommunication.PolicyUpdate --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonTestCases = require ('user_modules/shared_testcases/commonTestCases') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -43,7 +40,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_flow_SUCCEESS_EXTERNAL_PROPRIETARY() diff --git a/test_scripts/Policies/Policy_Table_Update/127_ATF_PTS_Creation_rule.lua b/test_scripts/Policies/Policy_Table_Update/127_ATF_PTS_Creation_rule.lua index e046534098..8d2345f5cc 100644 --- a/test_scripts/Policies/Policy_Table_Update/127_ATF_PTS_Creation_rule.lua +++ b/test_scripts/Policies/Policy_Table_Update/127_ATF_PTS_Creation_rule.lua @@ -14,15 +14,12 @@ -- Expected result: -- PTU is requested. PTS is created. --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -40,7 +37,6 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Test") function Test:TestStep_PTS_Creation_rule() local hmi_app1_id = self.applications[config.application1.registerAppInterfaceParams.appName] - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local result = true local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) @@ -54,14 +50,14 @@ function Test:TestStep_PTS_Creation_rule() testCasesForPolicyTable.time_trigger = timestamp() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true}}) end) EXPECT_HMICALL("BasicCommunication.PolicyUpdate", { file = "/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json" }) :Do(function(_,data) result = testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID}, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {hmi_app1_id}, "print") diff --git a/test_scripts/Policies/Policy_Table_Update/128_ATF_PTU_GetURLs.lua b/test_scripts/Policies/Policy_Table_Update/128_ATF_PTU_GetURLs.lua index 6dbab6f1f0..cba025497d 100644 --- a/test_scripts/Policies/Policy_Table_Update/128_ATF_PTU_GetURLs.lua +++ b/test_scripts/Policies/Policy_Table_Update/128_ATF_PTU_GetURLs.lua @@ -16,15 +16,12 @@ -- PTU is requested. PTS is created. -- SDL.GetURLs({urls[] = registered_App1, default}) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -41,7 +38,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/Policy_Table_Update/129_ATF_HMI_sends_GetURLs_one_app_registered.lua b/test_scripts/Policies/Policy_Table_Update/129_ATF_HMI_sends_GetURLs_one_app_registered.lua index 42791bfba5..e079421d67 100644 --- a/test_scripts/Policies/Policy_Table_Update/129_ATF_HMI_sends_GetURLs_one_app_registered.lua +++ b/test_scripts/Policies/Policy_Table_Update/129_ATF_HMI_sends_GetURLs_one_app_registered.lua @@ -16,15 +16,12 @@ -- PTU is requested. PTS is created. -- SDL.GetURLs({urls[] = registered_App1, default}) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -42,7 +39,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/Policy_Table_Update/130_ATF_HMI_sends_GetURLs_no_app_registered.lua b/test_scripts/Policies/Policy_Table_Update/130_ATF_HMI_sends_GetURLs_no_app_registered.lua index d912a9c6ec..50e79ce4e8 100644 --- a/test_scripts/Policies/Policy_Table_Update/130_ATF_HMI_sends_GetURLs_no_app_registered.lua +++ b/test_scripts/Policies/Policy_Table_Update/130_ATF_HMI_sends_GetURLs_no_app_registered.lua @@ -18,15 +18,12 @@ -- PTU is requested. PTS is created. -- SDL.GetURLs({urls[] = default}) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -44,7 +41,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_flow_PTU_SUCCEESS_EXTERNAL_PROPRIETARY() diff --git a/test_scripts/Policies/Policy_Table_Update/131_ATF_PTS_storage_on_file_system.lua b/test_scripts/Policies/Policy_Table_Update/131_ATF_PTS_storage_on_file_system.lua index 1952fb3d04..f2c08f7dfa 100644 --- a/test_scripts/Policies/Policy_Table_Update/131_ATF_PTS_storage_on_file_system.lua +++ b/test_scripts/Policies/Policy_Table_Update/131_ATF_PTS_storage_on_file_system.lua @@ -14,15 +14,12 @@ -- The policies manager must store the PT snapshot as a JSON file which filename and -- filepath are defined in "PathToSnapshot" parameter of smartDeviceLink.ini file. --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -41,7 +38,6 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_PTS_Storage_On_File_System() local SystemFilesPath = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") local PathToSnapshot = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) EXPECT_HMIRESPONSE(RequestId) @@ -52,7 +48,7 @@ function Test:TestStep_PTS_Storage_On_File_System() :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true}}) local function check_snapshot() if ( commonSteps:file_exists( SystemFilesPath..'/' .. PathToSnapshot) == false ) then self:FailTestCase(SystemFilesPath..'/' .. PathToSnapshot.."sdl_snapshot.json doesn't exist!") diff --git a/test_scripts/Policies/Policy_Table_Update/132_ATF_Timeout_to_wait_response_PTU.lua b/test_scripts/Policies/Policy_Table_Update/132_ATF_Timeout_to_wait_response_PTU.lua index c451e28afc..6a3c21b94d 100644 --- a/test_scripts/Policies/Policy_Table_Update/132_ATF_Timeout_to_wait_response_PTU.lua +++ b/test_scripts/Policies/Policy_Table_Update/132_ATF_Timeout_to_wait_response_PTU.lua @@ -14,15 +14,12 @@ -- To define the timeout to wait a response on PTU, Policies manager must refer PTS -- "module_config" section, key . --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -41,7 +38,6 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_PTS_Timeout_wait_response_PTU() local is_test_fail = false local hmi_app_id = self.applications[config.application1.registerAppInterfaceParams.appName] - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) EXPECT_HMIRESPONSE(RequestId) @@ -51,14 +47,14 @@ function Test:TestStep_PTS_Timeout_wait_response_PTU() EXPECT_HMIRESPONSE( RequestId1, {result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true}}) end) end) EXPECT_HMICALL("BasicCommunication.PolicyUpdate",{}) :Do(function(_,data) testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID}, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {hmi_app_id}) local timeout_after_x_seconds = testCasesForPolicyTableSnapshot:get_data_from_Preloaded_PT("module_config.timeout_after_x_seconds") @@ -79,4 +75,4 @@ function Test.Postcondition_Stop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Policy_Table_Update/133_ATF_PTU_retry_timeout_definition.lua b/test_scripts/Policies/Policy_Table_Update/133_ATF_PTU_retry_timeout_definition.lua index 739d65e74a..06553738ec 100644 --- a/test_scripts/Policies/Policy_Table_Update/133_ATF_PTU_retry_timeout_definition.lua +++ b/test_scripts/Policies/Policy_Table_Update/133_ATF_PTU_retry_timeout_definition.lua @@ -15,16 +15,13 @@ -- Number and values of the "retry" elements are provided as appropriate elements in -- "seconds_between_retries" section of Local PT. --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -43,7 +40,6 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Test") function Test:TestStep_PTS_Timeout_wait_response_PTU() local hmi_app_id = self.applications[config.application1.registerAppInterfaceParams.appName] - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) EXPECT_HMIRESPONSE(RequestId) @@ -53,14 +49,14 @@ function Test:TestStep_PTS_Timeout_wait_response_PTU() EXPECT_HMIRESPONSE( RequestId1, {result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true}}) end) EXPECT_HMICALL("BasicCommunication.PolicyUpdate",{}) :Do(function(_,_) testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID}, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {hmi_app_id}) local seconds_between_retries_pts = testCasesForPolicyTableSnapshot.seconds_between_retries local seconds_between_retries_preloaded = {} @@ -92,4 +88,4 @@ function Test.Postcondition_Stop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Policy_Table_Update/134_ATF_WiFi_one_application_registered.lua b/test_scripts/Policies/Policy_Table_Update/134_ATF_WiFi_one_application_registered.lua index b33938cc86..149e950be9 100644 --- a/test_scripts/Policies/Policy_Table_Update/134_ATF_WiFi_one_application_registered.lua +++ b/test_scripts/Policies/Policy_Table_Update/134_ATF_WiFi_one_application_registered.lua @@ -19,15 +19,12 @@ -- SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) -- SDL-> HMI: SDL.PolicyUpdate() --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -42,7 +39,7 @@ local mobile_session = require('mobile_session') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_Getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_flow_SUCCEESS_EXTERNAL_PROPRIETARY() @@ -73,7 +70,7 @@ function Test:TestStep_PTU_AppID_NotListed_PT_WiFi() :Do(function(_,_data1) testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID, config.application1.registerAppInterfaceParams.appID}, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {hmi_app_id1, hmi_app_id2}) local timeout_after_x_seconds = testCasesForPolicyTableSnapshot:get_data_from_PTS("module_config.timeout_after_x_seconds") diff --git a/test_scripts/Policies/Policy_Table_Update/135_ATF_PM_sends_PTS_to_HMI.lua b/test_scripts/Policies/Policy_Table_Update/135_ATF_PM_sends_PTS_to_HMI.lua index 02c3fdb912..6e37c76cc4 100644 --- a/test_scripts/Policies/Policy_Table_Update/135_ATF_PM_sends_PTS_to_HMI.lua +++ b/test_scripts/Policies/Policy_Table_Update/135_ATF_PM_sends_PTS_to_HMI.lua @@ -14,15 +14,12 @@ -- Expected result: -- SDL->HMI:SDL.PolicyUpdate(file, timeout, retry[]) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -43,7 +40,6 @@ commonFunctions:newTestCasesGroup("Preconditions") function Test:TestStep_PolicyManager_sends_PTS_to_HMI() local is_test_fail = false local hmi_app_id = self.applications[config.application1.registerAppInterfaceParams.appName] - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) EXPECT_HMIRESPONSE(RequestId) @@ -54,13 +50,13 @@ function Test:TestStep_PolicyManager_sends_PTS_to_HMI() :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true}}) EXPECT_HMICALL("BasicCommunication.PolicyUpdate",{}) :Do(function(_,data) testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID}, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {hmi_app_id}) local SystemFilesPath = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") @@ -84,4 +80,4 @@ function Test.Postcondition_Stop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Policy_Table_Update/136_ATF_Define_urls_PTS_will_sent_hmi.lua b/test_scripts/Policies/Policy_Table_Update/136_ATF_Define_urls_PTS_will_sent_hmi.lua index fb65e52977..3d10aebaec 100644 --- a/test_scripts/Policies/Policy_Table_Update/136_ATF_Define_urls_PTS_will_sent_hmi.lua +++ b/test_scripts/Policies/Policy_Table_Update/136_ATF_Define_urls_PTS_will_sent_hmi.lua @@ -17,14 +17,11 @@ -- Expected result: -- SDL.GetURLs({urls[] = default}, (, appID)) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -42,7 +39,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] @@ -81,4 +78,4 @@ function Test.Postcondition_Stop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Policy_Table_Update/137_ATF_Sending_PTS_to_mobile_application.lua b/test_scripts/Policies/Policy_Table_Update/137_ATF_Sending_PTS_to_mobile_application.lua index 8fa77b7d2c..e37dfb277d 100644 --- a/test_scripts/Policies/Policy_Table_Update/137_ATF_Sending_PTS_to_mobile_application.lua +++ b/test_scripts/Policies/Policy_Table_Update/137_ATF_Sending_PTS_to_mobile_application.lua @@ -20,15 +20,14 @@ -- Expected result: -- SDL->app: OnSystemRequest ('url', requestType:PROPRIETARY, fileType="JSON", appID) --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local mobile_session = require("mobile_session") local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() @@ -85,7 +84,7 @@ function Test:Trigger_getting_device_consent() EXPECT_HMIRESPONSE(requestId2) :Do( function() - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do( function(_, d2) diff --git a/test_scripts/Policies/Policy_Table_Update/138_ATF_Sending_PTS_to_app_OnSystemRequest_appID_default.lua b/test_scripts/Policies/Policy_Table_Update/138_ATF_Sending_PTS_to_app_OnSystemRequest_appID_default.lua index 0a2a8839b3..0d62ec3f8b 100644 --- a/test_scripts/Policies/Policy_Table_Update/138_ATF_Sending_PTS_to_app_OnSystemRequest_appID_default.lua +++ b/test_scripts/Policies/Policy_Table_Update/138_ATF_Sending_PTS_to_app_OnSystemRequest_appID_default.lua @@ -24,15 +24,12 @@ -- -- SDL->: OnSystemRequest ('url', requestType:PROPRIETARY, fileType="JSON") --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local mobileSession = require("mobile_session") +local utils = require ('user_modules/utils') --[[ Local Variables ]] local r_actual = { } @@ -54,7 +51,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:StartNewSession() diff --git a/test_scripts/Policies/Policy_Table_Update/139_ATF_PoliciesManager_changes_status_UPDATING.lua b/test_scripts/Policies/Policy_Table_Update/139_ATF_PoliciesManager_changes_status_UPDATING.lua index c581fc3047..569bd17b45 100644 --- a/test_scripts/Policies/Policy_Table_Update/139_ATF_PoliciesManager_changes_status_UPDATING.lua +++ b/test_scripts/Policies/Policy_Table_Update/139_ATF_PoliciesManager_changes_status_UPDATING.lua @@ -21,14 +21,11 @@ -- Expected result: -- SDL->HMI: SDL.OnStatusUpdate(UPDATING) right after SDL->app: OnSystemRequest --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -45,7 +42,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/Policy_Table_Update/140_ATF_timeout_countdown_start.lua b/test_scripts/Policies/Policy_Table_Update/140_ATF_timeout_countdown_start.lua index 2240824555..45fca43e28 100644 --- a/test_scripts/Policies/Policy_Table_Update/140_ATF_timeout_countdown_start.lua +++ b/test_scripts/Policies/Policy_Table_Update/140_ATF_timeout_countdown_start.lua @@ -22,16 +22,13 @@ -- SDL waits for SystemRequest response from within 'timeout' value, if no obtained, -- it starts retry sequence --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -48,7 +45,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/Policy_Table_Update/141_ATF_Got_PTU_from_mobile_application.lua b/test_scripts/Policies/Policy_Table_Update/141_ATF_Got_PTU_from_mobile_application.lua index 888baba6d8..1ff4926e20 100644 --- a/test_scripts/Policies/Policy_Table_Update/141_ATF_Got_PTU_from_mobile_application.lua +++ b/test_scripts/Policies/Policy_Table_Update/141_ATF_Got_PTU_from_mobile_application.lua @@ -22,15 +22,12 @@ -- Expected result: -- SDL->HMI: SystemRequest(requestType=PROPRIETARY, fileName, appID) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -47,7 +44,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/Policy_Table_Update/142_ATF_PoliciesManager_changes_status_to_UP_TO_DATE.lua b/test_scripts/Policies/Policy_Table_Update/142_ATF_PoliciesManager_changes_status_to_UP_TO_DATE.lua index a54b0f942e..5f9d6954f5 100644 --- a/test_scripts/Policies/Policy_Table_Update/142_ATF_PoliciesManager_changes_status_to_UP_TO_DATE.lua +++ b/test_scripts/Policies/Policy_Table_Update/142_ATF_PoliciesManager_changes_status_to_UP_TO_DATE.lua @@ -26,14 +26,11 @@ -- Expected result: -- SDL->HMI: OnStatusUpdate(UP_TO_DATE) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -50,7 +47,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/Policy_Table_Update/143_ATF_PTU_validation_rules.lua b/test_scripts/Policies/Policy_Table_Update/143_ATF_PTU_validation_rules.lua index ab1d740f7c..fc2e6c5799 100644 --- a/test_scripts/Policies/Policy_Table_Update/143_ATF_PTU_validation_rules.lua +++ b/test_scripts/Policies/Policy_Table_Update/143_ATF_PTU_validation_rules.lua @@ -27,15 +27,12 @@ -- SDL->HMI: OnStatusUpdate(UP_TO_DATE) -- SDL stops timeout started by OnSystemRequest. No other OnSystemRequest are received. --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --local testCasesForPolicyTableUpdateFile = require('user_modules/shared_testcases/testCasesForPolicyTableUpdateFile') @@ -54,7 +51,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] @@ -64,7 +61,7 @@ function Test:TestStep_PTU_validation_rules() local endpoints = {} is_verification_passed = testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID }, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {""}, "print") for i = 1, #testCasesForPolicyTableSnapshot.pts_endpoints do @@ -108,4 +105,4 @@ function Test.Postcondition_Stop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Policy_Table_Update/144_ATF_PTU_validation_failure.lua b/test_scripts/Policies/Policy_Table_Update/144_ATF_PTU_validation_failure.lua index b978a0c118..17b46d6f28 100644 --- a/test_scripts/Policies/Policy_Table_Update/144_ATF_PTU_validation_failure.lua +++ b/test_scripts/Policies/Policy_Table_Update/144_ATF_PTU_validation_failure.lua @@ -27,16 +27,13 @@ -- SDL->HMI: OnStatusUpdate(UPDATE_NEEDED) -- SDL removes 'policyfile' from the directory --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local testCasesForPolicySDLErrorsStops = require('user_modules/shared_testcases/testCasesForPolicySDLErrorsStops') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -53,7 +50,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/Policy_Table_Update/145_ATF_PTU_Merge_Into_LPT.lua b/test_scripts/Policies/Policy_Table_Update/145_ATF_PTU_Merge_Into_LPT.lua index 97da3c8321..3eb7089885 100644 --- a/test_scripts/Policies/Policy_Table_Update/145_ATF_PTU_Merge_Into_LPT.lua +++ b/test_scripts/Policies/Policy_Table_Update/145_ATF_PTU_Merge_Into_LPT.lua @@ -19,9 +19,6 @@ -- Expected result: -- Previous version of sections in LPT are replaced by a new ones --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local json = require("modules/json") local mobileSession = require("mobile_session") @@ -29,6 +26,7 @@ local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonPreconditions = require("user_modules/shared_testcases/commonPreconditions") local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local Variables ]] local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") @@ -96,7 +94,7 @@ require("user_modules/AppTypes") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_ActivateApp() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/Policy_Table_Update/146_ATF_HMILvl_on_PTU_affected_in_FULL_or_LIMITED.lua b/test_scripts/Policies/Policy_Table_Update/146_ATF_HMILvl_on_PTU_affected_in_FULL_or_LIMITED.lua index 36f903352b..9d54634a47 100644 --- a/test_scripts/Policies/Policy_Table_Update/146_ATF_HMILvl_on_PTU_affected_in_FULL_or_LIMITED.lua +++ b/test_scripts/Policies/Policy_Table_Update/146_ATF_HMILvl_on_PTU_affected_in_FULL_or_LIMITED.lua @@ -18,15 +18,13 @@ -- 3) After PTU OnPermissionsChange is called for both applications. --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local json = require('json') + --[[ Local Variables ]] local HMIAppID2 diff --git a/test_scripts/Policies/Policy_Table_Update/147_ATF_Policy_Table_Update_Trigger_After_N_Kilometers.lua b/test_scripts/Policies/Policy_Table_Update/147_ATF_Policy_Table_Update_Trigger_After_N_Kilometers.lua index 93f37d1681..47f99c7d56 100644 --- a/test_scripts/Policies/Policy_Table_Update/147_ATF_Policy_Table_Update_Trigger_After_N_Kilometers.lua +++ b/test_scripts/Policies/Policy_Table_Update/147_ATF_Policy_Table_Update_Trigger_After_N_Kilometers.lua @@ -21,9 +21,7 @@ -- PTS is created by SDL: -- SDL-> HMI: SDL.PolicyUpdate() //PTU sequence started --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -31,6 +29,7 @@ config.defaultProtocolVersion = 2 local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFiles() @@ -86,7 +85,7 @@ function Test:Precondition_Activate_App_And_Consent_Device_To_Start_PTU() local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data) self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/Policy_Table_Update/148_ATF_HMILvl_on_PTU_affected_in_BACKGROUND_or_NONE.lua b/test_scripts/Policies/Policy_Table_Update/148_ATF_HMILvl_on_PTU_affected_in_BACKGROUND_or_NONE.lua index 5c4177b96d..d02c1a2dbf 100644 --- a/test_scripts/Policies/Policy_Table_Update/148_ATF_HMILvl_on_PTU_affected_in_BACKGROUND_or_NONE.lua +++ b/test_scripts/Policies/Policy_Table_Update/148_ATF_HMILvl_on_PTU_affected_in_BACKGROUND_or_NONE.lua @@ -20,7 +20,6 @@ --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] @@ -28,6 +27,7 @@ local mobileSession = require("mobile_session") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local json = require("modules/json") +local utils = require ('user_modules/utils') --[[ Local Variables ]] local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") @@ -85,7 +85,7 @@ local function activate_app(self, id) local requestId2 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", { language = "EN-US", messageCodes = { "DataConsent" } }) EXPECT_HMIRESPONSE(requestId2) :Do(function() - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_, data2) self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", { }) diff --git a/test_scripts/Policies/Policy_Table_Update/149_ATF_Policy_Table_Update_Trigger_After_N_Days.lua b/test_scripts/Policies/Policy_Table_Update/149_ATF_Policy_Table_Update_Trigger_After_N_Days.lua index 34e6f4617a..972e661235 100644 --- a/test_scripts/Policies/Policy_Table_Update/149_ATF_Policy_Table_Update_Trigger_After_N_Days.lua +++ b/test_scripts/Policies/Policy_Table_Update/149_ATF_Policy_Table_Update_Trigger_After_N_Days.lua @@ -18,9 +18,7 @@ -- PTS is created by SDL: -- SDL-> HMI: SDL.PolicyUpdate() //PTU sequence started --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -28,6 +26,7 @@ config.defaultProtocolVersion = 2 local commonSteps = require ('user_modules/shared_testcases/commonSteps') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local Variables ]] local exchangeDays = 30 @@ -77,7 +76,7 @@ function Test:Precondition_Activate_App_Consent_Device() local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/Policy_Table_Update/150_ATF_Notifying_HMI_via_OnAppPermissionChanged.lua b/test_scripts/Policies/Policy_Table_Update/150_ATF_Notifying_HMI_via_OnAppPermissionChanged.lua index 1de22712c2..a3d4c43f7b 100644 --- a/test_scripts/Policies/Policy_Table_Update/150_ATF_Notifying_HMI_via_OnAppPermissionChanged.lua +++ b/test_scripts/Policies/Policy_Table_Update/150_ATF_Notifying_HMI_via_OnAppPermissionChanged.lua @@ -28,7 +28,6 @@ -- 6.SDL->HMI: SDL.OnAppPermissionChanged(, params) --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -37,6 +36,7 @@ local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local json = require('json') +local utils = require ('user_modules/utils') --[[ Local Variables ]] local basic_ptu_file = "files/ptu.json" @@ -75,7 +75,7 @@ function Test:Precondition_ActivateApp() local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/Policy_Table_Update/151_ATF_Apply_PTU_and_OnPermissionChange_notify.lua b/test_scripts/Policies/Policy_Table_Update/151_ATF_Apply_PTU_and_OnPermissionChange_notify.lua index e77bf134f9..f83035010e 100644 --- a/test_scripts/Policies/Policy_Table_Update/151_ATF_Apply_PTU_and_OnPermissionChange_notify.lua +++ b/test_scripts/Policies/Policy_Table_Update/151_ATF_Apply_PTU_and_OnPermissionChange_notify.lua @@ -28,16 +28,14 @@ -- 4. SDL removes 'policyfile' from the directory -- 5. SDL->appID_1: onPermissionChange(permisssions) -- 6. SDL->HMI: SDL.OnAppPermissionChanged(appID_1, permissions) - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - +--------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local json = require('json') local mobile_session = require('mobile_session') +local utils = require ('user_modules/utils') --[[ Local Variables ]] local HMIAppID diff --git a/test_scripts/Policies/Policy_Table_Update/152_ATF_PTU_Merge_Of_Consumer_Friendly_Messages.lua b/test_scripts/Policies/Policy_Table_Update/152_ATF_PTU_Merge_Of_Consumer_Friendly_Messages.lua index db62a28063..9892470219 100644 --- a/test_scripts/Policies/Policy_Table_Update/152_ATF_PTU_Merge_Of_Consumer_Friendly_Messages.lua +++ b/test_scripts/Policies/Policy_Table_Update/152_ATF_PTU_Merge_Of_Consumer_Friendly_Messages.lua @@ -17,19 +17,16 @@ -- Expected result: -- Previous version of consumer_friendly_messages.messages section in LPT has to be replaced by a new one. --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") +local utils = require ('user_modules/utils') --[[ Local Variables ]] --local db_file = config.pathToSDL .. "/" .. commonFunctions:read_parameter_from_smart_device_link_ini("AppStorageFolder") .. "/policy.sqlite" local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") -local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local ptu_file = "files/jsons/Policies/Policy_Table_Update/ptu_18192.json" --[[ Local Functions ]] @@ -70,7 +67,7 @@ function Test:Precondition_ActivateApp() EXPECT_HMIRESPONSE(requestId2) :Do(function(_, _) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = ServerAddress } }) + { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_, data2) self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", { }) diff --git a/test_scripts/Policies/Policy_Table_Update/153_ATF_PTU_Omit_Of_Consumer_Friendly_Messages.lua b/test_scripts/Policies/Policy_Table_Update/153_ATF_PTU_Omit_Of_Consumer_Friendly_Messages.lua index 5939b5f985..dd6fab8436 100644 --- a/test_scripts/Policies/Policy_Table_Update/153_ATF_PTU_Omit_Of_Consumer_Friendly_Messages.lua +++ b/test_scripts/Policies/Policy_Table_Update/153_ATF_PTU_Omit_Of_Consumer_Friendly_Messages.lua @@ -18,14 +18,12 @@ -- Previous version of consumer_friendly_messages section is retained -- Number of records is not changed --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local Variables ]] local r_expected @@ -81,7 +79,7 @@ function Test:Precondition_ActivateApp() EXPECT_HMIRESPONSE(requestId2) :Do(function(_, _) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_, data2) self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", { }) diff --git a/test_scripts/Policies/Policy_Table_Update/154_ATF_PTU_SDL_Must_Remove_PTU_File_Got_From_Sync_After_Getting_The_Updates.lua b/test_scripts/Policies/Policy_Table_Update/154_ATF_PTU_SDL_Must_Remove_PTU_File_Got_From_Sync_After_Getting_The_Updates.lua index 6defb13cc3..23ed25c5fb 100644 --- a/test_scripts/Policies/Policy_Table_Update/154_ATF_PTU_SDL_Must_Remove_PTU_File_Got_From_Sync_After_Getting_The_Updates.lua +++ b/test_scripts/Policies/Policy_Table_Update/154_ATF_PTU_SDL_Must_Remove_PTU_File_Got_From_Sync_After_Getting_The_Updates.lua @@ -19,13 +19,11 @@ -- Expected result: -- PTU file is deleted --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") +local utils = require ('user_modules/utils') --[[ Local Variables ]] local policy_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" @@ -65,7 +63,7 @@ function Test:Precondition_ActivateApp() EXPECT_HMIRESPONSE(requestId2) :Do(function(_, _) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_, data2) self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", { }) diff --git a/test_scripts/Policies/Policy_Table_Update/155_ATF_PTU_Policies_Manager_Changes_Status_To_UPDATE_NEEDED.lua b/test_scripts/Policies/Policy_Table_Update/155_ATF_PTU_Policies_Manager_Changes_Status_To_UPDATE_NEEDED.lua index efde703277..76543f6dd7 100644 --- a/test_scripts/Policies/Policy_Table_Update/155_ATF_PTU_Policies_Manager_Changes_Status_To_UPDATE_NEEDED.lua +++ b/test_scripts/Policies/Policy_Table_Update/155_ATF_PTU_Policies_Manager_Changes_Status_To_UPDATE_NEEDED.lua @@ -22,16 +22,13 @@ -- -- TODO: Reduce value of timeout_after_x_seconds parameter in LPT in order to make test faster --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() @@ -48,7 +45,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] @@ -56,7 +53,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_ChangeStatus_Update_Needed() local time_update_needed = {} local time_system_request = {} - local endpoints = {} + local endpoints = { { url = "http://policies.telematics.ford.com/api/policies" } } local is_test_fail = false local timeout_pts = testCasesForPolicyTableSnapshot:get_data_from_PTS("module_config.timeout_after_x_seconds") local seconds_between_retries = {} diff --git a/test_scripts/Policies/Policy_Table_Update/156_ATF_PTU_OnStatusUpdate_Trigger.lua b/test_scripts/Policies/Policy_Table_Update/156_ATF_PTU_OnStatusUpdate_Trigger.lua index 23d138bd79..7a5d774b04 100644 --- a/test_scripts/Policies/Policy_Table_Update/156_ATF_PTU_OnStatusUpdate_Trigger.lua +++ b/test_scripts/Policies/Policy_Table_Update/156_ATF_PTU_OnStatusUpdate_Trigger.lua @@ -17,14 +17,12 @@ -- Status changes in a wollowing way: -- "UPDATE_NEEDED" -> "UPDATING" -> "UP_TO_DATE" -> "UPDATE_NEEDED" -> "UPDATING" --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") +local utils = require ('user_modules/utils') --[[ Local variables ]] local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" @@ -45,7 +43,6 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_Trigger_Device_consent() local is_test_fail = false self.hmi_app1_id = self.applications[config.application1.registerAppInterfaceParams.appName] - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) @@ -58,7 +55,7 @@ function Test:TestStep_Trigger_Device_consent() testCasesForPolicyTable.time_trigger = timestamp() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true}}) -- EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATE_NEEDED"}) diff --git a/test_scripts/Policies/Policy_Table_Update/157_ATF_PTU_Policies_Manager_Changes_Status_To_UPDATING.lua b/test_scripts/Policies/Policy_Table_Update/157_ATF_PTU_Policies_Manager_Changes_Status_To_UPDATING.lua index d411818a20..f41cfdfd21 100644 --- a/test_scripts/Policies/Policy_Table_Update/157_ATF_PTU_Policies_Manager_Changes_Status_To_UPDATING.lua +++ b/test_scripts/Policies/Policy_Table_Update/157_ATF_PTU_Policies_Manager_Changes_Status_To_UPDATING.lua @@ -15,13 +15,11 @@ -- Expected result: -- SDL.OnStatusUpdate(UPDATING) notification is send right after SDL->MOB: OnSystemRequest --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -35,7 +33,7 @@ require("user_modules/AppTypes") commonFunctions:newTestCasesGroup("Precondition") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] @@ -91,4 +89,4 @@ function Test.Postcondition_StopSDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Policy_Table_Update/158_ATF_PTU_Policies_Manager_Changes_Status_To_UP_TO_DATE.lua b/test_scripts/Policies/Policy_Table_Update/158_ATF_PTU_Policies_Manager_Changes_Status_To_UP_TO_DATE.lua index b929dde4e5..27de595ea6 100644 --- a/test_scripts/Policies/Policy_Table_Update/158_ATF_PTU_Policies_Manager_Changes_Status_To_UP_TO_DATE.lua +++ b/test_scripts/Policies/Policy_Table_Update/158_ATF_PTU_Policies_Manager_Changes_Status_To_UP_TO_DATE.lua @@ -15,13 +15,11 @@ -- Expected result: -- SDL.OnStatusUpdate(UP_TO_DATE) notification is send right after successful validation of received PTU --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -35,7 +33,7 @@ require("user_modules/AppTypes") commonFunctions:newTestCasesGroup("Precondition") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/Policy_Table_Update/159_ATF_PTU_Requirements_For_HMILevel_Of_The_Application_Taking_Part_In_Policy_Update.lua b/test_scripts/Policies/Policy_Table_Update/159_ATF_PTU_Requirements_For_HMILevel_Of_The_Application_Taking_Part_In_Policy_Update.lua index 7f015057ef..f0d255d01b 100644 --- a/test_scripts/Policies/Policy_Table_Update/159_ATF_PTU_Requirements_For_HMILevel_Of_The_Application_Taking_Part_In_Policy_Update.lua +++ b/test_scripts/Policies/Policy_Table_Update/159_ATF_PTU_Requirements_For_HMILevel_Of_The_Application_Taking_Part_In_Policy_Update.lua @@ -19,7 +19,6 @@ -- app_1 doesn't take part in PTU (except of the case when app_1 is the only application being run on SDL) --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] @@ -28,6 +27,7 @@ local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +local utils = require ('user_modules/utils') --[[ Local Variables ]] local hmiLevels = { } @@ -99,7 +99,7 @@ function Test:TestStep_ActivateApp_2() EXPECT_HMIRESPONSE(requestId2) :Do(function(_, _) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) end) end end) diff --git a/test_scripts/Policies/Policy_Table_Update/160_ATF_Default_Policy_For_The_App_After_PTU.lua b/test_scripts/Policies/Policy_Table_Update/160_ATF_Default_Policy_For_The_App_After_PTU.lua index c6c2879131..64ae56ecee 100644 --- a/test_scripts/Policies/Policy_Table_Update/160_ATF_Default_Policy_For_The_App_After_PTU.lua +++ b/test_scripts/Policies/Policy_Table_Update/160_ATF_Default_Policy_For_The_App_After_PTU.lua @@ -19,9 +19,7 @@ -- b) PTU successfully passed -- c) SDL respons SUCCESS for allowed RPC and DISALLOW for disallow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.appName = "SPT" @@ -33,6 +31,7 @@ local commonFunctions = require ('user_modules/shared_testcases/commonFunctions' local commonSteps = require ('user_modules/shared_testcases/commonSteps') local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFiles() @@ -86,7 +85,7 @@ function Test:Precondition_Register_Activate_App_And_Consent_Device() local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data) self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/Policy_Table_Update/161_ATF_User_Trigger_PTU_While_Another_Is_In_Progress.lua b/test_scripts/Policies/Policy_Table_Update/161_ATF_User_Trigger_PTU_While_Another_Is_In_Progress.lua index cd043b6ad3..cded5fef83 100644 --- a/test_scripts/Policies/Policy_Table_Update/161_ATF_User_Trigger_PTU_While_Another_Is_In_Progress.lua +++ b/test_scripts/Policies/Policy_Table_Update/161_ATF_User_Trigger_PTU_While_Another_Is_In_Progress.lua @@ -19,15 +19,14 @@ -- c) PoliciesManager starts the PTU sequence: -- d) PTS is created by SDL: SDL-> HMI: SDL.PolicyUpdate() //PTU sequence started --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFiles() @@ -51,7 +50,7 @@ function Test:Precondition_Activate_App_And_Consent_Device_To_Start_PTU() local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data) self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/Policy_Table_Update/162_ATF_Policies_UTF-8_Encoding.lua b/test_scripts/Policies/Policy_Table_Update/162_ATF_Policies_UTF-8_Encoding.lua index a1f09ff15c..a2f973bbb8 100644 --- a/test_scripts/Policies/Policy_Table_Update/162_ATF_Policies_UTF-8_Encoding.lua +++ b/test_scripts/Policies/Policy_Table_Update/162_ATF_Policies_UTF-8_Encoding.lua @@ -16,12 +16,10 @@ -- Expected result: -- The texts in Russian & Chinese in appropriate are parsed correctly by SDL --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") +local utils = require ('user_modules/utils') --[[ Local Variables ]] local db_file = config.pathToSDL .. "/" .. commonFunctions:read_parameter_from_smart_device_link_ini("AppStorageFolder") .. "/policy.sqlite" @@ -86,7 +84,7 @@ function Test:Precondition_ActivateApp() EXPECT_HMIRESPONSE(requestId2) :Do(function(_, _) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_, data2) self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", { }) diff --git a/test_scripts/Policies/Policy_Table_Update/163_P_ATF_Register_NewApp_not_exist_inLocalPT_PTU.lua b/test_scripts/Policies/Policy_Table_Update/163_P_ATF_Register_NewApp_not_exist_inLocalPT_PTU.lua index 740272b8d7..7cc8c0e4fb 100644 --- a/test_scripts/Policies/Policy_Table_Update/163_P_ATF_Register_NewApp_not_exist_inLocalPT_PTU.lua +++ b/test_scripts/Policies/Policy_Table_Update/163_P_ATF_Register_NewApp_not_exist_inLocalPT_PTU.lua @@ -16,13 +16,13 @@ ------------------------------------------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local mobile_session = require('mobile_session') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local Functions ]] local registerAppInterfaceParams = @@ -60,7 +60,7 @@ require("user_modules/AppTypes") commonFunctions:newTestCasesGroup ("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PolicyUpdateStarted() diff --git a/test_scripts/Policies/Policy_Table_Update/164_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU.lua b/test_scripts/Policies/Policy_Table_Update/164_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU.lua index 470ff59dbb..c5ae25db58 100644 --- a/test_scripts/Policies/Policy_Table_Update/164_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU.lua +++ b/test_scripts/Policies/Policy_Table_Update/164_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU.lua @@ -21,13 +21,13 @@ ------------------------------------------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local mobile_session = require('mobile_session') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local Functions ]] local registerAppInterfaceParams = @@ -65,7 +65,7 @@ require("user_modules/AppTypes") commonFunctions:newTestCasesGroup ("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PolicyUpdateStarted() diff --git a/test_scripts/Policies/Policy_Table_Update/165_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp.lua b/test_scripts/Policies/Policy_Table_Update/165_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp.lua index 0c3fd75fb4..d923e9b6e0 100644 --- a/test_scripts/Policies/Policy_Table_Update/165_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp.lua +++ b/test_scripts/Policies/Policy_Table_Update/165_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp.lua @@ -22,7 +22,6 @@ ------------------------------------------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.application1.registerAppInterfaceParams.appHMIType = { "MEDIA" } --[[ Required Shared libraries ]] @@ -30,6 +29,7 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local mobile_session = require('mobile_session') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local Functions ]] local registerAppInterfaceParams = @@ -67,7 +67,7 @@ require("user_modules/AppTypes") commonFunctions:newTestCasesGroup ("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_PolicyUpdateStarted() diff --git a/test_scripts/Policies/Policy_Table_Update/166_ATF_HMI_sends_GetURLs_one_app_registered_urls_3default.lua b/test_scripts/Policies/Policy_Table_Update/166_ATF_HMI_sends_GetURLs_one_app_registered_urls_3default.lua index 80d2b30076..39815c5201 100644 --- a/test_scripts/Policies/Policy_Table_Update/166_ATF_HMI_sends_GetURLs_one_app_registered_urls_3default.lua +++ b/test_scripts/Policies/Policy_Table_Update/166_ATF_HMI_sends_GetURLs_one_app_registered_urls_3default.lua @@ -17,15 +17,12 @@ -- PTU is requested. PTS is created. -- SDL.GetURLs({urls[] = default urls}) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -43,7 +40,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/Policy_Table_Update/167_ATF_HMI_sends_GetURLs_one_app_registered_urls_3default_not_registered.lua b/test_scripts/Policies/Policy_Table_Update/167_ATF_HMI_sends_GetURLs_one_app_registered_urls_3default_not_registered.lua index aba60e9cbb..d09f4fb01c 100644 --- a/test_scripts/Policies/Policy_Table_Update/167_ATF_HMI_sends_GetURLs_one_app_registered_urls_3default_not_registered.lua +++ b/test_scripts/Policies/Policy_Table_Update/167_ATF_HMI_sends_GetURLs_one_app_registered_urls_3default_not_registered.lua @@ -17,15 +17,12 @@ -- PTU is requested. PTS is created. -- SDL.GetURLs({urls[] = default urls}) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -43,7 +40,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/Policy_Table_Update/168_ATF_HMI_sends_GetURLs_one_app_registered_urls_3default_registered.lua b/test_scripts/Policies/Policy_Table_Update/168_ATF_HMI_sends_GetURLs_one_app_registered_urls_3default_registered.lua index 3df39e25aa..ab533c014f 100644 --- a/test_scripts/Policies/Policy_Table_Update/168_ATF_HMI_sends_GetURLs_one_app_registered_urls_3default_registered.lua +++ b/test_scripts/Policies/Policy_Table_Update/168_ATF_HMI_sends_GetURLs_one_app_registered_urls_3default_registered.lua @@ -17,15 +17,12 @@ -- PTU is requested. PTS is created. -- SDL.GetURLs({urls[] = registered_App1, default}) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -43,7 +40,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/Policy_Table_Update/169_ATF_HMILvl_on_PTU_affected_app_in_LIMITED.lua b/test_scripts/Policies/Policy_Table_Update/169_ATF_HMILvl_on_PTU_affected_app_in_LIMITED.lua index bf3afbf41c..744fd1637f 100644 --- a/test_scripts/Policies/Policy_Table_Update/169_ATF_HMILvl_on_PTU_affected_app_in_LIMITED.lua +++ b/test_scripts/Policies/Policy_Table_Update/169_ATF_HMILvl_on_PTU_affected_app_in_LIMITED.lua @@ -18,14 +18,12 @@ -- 3) After PTU OnPermissionsChange is called --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local json = require('json') + --[[ Local Variables ]] local HMIAppID2 diff --git a/test_scripts/Policies/Policy_Table_Update/170_ATF_PTU_Trigger_On_Navi_App_Registration_And_No_Certificate.lua b/test_scripts/Policies/Policy_Table_Update/170_ATF_PTU_Trigger_On_Navi_App_Registration_And_No_Certificate.lua index 20786f971b..21ac723089 100644 --- a/test_scripts/Policies/Policy_Table_Update/170_ATF_PTU_Trigger_On_Navi_App_Registration_And_No_Certificate.lua +++ b/test_scripts/Policies/Policy_Table_Update/170_ATF_PTU_Trigger_On_Navi_App_Registration_And_No_Certificate.lua @@ -17,15 +17,14 @@ -- Expected result: -- a) SDL send SDL.OnStatusUpdate(UPDATE_NEEDED) --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() @@ -45,7 +44,7 @@ function Test:Precondition_Activate_App_And_Consent_Device() local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_, data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/Policy_Table_Update/171_ATF_Policies_Memory_Allocation_For_PTU.lua b/test_scripts/Policies/Policy_Table_Update/171_ATF_Policies_Memory_Allocation_For_PTU.lua index 1486804185..c0e392cc64 100644 --- a/test_scripts/Policies/Policy_Table_Update/171_ATF_Policies_Memory_Allocation_For_PTU.lua +++ b/test_scripts/Policies/Policy_Table_Update/171_ATF_Policies_Memory_Allocation_For_PTU.lua @@ -17,13 +17,10 @@ -- Expected result: -- PTU finished successfully and LPT is updated --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] - config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") - + local utils = require ('user_modules/utils') --[[ Local Variables ]] local db_file = config.pathToSDL .. "/" .. commonFunctions:read_parameter_from_smart_device_link_ini("AppStorageFolder") .. "/policy.sqlite" @@ -73,7 +70,7 @@ EXPECT_HMIRESPONSE(requestId2) :Do(function(_, _) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_, data2) self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", { }) @@ -130,4 +127,4 @@ StopSDL() end -return Test +return Test diff --git a/test_scripts/Policies/Policy_Table_Update/172_ATF_PTU_request_after_N_ignition_cycles.lua b/test_scripts/Policies/Policy_Table_Update/172_ATF_PTU_request_after_N_ignition_cycles.lua index 4f0062c0cb..bbdb9fd533 100644 --- a/test_scripts/Policies/Policy_Table_Update/172_ATF_PTU_request_after_N_ignition_cycles.lua +++ b/test_scripts/Policies/Policy_Table_Update/172_ATF_PTU_request_after_N_ignition_cycles.lua @@ -20,7 +20,6 @@ -- SDL must trigger a PolicyTableUpdate sequence --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.application1.registerAppInterfaceParams.appHMIType = {"DEFAULT"} --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 @@ -28,6 +27,7 @@ config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFiles() @@ -49,7 +49,7 @@ function Test:Precondition_Activate_App_Consent_Device_And_Update_Policy() local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) -- GetCurrentTimeStampDeviceConsent() EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) diff --git a/test_scripts/Policies/Related_HMI_API/173_ATF_OnAllowSDLFunctionality_allowed_false_with_device.lua b/test_scripts/Policies/Related_HMI_API/173_ATF_OnAllowSDLFunctionality_allowed_false_with_device.lua index 230556af48..77ee176a1c 100644 --- a/test_scripts/Policies/Related_HMI_API/173_ATF_OnAllowSDLFunctionality_allowed_false_with_device.lua +++ b/test_scripts/Policies/Related_HMI_API/173_ATF_OnAllowSDLFunctionality_allowed_false_with_device.lua @@ -11,18 +11,16 @@ -- device ('device' param) as NOT consented in Local PT ("user_consent_records"-> "device" sub-section) and send BasicCommunication.ActivateApp with -- 'level' param of the value from 'default_hmi' key of 'pre-DataConsent'section of Local PT to HMI. App should stay in NONE HMI level --------------------------------------------------------------------------------------------- -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ Local variables ]] local device_consent local device_consent_group -local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -36,7 +34,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] @@ -44,7 +42,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_Allowed_false_with_device() device_consent_group = testCasesForPolicyTableSnapshot:get_data_from_PTS("app_policies.device.groups.1") - device_consent = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records.device.consent_groups.DataConsent-2") + device_consent = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records.device.consent_groups.DataConsent-2") --print("device_consent = " ..device_consent) if( (device_consent == nil) or (device_consent_group == nil)) then self:FailTestCase("Device is not consented after user consent.") @@ -55,7 +53,7 @@ function Test:TestStep_Allowed_false_with_device() self:FailTestCase("Device is not consented after user consent.") else self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = false, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = false}}) + {allowed = false, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = false}}) end end end @@ -88,4 +86,4 @@ function Test.Postcondition_Stop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Related_HMI_API/174_ATF_OnAllowSDLFunctionality_allowed_false_without_device.lua b/test_scripts/Policies/Related_HMI_API/174_ATF_OnAllowSDLFunctionality_allowed_false_without_device.lua index afd34633fe..0e7668a651 100644 --- a/test_scripts/Policies/Related_HMI_API/174_ATF_OnAllowSDLFunctionality_allowed_false_without_device.lua +++ b/test_scripts/Policies/Related_HMI_API/174_ATF_OnAllowSDLFunctionality_allowed_false_without_device.lua @@ -10,13 +10,12 @@ -- In case PoliciesManager receives SDL.OnAllowSDLFunctionality with 'allowed=false' and without 'device' param from HMI, PoliciesManager must record -- all of currently registered devices as NOT consented in Local PT ("device_data" - > "", "", etc. - >"user_consent_records"- > "device" sub-section). --------------------------------------------------------------------------------------------- -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ Local variables ]] local device_consent @@ -34,7 +33,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] @@ -42,7 +41,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_Allowed_false_without_device() device_consent_group = testCasesForPolicyTableSnapshot:get_data_from_PTS("app_policies.device.groups.1") - device_consent = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records.device.consent_groups.DataConsent-2") + device_consent = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records.device.consent_groups.DataConsent-2") if( (device_consent == nil) or (device_consent_group == nil)) then self:FailTestCase("Device is not consented after user consent.") elseif (device_consent_group ~= "DataConsent-2") then diff --git a/test_scripts/Policies/Related_HMI_API/175_ATF_OnAllowSDLFunctionality_allowed_true_without_device.lua b/test_scripts/Policies/Related_HMI_API/175_ATF_OnAllowSDLFunctionality_allowed_true_without_device.lua index da7a12b80e..0816ad45fc 100644 --- a/test_scripts/Policies/Related_HMI_API/175_ATF_OnAllowSDLFunctionality_allowed_true_without_device.lua +++ b/test_scripts/Policies/Related_HMI_API/175_ATF_OnAllowSDLFunctionality_allowed_true_without_device.lua @@ -11,12 +11,10 @@ -- SDL->HMI:BC.ActivateApp(params, level: <â€default_hmiâ€-value-from-assigned-policies>) -- SDL->app: OnHMIStatus(params, level: <â€default_hmiâ€-value-from-assigned-policies>) --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -42,7 +40,7 @@ function Test:TestStep_RegisterApp_allowed_true_without_device() :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) end) EXPECT_HMICALL("BasicCommunication.PolicyUpdate",{}) diff --git a/test_scripts/Policies/Related_HMI_API/176_ATF_OnAllowSDLFunctionality_allowed_false_with_device.lua b/test_scripts/Policies/Related_HMI_API/176_ATF_OnAllowSDLFunctionality_allowed_false_with_device.lua index 5d68a4e37c..c690f9becc 100644 --- a/test_scripts/Policies/Related_HMI_API/176_ATF_OnAllowSDLFunctionality_allowed_false_with_device.lua +++ b/test_scripts/Policies/Related_HMI_API/176_ATF_OnAllowSDLFunctionality_allowed_false_with_device.lua @@ -14,16 +14,11 @@ -- app stays in NONE level on HMI. -- HMI->SDL: BasicCommunication.ActivateApp_response --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') - ---[[ Local variables ]] -local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -48,13 +43,13 @@ function Test:TestStep_RegisterApp_allowed_false_without_device() EXPECT_HMIRESPONSE( RequestId1, {result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = false, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = false}}) + {allowed = false, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = false}}) end) end) EXPECT_HMICALL("BasicCommunication.ActivateApp", {appID = self.applications[config.application1.registerAppInterfaceParams.appName], level = "NONE"}) - :Do(function(_,data) - self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) end) EXPECT_NOTIFICATION("OnHMIStatus"):Times(0) @@ -64,7 +59,7 @@ function Test:TestStep_CheckDeviceConsentGroup() os.execute("sleep 3") local result = commonFunctions:is_db_contains(config.pathToSDL.."/storage/policy.sqlite", "SELECT is_consented FROM device_consent_group", {"0"} ) if(result ~= true) then - self:FailTestCase("Error: Value of is_consented on policy DB should be false(0).") + self:FailTestCase("Error: Value of is_consented on policy DB should be false(0).") end end @@ -74,4 +69,4 @@ function Test.Postcondition_Stop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Related_HMI_API/177_ATF_OnAllowSDLFunctionality_allowed_true_with_device.lua b/test_scripts/Policies/Related_HMI_API/177_ATF_OnAllowSDLFunctionality_allowed_true_with_device.lua index 40b404fb98..857eff8706 100644 --- a/test_scripts/Policies/Related_HMI_API/177_ATF_OnAllowSDLFunctionality_allowed_true_with_device.lua +++ b/test_scripts/Policies/Related_HMI_API/177_ATF_OnAllowSDLFunctionality_allowed_true_with_device.lua @@ -17,16 +17,11 @@ -- HMI displays the device consent pormpt. User makes choice. -- HMI->SDL: OnAllowSDLFunctionality --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') - ---[[ Local variables ]] -local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -50,14 +45,14 @@ function Test:TestStep_ActivateApp_allowed_true_with_device() EXPECT_HMIRESPONSE( RequestId1, {result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true}}) end) EXPECT_HMICALL("BasicCommunication.PolicyUpdate",{}) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) testCasesForPolicyTableSnapshot:extract_pts({self.applications[config.application1.registerAppInterfaceParams.appName]}) - device_consent = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records.device.consent_groups.DataConsent-2") + device_consent = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records.device.consent_groups.DataConsent-2") if(device_consent ~= true) then self:FailTestCase("Device is not consented after user consented it.") @@ -77,4 +72,4 @@ function Test.Postcondition_Stop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Related_HMI_API/178_ATF_OnAppPermissionConsent_without_appID.lua b/test_scripts/Policies/Related_HMI_API/178_ATF_OnAppPermissionConsent_without_appID.lua index 19a135d269..f09544ce1a 100644 --- a/test_scripts/Policies/Related_HMI_API/178_ATF_OnAppPermissionConsent_without_appID.lua +++ b/test_scripts/Policies/Related_HMI_API/178_ATF_OnAppPermissionConsent_without_appID.lua @@ -23,14 +23,12 @@ -- 9. HMI->SDL: OnAppPermissionConsent {params} -- 10. PoliciesManager: update "" subsection of "user_consent_records" subsection of "" section of "device_data" section in Local PT --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -44,7 +42,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_ExitApplication() @@ -100,8 +98,8 @@ function Test:TestStep_check_LocalPT_for_updates() EXPECT_HMICALL("BasicCommunication.PolicyUpdate",{}) :Do(function(_,data) local is_test_fail = false - local app_consent_location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Location-1") - local app_consent_notifications = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Notifications") + local app_consent_location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Location-1") + local app_consent_notifications = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Notifications") if(app_consent_location ~= true) then commonFunctions:printError("Error: consent_groups.Location function for appID should be true") diff --git a/test_scripts/Policies/Related_HMI_API/179_ATF_OnAppPermissionConsent_with_appID.lua b/test_scripts/Policies/Related_HMI_API/179_ATF_OnAppPermissionConsent_with_appID.lua index fd8465f0f1..36fc939dd4 100644 --- a/test_scripts/Policies/Related_HMI_API/179_ATF_OnAppPermissionConsent_with_appID.lua +++ b/test_scripts/Policies/Related_HMI_API/179_ATF_OnAppPermissionConsent_with_appID.lua @@ -23,14 +23,12 @@ -- 9. HMI->SDL: OnAppPermissionConsent {params} -- 10. PoliciesManager: update "" subsection of "user_consent_records" subsection of "" section of "device_data" section in Local PT --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -44,7 +42,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_ExitApplication() @@ -96,8 +94,8 @@ function Test:TestStep_check_LocalPT_for_updates() EXPECT_HMICALL("BasicCommunication.PolicyUpdate",{}) :Do(function(_,data) testCasesForPolicyTableSnapshot:extract_pts({self.applications[config.application1.registerAppInterfaceParams.appName]}) - local app_consent_location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Location-1") - local app_consent_notifications = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Notifications") + local app_consent_location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Location-1") + local app_consent_notifications = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Notifications") if(app_consent_location ~= true) then commonFunctions:printError("Error: consent_groups.Location function for appID should be true") diff --git a/test_scripts/Policies/Related_HMI_API/180_ATF_GetUserFriendlyMessage_language_section_is_absent_in_LocalPT.lua b/test_scripts/Policies/Related_HMI_API/180_ATF_GetUserFriendlyMessage_language_section_is_absent_in_LocalPT.lua index a5701ce5ab..e0d9b77681 100644 --- a/test_scripts/Policies/Related_HMI_API/180_ATF_GetUserFriendlyMessage_language_section_is_absent_in_LocalPT.lua +++ b/test_scripts/Policies/Related_HMI_API/180_ATF_GetUserFriendlyMessage_language_section_is_absent_in_LocalPT.lua @@ -11,10 +11,6 @@ -- HMI->SDL: SDL.GetUserFriendlyMessage ("messageCodes": "AppPermissions") -- SDL->HMI: SDL.GetUserFriendlyMessage ("messages": {messageCode: "AppPermissions", ttsString: "%appName% is requesting the use of the following ....", line1: "Grant Requested", line2: "Permission(s)?"}) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') @@ -64,4 +60,4 @@ function Test.Postcondition_Stop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Related_HMI_API/181_ATF_GetUserFriendlyMessage_Language_not_found_in_localPT.lua b/test_scripts/Policies/Related_HMI_API/181_ATF_GetUserFriendlyMessage_Language_not_found_in_localPT.lua index fa2533cd3d..507deb78af 100644 --- a/test_scripts/Policies/Related_HMI_API/181_ATF_GetUserFriendlyMessage_Language_not_found_in_localPT.lua +++ b/test_scripts/Policies/Related_HMI_API/181_ATF_GetUserFriendlyMessage_Language_not_found_in_localPT.lua @@ -11,9 +11,6 @@ -- HMI->SDL: SDL.GetUserFriendlyMessage ("messageCodes": "AppPermissions") -- SDL->HMI: SDL.GetUserFriendlyMessage ("messages": {messageCode: "AppPermissions", ttsString: "%appName% is requesting the use of the following ....", line1: "Grant Requested", line2: "Permission(s)?"}) --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/Related_HMI_API/182_ATF_GetUserFriendlyMessage_with_Language.lua b/test_scripts/Policies/Related_HMI_API/182_ATF_GetUserFriendlyMessage_with_Language.lua index 8838b1d6b1..2d7348c3ff 100644 --- a/test_scripts/Policies/Related_HMI_API/182_ATF_GetUserFriendlyMessage_with_Language.lua +++ b/test_scripts/Policies/Related_HMI_API/182_ATF_GetUserFriendlyMessage_with_Language.lua @@ -11,9 +11,6 @@ -- HMI->SDL: SDL.GetUserFriendlyMessage ("messageCodes": "AppPermissions") -- SDL->HMI: SDL.GetUserFriendlyMessage ("messages": {messageCode: "AppPermissions", ttsString: "%appName% is requesting the use of the following ....", line1: "Grant Requested", line2: "Permission(s)?"}) --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/Related_HMI_API/183_ATF_PolManager_provides_data_consent_prompt_on_HMI_request.lua b/test_scripts/Policies/Related_HMI_API/183_ATF_PolManager_provides_data_consent_prompt_on_HMI_request.lua index f36932ff28..ace00778df 100644 --- a/test_scripts/Policies/Related_HMI_API/183_ATF_PolManager_provides_data_consent_prompt_on_HMI_request.lua +++ b/test_scripts/Policies/Related_HMI_API/183_ATF_PolManager_provides_data_consent_prompt_on_HMI_request.lua @@ -22,16 +22,11 @@ -- SDL->HMI: SDL.GetUserFriendlyMessage ("messages": -- {messageCode: "AppPermissions", ttsString: "%appName% is requesting the use of the following ....", line1: "Grant Requested", line2: "Permission(s)?"} ring: "%appName% is requesting the use of the following ....", line1: "Grant Requested", line2: "Permission(s)?"}) --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') - ---[[ Local variables ]] -local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() @@ -59,7 +54,7 @@ function Test:TestStep_ActivateApp_StatusNeeded() :Do(function() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true}}) -- EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }) diff --git a/test_scripts/Policies/Related_HMI_API/184_ATF_GetListOfPermissions_without_appID.lua b/test_scripts/Policies/Related_HMI_API/184_ATF_GetListOfPermissions_without_appID.lua index 29dd5c7ab0..229916f675 100644 --- a/test_scripts/Policies/Related_HMI_API/184_ATF_GetListOfPermissions_without_appID.lua +++ b/test_scripts/Policies/Related_HMI_API/184_ATF_GetListOfPermissions_without_appID.lua @@ -12,14 +12,12 @@ -- On getting SDL.GetListOfPermissions without appID parameter, PoliciesManager must respond with the list of s -- that have the field "user_consent_prompt" in corresponding and are assigned to the currently registered applications (section "" -> "groups") --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ Local Functions ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -35,7 +33,6 @@ require('user_modules/AppTypes') --[[ Test ]] commonFunctions:newTestCasesGroup("Test") function Test:TestStep_GetListOfPermissions_without_appID() - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) --Allow SDL functionality @@ -46,7 +43,7 @@ function Test:TestStep_GetListOfPermissions_without_appID() EXPECT_HMIRESPONSE( RequestId1, {result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true}}) end) end @@ -86,7 +83,7 @@ function Test:TestStep_trigger_user_request_update_from_HMI() end function Test:TestStep_verify_PermissionConsent() - local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.DrivingCharacteristics-3") + local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.DrivingCharacteristics-3") if(app_permission ~= true) then self:FailTestCase("DrivingCharacteristics-3 is not assigned to application, real: " ..app_permission) end diff --git a/test_scripts/Policies/Related_HMI_API/185_ATF_GetListOfPermissions_with_appID.lua b/test_scripts/Policies/Related_HMI_API/185_ATF_GetListOfPermissions_with_appID.lua index 5d90a3e10d..6a5c72e799 100644 --- a/test_scripts/Policies/Related_HMI_API/185_ATF_GetListOfPermissions_with_appID.lua +++ b/test_scripts/Policies/Related_HMI_API/185_ATF_GetListOfPermissions_with_appID.lua @@ -12,14 +12,12 @@ -- On getting SDL.GetListOfPermissions with appID parameter, PoliciesManager must respond with the list of s -- that have the field "user_consent_prompt" in corresponding and are assigned to the currently registered applications (section "" -> "groups") --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ Local Functions ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -35,7 +33,6 @@ require('user_modules/AppTypes') --[[ Test ]] commonFunctions:newTestCasesGroup("Test") function Test:TestStep_GetListOfPermissions_with_appID() - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) --Allow SDL functionality @@ -46,7 +43,7 @@ function Test:TestStep_GetListOfPermissions_with_appID() EXPECT_HMIRESPONSE( RequestId1, {result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true}}) end) end @@ -86,7 +83,7 @@ function Test:TestStep_trigger_user_request_update_from_HMI() end function Test:TestStep_verify_PermissionConsent() - local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.DrivingCharacteristics-3") + local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.DrivingCharacteristics-3") if(app_permission ~= true) then self:FailTestCase("DrivingCharacteristics-3 is not assigned to application, real: " ..app_permission) end diff --git a/test_scripts/Policies/Related_HMI_API/186_ATF_OnPolicyUpdate_initiation_of_PTU.lua b/test_scripts/Policies/Related_HMI_API/186_ATF_OnPolicyUpdate_initiation_of_PTU.lua index 0ce420c61a..a51a373ae1 100644 --- a/test_scripts/Policies/Related_HMI_API/186_ATF_OnPolicyUpdate_initiation_of_PTU.lua +++ b/test_scripts/Policies/Related_HMI_API/186_ATF_OnPolicyUpdate_initiation_of_PTU.lua @@ -10,13 +10,12 @@ -- Expected result: -- SDL->HMI: BasicCommunication.PolicyUpdate --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -68,8 +67,8 @@ function Test:Precondtion_Activate_App_Consent_Update() hmiDisplayLanguageDesired = "EN-US", deviceInfo = { - name = "127.0.0.1", - id = config.deviceMAC, + name = utils.getDeviceName(), + id = utils.getDeviceMAC(), transportType = "WIFI", isSDLAllowed = false } @@ -82,7 +81,7 @@ function Test:Precondtion_Activate_App_Consent_Update() local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/Related_HMI_API/187_ATF_Get_Status_Update_Request_from_HMI.lua b/test_scripts/Policies/Related_HMI_API/187_ATF_Get_Status_Update_Request_from_HMI.lua index 536e5917c1..7b25d3ee18 100644 --- a/test_scripts/Policies/Related_HMI_API/187_ATF_Get_Status_Update_Request_from_HMI.lua +++ b/test_scripts/Policies/Related_HMI_API/187_ATF_Get_Status_Update_Request_from_HMI.lua @@ -22,13 +22,10 @@ -- 4. Status: UPDATING -- 6. Status: UP_TO_DATE --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() @@ -51,7 +48,7 @@ function Test:Test_1_UPDATE_NEEDED() EXPECT_HMIRESPONSE(requestId2) :Do(function() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) local reqId = self.hmiConnection:SendRequest("SDL.GetStatusUpdate") EXPECT_HMIRESPONSE(reqId, { status = "UPDATE_NEEDED" }) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/224_ATF_pt_update_validation_rules_request_type_array_omitted.lua b/test_scripts/Policies/Validation_of_PolicyTables/224_ATF_pt_update_validation_rules_request_type_array_omitted.lua index d6a6073d20..f4032796ce 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/224_ATF_pt_update_validation_rules_request_type_array_omitted.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/224_ATF_pt_update_validation_rules_request_type_array_omitted.lua @@ -18,9 +18,7 @@ -- a) assign "RequestType" field from "default" section of PolicyDataBase to such app -- b) copy "RequestType" field from "default" section to "" section of PolicyDataBase --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] @@ -29,6 +27,7 @@ local commonFunctions = require ('user_modules/shared_testcases/commonFunctions' local commonSteps = require ('user_modules/shared_testcases/commonSteps') local mobile_session = require('mobile_session') local config = require('config') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() @@ -174,7 +173,7 @@ local function activateApp(self, HMIAppID) --hmi side: send request SDL.OnAllowSDLFunctionality self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) --hmi side: expect BasicCommunication.ActivateApp request EXPECT_HMICALL("BasicCommunication.ActivateApp") diff --git a/test_scripts/Policies/Validation_of_PolicyTables/225_ATF_pt_update_validation_rules_request_type_array_has_one_invalid_value.lua b/test_scripts/Policies/Validation_of_PolicyTables/225_ATF_pt_update_validation_rules_request_type_array_has_one_invalid_value.lua index daeaca67eb..55aec7e3e3 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/225_ATF_pt_update_validation_rules_request_type_array_has_one_invalid_value.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/225_ATF_pt_update_validation_rules_request_type_array_has_one_invalid_value.lua @@ -16,18 +16,17 @@ -- Expected result: -- SDL must: cut off the invalid value of "RequestType" array --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] Test = require('connecttest') local config = require('config') config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local json = require("modules/json") local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local mobile_session = require('mobile_session') +local utils = require ('user_modules/utils') require('cardinalities') require('user_modules/AppTypes') @@ -113,7 +112,7 @@ local function activateAppInSpecificLevel(self, HMIAppID, hmi_level) --hmi side: send request SDL.OnAllowSDLFunctionality self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) --hmi side: expect BasicCommunication.ActivateApp request EXPECT_HMICALL("BasicCommunication.ActivateApp") diff --git a/test_scripts/Policies/Validation_of_PolicyTables/226_ATF_pt_update_validation_rules_request_type_array_has_only_one_value_is_invalid.lua b/test_scripts/Policies/Validation_of_PolicyTables/226_ATF_pt_update_validation_rules_request_type_array_has_only_one_value_is_invalid.lua index 5800ad2cc7..ec867a8950 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/226_ATF_pt_update_validation_rules_request_type_array_has_only_one_value_is_invalid.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/226_ATF_pt_update_validation_rules_request_type_array_has_only_one_value_is_invalid.lua @@ -18,18 +18,17 @@ -- a) assign "RequestType" field from "default" section of PolicyDataBase to such app -- b) copy "RequestType" field from "default" section to "" section of PolicyDataBase --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] Test = require('connecttest') local config = require('config') config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local json = require("modules/json") local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local mobile_session = require('mobile_session') +local utils = require ('user_modules/utils') require('cardinalities') require('user_modules/AppTypes') @@ -156,7 +155,7 @@ local function activateAppInSpecificLevel(self, HMIAppID, hmi_level) --hmi side: send request SDL.OnAllowSDLFunctionality self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) --hmi side: expect BasicCommunication.ActivateApp request EXPECT_HMICALL("BasicCommunication.ActivateApp") diff --git a/test_scripts/Policies/Validation_of_PolicyTables/227_ATF_usage_and_error_counts_update_count_sync_out_of_memory.lua b/test_scripts/Policies/Validation_of_PolicyTables/227_ATF_usage_and_error_counts_update_count_sync_out_of_memory.lua index 7c9c8660d5..1353f34252 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/227_ATF_usage_and_error_counts_update_count_sync_out_of_memory.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/227_ATF_usage_and_error_counts_update_count_sync_out_of_memory.lua @@ -15,7 +15,6 @@ -- SDL must: increment "count_sync_out_of_memory" section value of Local Policy Table. --------------------------------------------------------------------------------------------- config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/228_ATF_usage_and_error_counts_update_count_of_sync_reboots.lua b/test_scripts/Policies/Validation_of_PolicyTables/228_ATF_usage_and_error_counts_update_count_of_sync_reboots.lua index a438dfcd02..32fd8b2226 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/228_ATF_usage_and_error_counts_update_count_of_sync_reboots.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/228_ATF_usage_and_error_counts_update_count_of_sync_reboots.lua @@ -14,7 +14,6 @@ -- Expected result: -- SDL must: increment "count_of_sync_reboots" section value of Local Policy Table. --------------------------------------------------------------------------------------------- - --[[ Required Shared libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') @@ -23,7 +22,6 @@ local commonSteps = require('user_modules/shared_testcases/commonSteps') Test = require('user_modules/dummy_connecttest') local config = require('config') config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" require('user_modules/AppTypes') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/229_ATF_usage_and_error_counts_update_count_of_iap_buffer_full.lua b/test_scripts/Policies/Validation_of_PolicyTables/229_ATF_usage_and_error_counts_update_count_of_iap_buffer_full.lua index e2fcd7b943..26b246544c 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/229_ATF_usage_and_error_counts_update_count_of_iap_buffer_full.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/229_ATF_usage_and_error_counts_update_count_of_iap_buffer_full.lua @@ -15,7 +15,6 @@ -- SDL must: increment "count_of_iap_buffer_full" section value of Local Policy Table. --------------------------------------------------------------------------------------------- config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/230_ATF_usage_and_error_counts_update_minutes_in_hmi_none.lua b/test_scripts/Policies/Validation_of_PolicyTables/230_ATF_usage_and_error_counts_update_minutes_in_hmi_none.lua index 8ff909c479..e1fa5a5afa 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/230_ATF_usage_and_error_counts_update_minutes_in_hmi_none.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/230_ATF_usage_and_error_counts_update_minutes_in_hmi_none.lua @@ -25,18 +25,17 @@ -- Expected result: -- SDL must: increment value of "minutes_in_hmi_none" for this minutes in Local Policy Table. --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] Test = require('connecttest') local config = require('config') config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local json = require("modules/json") local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local mobile_session = require('mobile_session') +local utils = require ('user_modules/utils') require('cardinalities') require('user_modules/AppTypes') @@ -299,7 +298,7 @@ local function activateAppInSpecificLevel(self, HMIAppID, hmi_level) --hmi side: send request SDL.OnAllowSDLFunctionality self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) --hmi side: expect BasicCommunication.ActivateApp request EXPECT_HMICALL("BasicCommunication.ActivateApp") diff --git a/test_scripts/Policies/Validation_of_PolicyTables/231_ATF_usage_and_error_counts_update_minutes_in_hmi_limited.lua b/test_scripts/Policies/Validation_of_PolicyTables/231_ATF_usage_and_error_counts_update_minutes_in_hmi_limited.lua index 61a23e1e5e..83fc518a28 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/231_ATF_usage_and_error_counts_update_minutes_in_hmi_limited.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/231_ATF_usage_and_error_counts_update_minutes_in_hmi_limited.lua @@ -26,7 +26,6 @@ -- SDL must: increment value of "minutes_in_hmi_limited" for this minutes in Local Policy Table. --------------------------------------------------------------------------------------------- config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.application1.registerAppInterfaceParams.isMediaApplication = true --[[ Required Shared libraries ]] @@ -34,6 +33,7 @@ local json = require("modules/json") local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local mobile_session = require('mobile_session') +local utils = require ('user_modules/utils') commonSteps:DeleteLogsFiles() commonSteps:DeletePolicyTable() @@ -305,7 +305,7 @@ local function activateAppInSpecificLevel(self, HMIAppID, hmi_level) --hmi side: send request SDL.OnAllowSDLFunctionality self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) --hmi side: expect BasicCommunication.ActivateApp request EXPECT_HMICALL("BasicCommunication.ActivateApp") diff --git a/test_scripts/Policies/Validation_of_PolicyTables/232_ATF_usage_and_error_counts_update_minutes_in_hmi_full.lua b/test_scripts/Policies/Validation_of_PolicyTables/232_ATF_usage_and_error_counts_update_minutes_in_hmi_full.lua index 6c4624d5b6..eda0852b85 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/232_ATF_usage_and_error_counts_update_minutes_in_hmi_full.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/232_ATF_usage_and_error_counts_update_minutes_in_hmi_full.lua @@ -30,13 +30,13 @@ Test = require('connecttest') local config = require('config') config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local json = require("modules/json") local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local mobile_session = require('mobile_session') +local utils = require ('user_modules/utils') require('cardinalities') require('user_modules/AppTypes') @@ -299,7 +299,7 @@ local function activateAppInSpecificLevel(self, HMIAppID, hmi_level) --hmi side: send request SDL.OnAllowSDLFunctionality self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) --hmi side: expect BasicCommunication.ActivateApp request EXPECT_HMICALL("BasicCommunication.ActivateApp") diff --git a/test_scripts/Policies/Validation_of_PolicyTables/233_ATF_usage_and_error_counts_update_minutes_in_hmi_background.lua b/test_scripts/Policies/Validation_of_PolicyTables/233_ATF_usage_and_error_counts_update_minutes_in_hmi_background.lua index c253a2ce1f..b82bd2e204 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/233_ATF_usage_and_error_counts_update_minutes_in_hmi_background.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/233_ATF_usage_and_error_counts_update_minutes_in_hmi_background.lua @@ -25,18 +25,17 @@ -- Expected result: -- SDL must: increment value of "minutes_in_hmi_none" for this minutes in Local Policy Table. --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] Test = require('connecttest') local config = require('config') config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local json = require("modules/json") local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local mobile_session = require('mobile_session') +local utils = require ('user_modules/utils') require('cardinalities') require('user_modules/AppTypes') @@ -302,7 +301,7 @@ local function activateAppInSpecificLevel(self, HMIAppID, hmi_level) --hmi side: send request SDL.OnAllowSDLFunctionality self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) --hmi side: expect BasicCommunication.ActivateApp request EXPECT_HMICALL("BasicCommunication.ActivateApp") diff --git a/test_scripts/Policies/Validation_of_PolicyTables/234_ATF_preloaded_pt_validation_rules_for_omited_parameters_exist.lua b/test_scripts/Policies/Validation_of_PolicyTables/234_ATF_preloaded_pt_validation_rules_for_omited_parameters_exist.lua index 21eca856fb..a7e6a338e1 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/234_ATF_preloaded_pt_validation_rules_for_omited_parameters_exist.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/234_ATF_preloaded_pt_validation_rules_for_omited_parameters_exist.lua @@ -14,7 +14,6 @@ -- Expected result: -- PolicyManager shut SDL down --------------------------------------------------------------------------------------------- - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/237_ATF_preloaded_pt_validation_rules_for_required_parameters.lua b/test_scripts/Policies/Validation_of_PolicyTables/237_ATF_preloaded_pt_validation_rules_for_required_parameters.lua index b4ce71898e..d26940543d 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/237_ATF_preloaded_pt_validation_rules_for_required_parameters.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/237_ATF_preloaded_pt_validation_rules_for_required_parameters.lua @@ -14,9 +14,6 @@ -- Expected result: -- SDL is shutdown --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/240_ATF_preloaded_pt_exists_with_read_permissions.lua b/test_scripts/Policies/Validation_of_PolicyTables/240_ATF_preloaded_pt_exists_with_read_permissions.lua index e0c5d14a3e..0c9b67ff3d 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/240_ATF_preloaded_pt_exists_with_read_permissions.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/240_ATF_preloaded_pt_exists_with_read_permissions.lua @@ -14,10 +14,6 @@ -- Expected result: -- SDL started successfully --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/243_ATF_preloaded_pt_exists.lua b/test_scripts/Policies/Validation_of_PolicyTables/243_ATF_preloaded_pt_exists.lua index 828e562b9f..15f13496fa 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/243_ATF_preloaded_pt_exists.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/243_ATF_preloaded_pt_exists.lua @@ -16,9 +16,6 @@ -- Expected result: -- SDL started successfully --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/245_ATF_preloaded_pt_parameter_trigger_in_local_pt.lua b/test_scripts/Policies/Validation_of_PolicyTables/245_ATF_preloaded_pt_parameter_trigger_in_local_pt.lua index 8da7fb083d..753b873508 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/245_ATF_preloaded_pt_parameter_trigger_in_local_pt.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/245_ATF_preloaded_pt_parameter_trigger_in_local_pt.lua @@ -16,15 +16,12 @@ -- Expected result: -- SDL must change the value of "preloaded_pt" field to "false" --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require ('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General configuration parameters ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -203,7 +200,7 @@ end function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_Status_UP_TO_DATE() @@ -234,4 +231,4 @@ function Test.Postcondition_Stop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/246_ATF_preloaded_pt_requesttype_parameters_all_are_invalid.lua b/test_scripts/Policies/Validation_of_PolicyTables/246_ATF_preloaded_pt_requesttype_parameters_all_are_invalid.lua index 2303b34b29..8f0aab1373 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/246_ATF_preloaded_pt_requesttype_parameters_all_are_invalid.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/246_ATF_preloaded_pt_requesttype_parameters_all_are_invalid.lua @@ -14,7 +14,6 @@ -- Expected result: -- SDL must shutdown --------------------------------------------------------------------------------------------- - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') @@ -36,7 +35,6 @@ end --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.ExitOnCrash = false commonSteps:DeleteLogsFileAndPolicyTable() diff --git a/test_scripts/Policies/Validation_of_PolicyTables/247_ATF_merge_preloaded_pt_into_local_pt_consumer_frendly_messages_exists.lua b/test_scripts/Policies/Validation_of_PolicyTables/247_ATF_merge_preloaded_pt_into_local_pt_consumer_frendly_messages_exists.lua index 802ca311e3..e5e8049f2a 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/247_ATF_merge_preloaded_pt_into_local_pt_consumer_frendly_messages_exists.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/247_ATF_merge_preloaded_pt_into_local_pt_consumer_frendly_messages_exists.lua @@ -17,7 +17,6 @@ -- Expected result: -- SDL must leave fields&values of "consumer_friendly_messages" section in LocalPT base without changes --------------------------------------------------------------------------------------------- - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/248_ATF_merge_preloaded_pt_into_local_pt_consumer_frendly_messages_do_not_exists.lua b/test_scripts/Policies/Validation_of_PolicyTables/248_ATF_merge_preloaded_pt_into_local_pt_consumer_frendly_messages_do_not_exists.lua index 3c4bb947c1..9b02478b9b 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/248_ATF_merge_preloaded_pt_into_local_pt_consumer_frendly_messages_do_not_exists.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/248_ATF_merge_preloaded_pt_into_local_pt_consumer_frendly_messages_do_not_exists.lua @@ -17,7 +17,6 @@ -- Expected result: -- SDL must add fields&values of "consumer_friendly_messages" section to LocalPT based on updated PreloadedPT --------------------------------------------------------------------------------------------- - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/249_ATF_merge_preloaded_pt_into_local_pt_consumer_frendly_messages_exists_in_both.lua b/test_scripts/Policies/Validation_of_PolicyTables/249_ATF_merge_preloaded_pt_into_local_pt_consumer_frendly_messages_exists_in_both.lua index 9806b5af89..1695f3494a 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/249_ATF_merge_preloaded_pt_into_local_pt_consumer_frendly_messages_exists_in_both.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/249_ATF_merge_preloaded_pt_into_local_pt_consumer_frendly_messages_exists_in_both.lua @@ -17,7 +17,6 @@ -- Expected result: -- SDL must overwrite fields&values of "consumer_friendly_messages" section at LocalPT based on updated PreloadedPT --------------------------------------------------------------------------------------------- - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/250_ATF_merge_preloaded_pt_into_local_pt_app_policies.lua b/test_scripts/Policies/Validation_of_PolicyTables/250_ATF_merge_preloaded_pt_into_local_pt_app_policies.lua index b286f9f258..4e9abb6428 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/250_ATF_merge_preloaded_pt_into_local_pt_app_policies.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/250_ATF_merge_preloaded_pt_into_local_pt_app_policies.lua @@ -16,7 +16,6 @@ -- leave the "" sub-section of "app_policies" section at LocalPT without changes -- overwrite fields&values of "default", "device", "pre_DataConsent" subsections based on updated PreloadedPT --------------------------------------------------------------------------------------------- - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/251_ATF_merge_preloaded_pt_into_local_pt_functional_groupings_exists.lua b/test_scripts/Policies/Validation_of_PolicyTables/251_ATF_merge_preloaded_pt_into_local_pt_functional_groupings_exists.lua index 04d0b460a0..4d64aaf64e 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/251_ATF_merge_preloaded_pt_into_local_pt_functional_groupings_exists.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/251_ATF_merge_preloaded_pt_into_local_pt_functional_groupings_exists.lua @@ -15,7 +15,6 @@ -- Expected result: -- SDL must leave the "functional_group_name" sectionat LocalPT without changes (with all 3 groups) --------------------------------------------------------------------------------------------- - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') @@ -298,4 +297,4 @@ function Test.Postcondition() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/252_ATF_merge_preloaded_pt_into_local_pt_functional_groupings_does_not_exist.lua b/test_scripts/Policies/Validation_of_PolicyTables/252_ATF_merge_preloaded_pt_into_local_pt_functional_groupings_does_not_exist.lua index e3bc7b4fe9..664b310f11 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/252_ATF_merge_preloaded_pt_into_local_pt_functional_groupings_does_not_exist.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/252_ATF_merge_preloaded_pt_into_local_pt_functional_groupings_does_not_exist.lua @@ -15,7 +15,6 @@ -- Expected result: -- SDL must add the "functional_group_name" sectionat LocalPT without changes (with all 4 groups) --------------------------------------------------------------------------------------------- - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/253_ATF_merge_preloaded_pt_into_local_pt_usage_and_error_counts.lua b/test_scripts/Policies/Validation_of_PolicyTables/253_ATF_merge_preloaded_pt_into_local_pt_usage_and_error_counts.lua index e6bb07ea7d..024ece23e3 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/253_ATF_merge_preloaded_pt_into_local_pt_usage_and_error_counts.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/253_ATF_merge_preloaded_pt_into_local_pt_usage_and_error_counts.lua @@ -15,10 +15,6 @@ -- Expected result: -- SDL must leave all fields & their values of "usage_and_error_count" section as it was in the database without changes --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/254_ATF_merge_preloaded_pt_into_local_pt_device_data.lua b/test_scripts/Policies/Validation_of_PolicyTables/254_ATF_merge_preloaded_pt_into_local_pt_device_data.lua index ca40647437..aa8a657062 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/254_ATF_merge_preloaded_pt_into_local_pt_device_data.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/254_ATF_merge_preloaded_pt_into_local_pt_device_data.lua @@ -15,15 +15,13 @@ -- Expected result: -- SDL must leave all fields & their values of "device_data" section as it was in the database without changes --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') local json = require("modules/json") +local utils = require ('user_modules/utils') --[[ General configuration parameters ]] Test = require('connecttest') @@ -37,7 +35,7 @@ local TESTED_DATA = { preloaded_date = {"1988-12-01","2015-05-02"}, device = { --device_data - id = tostring(config.deviceMAC), + id = tostring(utils.getDeviceMAC()), hardware = tostring(config.application1.registerAppInterfaceParams.deviceInfo.hardware), firmware_rev = tostring(config.application1.registerAppInterfaceParams.deviceInfo.firmwareRev), os = tostring(config.application1.registerAppInterfaceParams.deviceInfo.os), @@ -46,7 +44,7 @@ local TESTED_DATA = { max_number_rfcom_ports = tostring(config.application1.registerAppInterfaceParams.deviceInfo.maxNumberRFCOMMPorts) }, device_consent_group = { - device_id = tostring(config.deviceMAC), + device_id = tostring(utils.getDeviceMAC()), functional_group_id = "DataConsent-2", is_consented = "1", input = "GUI", @@ -269,7 +267,7 @@ function Test:TestStep_VerifyInitialLocalPT() end function Test:TestStep_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:TestStep_VerifyLocalPT_DeviceConsent() diff --git a/test_scripts/Policies/Validation_of_PolicyTables/255_ATF_merge_preloaded_pt_into_local_pt_launch.lua b/test_scripts/Policies/Validation_of_PolicyTables/255_ATF_merge_preloaded_pt_into_local_pt_launch.lua index 8559f328aa..1eb01ae608 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/255_ATF_merge_preloaded_pt_into_local_pt_launch.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/255_ATF_merge_preloaded_pt_into_local_pt_launch.lua @@ -14,10 +14,6 @@ -- Expected result: -- SDL must merge all updates from PreloadedPT to existing database by rules --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/256_ATF_merge_preloaded_pt_into_local_pt_launch_does_not_changed.lua b/test_scripts/Policies/Validation_of_PolicyTables/256_ATF_merge_preloaded_pt_into_local_pt_launch_does_not_changed.lua index 8c6ec0785b..8d970d67b7 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/256_ATF_merge_preloaded_pt_into_local_pt_launch_does_not_changed.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/256_ATF_merge_preloaded_pt_into_local_pt_launch_does_not_changed.lua @@ -14,10 +14,6 @@ -- Expected result: -- SDL must not update the created database --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') @@ -283,4 +279,4 @@ function Test.Postcondition() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/257_ATF_merge_preloaded_pt_into_local_pt_module_config.lua b/test_scripts/Policies/Validation_of_PolicyTables/257_ATF_merge_preloaded_pt_into_local_pt_module_config.lua index 9a55e30f5f..b4a326cfdd 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/257_ATF_merge_preloaded_pt_into_local_pt_module_config.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/257_ATF_merge_preloaded_pt_into_local_pt_module_config.lua @@ -20,9 +20,6 @@ -- leave fields and values of "vehicle_make", “modelâ€, “year†params as they were in the database without changes -- overwrite the values with the new ones from PreloadedPT for all other fields --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/258_ATF_pt_snapshot_path_is_correct.lua b/test_scripts/Policies/Validation_of_PolicyTables/258_ATF_pt_snapshot_path_is_correct.lua index 2910b77202..0a60a43a1c 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/258_ATF_pt_snapshot_path_is_correct.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/258_ATF_pt_snapshot_path_is_correct.lua @@ -14,7 +14,6 @@ -- SDL must continue working --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -23,6 +22,7 @@ local commonFunctions = require ('user_modules/shared_testcases/commonFunctions' local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local SDL = require('modules/SDL') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -46,7 +46,7 @@ end commonFunctions:newTestCasesGroup("Test") function Test:TestStep_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:TestStep_Check_snapshot_created() @@ -71,4 +71,4 @@ function Test.Postcondition_StopSDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/259_ATF_pt_snapshot_path_is_incorrect.lua b/test_scripts/Policies/Validation_of_PolicyTables/259_ATF_pt_snapshot_path_is_incorrect.lua index 85108bf690..1fc9a7527b 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/259_ATF_pt_snapshot_path_is_incorrect.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/259_ATF_pt_snapshot_path_is_incorrect.lua @@ -14,7 +14,6 @@ -- SDL must shutdown --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --TODO(istoimenova): shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 config.ExitOnCrash = false diff --git a/test_scripts/Policies/Validation_of_PolicyTables/260_ATF_local_pt_from_preloaded_pt_master_reset.lua b/test_scripts/Policies/Validation_of_PolicyTables/260_ATF_local_pt_from_preloaded_pt_master_reset.lua index 89e5543c39..a1cd259cd1 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/260_ATF_local_pt_from_preloaded_pt_master_reset.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/260_ATF_local_pt_from_preloaded_pt_master_reset.lua @@ -15,9 +15,6 @@ -- Expected result: -- SDL must populate the LocalPT with items from PreloadedPT --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/261_ATF_pt_snapshot_validation_rules_for_optional_parameters.lua b/test_scripts/Policies/Validation_of_PolicyTables/261_ATF_pt_snapshot_validation_rules_for_optional_parameters.lua index f459698c6e..5f5bbecc45 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/261_ATF_pt_snapshot_validation_rules_for_optional_parameters.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/261_ATF_pt_snapshot_validation_rules_for_optional_parameters.lua @@ -13,15 +13,12 @@ -- Expected result: -- SDL must store the PT snapshot with optional parameters and keep running --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start]] config.defaultProtocolVersion = 2 @@ -46,7 +43,7 @@ end --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] @@ -55,7 +52,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_CheckPTS() local result = testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID}, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {self.applications[config.application1.registerAppInterfaceParams.appName]}, "print") if(result == false) then @@ -70,4 +67,4 @@ function Test.Postcondition_StopSDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/262_ATF_pt_snapshot_validation_rules_for_omitted_parameters.lua b/test_scripts/Policies/Validation_of_PolicyTables/262_ATF_pt_snapshot_validation_rules_for_omitted_parameters.lua index 8ea935b4cc..5744f4e7c5 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/262_ATF_pt_snapshot_validation_rules_for_omitted_parameters.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/262_ATF_pt_snapshot_validation_rules_for_omitted_parameters.lua @@ -13,15 +13,12 @@ -- Expected result: -- SDL must store the PT snapshot without omitted parameters and keep running --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start]] config.defaultProtocolVersion = 2 @@ -45,7 +42,7 @@ end --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] @@ -54,7 +51,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_CheckPTS() local result = testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID}, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {self.applications[config.application1.registerAppInterfaceParams.appName]}, "print") if(result == false) then @@ -68,4 +65,4 @@ function Test.Postcondition_StopSDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/263_ATF_pt_snapshot_validation_rules_for_required_parameters.lua b/test_scripts/Policies/Validation_of_PolicyTables/263_ATF_pt_snapshot_validation_rules_for_required_parameters.lua index 2ebda66e0e..edce65abe8 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/263_ATF_pt_snapshot_validation_rules_for_required_parameters.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/263_ATF_pt_snapshot_validation_rules_for_required_parameters.lua @@ -13,15 +13,12 @@ -- Expected result: -- SDL must store the PT snapshot without required parameters log the corresponding error internally and keep running --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start]] config.defaultProtocolVersion = 2 @@ -45,7 +42,7 @@ end --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] @@ -54,7 +51,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_CheckPTS() local result = testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID}, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {self.applications[config.application1.registerAppInterfaceParams.appName]}, "print") if(result == false) then @@ -68,4 +65,4 @@ function Test.Postcondition_StopSDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/264_ATF_pt_snapshot_creation_rule.lua b/test_scripts/Policies/Validation_of_PolicyTables/264_ATF_pt_snapshot_creation_rule.lua index 4d7c7430e8..1be471a1fc 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/264_ATF_pt_snapshot_creation_rule.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/264_ATF_pt_snapshot_creation_rule.lua @@ -13,15 +13,12 @@ -- Expected result: -- SDL must copy the Local Policy Table into memory and remove "messages" sub-section from "consumer_friendly_messages" section and store information as PT snapshot --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local json = require("modules/json") local commonSteps = require ('user_modules/shared_testcases/commonSteps') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start]] config.defaultProtocolVersion = 2 @@ -64,7 +61,7 @@ end --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] @@ -82,4 +79,4 @@ function Test.Postcondition_StopSDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/265_ATF_pt_snapshot_storage_on_file_system.lua b/test_scripts/Policies/Validation_of_PolicyTables/265_ATF_pt_snapshot_storage_on_file_system.lua index 9508e8ee32..08baa118d0 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/265_ATF_pt_snapshot_storage_on_file_system.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/265_ATF_pt_snapshot_storage_on_file_system.lua @@ -13,19 +13,18 @@ -- Expected result: -- SDL must store the PT snapshot as a JSON file which filename and filepath are defined in "PathToSnapshot" parameter of smartDeviceLink.ini file. --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] Test = require('connecttest') local config = require('config') require('user_modules/AppTypes') config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') require('cardinalities') local mobile_session = require('mobile_session') +local utils = require ('user_modules/utils') --[[ Local Variables ]] local POLICY_SNAPSHOT_FILE_NAME = "sdl_mega_snapshot.json" @@ -194,8 +193,8 @@ function Test:Precondition_ActivateApp() hmiDisplayLanguageDesired = "EN-US", deviceInfo = { - name = "127.0.0.1", - id = config.deviceMAC, + name = utils.getDeviceName(), + id = utils.getDeviceMAC(), transportType = "WIFI", isSDLAllowed = false } @@ -212,7 +211,7 @@ function Test:Precondition_ActivateApp() local RequestId2 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestId2,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data2) self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/266_ATF_pt_update_validation_rules_optional_parameters_type.lua b/test_scripts/Policies/Validation_of_PolicyTables/266_ATF_pt_update_validation_rules_optional_parameters_type.lua index 9889451979..4782e5de8e 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/266_ATF_pt_update_validation_rules_optional_parameters_type.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/266_ATF_pt_update_validation_rules_optional_parameters_type.lua @@ -16,10 +16,10 @@ -- Expected result: -- SDL must invalidate this received PolicyTableUpdated and log corresponding error internally --------------------------------------------------------------------------------------------- - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() @@ -30,7 +30,6 @@ Test = require('connecttest') local config = require('config') require('user_modules/AppTypes') config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" local function activateAppInSpecificLevel(self) local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) @@ -49,7 +48,7 @@ local function activateAppInSpecificLevel(self) --hmi side: send request SDL.OnAllowSDLFunctionality self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) --hmi side: expect BasicCommunication.ActivateApp request EXPECT_HMICALL("BasicCommunication.ActivateApp") diff --git a/test_scripts/Policies/Validation_of_PolicyTables/267_ATF_pt_update_validation_rules_required_parameters_type.lua b/test_scripts/Policies/Validation_of_PolicyTables/267_ATF_pt_update_validation_rules_required_parameters_type.lua index 6417c8e827..d20c39fe7b 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/267_ATF_pt_update_validation_rules_required_parameters_type.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/267_ATF_pt_update_validation_rules_required_parameters_type.lua @@ -16,12 +16,12 @@ -- Expected result: -- SDL must invalidate this received PolicyTableUpdated and log corresponding error internally --------------------------------------------------------------------------------------------- - --[[ Required Shared libraries ]] local json = require("modules/json") local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local testCasesForPolicySDLErrorsStops = require ('user_modules/shared_testcases/testCasesForPolicySDLErrorsStops') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -32,7 +32,6 @@ local config = require('config') require('cardinalities') require('user_modules/AppTypes') config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Local Variables ]] --local basePtuFile = "files/ptu.json" @@ -136,7 +135,7 @@ local function activateAppInSpecificLevel(self, HMIAppID, hmi_level) --hmi side: send request SDL.OnAllowSDLFunctionality self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) --hmi side: expect BasicCommunication.ActivateApp request EXPECT_HMICALL("BasicCommunication.ActivateApp") diff --git a/test_scripts/Policies/Validation_of_PolicyTables/268_ATF_pt_update_validation_rules_general.lua b/test_scripts/Policies/Validation_of_PolicyTables/268_ATF_pt_update_validation_rules_general.lua index 5f47157a91..dee8cc4cbb 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/268_ATF_pt_update_validation_rules_general.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/268_ATF_pt_update_validation_rules_general.lua @@ -31,7 +31,6 @@ commonSteps:DeleteLogsFileAndPolicyTable() Test = require('connecttest') local config = require('config') config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" require('cardinalities') require('user_modules/AppTypes') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/269_ATF_pt_update_validation_rules_consumer_friendly_message.lua b/test_scripts/Policies/Validation_of_PolicyTables/269_ATF_pt_update_validation_rules_consumer_friendly_message.lua index c9de2cae2c..d4455aa92a 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/269_ATF_pt_update_validation_rules_consumer_friendly_message.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/269_ATF_pt_update_validation_rules_consumer_friendly_message.lua @@ -16,17 +16,16 @@ -- Expected result: -- In case "en-us" sub-section for at least one is not found in PTUpdate , PoliciesManager must reject PTU and assume it as invalid --------------------------------------------------------------------------------------------- - --[[ Required Shared libraries ]] local json = require("modules/json") local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local testCasesForPolicySDLErrorsStops = require ('user_modules/shared_testcases/testCasesForPolicySDLErrorsStops') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ General configuration parameters ]] Test = require('connecttest') @@ -153,7 +152,7 @@ local function activateAppInSpecificLevel(self, HMIAppID, hmi_level) --hmi side: send request SDL.OnAllowSDLFunctionality self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) --hmi side: expect BasicCommunication.ActivateApp request EXPECT_HMICALL("BasicCommunication.ActivateApp") @@ -423,4 +422,4 @@ function Test.Postcondition_Stop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/270_ATF_Validate_default_hmi_default_policies.lua b/test_scripts/Policies/Validation_of_PolicyTables/270_ATF_Validate_default_hmi_default_policies.lua index f5075956ae..ca54c264df 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/270_ATF_Validate_default_hmi_default_policies.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/270_ATF_Validate_default_hmi_default_policies.lua @@ -16,12 +16,10 @@ -- Expected result: -- PoliciesManager must validate "default_hmi" sub-section in "default" and treat it as valid -> PTU invalid --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFiles() @@ -36,7 +34,6 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_Activate_app() - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) EXPECT_HMIRESPONSE(RequestId) :Do(function(_,data) @@ -45,7 +42,7 @@ function Test:Precondition_Activate_app() EXPECT_HMIRESPONSE(RequestIdGetMes) :Do(function() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,_data1) self.hmiConnection:SendResponse(_data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) @@ -94,4 +91,4 @@ function Test.Postcondition_StopSDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/271_ATF_Validate_preconsented_groups_default_policies.lua b/test_scripts/Policies/Validation_of_PolicyTables/271_ATF_Validate_preconsented_groups_default_policies.lua index 69af0334d8..068fba1d5f 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/271_ATF_Validate_preconsented_groups_default_policies.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/271_ATF_Validate_preconsented_groups_default_policies.lua @@ -15,12 +15,10 @@ -- Expected result: -- PoliciesManager must validate "preconsented_groups" sub-section in "default" and treat it as valid -> PTU is valid --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFiles() @@ -35,7 +33,6 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_Activate_app() - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) EXPECT_HMIRESPONSE(RequestId) :Do(function(_,data) @@ -44,7 +41,7 @@ function Test:Precondition_Activate_app() EXPECT_HMIRESPONSE(RequestIdGetMes) :Do(function() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) @@ -102,4 +99,4 @@ function Test.Postcondition_SDLStop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/272_ATF_Validate_groups_default_policies.lua b/test_scripts/Policies/Validation_of_PolicyTables/272_ATF_Validate_groups_default_policies.lua index 8a748a0d30..c4aa108680 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/272_ATF_Validate_groups_default_policies.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/272_ATF_Validate_groups_default_policies.lua @@ -15,12 +15,10 @@ -- Expected result: -- PoliciesManager must validate "groups" sub-section in "default" and treat it as valid -> PTU is valid --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFiles() @@ -42,7 +40,7 @@ function Test:Precondition_Activate_app() local RequestIdGetMes = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetMes) :Do(function() - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/273_ATF_Validate_default_hmi_appId_policies.lua b/test_scripts/Policies/Validation_of_PolicyTables/273_ATF_Validate_default_hmi_appId_policies.lua index 69c77b0cf5..0e98440c84 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/273_ATF_Validate_default_hmi_appId_policies.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/273_ATF_Validate_default_hmi_appId_policies.lua @@ -18,13 +18,13 @@ -- PoliciesManager must validate "default_hmi" sub-section in "" and treat it as valid -> PTU valid --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -53,7 +53,6 @@ function Test:Precondition_Register_app() end function Test:Precondition_Activate_app() - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", {appID = self.HMIAppID2 }) EXPECT_HMIRESPONSE(RequestId,{}) :Do(function(_,data) @@ -63,7 +62,7 @@ function Test:Precondition_Activate_app() EXPECT_HMIRESPONSE(RequestIdGetMes) :Do(function() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) @@ -120,4 +119,4 @@ function Test.Postcondition_SDLStop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/274_ATF_Validate_appID_and_steal_focus_false.lua b/test_scripts/Policies/Validation_of_PolicyTables/274_ATF_Validate_appID_and_steal_focus_false.lua index 6058b466ca..de85d5bfca 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/274_ATF_Validate_appID_and_steal_focus_false.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/274_ATF_Validate_appID_and_steal_focus_false.lua @@ -16,13 +16,13 @@ -- respond (resultCode:DISALLOWED, success:false) to mobile application --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -127,7 +127,7 @@ function Test:Precondition_Activate_app() EXPECT_HMIRESPONSE(RequestIdGetMes) :Do(function() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) @@ -180,4 +180,4 @@ function Test.Postcondition_SDLStop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/275_ATF_Validate_appID_and_steal_focus_true.lua b/test_scripts/Policies/Validation_of_PolicyTables/275_ATF_Validate_appID_and_steal_focus_true.lua index eae08bfb5c..07cf784da9 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/275_ATF_Validate_appID_and_steal_focus_true.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/275_ATF_Validate_appID_and_steal_focus_true.lua @@ -19,13 +19,13 @@ -- PoliciesManager must allow SDL to pass RPC --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -130,7 +130,7 @@ function Test:Precondition_Activate_app() EXPECT_HMIRESPONSE(RequestIdGetMes) :Do(function() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) @@ -204,4 +204,4 @@ function Test.Postcondition_SDLStop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/276_ATF_Validate_appID_and_keep_context_true.lua b/test_scripts/Policies/Validation_of_PolicyTables/276_ATF_Validate_appID_and_keep_context_true.lua index ac9ec242a1..b939b3e956 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/276_ATF_Validate_appID_and_keep_context_true.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/276_ATF_Validate_appID_and_keep_context_true.lua @@ -19,13 +19,13 @@ -- PoliciesManager must allow SDL to pass RPC --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -130,7 +130,7 @@ function Test:Precondition_Activate_app() EXPECT_HMIRESPONSE(RequestIdGetMes) :Do(function() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) @@ -204,4 +204,4 @@ function Test.Postcondition_SDLStop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/277_ATF_Validate_appID_and_keep_context_false.lua b/test_scripts/Policies/Validation_of_PolicyTables/277_ATF_Validate_appID_and_keep_context_false.lua index 18e3a7734c..af80b5cfe3 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/277_ATF_Validate_appID_and_keep_context_false.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/277_ATF_Validate_appID_and_keep_context_false.lua @@ -16,13 +16,13 @@ -- respond (resultCode:DISALLOWED, success:false) to mobile application --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -127,7 +127,7 @@ function Test:Precondition_Activate_app() EXPECT_HMIRESPONSE(RequestIdGetMes) :Do(function() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) @@ -181,4 +181,4 @@ function Test.Postcondition_SDLStop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/278_ATF_Validate_groups_appID_policies.lua b/test_scripts/Policies/Validation_of_PolicyTables/278_ATF_Validate_groups_appID_policies.lua index dff5086ee9..552358c07b 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/278_ATF_Validate_groups_appID_policies.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/278_ATF_Validate_groups_appID_policies.lua @@ -17,13 +17,13 @@ -- PoliciesManager must validate "groups" sub-section in "" and treat it as valid -> PTU is valid --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -52,7 +52,6 @@ function Test:Precondition_Register_app() end function Test:Precondition_Activate_app() - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", {appID = self.HMIAppID2 }) EXPECT_HMIRESPONSE(RequestId,{}) :Do(function(_,data) @@ -62,7 +61,7 @@ function Test:Precondition_Activate_app() EXPECT_HMIRESPONSE(RequestIdGetMes) :Do(function() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) @@ -118,4 +117,4 @@ function Test.Postcondition_SDLStop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/279_ATF_Store_vin_from_GetVehicleData_in_PT.lua b/test_scripts/Policies/Validation_of_PolicyTables/279_ATF_Store_vin_from_GetVehicleData_in_PT.lua index cb7af4d787..425a7889ae 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/279_ATF_Store_vin_from_GetVehicleData_in_PT.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/279_ATF_Store_vin_from_GetVehicleData_in_PT.lua @@ -15,7 +15,6 @@ -- PoliciesManager writes to "module_meta" section of created LocalPT --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 diff --git a/test_scripts/Policies/Validation_of_PolicyTables/280_ATF_Reset_ignition_cycles_since_last_exchange_in_PT.lua b/test_scripts/Policies/Validation_of_PolicyTables/280_ATF_Reset_ignition_cycles_since_last_exchange_in_PT.lua index cb67722a31..6a0fa2f6b7 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/280_ATF_Reset_ignition_cycles_since_last_exchange_in_PT.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/280_ATF_Reset_ignition_cycles_since_last_exchange_in_PT.lua @@ -19,7 +19,6 @@ -- On successful PolicyTable exchange, Policies Manager must reset to "0" the value in 'ignition_cycles_since_last_exchange" --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.appHMIType = { "MEDIA" } @@ -29,6 +28,7 @@ local commonFunctions = require ('user_modules/shared_testcases/commonFunctions' local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local commonTestCases = require ('user_modules/shared_testcases/commonTestCases') +local utils = require ('user_modules/utils') --[[ Local variables ]] local ignition_cycles_before_ptu @@ -149,7 +149,7 @@ function Test:TestStep_Ignition_cycles_since_last_exchange_not_reset_after_RAI() end end function Test:TestStep_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:TestStep_flow_SUCCEESS_EXTERNAL_PROPRIETARY() diff --git a/test_scripts/Policies/Validation_of_PolicyTables/281_ATF_Store_ignition_cycles_since_last_exchange_in_PT.lua b/test_scripts/Policies/Validation_of_PolicyTables/281_ATF_Store_ignition_cycles_since_last_exchange_in_PT.lua index 9ebfdc142c..a31eb8db13 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/281_ATF_Store_ignition_cycles_since_last_exchange_in_PT.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/281_ATF_Store_ignition_cycles_since_last_exchange_in_PT.lua @@ -19,7 +19,6 @@ -- Pollicies Manager must increment the value in 'ignition_cycles_since_last_exchange' section of LocalPT --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 diff --git a/test_scripts/Policies/Validation_of_PolicyTables/282_ATF_PT_Exchanged_X_Days_After_Epoch_In_PTS.lua b/test_scripts/Policies/Validation_of_PolicyTables/282_ATF_PT_Exchanged_X_Days_After_Epoch_In_PTS.lua index e40830168c..5e41cabfea 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/282_ATF_PT_Exchanged_X_Days_After_Epoch_In_PTS.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/282_ATF_PT_Exchanged_X_Days_After_Epoch_In_PTS.lua @@ -14,15 +14,14 @@ -- Expected result: -- a) pt_exchanged_x_days_after_epoch value is equal to time of successfully updating --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonSteps = require ('user_modules/shared_testcases/commonSteps') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFiles() @@ -63,7 +62,7 @@ function Test:Precondition_Activate_App_Consent_Device_And_Update_Policy() local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) -- GetCurrentTimeStampDeviceConsent() EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) @@ -129,4 +128,4 @@ function Test.Postcondition_StopSDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/283_ATF_Store_pt_exchanged_at_odometer_x_in_PT.lua b/test_scripts/Policies/Validation_of_PolicyTables/283_ATF_Store_pt_exchanged_at_odometer_x_in_PT.lua index 8b6163d79d..f676583ff2 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/283_ATF_Store_pt_exchanged_at_odometer_x_in_PT.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/283_ATF_Store_pt_exchanged_at_odometer_x_in_PT.lua @@ -18,13 +18,13 @@ -- value must be stored in LocalPT in "pt_exchanged_at_odometer_x" of "meta_data" section --------------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -47,7 +47,7 @@ function Test:Precondition_Activate_app() EXPECT_HMIRESPONSE(RequestIdGetMes) :Do(function() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/284_ATF_Store_wers_country_code_in_PT.lua b/test_scripts/Policies/Validation_of_PolicyTables/284_ATF_Store_wers_country_code_in_PT.lua index b191d75343..6e8029cb58 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/284_ATF_Store_wers_country_code_in_PT.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/284_ATF_Store_wers_country_code_in_PT.lua @@ -17,7 +17,6 @@ -- SDL must set received value to "wers_country_code" section of "module_meta" section in PolicyTable --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 diff --git a/test_scripts/Policies/Validation_of_PolicyTables/285_ATF_Store_language_in_PT.lua b/test_scripts/Policies/Validation_of_PolicyTables/285_ATF_Store_language_in_PT.lua index 97db7a1e65..02479ac53c 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/285_ATF_Store_language_in_PT.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/285_ATF_Store_language_in_PT.lua @@ -17,7 +17,6 @@ -- SDL must set received value to "language" section of "module_meta" section in PolicyTable --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 diff --git a/test_scripts/Policies/Validation_of_PolicyTables/286_ATF_RAI_ccpu_version_via_GetSystemInfo.lua b/test_scripts/Policies/Validation_of_PolicyTables/286_ATF_RAI_ccpu_version_via_GetSystemInfo.lua index 51b29a41d2..89bc898936 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/286_ATF_RAI_ccpu_version_via_GetSystemInfo.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/286_ATF_RAI_ccpu_version_via_GetSystemInfo.lua @@ -15,7 +15,6 @@ -- SDL must request 'ccpu_version' ONLY once in ign cycle --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 diff --git a/test_scripts/Policies/Validation_of_PolicyTables/287_ATF_Validate_appHMIType_appID_policies.lua b/test_scripts/Policies/Validation_of_PolicyTables/287_ATF_Validate_appHMIType_appID_policies.lua index fdcb9a6cc2..8aa5099f10 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/287_ATF_Validate_appHMIType_appID_policies.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/287_ATF_Validate_appHMIType_appID_policies.lua @@ -17,13 +17,13 @@ -- PoliciesManager must validate "appHMIType" sub-section in "" and treat it as valid -> PTU is valid --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -61,7 +61,7 @@ function Test:Precondition_Activate_app() EXPECT_HMIRESPONSE(RequestIdGetMes) :Do(function() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) @@ -118,4 +118,4 @@ function Test.Postcondition_SDLStop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/288_ATF_EmptyArray_preconsented_groups_preDataConsent.lua b/test_scripts/Policies/Validation_of_PolicyTables/288_ATF_EmptyArray_preconsented_groups_preDataConsent.lua index c61d41ce36..084f3e8d5d 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/288_ATF_EmptyArray_preconsented_groups_preDataConsent.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/288_ATF_EmptyArray_preconsented_groups_preDataConsent.lua @@ -16,7 +16,6 @@ -- PoliciesManager must validate "preconsented_groups" sub-section in "pre_DataConsent" and treat it as invalid -> PTU invalid --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 config.ExitOnCrash = false diff --git a/test_scripts/Policies/Validation_of_PolicyTables/289_ATF_EmptyValue_preconsented_groups_preDataConsent.lua b/test_scripts/Policies/Validation_of_PolicyTables/289_ATF_EmptyValue_preconsented_groups_preDataConsent.lua index f1623db9ab..e8c41d0cb7 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/289_ATF_EmptyValue_preconsented_groups_preDataConsent.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/289_ATF_EmptyValue_preconsented_groups_preDataConsent.lua @@ -16,7 +16,6 @@ -- PoliciesManager must validate "preconsented_groups" sub-section in "pre_DataConsent" and treat it as invalid -> PTU invalid --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 config.ExitOnCrash = false diff --git a/test_scripts/Policies/Validation_of_PolicyTables/290_ATF_Nonfunctional_preconsented_groups_preDataConsent.lua b/test_scripts/Policies/Validation_of_PolicyTables/290_ATF_Nonfunctional_preconsented_groups_preDataConsent.lua index cef8ccc052..b777edbf11 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/290_ATF_Nonfunctional_preconsented_groups_preDataConsent.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/290_ATF_Nonfunctional_preconsented_groups_preDataConsent.lua @@ -16,7 +16,6 @@ -- PoliciesManager must validate "preconsented_groups" sub-section in "pre_DataConsent" and treat it as invalid -> PTU invalid --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/Validation_of_PolicyTables/291_ATF_Valid_preconsented_groups_preDataConsent.lua b/test_scripts/Policies/Validation_of_PolicyTables/291_ATF_Valid_preconsented_groups_preDataConsent.lua index ddb83a0c14..8e2fb83708 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/291_ATF_Valid_preconsented_groups_preDataConsent.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/291_ATF_Valid_preconsented_groups_preDataConsent.lua @@ -16,7 +16,6 @@ -- PoliciesManager must validate "preconsented_groups" sub-section in "pre_DataConsent" and treat it as valid->PTU is valid --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 diff --git a/test_scripts/Policies/Validation_of_PolicyTables/292_ATF_Valid_default_hmi_preDataConsent.lua b/test_scripts/Policies/Validation_of_PolicyTables/292_ATF_Valid_default_hmi_preDataConsent.lua index c5796888ea..26c03c00ea 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/292_ATF_Valid_default_hmi_preDataConsent.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/292_ATF_Valid_default_hmi_preDataConsent.lua @@ -16,7 +16,6 @@ -- PoliciesManager must validate "default_hmi"(BACKGROUND) sub-section in "pre_DataConsent" and treat it valid --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 diff --git a/test_scripts/Policies/Validation_of_PolicyTables/293_ATF_Validate_default_priority_preDataConsent.lua b/test_scripts/Policies/Validation_of_PolicyTables/293_ATF_Validate_default_priority_preDataConsent.lua index adfcaef268..d2c98e76c8 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/293_ATF_Validate_default_priority_preDataConsent.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/293_ATF_Validate_default_priority_preDataConsent.lua @@ -16,16 +16,13 @@ -- Expected result: -- PoliciesManager must not provide to HMI the app`s priority value --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -56,8 +53,8 @@ function Test:Precondition_Connect_device() { deviceList = { { - id = config.deviceMAC, - name = "127.0.0.1", + id = utils.getDeviceMAC(), + name = utils.getDeviceName(), transportType = "WIFI" } } diff --git a/test_scripts/Policies/Validation_of_PolicyTables/294_ATF_Validate_nondefault_priority_preDataConsent.lua b/test_scripts/Policies/Validation_of_PolicyTables/294_ATF_Validate_nondefault_priority_preDataConsent.lua index 31f85477d1..33c32392dc 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/294_ATF_Validate_nondefault_priority_preDataConsent.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/294_ATF_Validate_nondefault_priority_preDataConsent.lua @@ -17,15 +17,13 @@ -- Expected result: -- PoliciesManager must not provide to HMI the app`s priority value --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -54,8 +52,8 @@ function Test:Precondition_Connect_device() { deviceList = { { - id = config.deviceMAC, - name = "127.0.0.1", + id = utils.getDeviceMAC(), + name = utils.getDeviceName(), transportType = "WIFI" } } diff --git a/test_scripts/Policies/Validation_of_PolicyTables/295_ATF_Validate_preDataConsent_and_stealFocus_false.lua b/test_scripts/Policies/Validation_of_PolicyTables/295_ATF_Validate_preDataConsent_and_stealFocus_false.lua index 7185646da5..b27286fd46 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/295_ATF_Validate_preDataConsent_and_stealFocus_false.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/295_ATF_Validate_preDataConsent_and_stealFocus_false.lua @@ -15,9 +15,6 @@ -- PoliciesManager must validate "steal_focus" section, SDL must reject RPC-> -- respond (resultCode:DISALLOWED, success:false) to mobile application --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') @@ -73,4 +70,4 @@ function Test.Postcondition_SDLStop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/296_ATF_Validate_preDataConsent_and_stealFocus_true.lua b/test_scripts/Policies/Validation_of_PolicyTables/296_ATF_Validate_preDataConsent_and_stealFocus_true.lua index 631bd659d7..7a0af50df7 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/296_ATF_Validate_preDataConsent_and_stealFocus_true.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/296_ATF_Validate_preDataConsent_and_stealFocus_true.lua @@ -15,9 +15,6 @@ -- PoliciesManager must validate "steal_focus" section-> -- PoliciesManager must allow SDL to pas RPC --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') @@ -93,4 +90,4 @@ function Test.Postcondition_SDLStop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/297_ATF_Validate_preDataConsent_and_keepContext_false.lua b/test_scripts/Policies/Validation_of_PolicyTables/297_ATF_Validate_preDataConsent_and_keepContext_false.lua index d707f4cf72..bb54d76fb8 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/297_ATF_Validate_preDataConsent_and_keepContext_false.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/297_ATF_Validate_preDataConsent_and_keepContext_false.lua @@ -20,9 +20,6 @@ Test = require('connecttest') require('cardinalities') require('user_modules/AppTypes') ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') @@ -73,4 +70,4 @@ function Test.Postcondition_SDLStop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/298_ATF_Validate_preDataConsent_and_keepContext_true.lua b/test_scripts/Policies/Validation_of_PolicyTables/298_ATF_Validate_preDataConsent_and_keepContext_true.lua index 77f53b1038..91be927c4e 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/298_ATF_Validate_preDataConsent_and_keepContext_true.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/298_ATF_Validate_preDataConsent_and_keepContext_true.lua @@ -15,9 +15,6 @@ -- PoliciesManager must validate "keep_context" section-> -- PoliciesManager must allow SDL to pass RPC --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') @@ -93,4 +90,4 @@ function Test.Postcondition_SDLStop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/299_ATF_Memory_Kb_Constraints_Ignoring.lua b/test_scripts/Policies/Validation_of_PolicyTables/299_ATF_Memory_Kb_Constraints_Ignoring.lua index 390bd2a014..6aa3b91790 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/299_ATF_Memory_Kb_Constraints_Ignoring.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/299_ATF_Memory_Kb_Constraints_Ignoring.lua @@ -17,9 +17,7 @@ -- a) PutFile SUCCESS resultCode - memory_kb parameter is ignored for app -- b) PutFile OUT_OF_MEMORY resultCode - AppDirectoryQuota applies for app --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.appName = "SPT" @@ -31,6 +29,7 @@ local commonFunctions = require ('user_modules/shared_testcases/commonFunctions' local commonSteps = require ('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() @@ -65,7 +64,7 @@ function Test:TestStep_PredataConsent_Send_PutFile_Bigger_Than_AppDirectoryQuota end function Test:TestStep_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:TestStep_Default_Send_PutFile_Bigger_Than_AppDirectoryQuota_OUT_OF_MEMORY() diff --git a/test_scripts/Policies/Validation_of_PolicyTables/300_ATF_HP_Applying_Heart_Beat_Timeout_Ms_From_PT.lua b/test_scripts/Policies/Validation_of_PolicyTables/300_ATF_HP_Applying_Heart_Beat_Timeout_Ms_From_PT.lua index 80af820cdd..baf4fdb578 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/300_ATF_HP_Applying_Heart_Beat_Timeout_Ms_From_PT.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/300_ATF_HP_Applying_Heart_Beat_Timeout_Ms_From_PT.lua @@ -17,10 +17,6 @@ -- Expected result: -- a) SDL send HB with time specified in pre_DataConsent section (4000 ms) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/301_ATF_usage_and_error_counts_update_app_registration_language_vui.lua b/test_scripts/Policies/Validation_of_PolicyTables/301_ATF_usage_and_error_counts_update_app_registration_language_vui.lua index d0e44608c2..45e06d4023 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/301_ATF_usage_and_error_counts_update_app_registration_language_vui.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/301_ATF_usage_and_error_counts_update_app_registration_language_vui.lua @@ -16,18 +16,17 @@ -- SDL must: must write "languageDesired" value received via RegisterAppInterface into Local Policy Table -- as "app_registration_language_vui" key value of "usage_and_error_counts"- >"app_level" - > section. --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] Test = require('connecttest') local config = require('config') config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local json = require("modules/json") local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTableSnapshot = require ('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') require('cardinalities') require('user_modules/AppTypes') @@ -332,7 +331,7 @@ local function activateAppInSpecificLevel(self, HMIAppID, hmi_level) --hmi side: send request SDL.OnAllowSDLFunctionality self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) --hmi side: expect BasicCommunication.ActivateApp request EXPECT_HMICALL("BasicCommunication.ActivateApp") diff --git a/test_scripts/Policies/Validation_of_PolicyTables/302_ATF_HP_Applying_Heart_Beat_Timeout_Ms_After_PTU.lua b/test_scripts/Policies/Validation_of_PolicyTables/302_ATF_HP_Applying_Heart_Beat_Timeout_Ms_After_PTU.lua index f03fda6e25..3e69d958a5 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/302_ATF_HP_Applying_Heart_Beat_Timeout_Ms_After_PTU.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/302_ATF_HP_Applying_Heart_Beat_Timeout_Ms_After_PTU.lua @@ -18,15 +18,12 @@ -- Expected result: -- a) SDL send HB with time specified in pre_DataConsent section (4000 ms) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') +local utils = require ('user_modules/utils') --Heartbeat is supported after protocolversion 3 config.defaultProtocolVersion = 3 @@ -83,11 +80,11 @@ function Test:Precondition_RegisterApp() end function Test:Precondition_Activate_Consent_App() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_Update_Policy_With_heart_beat_timeout_ms_Param() - testCasesForPolicyTable:flow_SUCCEESS_EXTERNAL_PROPRIETARY(self, config.application1.registerAppInterfaceParams.appID, config.deviceMAC, + testCasesForPolicyTable:flow_SUCCEESS_EXTERNAL_PROPRIETARY(self, config.application1.registerAppInterfaceParams.appID, utils.getDeviceMAC(), self.HMIAppID, nil, nil, "ptu_heart_beat_timeout_ms_app_1234567.json") end diff --git a/test_scripts/Policies/Validation_of_PolicyTables/303_ATF_HP_Usage_And_Error_Counts_For_AppID.lua b/test_scripts/Policies/Validation_of_PolicyTables/303_ATF_HP_Usage_And_Error_Counts_For_AppID.lua index 60660b3637..8a03780882 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/303_ATF_HP_Usage_And_Error_Counts_For_AppID.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/303_ATF_HP_Usage_And_Error_Counts_For_AppID.lua @@ -15,7 +15,6 @@ -- a) App present in usage_and_error_counts section in PTS --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -26,6 +25,7 @@ require('cardinalities') --[[ Required Shared libraries ]] local commonSteps = require ('user_modules/shared_testcases/commonSteps') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') +local utils = require ('user_modules/utils') require('user_modules/AppTypes') --[[ General Precondition before ATF start ]] @@ -57,12 +57,12 @@ function Test:Activate_App_Consent_Device_And_Check_Error_Count_For_App_In_PTS() local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) end) - :Times(AtLeast(1)) + :Times(AtLeast(1)) end) end) EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "FULL", systemContext = "MAIN"}) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/304_ATF_HP_Validation_Count_Of_User_Selections.lua b/test_scripts/Policies/Validation_of_PolicyTables/304_ATF_HP_Validation_Count_Of_User_Selections.lua index a7fcbc6852..1b73cd8b72 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/304_ATF_HP_Validation_Count_Of_User_Selections.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/304_ATF_HP_Validation_Count_Of_User_Selections.lua @@ -18,7 +18,6 @@ -- a) "count_of_user_selections" in PTS is equal actual numbers of app activation --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -29,6 +28,7 @@ require('cardinalities') --[[ Required Shared libraries ]] local commonSteps = require ('user_modules/shared_testcases/commonSteps') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') +local utils = require ('user_modules/utils') require('user_modules/AppTypes') --[[ General Precondition before ATF start ]] @@ -48,7 +48,7 @@ function Test:Precondition_Activate_App_Consent_Device() local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data) self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/306_ATF_Update_count_of_run_attempts_while_revoked_in_PT.lua b/test_scripts/Policies/Validation_of_PolicyTables/306_ATF_Update_count_of_run_attempts_while_revoked_in_PT.lua index 82be8e7d61..16208cb518 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/306_ATF_Update_count_of_run_attempts_while_revoked_in_PT.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/306_ATF_Update_count_of_run_attempts_while_revoked_in_PT.lua @@ -22,13 +22,13 @@ -- PoliciesManager increments "count_of_run_attempts_while_revoked" at PolicyTable --------------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local Variables ]] local HMIAppID @@ -48,7 +48,7 @@ require('cardinalities') --[[ Precondtions]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:TestStep_PTU_appPermissionsConsentNeeded_true() diff --git a/test_scripts/Policies/Validation_of_PolicyTables/307_ATF_Validate_preDataConsent_RequestType_disallowed.lua b/test_scripts/Policies/Validation_of_PolicyTables/307_ATF_Validate_preDataConsent_RequestType_disallowed.lua index d859acc5b5..e67de731cb 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/307_ATF_Validate_preDataConsent_RequestType_disallowed.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/307_ATF_Validate_preDataConsent_RequestType_disallowed.lua @@ -18,7 +18,6 @@ -- PoliciesManager must ignore RPC, SDL must respond (resultCode:DISALLOWED, success:false) to mobile application --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[ToDo: should be removed when fixed: "ATF does not stop HB timers by closing session and connection" config.defaultProtocolVersion = 2 @@ -137,4 +136,4 @@ end function Test.Postcondition_Restore_preloaded() Restore_preloaded() -end \ No newline at end of file +end diff --git a/test_scripts/Policies/Validation_of_PolicyTables/308_ATF_Check_app_registration_language_gui.lua b/test_scripts/Policies/Validation_of_PolicyTables/308_ATF_Check_app_registration_language_gui.lua index e6d99c0e8f..a8c7c10fa6 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/308_ATF_Check_app_registration_language_gui.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/308_ATF_Check_app_registration_language_gui.lua @@ -19,9 +19,7 @@ -- Expected: -- 4. PolciesManager writes to "app_registration_language_gui" field at LocalPT --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.application1.registerAppInterfaceParams.appHMIType = { "MEDIA" } config.defaultProtocolVersion = 2 diff --git a/test_scripts/Policies/Validation_of_PolicyTables/309_ATF_Check_count_of_rejected_rpcs_calls.lua b/test_scripts/Policies/Validation_of_PolicyTables/309_ATF_Check_count_of_rejected_rpcs_calls.lua index a6849d62d2..054a8f3150 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/309_ATF_Check_count_of_rejected_rpcs_calls.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/309_ATF_Check_count_of_rejected_rpcs_calls.lua @@ -19,9 +19,6 @@ -- Expected: -- PoliciesManager increments "count_of_rejected_rpcs_calls" field at PolicyTable --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/310_ATF_Check_count_of_removals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua b/test_scripts/Policies/Validation_of_PolicyTables/310_ATF_Check_count_of_removals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua index 049daf439c..71c9a134b8 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/310_ATF_Check_count_of_removals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/310_ATF_Check_count_of_removals_for_bad_behavior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua @@ -27,9 +27,8 @@ -- 3. PoliciesManager increments value of -- Thic - +--------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 config.ExitOnCrash = false @@ -38,6 +37,7 @@ local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local Preconditions = require('user_modules/shared_testcases/commonPreconditions') local mobile_session = require('mobile_session') + -- local variables local count_of_requests = 10 -- local HMIAppID diff --git a/test_scripts/Policies/Validation_of_PolicyTables/311_ATF_Check_count_of_removals_for_bad_behavior_too_many_pending_requests.lua b/test_scripts/Policies/Validation_of_PolicyTables/311_ATF_Check_count_of_removals_for_bad_behavior_too_many_pending_requests.lua index 5618d5d30c..5a3b3dd5f7 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/311_ATF_Check_count_of_removals_for_bad_behavior_too_many_pending_requests.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/311_ATF_Check_count_of_removals_for_bad_behavior_too_many_pending_requests.lua @@ -22,9 +22,7 @@ -- Application is unregistered: SDL->appID: OnAppUnregistered(TOO_MANY_REQUESTS) -- PoliciesManager increments value of --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 config.ExitOnCrash = false @@ -33,6 +31,7 @@ local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonPreconditions = require("user_modules/shared_testcases/commonPreconditions") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +local utils = require ('user_modules/utils') -- local variables local count_of_requests = 10 @@ -63,7 +62,7 @@ function Test:ActivateApp() local requestId2 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", { language = "EN-US", messageCodes = { "DataConsent" } }) EXPECT_HMIRESPONSE(requestId2) :Do(function() - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_, d2) self.hmiConnection:SendResponse(d2.id,"BasicCommunication.ActivateApp", "SUCCESS", { }) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/312_ATF_Check_count_of_removals_for_bad_behavior_too_many_requests.lua b/test_scripts/Policies/Validation_of_PolicyTables/312_ATF_Check_count_of_removals_for_bad_behavior_too_many_requests.lua index 64a72b6e91..ce9c15a8ff 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/312_ATF_Check_count_of_removals_for_bad_behavior_too_many_requests.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/312_ATF_Check_count_of_removals_for_bad_behavior_too_many_requests.lua @@ -23,9 +23,8 @@ -- Expected: -- 3. PoliciesManager increments value of - +--------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] @@ -33,6 +32,7 @@ local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local mobile_session = require('mobile_session') local Preconditions = require('user_modules/shared_testcases/commonPreconditions') + -- local variables local count_of_requests = 10 local HMIAppID diff --git a/test_scripts/Policies/Validation_of_PolicyTables/313_ATF_Check_count_of_rpcs_sent_in_hmi_none.lua b/test_scripts/Policies/Validation_of_PolicyTables/313_ATF_Check_count_of_rpcs_sent_in_hmi_none.lua index 18e3ffc4bb..90febc2f37 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/313_ATF_Check_count_of_rpcs_sent_in_hmi_none.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/313_ATF_Check_count_of_rpcs_sent_in_hmi_none.lua @@ -16,10 +16,7 @@ -- Expected: -- 2. PoliciesManager increment "count_of_rpcs_sent_in_hmi_none" at LocalPT for this app - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - +--------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') @@ -56,4 +53,4 @@ function Test:CheckDB_updated_count_of_rejections_duplicate_name() end end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/314_ATF_Check_count_of_user_selections.lua b/test_scripts/Policies/Validation_of_PolicyTables/314_ATF_Check_count_of_user_selections.lua index 43cd8b5202..1319958c88 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/314_ATF_Check_count_of_user_selections.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/314_ATF_Check_count_of_user_selections.lua @@ -18,7 +18,6 @@ -- 3. PoliciesMananger increments "count_of_rejections_duplicate_name" filed at PolicyTable --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 diff --git a/test_scripts/Policies/appID_Management/031_ATF_Register_App_Interface_App_Unauthorized.lua b/test_scripts/Policies/appID_Management/031_ATF_Register_App_Interface_App_Unauthorized.lua index 91d878a711..0534e0e500 100644 --- a/test_scripts/Policies/appID_Management/031_ATF_Register_App_Interface_App_Unauthorized.lua +++ b/test_scripts/Policies/appID_Management/031_ATF_Register_App_Interface_App_Unauthorized.lua @@ -21,16 +21,13 @@ -- currently registered appName is different from value in policy table -> -- SDL->app: OnAppInterfaceUnregistered (APP_UNAUTHORIZED) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local testCasesForPolicyAppIdManagament = require("user_modules/shared_testcases/testCasesForPolicyAppIdManagament") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -44,7 +41,7 @@ local mobileSession = require("mobile_session") commonFunctions:newTestCasesGroup("Preconditions") function Test:Pecondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:UpdatePolicy() diff --git a/test_scripts/Policies/appID_Management/032_ATF_Register_App_Interface_Successful_Nickname_Validation.lua b/test_scripts/Policies/appID_Management/032_ATF_Register_App_Interface_Successful_Nickname_Validation.lua index f28183008a..05804c0f1a 100644 --- a/test_scripts/Policies/appID_Management/032_ATF_Register_App_Interface_Successful_Nickname_Validation.lua +++ b/test_scripts/Policies/appID_Management/032_ATF_Register_App_Interface_Successful_Nickname_Validation.lua @@ -21,16 +21,13 @@ -- SDL must successfully register such application: -- RegisterAppInterface_response (, success: true) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyAppIdManagament = require("user_modules/shared_testcases/testCasesForPolicyAppIdManagament") local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -42,7 +39,7 @@ require("user_modules/AppTypes") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Pecondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:UpdatePolicy() diff --git a/test_scripts/Policies/appID_Management/033_ATF_Register_App_Interface_Order_Of_Nickname_Validation.lua b/test_scripts/Policies/appID_Management/033_ATF_Register_App_Interface_Order_Of_Nickname_Validation.lua index f3c2acd24e..684a36a19a 100644 --- a/test_scripts/Policies/appID_Management/033_ATF_Register_App_Interface_Order_Of_Nickname_Validation.lua +++ b/test_scripts/Policies/appID_Management/033_ATF_Register_App_Interface_Order_Of_Nickname_Validation.lua @@ -22,16 +22,13 @@ -- Expected result: -- SDL returns RegisterAppInterface's response (DISALLOWED, success: false) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") local testCasesForPolicyAppIdManagament = require("user_modules/shared_testcases/testCasesForPolicyAppIdManagament") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -43,7 +40,7 @@ require("user_modules/AppTypes") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Pecondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:UpdatePolicy() diff --git a/test_scripts/Policies/appID_Management/034_ATF_Register_App_Interface_Disallowed.lua b/test_scripts/Policies/appID_Management/034_ATF_Register_App_Interface_Disallowed.lua index d8dc25815b..58076db06d 100644 --- a/test_scripts/Policies/appID_Management/034_ATF_Register_App_Interface_Disallowed.lua +++ b/test_scripts/Policies/appID_Management/034_ATF_Register_App_Interface_Disallowed.lua @@ -18,16 +18,13 @@ -- Expected result: -- SDL must respond with the following data: success = false, resultCode = "DISALLOWED" --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") local testCasesForPolicyAppIdManagament = require("user_modules/shared_testcases/testCasesForPolicyAppIdManagament") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -39,7 +36,7 @@ require("user_modules/AppTypes") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Pecondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:UpdatePolicy() diff --git a/test_scripts/Policies/appID_Management/035_ATF_Register_App_Interface_Case-insensitivity_Of_AppName.lua b/test_scripts/Policies/appID_Management/035_ATF_Register_App_Interface_Case-insensitivity_Of_AppName.lua index df9ddbd6e8..fd14d8a55d 100644 --- a/test_scripts/Policies/appID_Management/035_ATF_Register_App_Interface_Case-insensitivity_Of_AppName.lua +++ b/test_scripts/Policies/appID_Management/035_ATF_Register_App_Interface_Case-insensitivity_Of_AppName.lua @@ -19,16 +19,13 @@ -- Expected result: -- SDL must respond with the following data: success = true, resultCode = "SUCCESS" --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") local testCasesForPolicyAppIdManagament = require("user_modules/shared_testcases/testCasesForPolicyAppIdManagament") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -40,7 +37,7 @@ require("user_modules/AppTypes") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Pecondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:UpdatePolicy() @@ -68,4 +65,4 @@ function Test.Postcondition_Stop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/appID_Management/036_ATF_Change_Registration_Disallowed.lua b/test_scripts/Policies/appID_Management/036_ATF_Change_Registration_Disallowed.lua index 78dd06b8e4..8b9bc690ed 100644 --- a/test_scripts/Policies/appID_Management/036_ATF_Change_Registration_Disallowed.lua +++ b/test_scripts/Policies/appID_Management/036_ATF_Change_Registration_Disallowed.lua @@ -18,10 +18,6 @@ -- Expected result: -- Response has the following data: success = false, resultCode = "DISALLOWED" --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") local testCasesForPolicyAppIdManagament = require("user_modules/shared_testcases/testCasesForPolicyAppIdManagament") @@ -29,6 +25,7 @@ local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -40,7 +37,7 @@ require("user_modules/AppTypes") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Pecondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_UpdatePolicy() diff --git a/test_scripts/Policies/appID_Management/037_ATF_Register_App_Interface_Assign_Existing_Policies.lua b/test_scripts/Policies/appID_Management/037_ATF_Register_App_Interface_Assign_Existing_Policies.lua index c8ae092178..6bee5f39d4 100644 --- a/test_scripts/Policies/appID_Management/037_ATF_Register_App_Interface_Assign_Existing_Policies.lua +++ b/test_scripts/Policies/appID_Management/037_ATF_Register_App_Interface_Assign_Existing_Policies.lua @@ -23,10 +23,6 @@ -- Status of response: sucess = false, resultCode = "DISALLOWED" --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") local testCasesForPolicyAppIdManagament = require("user_modules/shared_testcases/testCasesForPolicyAppIdManagament") @@ -34,6 +30,7 @@ local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTableSnapshot = require("user_modules/shared_testcases/testCasesForPolicyTableSnapshot") local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -45,7 +42,7 @@ require("user_modules/AppTypes") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Pecondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:UpdatePolicy() diff --git a/test_scripts/Policies/appID_Management/038_ATF_Register_App_Interface_Without_Data_Consent_Assign_pre_DataConsent_Policies.lua b/test_scripts/Policies/appID_Management/038_ATF_Register_App_Interface_Without_Data_Consent_Assign_pre_DataConsent_Policies.lua index 7ecbebb2b4..9c3fbc3ec8 100644 --- a/test_scripts/Policies/appID_Management/038_ATF_Register_App_Interface_Without_Data_Consent_Assign_pre_DataConsent_Policies.lua +++ b/test_scripts/Policies/appID_Management/038_ATF_Register_App_Interface_Without_Data_Consent_Assign_pre_DataConsent_Policies.lua @@ -18,13 +18,10 @@ -- 1. sdl_snapshot is created. -- 2. Application is added to policy and assigns pre_DataConsent group --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") +local utils = require ('user_modules/utils') --[[ Local Functions ]] local function get_permission_code(app_id) diff --git a/test_scripts/Policies/appID_Management/039_ATF_Register_App_Interface_With_Data_Consent_Assign_Default_Policies.lua b/test_scripts/Policies/appID_Management/039_ATF_Register_App_Interface_With_Data_Consent_Assign_Default_Policies.lua index 06029badf9..274151146b 100644 --- a/test_scripts/Policies/appID_Management/039_ATF_Register_App_Interface_With_Data_Consent_Assign_Default_Policies.lua +++ b/test_scripts/Policies/appID_Management/039_ATF_Register_App_Interface_With_Data_Consent_Assign_Default_Policies.lua @@ -24,13 +24,10 @@ -- Status of response: success = true, resultCode = "SUCCESS" for PutFile -- Status of response: success = false, resultCode = "DISALLOWED" for GetVehicleData --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() diff --git a/test_scripts/Policies/appID_Management/040_ATF_Register_App_Interface_Case-insensitivity_Of_AppId.lua b/test_scripts/Policies/appID_Management/040_ATF_Register_App_Interface_Case-insensitivity_Of_AppId.lua index 0d95c29521..4cc41ec923 100644 --- a/test_scripts/Policies/appID_Management/040_ATF_Register_App_Interface_Case-insensitivity_Of_AppId.lua +++ b/test_scripts/Policies/appID_Management/040_ATF_Register_App_Interface_Case-insensitivity_Of_AppId.lua @@ -19,16 +19,13 @@ -- SDL must allow application registration, not considering the case letters when comparing -- with appID from policies: SDL->appID: SUCCESS: RegisterAppInterface() --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") local testCasesForPolicyAppIdManagament = require("user_modules/shared_testcases/testCasesForPolicyAppIdManagament") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -40,7 +37,7 @@ require("user_modules/AppTypes") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Pecondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:UpdatePolicy() diff --git a/test_scripts/Policies/appID_Management/041_ATF_OnAppPermissionChanged_appRevoked_true.lua b/test_scripts/Policies/appID_Management/041_ATF_OnAppPermissionChanged_appRevoked_true.lua index 4aea1e2f7d..16f596696f 100644 --- a/test_scripts/Policies/appID_Management/041_ATF_OnAppPermissionChanged_appRevoked_true.lua +++ b/test_scripts/Policies/appID_Management/041_ATF_OnAppPermissionChanged_appRevoked_true.lua @@ -17,16 +17,15 @@ -- Expected result: -- SDL -> HMI: OnAppPermissionChanged (, appRevoked=true, params) --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] -- local mobileSession = require("mobile_session") local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local json = require("modules/json") +local utils = require ('user_modules/utils') --[[ Local Variables ]] local ptu_table @@ -78,7 +77,7 @@ function Test:ActivateApp() EXPECT_HMIRESPONSE(requestId2) :Do(function() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_, data2) self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", { }) diff --git a/test_scripts/Policies/appID_Management/042_ATF_PolicyTable_RAI_with_NULL_policies_RPCs_DISALLOWED.lua b/test_scripts/Policies/appID_Management/042_ATF_PolicyTable_RAI_with_NULL_policies_RPCs_DISALLOWED.lua index c5a4805ccd..c1f729d1c4 100644 --- a/test_scripts/Policies/appID_Management/042_ATF_PolicyTable_RAI_with_NULL_policies_RPCs_DISALLOWED.lua +++ b/test_scripts/Policies/appID_Management/042_ATF_PolicyTable_RAI_with_NULL_policies_RPCs_DISALLOWED.lua @@ -12,16 +12,15 @@ -- 2. MOB-SDL - send the list of RPCs -- 3. SDL responce, success = false, resultCode = "DISALLOWED" --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local json = require("modules/json") +local utils = require ('user_modules/utils') --[[ Local Variables ]] local ptu_table @@ -76,7 +75,7 @@ function Test:ActivateApp() EXPECT_HMIRESPONSE(requestId2) :Do(function() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_, data2) self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", { }) diff --git a/test_scripts/Policies/appID_Management/043_ATF_HMI_Status_Appid_Gets_Null_In_Case_Of_PTU.lua b/test_scripts/Policies/appID_Management/043_ATF_HMI_Status_Appid_Gets_Null_In_Case_Of_PTU.lua index 4ad42bd58f..94ab4bf7f9 100644 --- a/test_scripts/Policies/appID_Management/043_ATF_HMI_Status_Appid_Gets_Null_In_Case_Of_PTU.lua +++ b/test_scripts/Policies/appID_Management/043_ATF_HMI_Status_Appid_Gets_Null_In_Case_Of_PTU.lua @@ -20,9 +20,7 @@ -- OnHMIStatus: hmiLevel="NONE", systemContext="MAIN", audioStreamingState="NOT_AUDIBLE" -- --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.application1.registerAppInterfaceParams.appName = "App1" config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } config.application2.registerAppInterfaceParams.appHMIType = { "MEDIA" } @@ -34,6 +32,7 @@ local testCasesForPolicyAppIdManagament = require("user_modules/shared_testcases local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -46,7 +45,7 @@ local HMIAppID --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Pecondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:UpdatePolicy() diff --git a/test_scripts/Policies/appID_Management/044_ATF_HMI_Status_Value_Of_AppId_In_PT_Is_Null.lua b/test_scripts/Policies/appID_Management/044_ATF_HMI_Status_Value_Of_AppId_In_PT_Is_Null.lua index ad0daa85f6..97b681e125 100644 --- a/test_scripts/Policies/appID_Management/044_ATF_HMI_Status_Value_Of_AppId_In_PT_Is_Null.lua +++ b/test_scripts/Policies/appID_Management/044_ATF_HMI_Status_Value_Of_AppId_In_PT_Is_Null.lua @@ -18,9 +18,7 @@ -- 1. status = "REJECTED" -- 2. hmiLevel = "NONE" --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.application1.registerAppInterfaceParams.appName = "App1" config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } config.application2.registerAppInterfaceParams.appHMIType = { "MEDIA" } @@ -32,6 +30,7 @@ local testCasesForPolicyAppIdManagament = require("user_modules/shared_testcases local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -44,7 +43,7 @@ local HMIAppID --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Pecondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:UpdatePolicy() diff --git a/test_scripts/Policies/appID_Management/045_ATF_Register_App_Interface_Assign_Default_Policies_To_Application_Which_Appid_Does_Not_Exist_In_LPT.lua b/test_scripts/Policies/appID_Management/045_ATF_Register_App_Interface_Assign_Default_Policies_To_Application_Which_Appid_Does_Not_Exist_In_LPT.lua index d689ab873c..e36ab81985 100644 --- a/test_scripts/Policies/appID_Management/045_ATF_Register_App_Interface_Assign_Default_Policies_To_Application_Which_Appid_Does_Not_Exist_In_LPT.lua +++ b/test_scripts/Policies/appID_Management/045_ATF_Register_App_Interface_Assign_Default_Policies_To_Application_Which_Appid_Does_Not_Exist_In_LPT.lua @@ -17,12 +17,10 @@ -- Expected result: -- Default permissions is assigned for app --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") +local utils = require ('user_modules/utils') --[[ Local Variables ]] local db_file = config.pathToSDL .. "/" .. commonFunctions:read_parameter_from_smart_device_link_ini("AppStorageFolder") .. "/policy.sqlite" @@ -94,7 +92,7 @@ function Test:TestStep_ActivateApp() EXPECT_HMIRESPONSE(requestId2) :Do(function(_, _) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_, data2) self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", { }) diff --git a/test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua b/test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua index ffe027dd9c..1f98d94931 100644 --- a/test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua +++ b/test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua @@ -19,13 +19,13 @@ -- Permissions in payload of OnPermissionsChange() notification is the same as defined in LPT (specific) --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") +local utils = require ('user_modules/utils') --[[ Local Variables ]] local policy_file_name = "PolicyTableUpdate" @@ -73,7 +73,7 @@ function Test:ActivateApp() EXPECT_HMIRESPONSE(requestId2) :Do(function(_, _) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_, data2) self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", { }) diff --git a/test_scripts/Policies/build_options/047_ATF_SDL_Build_DEXTENDED_POLICY_EXTERNAL_PROPRIETARY.lua b/test_scripts/Policies/build_options/047_ATF_SDL_Build_DEXTENDED_POLICY_EXTERNAL_PROPRIETARY.lua index d9741400ad..fc54cc2a2b 100644 --- a/test_scripts/Policies/build_options/047_ATF_SDL_Build_DEXTENDED_POLICY_EXTERNAL_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/047_ATF_SDL_Build_DEXTENDED_POLICY_EXTERNAL_PROPRIETARY.lua @@ -15,14 +15,11 @@ -- PTU passes successfully --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -36,7 +33,7 @@ require('user_modules/AppTypes') --[[ Test ]] commonFunctions:newTestCasesGroup("Test") function Test:TestStep_Device_Consented() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:TestStep_SUCCEESS_Flow_EXTERNAL_PROPRIETARY() @@ -49,4 +46,4 @@ function Test.Postcondition_Stop_SDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/build_options/048_ATF_SDL_Build_Flag_DEXTENDED_POLICY_PROPRIETARY.lua b/test_scripts/Policies/build_options/048_ATF_SDL_Build_Flag_DEXTENDED_POLICY_PROPRIETARY.lua index c3e16f7a83..0e1e3ee7fe 100644 --- a/test_scripts/Policies/build_options/048_ATF_SDL_Build_Flag_DEXTENDED_POLICY_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/048_ATF_SDL_Build_Flag_DEXTENDED_POLICY_PROPRIETARY.lua @@ -15,9 +15,8 @@ -- PTU passes successfully --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local mobile_session = require("mobile_session") diff --git a/test_scripts/Policies/build_options/050_ATF_Request_PTU_Trigger_PTU_failed_previous_IGN_ON_HTTP.lua b/test_scripts/Policies/build_options/050_ATF_Request_PTU_Trigger_PTU_failed_previous_IGN_ON_HTTP.lua index f210cdf8bc..ebd8a953af 100644 --- a/test_scripts/Policies/build_options/050_ATF_Request_PTU_Trigger_PTU_failed_previous_IGN_ON_HTTP.lua +++ b/test_scripts/Policies/build_options/050_ATF_Request_PTU_Trigger_PTU_failed_previous_IGN_ON_HTTP.lua @@ -21,9 +21,7 @@ -- PTU is requested. PTS is created. -- SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.application1.registerAppInterfaceParams.appHMIType = { "MEDIA" } config.ExitOnCrash = false diff --git a/test_scripts/Policies/build_options/051_ATF_Policy_Table_Update_Trigger_After_N_Kilometers_HTTP.lua b/test_scripts/Policies/build_options/051_ATF_Policy_Table_Update_Trigger_After_N_Kilometers_HTTP.lua index 72f858d122..96e5bb5fb9 100644 --- a/test_scripts/Policies/build_options/051_ATF_Policy_Table_Update_Trigger_After_N_Kilometers_HTTP.lua +++ b/test_scripts/Policies/build_options/051_ATF_Policy_Table_Update_Trigger_After_N_Kilometers_HTTP.lua @@ -25,9 +25,7 @@ -- Expected result: -- PTU flow started --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: Should be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -35,6 +33,7 @@ config.defaultProtocolVersion = 2 local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFiles() @@ -91,7 +90,7 @@ function Test:Precondition_Activate_App_Start_PTU() EXPECT_HMIRESPONSE(RequestId) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data2) self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/build_options/052_ATF_PTU_Trigger_IGN_Cycles_HTTP.lua b/test_scripts/Policies/build_options/052_ATF_PTU_Trigger_IGN_Cycles_HTTP.lua index 80e1722fc7..b493a7f8b7 100644 --- a/test_scripts/Policies/build_options/052_ATF_PTU_Trigger_IGN_Cycles_HTTP.lua +++ b/test_scripts/Policies/build_options/052_ATF_PTU_Trigger_IGN_Cycles_HTTP.lua @@ -18,9 +18,7 @@ -- gets equal to the value of field "exchange_after_x_ignition_cycles" ("module_config" section) ----PTU sequence is triggered and SDL sends to HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" Test = require('connecttest') --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/build_options/053_ATF_Policy_Table_Update_Trigger_After_N_Days_HTTP.lua b/test_scripts/Policies/build_options/053_ATF_Policy_Table_Update_Trigger_After_N_Days_HTTP.lua index d018d7858b..6e42ec7518 100644 --- a/test_scripts/Policies/build_options/053_ATF_Policy_Table_Update_Trigger_After_N_Days_HTTP.lua +++ b/test_scripts/Policies/build_options/053_ATF_Policy_Table_Update_Trigger_After_N_Days_HTTP.lua @@ -18,9 +18,7 @@ -- SDL initiates PTU: SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) -- PTS is created by SDL: SDL-> HMI: SDL.PolicyUpdate() //PTU sequence started --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/build_options/054_ATF_Request_PTU_UPDATE_NEEDED_new_PTU_Request_HTTP.lua b/test_scripts/Policies/build_options/054_ATF_Request_PTU_UPDATE_NEEDED_new_PTU_Request_HTTP.lua index 53e8ddc346..fd526b008a 100644 --- a/test_scripts/Policies/build_options/054_ATF_Request_PTU_UPDATE_NEEDED_new_PTU_Request_HTTP.lua +++ b/test_scripts/Policies/build_options/054_ATF_Request_PTU_UPDATE_NEEDED_new_PTU_Request_HTTP.lua @@ -17,10 +17,6 @@ -- SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) -- SDL->HMI: BasicCommunication.PolicyUpdate --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/build_options/055_ATF_Policy_Table_Snapshot_Creation_HTTP.lua b/test_scripts/Policies/build_options/055_ATF_Policy_Table_Snapshot_Creation_HTTP.lua index 2385c924a4..bd845b99fc 100644 --- a/test_scripts/Policies/build_options/055_ATF_Policy_Table_Snapshot_Creation_HTTP.lua +++ b/test_scripts/Policies/build_options/055_ATF_Policy_Table_Snapshot_Creation_HTTP.lua @@ -14,10 +14,6 @@ -- PTU is requested. PTS is created. -- For HTTP sdl_snapshot.json is not saved to file system. --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/build_options/056_ATF_PTU_Transfer_Several_Apps_Different_HMI_Levels_HTTP.lua b/test_scripts/Policies/build_options/056_ATF_PTU_Transfer_Several_Apps_Different_HMI_Levels_HTTP.lua index 42b23e21f1..2b51fef96d 100644 --- a/test_scripts/Policies/build_options/056_ATF_PTU_Transfer_Several_Apps_Different_HMI_Levels_HTTP.lua +++ b/test_scripts/Policies/build_options/056_ATF_PTU_Transfer_Several_Apps_Different_HMI_Levels_HTTP.lua @@ -21,7 +21,6 @@ -- app_1 doesn't take part in PTU (except of the case when app_1 is the only application being run on SDL) --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/build_options/057_ATF_PTS_Define_URL_to_send_PTS_HTTP.lua b/test_scripts/Policies/build_options/057_ATF_PTS_Define_URL_to_send_PTS_HTTP.lua index c5c7546a7d..29985658b5 100644 --- a/test_scripts/Policies/build_options/057_ATF_PTS_Define_URL_to_send_PTS_HTTP.lua +++ b/test_scripts/Policies/build_options/057_ATF_PTS_Define_URL_to_send_PTS_HTTP.lua @@ -18,10 +18,6 @@ -- SDL.GetURLs({urls[] = default}, (, appID)) -- SDL-> ->OnSystemRequest(params, url, timeout) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") local commonSteps = require('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/build_options/058_ATF_HMI_sends_GetURLs_no_app_registered_HTTP.lua b/test_scripts/Policies/build_options/058_ATF_HMI_sends_GetURLs_no_app_registered_HTTP.lua index 4373ac5553..db42e950f2 100644 --- a/test_scripts/Policies/build_options/058_ATF_HMI_sends_GetURLs_no_app_registered_HTTP.lua +++ b/test_scripts/Policies/build_options/058_ATF_HMI_sends_GetURLs_no_app_registered_HTTP.lua @@ -19,10 +19,6 @@ -- PTU is requested. PTS is created. -- SDL.GetURLs({urls[] = default}) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') @@ -30,7 +26,6 @@ local testCasesForPolicyTable = require('user_modules/shared_testcases/testCases local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local mobile_session = require('mobile_session') - --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() commonSteps:DeleteLogsFileAndPolicyTable() @@ -106,4 +101,4 @@ function Test.Postcondition_Stop_SDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/build_options/059_ATF_HMI_sends_GetURLs_one_app_registered_HTTP.lua b/test_scripts/Policies/build_options/059_ATF_HMI_sends_GetURLs_one_app_registered_HTTP.lua index da732cb9bf..3752ee7310 100644 --- a/test_scripts/Policies/build_options/059_ATF_HMI_sends_GetURLs_one_app_registered_HTTP.lua +++ b/test_scripts/Policies/build_options/059_ATF_HMI_sends_GetURLs_one_app_registered_HTTP.lua @@ -17,10 +17,6 @@ -- PTU is requested. PTS is created. -- SDL.GetURLs({urls[] = registered_App1, default}) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/build_options/060_ATF_Timeout_to_wait_response_PTU_HTTP.lua b/test_scripts/Policies/build_options/060_ATF_Timeout_to_wait_response_PTU_HTTP.lua index c1a1516315..cdcf28b07b 100644 --- a/test_scripts/Policies/build_options/060_ATF_Timeout_to_wait_response_PTU_HTTP.lua +++ b/test_scripts/Policies/build_options/060_ATF_Timeout_to_wait_response_PTU_HTTP.lua @@ -15,9 +15,7 @@ -- SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) -- SDL->HMI:BC.PolicyUpdate(file, timeout, retry[]) where --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/build_options/061_ATF_Sending_PTS_to_Mobile_Application_HTTP.lua b/test_scripts/Policies/build_options/061_ATF_Sending_PTS_to_Mobile_Application_HTTP.lua index 695cc8ef16..632ff3b984 100644 --- a/test_scripts/Policies/build_options/061_ATF_Sending_PTS_to_Mobile_Application_HTTP.lua +++ b/test_scripts/Policies/build_options/061_ATF_Sending_PTS_to_Mobile_Application_HTTP.lua @@ -19,10 +19,6 @@ -- Expected result: -- SDL->app: OnSystemRequest ('url', requestType:HTTP, fileType="JSON", appID) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/build_options/062_ATF_Timeout_Countdown_Start_PTU_Response_HTTP.lua b/test_scripts/Policies/build_options/062_ATF_Timeout_Countdown_Start_PTU_Response_HTTP.lua index b451900e6e..bcb70eac89 100644 --- a/test_scripts/Policies/build_options/062_ATF_Timeout_Countdown_Start_PTU_Response_HTTP.lua +++ b/test_scripts/Policies/build_options/062_ATF_Timeout_Countdown_Start_PTU_Response_HTTP.lua @@ -22,10 +22,6 @@ --SDL waits for SystemRequest response from within 'timeout' value, --if no obtained, it starts retry sequence --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/build_options/063_ATF_PoliciesManager_Sets_Status_UPDATING_HTTP.lua b/test_scripts/Policies/build_options/063_ATF_PoliciesManager_Sets_Status_UPDATING_HTTP.lua index 654ea8fe13..6cc45ba439 100644 --- a/test_scripts/Policies/build_options/063_ATF_PoliciesManager_Sets_Status_UPDATING_HTTP.lua +++ b/test_scripts/Policies/build_options/063_ATF_PoliciesManager_Sets_Status_UPDATING_HTTP.lua @@ -21,10 +21,6 @@ -- Expected result: -- SDL->HMI: SDL.OnStatusUpdate(UPDATING) right after SDL->app: OnSystemRequest --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/build_options/064_ATF_Received_PTU_From_Mobile_Application_HTTP.lua b/test_scripts/Policies/build_options/064_ATF_Received_PTU_From_Mobile_Application_HTTP.lua index 92a6591956..1b08145864 100644 --- a/test_scripts/Policies/build_options/064_ATF_Received_PTU_From_Mobile_Application_HTTP.lua +++ b/test_scripts/Policies/build_options/064_ATF_Received_PTU_From_Mobile_Application_HTTP.lua @@ -21,7 +21,6 @@ -- LPT is updated successfully --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/build_options/066_ATF_PTU_Validation_Failure_HTTP.lua b/test_scripts/Policies/build_options/066_ATF_PTU_Validation_Failure_HTTP.lua index bbe44226a0..6e54361895 100644 --- a/test_scripts/Policies/build_options/066_ATF_PTU_Validation_Failure_HTTP.lua +++ b/test_scripts/Policies/build_options/066_ATF_PTU_Validation_Failure_HTTP.lua @@ -21,7 +21,6 @@ -- SDL->HMI: OnStatusUpdate(UPDATE_NEEDED) --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] @@ -126,7 +125,7 @@ function Test:RAI_PTU() function(_, d1) log("SDL->HMI: N: BC.OnAppRegistered") self.applications[config.application1.registerAppInterfaceParams.appID] = d1.params.application.appID - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UPDATE_NEEDED" }) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) :Do( function(_, d2) log("SDL->HMI: N: SDL.OnStatusUpdate", d2.params.status) diff --git a/test_scripts/Policies/build_options/067_ATF_PoliciesManager_Sets_Status_to_UP_TO_DATE_HTTP.lua b/test_scripts/Policies/build_options/067_ATF_PoliciesManager_Sets_Status_to_UP_TO_DATE_HTTP.lua index e80e04c4b7..c50971385f 100644 --- a/test_scripts/Policies/build_options/067_ATF_PoliciesManager_Sets_Status_to_UP_TO_DATE_HTTP.lua +++ b/test_scripts/Policies/build_options/067_ATF_PoliciesManager_Sets_Status_to_UP_TO_DATE_HTTP.lua @@ -25,10 +25,6 @@ -- Expected result: -- SDL->HMI: OnStatusUpdate(UP_TO_DATE) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/build_options/068_ATF_PTU_Merge_Into_Local_PT_HTTP.lua b/test_scripts/Policies/build_options/068_ATF_PTU_Merge_Into_Local_PT_HTTP.lua index 2339dc6d3b..f848994aa8 100644 --- a/test_scripts/Policies/build_options/068_ATF_PTU_Merge_Into_Local_PT_HTTP.lua +++ b/test_scripts/Policies/build_options/068_ATF_PTU_Merge_Into_Local_PT_HTTP.lua @@ -27,9 +27,7 @@ -- SDL replaces the following sections of the Local Policy Table with the --corresponding sections from PTU: module_config, functional_groupings and app_policies --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.application1.registerAppInterfaceParams.appHMIType = { "MEDIA" } config.application2.registerAppInterfaceParams.appHMIType = { "DEFAULT" } @@ -41,6 +39,7 @@ local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local utils = require ('user_modules/utils') --[[ Local Functions ]] local function is_table_equal(t1, t2) @@ -77,16 +76,15 @@ local ptu commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_ConnectDevice() - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") commonTestCases:DelayedExp(2000) self:connectMobile() EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { deviceList = { { - id = config.deviceMAC, + id = utils.getDeviceMAC(), isSDLAllowed = true, - name = ServerAddress, + name = utils.getDeviceName(), transportType = "WIFI" } } @@ -173,7 +171,7 @@ function Test:TestStep_RegisterNewApp() self:FailTestCase("OnSystemRequest, HTTP for app1 is not received.") end end) - + commonTestCases:DelayedExp(10000) end diff --git a/test_scripts/Policies/build_options/069_ATF_PTU_Merge_Into_Local_PT_ConsumerFriendlyMessages_HTTP.lua b/test_scripts/Policies/build_options/069_ATF_PTU_Merge_Into_Local_PT_ConsumerFriendlyMessages_HTTP.lua index 15b592b103..ed2660e500 100644 --- a/test_scripts/Policies/build_options/069_ATF_PTU_Merge_Into_Local_PT_ConsumerFriendlyMessages_HTTP.lua +++ b/test_scripts/Policies/build_options/069_ATF_PTU_Merge_Into_Local_PT_ConsumerFriendlyMessages_HTTP.lua @@ -28,19 +28,15 @@ --corresponding sections from PTU: module_config, functional_groupings, app_policies --and consumer_friendly_messages->'messages' --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local Variables ]] --local db_file = config.pathToSDL .. "/" .. commonFunctions:read_parameter_from_smart_device_link_ini("AppStorageFolder") .. "/policy.sqlite" local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") -local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local ptu_file = "files/jsons/Policies/Policy_Table_Update/ptu_18192.json" --[[ Local Functions ]] @@ -101,7 +97,7 @@ function Test:Precondition_ActivateApp() EXPECT_HMIRESPONSE(requestId2) :Do(function(_, _) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = ServerAddress } }) + { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_, data2) self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", { }) diff --git a/test_scripts/Policies/build_options/070_ATF_PTU_Merge_Into_Local_PT_ConsumerFriendlyMessages_Omitted_HTTP.lua b/test_scripts/Policies/build_options/070_ATF_PTU_Merge_Into_Local_PT_ConsumerFriendlyMessages_Omitted_HTTP.lua index 0979950dad..50a0d35096 100644 --- a/test_scripts/Policies/build_options/070_ATF_PTU_Merge_Into_Local_PT_ConsumerFriendlyMessages_Omitted_HTTP.lua +++ b/test_scripts/Policies/build_options/070_ATF_PTU_Merge_Into_Local_PT_ConsumerFriendlyMessages_Omitted_HTTP.lua @@ -28,14 +28,15 @@ -- SDL replaces the following sections of the Local Policy Table with the --corresponding sections from PTU: module_config, functional_groupings and app_policies --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +--[[ General Settings for configuration ]] +config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local mobile_session = require("mobile_session") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local json = require("modules/json") +local utils = require ('user_modules/utils') --[[ Local Variables ]] local db_file = config.pathToSDL .. "/" .. commonFunctions:read_parameter_from_smart_device_link_ini("AppStorageFolder") .. "/policy.sqlite" @@ -66,8 +67,8 @@ function Test:ConnectMobile() { deviceList = { { - id = config.deviceMAC, - name = "127.0.0.1", + id = utils.getDeviceMAC(), + name = utils.getDeviceName(), transportType = "WIFI" } } @@ -91,8 +92,8 @@ function Test:RegisterApp() { deviceInfo = { - id = config.deviceMAC, - name = "127.0.0.1", + id = utils.getDeviceMAC(), + name = utils.getDeviceName(), transportType = "WIFI" } } @@ -154,15 +155,11 @@ function Test:PerformPTUSuccess() end function Test:ValidateNumberMessages() - self.mobileSession:ExpectAny() - :ValidIf(function(_, _) - r_actual = get_num_records() - if r_expected ~= r_actual then - return false, "Expected number of records: " .. r_expected .. ", got: " .. r_actual - end - print("Number of records: " .. r_actual) - return true - end) + r_actual = get_num_records() + if r_expected ~= r_actual then + self:FailTestCase("Expected number of records: " .. r_expected .. ", got: " .. r_actual) + end + print("Number of records: " .. r_actual) end --[[ Postconditions ]] diff --git a/test_scripts/Policies/build_options/071_ATF_PTU_Local_PT_Start_Retry_Sequence_HTTP.lua b/test_scripts/Policies/build_options/071_ATF_PTU_Local_PT_Start_Retry_Sequence_HTTP.lua index 2cab313782..a2b5a2ca07 100644 --- a/test_scripts/Policies/build_options/071_ATF_PTU_Local_PT_Start_Retry_Sequence_HTTP.lua +++ b/test_scripts/Policies/build_options/071_ATF_PTU_Local_PT_Start_Retry_Sequence_HTTP.lua @@ -22,9 +22,6 @@ -- Timeout expires and retry sequence started -- SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local mobile_session = require("mobile_session") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") diff --git a/test_scripts/Policies/build_options/072_ATF_PTU_PM_Sets_Status_UPDATE_NEEDED_HTTP.lua b/test_scripts/Policies/build_options/072_ATF_PTU_PM_Sets_Status_UPDATE_NEEDED_HTTP.lua index 9d2d32bfd1..663c7687e6 100644 --- a/test_scripts/Policies/build_options/072_ATF_PTU_PM_Sets_Status_UPDATE_NEEDED_HTTP.lua +++ b/test_scripts/Policies/build_options/072_ATF_PTU_PM_Sets_Status_UPDATE_NEEDED_HTTP.lua @@ -16,9 +16,7 @@ -- Expected result: -- SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/build_options/073_ATF_PTU_Retry_Sequence_Retry_Timeout_Computation_HTTP.lua b/test_scripts/Policies/build_options/073_ATF_PTU_Retry_Sequence_Retry_Timeout_Computation_HTTP.lua index 6f73785ee8..af212b0915 100644 --- a/test_scripts/Policies/build_options/073_ATF_PTU_Retry_Sequence_Retry_Timeout_Computation_HTTP.lua +++ b/test_scripts/Policies/build_options/073_ATF_PTU_Retry_Sequence_Retry_Timeout_Computation_HTTP.lua @@ -29,9 +29,7 @@ -- t[4] = timeout_after_x_seconds + seconds_between_retries[4] + t[3] -- t[5] = timeout_after_x_seconds + seconds_between_retries[5] + t[4] --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/build_options/074_ATF_PTU_Restarting_Policy_Table_Exchange_HTTP.lua b/test_scripts/Policies/build_options/074_ATF_PTU_Restarting_Policy_Table_Exchange_HTTP.lua index 007fe31be9..b3274c93fb 100644 --- a/test_scripts/Policies/build_options/074_ATF_PTU_Restarting_Policy_Table_Exchange_HTTP.lua +++ b/test_scripts/Policies/build_options/074_ATF_PTU_Restarting_Policy_Table_Exchange_HTTP.lua @@ -21,27 +21,24 @@ -- SDL->app: OnSystemRequest() --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonSteps = require ('user_modules/shared_testcases/commonSteps') local commonTestCases = require ('user_modules/shared_testcases/commonTestCases') -local events = require('events') --[[ Local Variables ]] local seconds_between_retries = {1, 1, 1, 1, 1} -- in min local timeout_after_x_seconds = 30 -- in sec local timeout = {} -- in sec -timeout[1] = timeout_after_x_seconds -timeout[2] = timeout[1] + seconds_between_retries[1] -timeout[3] = timeout[1] + timeout[2] + seconds_between_retries[2] -timeout[4] = timeout[1] + timeout[3] + seconds_between_retries[3] -timeout[5] = timeout[1] + timeout[4] + seconds_between_retries[4] -timeout[6] = timeout[1] + timeout[5] + seconds_between_retries[5] +timeout[1] = timeout_after_x_seconds -- 30 +timeout[2] = timeout_after_x_seconds + seconds_between_retries[1] -- 30 + 1 = 31 +timeout[3] = timeout_after_x_seconds + seconds_between_retries[2] + timeout[2] -- 30 + 1 + 31 = 62 +timeout[4] = timeout_after_x_seconds + seconds_between_retries[3] + timeout[3] -- 30 + 1 + 62 = 93 +timeout[5] = timeout_after_x_seconds + seconds_between_retries[4] + timeout[4] -- 30 + 1 + 93 = 124 +timeout[6] = timeout_after_x_seconds + seconds_between_retries[5] + timeout[5] -- 30 + 1 + 124 = 155 local onsysrequest_app1 = false local onsysrequest_app2 = false @@ -81,16 +78,6 @@ local function SetRetryValuesInPreloadedFile() file:close() end -local function DelayedExp(time) - local event = events.Event() - event.matches = function(self, e) return self == e end - EXPECT_EVENT(event, "Delayed event") - :Timeout(time + 1000) - RUN_AFTER(function() - RAISE_EVENT(event, event) - end, time) - end - --[[ Preconditions ]] function Test.Precondition_StopSDL() StopSDL() @@ -136,7 +123,8 @@ local function DelayedExp(time) --[[ Test ]] function Test:TestStep_Register_App_And_Check_Retry_Timeouts() - print("Wait retry sequence to elapse: " .. (timeout[1] + timeout[2] + timeout[3] + timeout[4] + timeout[5] + timeout[6]) .. "sec. + 2min tolerance") + local totalTimeout = timeout[1] + timeout[2] + timeout[3] + timeout[4] + timeout[5] + timeout[6] + 30 + print("Wait retry sequence to elapse: " .. totalTimeout .. "sec.") local startPTUtime = 0 local firstTryTime = 0 local secondTryTime = 0 @@ -164,8 +152,10 @@ local function DelayedExp(time) maxNumberRFCOMMPorts = 1 } }) + EXPECT_RESPONSE(CorIdRAI, { success = true, resultCode = "SUCCESS"}) EXPECT_NOTIFICATION("OnSystemRequest") :ValidIf(function(exp,data) + if(data.payload.requestType == "HTTP") then if exp.occurences == 2 then @@ -173,62 +163,62 @@ local function DelayedExp(time) return true end - if exp.occurences == 3 and timeout[2] == (os.time() - startPTUtime) then + if exp.occurences == 3 and (os.time() - startPTUtime) >= timeout[1] - 1 and (os.time() - startPTUtime) <= timeout[1] + 1 then firstTryTime = os.time() - print ("first retry time: " .. timeout[2]) + print ("first retry time: " .. timeout[1]) return true - elseif exp.occurences == 3 and timeout[2] ~= (os.time() - startPTUtime) then + elseif exp.occurences == 3 and timeout[1] ~= (os.time() - startPTUtime) then firstTryTime = os.time() - print ("Wrong first retry time! Expected: " .. timeout[2] .. " Actual: " .. (os.time() - startPTUtime) ) + print ("Wrong first retry time! Expected: " .. timeout[1] .. " Actual: " .. (os.time() - startPTUtime) ) return false end - if exp.occurences == 4 and timeout[3] == (os.time() - firstTryTime) then + if exp.occurences == 4 and (os.time() - firstTryTime) >= timeout[2] - 1 and (os.time() - firstTryTime) <= timeout[2] + 1 then secondTryTime = os.time() - print ("second retry time: " .. timeout[3]) + print ("second retry time: " .. timeout[2]) return true - elseif exp.occurences == 4 and timeout[3] ~= (os.time() - firstTryTime) then + elseif exp.occurences == 4 and timeout[2] ~= (os.time() - firstTryTime) then secondTryTime = os.time() - print ("Wrong second retry time! Expected: " .. timeout[3] .. " Actual: " .. (os.time() - firstTryTime) ) + print ("Wrong second retry time! Expected: " .. timeout[2] .. " Actual: " .. (os.time() - firstTryTime) ) return false end - if exp.occurences == 5 and timeout[4] == (os.time() - secondTryTime) then + if exp.occurences == 5 and (os.time() - secondTryTime) >= timeout[3] - 1 and (os.time() - secondTryTime) <= timeout[3] + 1 then thirdTryTime = os.time() - print ("third retry time: " .. timeout[4]) + print ("third retry time: " .. timeout[3]) return true - elseif exp.occurences == 5 and timeout[4] ~= (os.time() - secondTryTime) then + elseif exp.occurences == 5 and timeout[3] ~= (os.time() - secondTryTime) then thirdTryTime = os.time() - print ("Wrong third retry time! Expected: " .. timeout[4] .. " Actual: " .. (os.time() - secondTryTime) ) + print ("Wrong third retry time! Expected: " .. timeout[3] .. " Actual: " .. (os.time() - secondTryTime) ) return false end - if exp.occurences == 6 and timeout[5] == (os.time() - thirdTryTime) then + if exp.occurences == 6 and (os.time() - thirdTryTime) >= timeout[4] - 1 and (os.time() - thirdTryTime) <= timeout[4] + 1 then fourthTryTime = os.time() - print ("fourth retry time: " .. timeout[5]) + print ("fourth retry time: " .. timeout[4]) return true - elseif exp.occurences == 6 and timeout[5] ~= (os.time() - thirdTryTime) then + elseif exp.occurences == 6 and timeout[4] ~= (os.time() - thirdTryTime) then fourthTryTime = os.time() - print ("Wrong fourth retry time! Expected: " .. timeout[5] .. " Actual: " .. (os.time() - thirdTryTime) ) + print ("Wrong fourth retry time! Expected: " .. timeout[4] .. " Actual: " .. (os.time() - thirdTryTime) ) return false end - if exp.occurences == 7 and timeout[6] == (os.time() - fourthTryTime) then - print ("fifth retry time: " .. timeout[6]) + if exp.occurences == 7 and (os.time() - fourthTryTime) >= timeout[5] - 1 and (os.time() - fourthTryTime) <= timeout[5] + 1 then + print ("fifth retry time: " .. timeout[5]) return true - elseif exp.occurences == 7 and timeout[6] ~= (os.time() - fourthTryTime) then - print ("Wrong fifth retry time! Expected: " .. timeout[6] .. " Actual: " .. (os.time() - fourthTryTime) ) + elseif exp.occurences == 7 and timeout[5] ~= (os.time() - fourthTryTime) then + print ("Wrong fifth retry time! Expected: " .. timeout[5] .. " Actual: " .. (os.time() - fourthTryTime) ) return false end + end - return false + return true end) :Times(#seconds_between_retries + 2) -- 6 HTTP, 1 LOCK_SCREEN_ICON_URL - - DelayedExp((timeout[1] + timeout[2] + timeout[3] + timeout[4] + timeout[5] + timeout[6])*1000 + 2*60000) --msec - EXPECT_RESPONSE(CorIdRAI, { success = true, resultCode = "SUCCESS"}) + :Timeout(totalTimeout * 1000) + commonTestCases:DelayedExp(totalTimeout * 1000) end function Test:TestStep_StartSession2() diff --git a/test_scripts/Policies/build_options/075_ATF_PTU_Retry_Sequence_Retry_Timeout_Expiration_HTTP.lua b/test_scripts/Policies/build_options/075_ATF_PTU_Retry_Sequence_Retry_Timeout_Expiration_HTTP.lua index 5c5ae1cb79..63a8eb06aa 100644 --- a/test_scripts/Policies/build_options/075_ATF_PTU_Retry_Sequence_Retry_Timeout_Expiration_HTTP.lua +++ b/test_scripts/Policies/build_options/075_ATF_PTU_Retry_Sequence_Retry_Timeout_Expiration_HTTP.lua @@ -24,9 +24,7 @@ -- Expected result: -- Number of retries corresponds to number of elements in 'seconds_between_retries' array --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/build_options/076_ATF_PTU_Changes_Applied_OnPermissionChange_Notification_App_HTTP.lua b/test_scripts/Policies/build_options/076_ATF_PTU_Changes_Applied_OnPermissionChange_Notification_App_HTTP.lua index 1a53006b39..f15e6989be 100644 --- a/test_scripts/Policies/build_options/076_ATF_PTU_Changes_Applied_OnPermissionChange_Notification_App_HTTP.lua +++ b/test_scripts/Policies/build_options/076_ATF_PTU_Changes_Applied_OnPermissionChange_Notification_App_HTTP.lua @@ -19,8 +19,8 @@ -- SDL->HMI:OnStatusUpdate("UP_TO_DATE") -- SDL->app: onPermissionChange(permisssions) --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +--[[ General Settings for configuration ]] +config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local mobile_session = require("mobile_session") diff --git a/test_scripts/Policies/build_options/077_ATF_PTU_Changes_Applied_OnPermissionChange_Notification_HMI_HTTP.lua b/test_scripts/Policies/build_options/077_ATF_PTU_Changes_Applied_OnPermissionChange_Notification_HMI_HTTP.lua index a924f4608e..9547e686ef 100644 --- a/test_scripts/Policies/build_options/077_ATF_PTU_Changes_Applied_OnPermissionChange_Notification_HMI_HTTP.lua +++ b/test_scripts/Policies/build_options/077_ATF_PTU_Changes_Applied_OnPermissionChange_Notification_HMI_HTTP.lua @@ -22,7 +22,6 @@ -- SDL->HMI: SDL.OnAppPermissionChanged(appID, params) --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/build_options/078_ATF_PTU_HMI_Level_Affected_Apps_FULL_LIMITED_HTTP.lua b/test_scripts/Policies/build_options/078_ATF_PTU_HMI_Level_Affected_Apps_FULL_LIMITED_HTTP.lua index 618b00db46..6d0a0e91e5 100644 --- a/test_scripts/Policies/build_options/078_ATF_PTU_HMI_Level_Affected_Apps_FULL_LIMITED_HTTP.lua +++ b/test_scripts/Policies/build_options/078_ATF_PTU_HMI_Level_Affected_Apps_FULL_LIMITED_HTTP.lua @@ -20,7 +20,6 @@ -- 2) Mobile application 2 remains in LIMITED --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.application1.registerAppInterfaceParams.isMediaApplication = true config.application1.registerAppInterfaceParams.appHMIType = { "MEDIA" } config.application2.registerAppInterfaceParams.isMediaApplication = false diff --git a/test_scripts/Policies/build_options/079_ATF_PTU_HMI_Level_Affected_Apps_NONE_BACKGROUND_HTTP.lua b/test_scripts/Policies/build_options/079_ATF_PTU_HMI_Level_Affected_Apps_NONE_BACKGROUND_HTTP.lua index b950bb14b9..b273bb08f5 100644 --- a/test_scripts/Policies/build_options/079_ATF_PTU_HMI_Level_Affected_Apps_NONE_BACKGROUND_HTTP.lua +++ b/test_scripts/Policies/build_options/079_ATF_PTU_HMI_Level_Affected_Apps_NONE_BACKGROUND_HTTP.lua @@ -21,7 +21,6 @@ -- 1) SDL->appID_2: NONE OnHMIStatus -- should keep last value NONE --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } config.application1.registerAppInterfaceParams.isMediaApplication = false diff --git a/test_scripts/Policies/build_options/080_ATF_PTU_OnStatsusUpdate_Trigger_UPDATE_NEEDED_HTTP.lua b/test_scripts/Policies/build_options/080_ATF_PTU_OnStatsusUpdate_Trigger_UPDATE_NEEDED_HTTP.lua index fce9e558ff..3c97e7cf3b 100644 --- a/test_scripts/Policies/build_options/080_ATF_PTU_OnStatsusUpdate_Trigger_UPDATE_NEEDED_HTTP.lua +++ b/test_scripts/Policies/build_options/080_ATF_PTU_OnStatsusUpdate_Trigger_UPDATE_NEEDED_HTTP.lua @@ -15,9 +15,6 @@ -- Expected result: --SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/build_options/081_ATF_PTU_OnStatsusUpdate_Trigger_UPDATING_HTTP.lua b/test_scripts/Policies/build_options/081_ATF_PTU_OnStatsusUpdate_Trigger_UPDATING_HTTP.lua index f73dbb5fd2..8b4930d4fb 100644 --- a/test_scripts/Policies/build_options/081_ATF_PTU_OnStatsusUpdate_Trigger_UPDATING_HTTP.lua +++ b/test_scripts/Policies/build_options/081_ATF_PTU_OnStatsusUpdate_Trigger_UPDATING_HTTP.lua @@ -20,9 +20,6 @@ -- SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) -- SDL->HMI: SDL.OnStatusUpdate(UPDATING) right after SDL->app: OnSystemRequest --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/build_options/082_ATF_PTU_OnStatsusUpdate_Trigger_UP_TO_DATE_HTTP.lua b/test_scripts/Policies/build_options/082_ATF_PTU_OnStatsusUpdate_Trigger_UP_TO_DATE_HTTP.lua index 71f4f88bdd..e75591fd9c 100644 --- a/test_scripts/Policies/build_options/082_ATF_PTU_OnStatsusUpdate_Trigger_UP_TO_DATE_HTTP.lua +++ b/test_scripts/Policies/build_options/082_ATF_PTU_OnStatsusUpdate_Trigger_UP_TO_DATE_HTTP.lua @@ -26,10 +26,6 @@ -- Expected result: -- SDL->HMI: OnStatusUpdate(UP_TO_DATE) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') @@ -68,4 +64,4 @@ function Test.Stop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/build_options/083_ATF_PTU_UTF8_Encoding_Check_HTTP.lua b/test_scripts/Policies/build_options/083_ATF_PTU_UTF8_Encoding_Check_HTTP.lua index b1aaad5571..fd60420e68 100644 --- a/test_scripts/Policies/build_options/083_ATF_PTU_UTF8_Encoding_Check_HTTP.lua +++ b/test_scripts/Policies/build_options/083_ATF_PTU_UTF8_Encoding_Check_HTTP.lua @@ -17,9 +17,6 @@ -- Expected result: -- The texts in Russian & Chinese in appropriate are parsed correctly by SDL --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") diff --git a/test_scripts/Policies/build_options/084_ATF_Default_Policy_For_The_App_After_PTU_HTTP.lua b/test_scripts/Policies/build_options/084_ATF_Default_Policy_For_The_App_After_PTU_HTTP.lua index 8c7f204be3..b2e60238c6 100644 --- a/test_scripts/Policies/build_options/084_ATF_Default_Policy_For_The_App_After_PTU_HTTP.lua +++ b/test_scripts/Policies/build_options/084_ATF_Default_Policy_For_The_App_After_PTU_HTTP.lua @@ -8,7 +8,6 @@ -- In case Policies Manager assigns the "default" policies to app AND the value of "default" policies was updated in case of PolicyTable update --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/build_options/085_ATF_PTU_In_Progress_New_App_Registers_HTTP.lua b/test_scripts/Policies/build_options/085_ATF_PTU_In_Progress_New_App_Registers_HTTP.lua index eadf28fd5f..836015594e 100644 --- a/test_scripts/Policies/build_options/085_ATF_PTU_In_Progress_New_App_Registers_HTTP.lua +++ b/test_scripts/Policies/build_options/085_ATF_PTU_In_Progress_New_App_Registers_HTTP.lua @@ -22,9 +22,7 @@ -- SDL adds application with App 2 data into LocalPT according to general rules -- of adding app data into LocalPT --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/build_options/086_ATF_PTU_Merging_wtih_LPT_HTTP.lua b/test_scripts/Policies/build_options/086_ATF_PTU_Merging_wtih_LPT_HTTP.lua index 95a4fd629d..3649ffb5ac 100644 --- a/test_scripts/Policies/build_options/086_ATF_PTU_Merging_wtih_LPT_HTTP.lua +++ b/test_scripts/Policies/build_options/086_ATF_PTU_Merging_wtih_LPT_HTTP.lua @@ -24,10 +24,6 @@ --module_config, functional_groupings and app_policies --App 2 added to Local PT during PT Exchange process left after merge in LocalPT (not being lost on merge) ------------------------------------------------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/build_options/087_ATF_New_PTU_Sequence_AppRegistered_PTU_Progress_HTTP.lua b/test_scripts/Policies/build_options/087_ATF_New_PTU_Sequence_AppRegistered_PTU_Progress_HTTP.lua index 6b884f9a0d..2706ddfdc6 100644 --- a/test_scripts/Policies/build_options/087_ATF_New_PTU_Sequence_AppRegistered_PTU_Progress_HTTP.lua +++ b/test_scripts/Policies/build_options/087_ATF_New_PTU_Sequence_AppRegistered_PTU_Progress_HTTP.lua @@ -22,15 +22,11 @@ -- 4. app_2 added to Local PT during PT Exchange process left after merge in LocalPT (not being lost on merge) -- 5. SDL creates the new snapshot and initiates the new PTU for the app_2 Policies obtaining: SDL-> HMI: SDL.PolicyUpdate()//new PTU sequence started ------------------------------------------------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local mobile_session = require('mobile_session') - --[[ Local Functions ]] local registerAppInterfaceParams = { @@ -89,7 +85,8 @@ function Test:TestStep_PoliciesManager_changes_UP_TO_DATE() EXPECT_RESPONSE(CorIdSystemRequest, { success = true, resultCode = "SUCCESS"}) EXPECT_HMICALL("BasicCommunication.SystemRequest"):Times(0) - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UP_TO_DATE"}, {status = "UPDATE_NEEDED"}):Times(2) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UP_TO_DATE"}, {status = "UPDATE_NEEDED"}, {status = "UPDATING"}) + :Times(3) end --[[ Postconditions ]] @@ -98,4 +95,4 @@ function Test.Stop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/build_options/088_ATF_Apply_UpdatedPT_after_OnReceivedPolicyUpdate_from_HMI_PROPRIETARY.lua b/test_scripts/Policies/build_options/088_ATF_Apply_UpdatedPT_after_OnReceivedPolicyUpdate_from_HMI_PROPRIETARY.lua index 1418157a65..3f6339d7df 100644 --- a/test_scripts/Policies/build_options/088_ATF_Apply_UpdatedPT_after_OnReceivedPolicyUpdate_from_HMI_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/088_ATF_Apply_UpdatedPT_after_OnReceivedPolicyUpdate_from_HMI_PROPRIETARY.lua @@ -12,9 +12,8 @@ -- Expected result: -- SDL->MOB: BasicCommunication.SystemRequest ( + )) to HMI --------------------------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() @@ -41,8 +39,8 @@ function Test:ConnectMobile() { deviceList = { { - id = config.deviceMAC, - name = "127.0.0.1", + id = utils.getDeviceMAC(), + name = utils.getDeviceName(), transportType = "WIFI" } } diff --git a/test_scripts/Policies/build_options/090_ATF_For_PTU_use_consented_device_only.lua b/test_scripts/Policies/build_options/090_ATF_For_PTU_use_consented_device_only.lua index aa7758602a..683bf4d248 100644 --- a/test_scripts/Policies/build_options/090_ATF_For_PTU_use_consented_device_only.lua +++ b/test_scripts/Policies/build_options/090_ATF_For_PTU_use_consented_device_only.lua @@ -24,9 +24,9 @@ local tcp = require('tcp_connection') local file_connection = require('file_connection') local mobile = require('mobile_connection') local events = require('events') +local utils = require ('user_modules/utils') --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" -- Create dummy connection os.execute("ifconfig lo:1 1.0.0.1") @@ -54,8 +54,8 @@ function Test:Precondition_Connect_device1() { deviceList = { { - id = config.deviceMAC, - name = "127.0.0.1", + id = utils.getDeviceMAC(), + name = utils.getDeviceName(), transportType = "WIFI" } } @@ -83,13 +83,13 @@ end function Test:Precondition_Activate_app_1() local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.HMIAppID}) - EXPECT_HMIRESPONSE(RequestId, {result = { code = 0, device = { id = config.deviceMAC, name = "127.0.0.1" }, isSDLAllowed = false, method ="SDL.ActivateApp" }}) + EXPECT_HMIRESPONSE(RequestId, {result = { code = 0, device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() }, isSDLAllowed = false, method ="SDL.ActivateApp" }}) :Do(function(_, _) local RequestIdGetMes = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetMes) :Do(function() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_, data) self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) @@ -112,8 +112,8 @@ function Test:Precondition_Connect_device_2() { deviceList = { { - id = config.deviceMAC, - name = "127.0.0.1", + id = utils.getDeviceMAC(), + name = utils.getDeviceName(), transportType = "WIFI" }, { diff --git a/test_scripts/Policies/build_options/091_ATF_Check_STATUS_UPDATE_NEEDED_PROPRIETARY.lua b/test_scripts/Policies/build_options/091_ATF_Check_STATUS_UPDATE_NEEDED_PROPRIETARY.lua index fd17ec24f9..e99efade7c 100644 --- a/test_scripts/Policies/build_options/091_ATF_Check_STATUS_UPDATE_NEEDED_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/091_ATF_Check_STATUS_UPDATE_NEEDED_PROPRIETARY.lua @@ -18,12 +18,12 @@ --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local mobile_session = require('mobile_session') +local utils = require ('user_modules/utils') --[[ Local Variables ]] --NewTestSuiteNumber = 0 @@ -109,7 +109,7 @@ function Test:Precondition_ActivateApplication() RequestId = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestId) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,_) self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) @@ -120,7 +120,7 @@ function Test:Precondition_ActivateApplication() end) EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN"}) end - + function Test:Precondition_MoveSystem_UP_TO_DATE() policyUpdate(self) end @@ -144,4 +144,4 @@ end commonFunctions:newTestCasesGroup("Postconditions") function Test.Postcondition_SDLStop() StopSDL() -end \ No newline at end of file +end diff --git a/test_scripts/Policies/build_options/092_ATF_Check_STATUS_vai_USER_Request_PROPRIETARY.lua b/test_scripts/Policies/build_options/092_ATF_Check_STATUS_vai_USER_Request_PROPRIETARY.lua index 742d716a3f..e0210a8ef6 100644 --- a/test_scripts/Policies/build_options/092_ATF_Check_STATUS_vai_USER_Request_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/092_ATF_Check_STATUS_vai_USER_Request_PROPRIETARY.lua @@ -17,14 +17,13 @@ -- SDL->HMI: SDL.OnStatusUpdate(UPDATING) -- SDL->HMI: BasicCommunication.PolicyUpdate ------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -83,7 +82,7 @@ function Test:Preconditions_ActivateApplication() RequestId = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestId) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,_) self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/build_options/093_ATF_OnStatusUpdate_Trigger_PROPRIETARY.lua b/test_scripts/Policies/build_options/093_ATF_OnStatusUpdate_Trigger_PROPRIETARY.lua index fcbccd09ed..950ef5e2d3 100644 --- a/test_scripts/Policies/build_options/093_ATF_OnStatusUpdate_Trigger_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/093_ATF_OnStatusUpdate_Trigger_PROPRIETARY.lua @@ -19,7 +19,7 @@ -- "UPDATE_NEEDED" -> "UPDATING" -> "UP_TO_DATE" -> "UPDATE_NEEDED" -> "UPDATING" --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") diff --git a/test_scripts/Policies/build_options/094_ATF_PTS_creation_rule_PROPRIETARY.lua b/test_scripts/Policies/build_options/094_ATF_PTS_creation_rule_PROPRIETARY.lua index ba0d4350ba..8dd8654a5c 100644 --- a/test_scripts/Policies/build_options/094_ATF_PTS_creation_rule_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/094_ATF_PTS_creation_rule_PROPRIETARY.lua @@ -14,15 +14,12 @@ -- Expected result: -- PTU is requested. PTS is created. --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -41,7 +38,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_PTS_Creation_rule() local result = testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID}, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {""}, "print", "PROPRIETARY") diff --git a/test_scripts/Policies/build_options/095_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua b/test_scripts/Policies/build_options/095_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua index 2dd8bc9e79..ac28d6dfcf 100644 --- a/test_scripts/Policies/build_options/095_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/095_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua @@ -21,7 +21,6 @@ ------------------------------------------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/build_options/096_ATF_SDL_Send_PolicyUpdat_To_HMI_In_Case_PTU_Is_Triggered_PROPRIETARY.lua b/test_scripts/Policies/build_options/096_ATF_SDL_Send_PolicyUpdat_To_HMI_In_Case_PTU_Is_Triggered_PROPRIETARY.lua index af26b7a06c..85ebcb9f8f 100644 --- a/test_scripts/Policies/build_options/096_ATF_SDL_Send_PolicyUpdat_To_HMI_In_Case_PTU_Is_Triggered_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/096_ATF_SDL_Send_PolicyUpdat_To_HMI_In_Case_PTU_Is_Triggered_PROPRIETARY.lua @@ -15,9 +15,7 @@ -- Expected result: -- a) SDL send BasicCommunication.PolicyUpdate ( , , ) to HMI. --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 diff --git a/test_scripts/Policies/build_options/097_ATF_PTU_Cycleing_Through_The_URLs_During_Retry_Sequence_HTTP.lua b/test_scripts/Policies/build_options/097_ATF_PTU_Cycleing_Through_The_URLs_During_Retry_Sequence_HTTP.lua index 6ef8b892ec..d3aaa80412 100644 --- a/test_scripts/Policies/build_options/097_ATF_PTU_Cycleing_Through_The_URLs_During_Retry_Sequence_HTTP.lua +++ b/test_scripts/Policies/build_options/097_ATF_PTU_Cycleing_Through_The_URLs_During_Retry_Sequence_HTTP.lua @@ -18,9 +18,6 @@ -- Expected result: -- Url parameter is taken cyclically from list of available URLs --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") diff --git a/test_scripts/Policies/build_options/098_ATF_PTU_Unsuccessful_Even_After_Retry_Strategy_HTTP.lua b/test_scripts/Policies/build_options/098_ATF_PTU_Unsuccessful_Even_After_Retry_Strategy_HTTP.lua index 7c9a93224e..98ff18b689 100644 --- a/test_scripts/Policies/build_options/098_ATF_PTU_Unsuccessful_Even_After_Retry_Strategy_HTTP.lua +++ b/test_scripts/Policies/build_options/098_ATF_PTU_Unsuccessful_Even_After_Retry_Strategy_HTTP.lua @@ -23,9 +23,7 @@ -- Expected result: -- Status is UPDATE_NEEDED and PTS is sent as binary data of OnSystemRequest to Mobile --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/build_options/099_ATF_SDL_Send_BC_PolicyUpdate_To_HMI_In_Case_PTU_Is_Triggered_PROPRIETARY.lua b/test_scripts/Policies/build_options/099_ATF_SDL_Send_BC_PolicyUpdate_To_HMI_In_Case_PTU_Is_Triggered_PROPRIETARY.lua index 0cd35b1e44..2a449a5b4f 100644 --- a/test_scripts/Policies/build_options/099_ATF_SDL_Send_BC_PolicyUpdate_To_HMI_In_Case_PTU_Is_Triggered_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/099_ATF_SDL_Send_BC_PolicyUpdate_To_HMI_In_Case_PTU_Is_Triggered_PROPRIETARY.lua @@ -20,9 +20,6 @@ -- 2. Parameters (retry, timeout, file) are defined -- 3. Status changed to 'UPDATING' --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") diff --git a/test_scripts/Policies/build_options/100_ATF_PTU_Transfer_Several_Apps_Different_HMI_Levels_PROPRIETARY.lua b/test_scripts/Policies/build_options/100_ATF_PTU_Transfer_Several_Apps_Different_HMI_Levels_PROPRIETARY.lua index 80eb5236f6..4f314bfd18 100644 --- a/test_scripts/Policies/build_options/100_ATF_PTU_Transfer_Several_Apps_Different_HMI_Levels_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/100_ATF_PTU_Transfer_Several_Apps_Different_HMI_Levels_PROPRIETARY.lua @@ -20,7 +20,7 @@ -- app_1 doesn't take part in PTU (except of the case when app_1 is the only application being run on SDL) --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local mobileSession = require("mobile_session") diff --git a/test_scripts/Policies/build_options/101_ATF_SDL_Build_EXTENDED_POLICY_HTTP.lua b/test_scripts/Policies/build_options/101_ATF_SDL_Build_EXTENDED_POLICY_HTTP.lua index b532baccbc..f0216aff8d 100644 --- a/test_scripts/Policies/build_options/101_ATF_SDL_Build_EXTENDED_POLICY_HTTP.lua +++ b/test_scripts/Policies/build_options/101_ATF_SDL_Build_EXTENDED_POLICY_HTTP.lua @@ -13,9 +13,7 @@ -- The flag EXTENDED_POLICY is set to HTTP -- PTU passes successfully --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/build_options/102_ATF_Timeout_countdown_start_PROPRIETARY.lua b/test_scripts/Policies/build_options/102_ATF_Timeout_countdown_start_PROPRIETARY.lua index 6ad36ef943..c30017aa63 100644 --- a/test_scripts/Policies/build_options/102_ATF_Timeout_countdown_start_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/102_ATF_Timeout_countdown_start_PROPRIETARY.lua @@ -21,10 +21,6 @@ -- SDL waits for SystemRequest response from within 'timeout' value, if no obtained, -- it starts retry sequence --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/build_options/103_ATF_Timeout_wait_response_PTU_PROPRIETARY.lua b/test_scripts/Policies/build_options/103_ATF_Timeout_wait_response_PTU_PROPRIETARY.lua index 638ce7accf..6344af893a 100644 --- a/test_scripts/Policies/build_options/103_ATF_Timeout_wait_response_PTU_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/103_ATF_Timeout_wait_response_PTU_PROPRIETARY.lua @@ -14,10 +14,6 @@ -- To define the timeout to wait a response on PTU, Policies manager must refer PTS -- "module_config" section, key . --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/build_options/104_ATF_Transfer_OnSystemRequest_toApp_PROPRIETARY.lua b/test_scripts/Policies/build_options/104_ATF_Transfer_OnSystemRequest_toApp_PROPRIETARY.lua index 10059a5ce9..478a8a5769 100644 --- a/test_scripts/Policies/build_options/104_ATF_Transfer_OnSystemRequest_toApp_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/104_ATF_Transfer_OnSystemRequest_toApp_PROPRIETARY.lua @@ -13,10 +13,6 @@ -- Expected result: -- Payload (Snapshot and Binary Header) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/build_options/105_ATF_PM_change_status_UPDATE_NEEDED_after_timeout_expired_PROPRIETARY.lua b/test_scripts/Policies/build_options/105_ATF_PM_change_status_UPDATE_NEEDED_after_timeout_expired_PROPRIETARY.lua index 5bf8a246d2..67c36c856e 100644 --- a/test_scripts/Policies/build_options/105_ATF_PM_change_status_UPDATE_NEEDED_after_timeout_expired_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/105_ATF_PM_change_status_UPDATE_NEEDED_after_timeout_expired_PROPRIETARY.lua @@ -15,9 +15,7 @@ -- Expected result: --SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/build_options/106_ATF_PolicyManager_changes_status_to_UPDATING_PROPRIETARY.lua b/test_scripts/Policies/build_options/106_ATF_PolicyManager_changes_status_to_UPDATING_PROPRIETARY.lua index 295e73ac03..a6cf7217ff 100644 --- a/test_scripts/Policies/build_options/106_ATF_PolicyManager_changes_status_to_UPDATING_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/106_ATF_PolicyManager_changes_status_to_UPDATING_PROPRIETARY.lua @@ -17,7 +17,7 @@ -- SDL.OnStatusUpdate(UPDATING) notification is send right after SDL->MOB: OnSystemRequest --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" +config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local mobile_session = require("mobile_session") diff --git a/test_scripts/Policies/build_options/107_ATF_PTU_in_case_of_failed_retry_strategy_during_previous_IGN_ON_PROPRIETARY.lua b/test_scripts/Policies/build_options/107_ATF_PTU_in_case_of_failed_retry_strategy_during_previous_IGN_ON_PROPRIETARY.lua index 07ddeb47bd..4c380166d7 100644 --- a/test_scripts/Policies/build_options/107_ATF_PTU_in_case_of_failed_retry_strategy_during_previous_IGN_ON_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/107_ATF_PTU_in_case_of_failed_retry_strategy_during_previous_IGN_ON_PROPRIETARY.lua @@ -17,9 +17,7 @@ -- 3. PTU sequence started: *SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED)* -- 4. PTS is created by SDL.....//PTU started --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.application1.registerAppInterfaceParams.appHMIType = {"DEFAULT"} --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/build_options/108_ATF_PTU_Trigger_days_PROPRIETARY.lua b/test_scripts/Policies/build_options/108_ATF_PTU_Trigger_days_PROPRIETARY.lua index d4aac9e32a..1781432267 100644 --- a/test_scripts/Policies/build_options/108_ATF_PTU_Trigger_days_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/108_ATF_PTU_Trigger_days_PROPRIETARY.lua @@ -17,9 +17,7 @@ -- Expected result: -- SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) //start PTU flow --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] @@ -138,4 +136,4 @@ function Test.Postcondition_StopSDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/build_options/109_ATF_PTU_Trigger_IGN_cycles_PROPRIETARY.lua b/test_scripts/Policies/build_options/109_ATF_PTU_Trigger_IGN_cycles_PROPRIETARY.lua index f07709c155..638ae9e5c8 100644 --- a/test_scripts/Policies/build_options/109_ATF_PTU_Trigger_IGN_cycles_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/109_ATF_PTU_Trigger_IGN_cycles_PROPRIETARY.lua @@ -13,9 +13,7 @@ -- When amount of ignition cycles notified by HMI via BasicCommunication.OnIgnitionCycleOver gets equal to the value of "exchange_after_x_ignition_cycles" -- field ("module_config" section) of policies database, SDL must trigger a PolicyTableUpdate sequence --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.application1.registerAppInterfaceParams.appID = "123456" config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } diff --git a/test_scripts/Policies/build_options/110_ATF_PTU_Trigger_kilometers_PROPRIETARY.lua b/test_scripts/Policies/build_options/110_ATF_PTU_Trigger_kilometers_PROPRIETARY.lua index f1a4ed8e1c..95f14011fa 100644 --- a/test_scripts/Policies/build_options/110_ATF_PTU_Trigger_kilometers_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/110_ATF_PTU_Trigger_kilometers_PROPRIETARY.lua @@ -19,9 +19,7 @@ -- Expected result: -- PTU flow started --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -29,6 +27,7 @@ config.defaultProtocolVersion = 2 local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFiles() @@ -85,7 +84,7 @@ function Test:Precondition_Activate_App_Start_PTU() EXPECT_HMIRESPONSE(RequestId) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data2) self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/build_options/111_ATF_Start_PTU_retry_sequence_PROPRIETARY.lua b/test_scripts/Policies/build_options/111_ATF_Start_PTU_retry_sequence_PROPRIETARY.lua index 6788c64ca0..24108cb111 100644 --- a/test_scripts/Policies/build_options/111_ATF_Start_PTU_retry_sequence_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/111_ATF_Start_PTU_retry_sequence_PROPRIETARY.lua @@ -21,7 +21,6 @@ -- SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.application1.registerAppInterfaceParams.appHMIType = { "MEDIA" } config.defaultProtocolVersion = 2 diff --git a/test_scripts/Policies/build_options/112_ATF_transfer_SystemRequest_from_app_to_HMI_PROPRIETARY.lua b/test_scripts/Policies/build_options/112_ATF_transfer_SystemRequest_from_app_to_HMI_PROPRIETARY.lua index 00fb2750f8..6c47e00eff 100644 --- a/test_scripts/Policies/build_options/112_ATF_transfer_SystemRequest_from_app_to_HMI_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/112_ATF_transfer_SystemRequest_from_app_to_HMI_PROPRIETARY.lua @@ -11,10 +11,6 @@ -- Expected result: -- SDL must send BasicCommunication.SystemRequest (, PROPRIETARY, params) to HMI --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/build_options/113_ATF_transfer_SystemRequest_from_HMI_to_app_PROPRIETARY.lua b/test_scripts/Policies/build_options/113_ATF_transfer_SystemRequest_from_HMI_to_app_PROPRIETARY.lua index 60f82ff77c..4f2aea556e 100644 --- a/test_scripts/Policies/build_options/113_ATF_transfer_SystemRequest_from_HMI_to_app_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/113_ATF_transfer_SystemRequest_from_HMI_to_app_PROPRIETARY.lua @@ -11,10 +11,6 @@ -- Expected result: -- SDL->MOB: SystemRequest (result code from HMI response) --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/build_options/114_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua b/test_scripts/Policies/build_options/114_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua index c2492cce7a..b70ebe4724 100644 --- a/test_scripts/Policies/build_options/114_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/114_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua @@ -22,7 +22,6 @@ ------------------------------------------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --[[ Required Shared libraries ]] Test = require('connecttest') @@ -45,7 +44,7 @@ local registerAppInterfaceParams = languageDesired = 'EN-US', hmiDisplayLanguageDesired = 'EN-US', appHMIType = {"NAVIGATION"}, - appID = "MyTestApp", + appID = "mytestapp", deviceInfo = { os = "Android", diff --git a/test_scripts/Policies/build_options/115_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp_PROPRIETARY.lua b/test_scripts/Policies/build_options/115_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp_PROPRIETARY.lua index d7897c74c3..3faf128056 100644 --- a/test_scripts/Policies/build_options/115_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/115_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp_PROPRIETARY.lua @@ -21,7 +21,6 @@ ------------------------------------------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.application1.registerAppInterfaceParams.appHMIType = { "MEDIA" } --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/build_options/116_ATF_DEXTENDED_POLICY_OFF_HTTP.lua b/test_scripts/Policies/build_options/116_ATF_DEXTENDED_POLICY_OFF_HTTP.lua index 45fa5f037b..ad32737e04 100644 --- a/test_scripts/Policies/build_options/116_ATF_DEXTENDED_POLICY_OFF_HTTP.lua +++ b/test_scripts/Policies/build_options/116_ATF_DEXTENDED_POLICY_OFF_HTTP.lua @@ -12,10 +12,6 @@ -- The flag EXTENDED_POLICY is set to HTTP -- PTU passes successfully --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/build_options/117_ATF_DEXTENDED_POLICY_No_Flag_HTTP.lua b/test_scripts/Policies/build_options/117_ATF_DEXTENDED_POLICY_No_Flag_HTTP.lua index cd0ff7a7e7..5a64b03d19 100644 --- a/test_scripts/Policies/build_options/117_ATF_DEXTENDED_POLICY_No_Flag_HTTP.lua +++ b/test_scripts/Policies/build_options/117_ATF_DEXTENDED_POLICY_No_Flag_HTTP.lua @@ -14,10 +14,6 @@ -- The flag -DEXTENDED_POLICY: is set to HTTP -- PTU passes successfully --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/build_options/118_ATF_Request_PTU_Trigger_App_Excluded_PT_HTTP.lua b/test_scripts/Policies/build_options/118_ATF_Request_PTU_Trigger_App_Excluded_PT_HTTP.lua index 1653fe7395..8ecfa98777 100644 --- a/test_scripts/Policies/build_options/118_ATF_Request_PTU_Trigger_App_Excluded_PT_HTTP.lua +++ b/test_scripts/Policies/build_options/118_ATF_Request_PTU_Trigger_App_Excluded_PT_HTTP.lua @@ -19,10 +19,6 @@ -- SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) -- SDL->HMI: BasicCommunication.PolicyUpdate --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/Policies/user_consent_of_Policies/188_ATF_HP_Device_Data_Section_Validation.lua b/test_scripts/Policies/user_consent_of_Policies/188_ATF_HP_Device_Data_Section_Validation.lua index 7637d1dcd4..d79d83554e 100644 --- a/test_scripts/Policies/user_consent_of_Policies/188_ATF_HP_Device_Data_Section_Validation.lua +++ b/test_scripts/Policies/user_consent_of_Policies/188_ATF_HP_Device_Data_Section_Validation.lua @@ -44,6 +44,7 @@ require('cardinalities') --[[ Required Shared libraries ]] local commonSteps = require ('user_modules/shared_testcases/commonSteps') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') +local utils = require ('user_modules/utils') require('user_modules/AppTypes') --[[ General Precondition before ATF start ]] @@ -93,7 +94,7 @@ function Test:Precondition_Get_List_Of_Connected_Devices() deviceList = { { - name = "127.0.0.1", + name = utils.getDeviceName(), transportType = "WIFI", isSDLAllowed = false } @@ -112,7 +113,7 @@ function Test:Precondition_Activate_App_Consent_Device_Make_PTU_Consent_Group() local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = MACHash, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = MACHash, name = utils.getDeviceName()}}) GetCurrentTimeStampDeviceConsent() EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) diff --git a/test_scripts/Policies/user_consent_of_Policies/189_ATF_isAppPermissionsRevoked_true.lua b/test_scripts/Policies/user_consent_of_Policies/189_ATF_isAppPermissionsRevoked_true.lua index 6a2744d3e3..ac5a10f5e5 100644 --- a/test_scripts/Policies/user_consent_of_Policies/189_ATF_isAppPermissionsRevoked_true.lua +++ b/test_scripts/Policies/user_consent_of_Policies/189_ATF_isAppPermissionsRevoked_true.lua @@ -22,13 +22,11 @@ -- Expected result: -- PoliciesManager must respond with "isAppPermissionRevoked:true" and "AppRevokedPermissions" param containing the list of revoked permissions to HMI --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local Variables ]] local HMIAppID @@ -52,7 +50,7 @@ function Test:SetHMIAppID() end function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:TestStep_PTU_appPermissionsConsentNeeded_true() diff --git a/test_scripts/Policies/user_consent_of_Policies/190_ATF_Device_treated_as_consented.lua b/test_scripts/Policies/user_consent_of_Policies/190_ATF_Device_treated_as_consented.lua index 100f915eff..85e0df4eb3 100644 --- a/test_scripts/Policies/user_consent_of_Policies/190_ATF_Device_treated_as_consented.lua +++ b/test_scripts/Policies/user_consent_of_Policies/190_ATF_Device_treated_as_consented.lua @@ -15,9 +15,6 @@ -- Expected result: -- Policies Manager must treat the device as consented If "device" sub-section of "app_policies" has its group listed in "preconsented_groups". --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/user_consent_of_Policies/191_ATF_UpdateDeviceList_on_device_connect.lua b/test_scripts/Policies/user_consent_of_Policies/191_ATF_UpdateDeviceList_on_device_connect.lua index c0590c5035..b35825d2b5 100644 --- a/test_scripts/Policies/user_consent_of_Policies/191_ATF_UpdateDeviceList_on_device_connect.lua +++ b/test_scripts/Policies/user_consent_of_Policies/191_ATF_UpdateDeviceList_on_device_connect.lua @@ -14,14 +14,12 @@ -- Expected result: -- SDL sends UpdateDeviceList to HMI right after new device connects over WiFi --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require ('user_modules/shared_testcases/commonSteps') local commonTestCases = require ('user_modules/shared_testcases/commonTestCases') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -37,16 +35,14 @@ require('mobile_session') commonFunctions:newTestCasesGroup("Test") function Test:UpdateDeviceList_on_device_connect() - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") - self:connectMobile() EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { deviceList = { { - id = config.deviceMAC, + id = utils.getDeviceMAC(), isSDLAllowed = false, - name = ServerAddress, + name = utils.getDeviceName(), transportType = "WIFI" } } @@ -63,4 +59,4 @@ function Test.Postcondition_Stop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/user_consent_of_Policies/192_ATF_isPermissionsConsentNeeded_false.lua b/test_scripts/Policies/user_consent_of_Policies/192_ATF_isPermissionsConsentNeeded_false.lua index 3ab75c177e..dcae207fb3 100644 --- a/test_scripts/Policies/user_consent_of_Policies/192_ATF_isPermissionsConsentNeeded_false.lua +++ b/test_scripts/Policies/user_consent_of_Policies/192_ATF_isPermissionsConsentNeeded_false.lua @@ -15,10 +15,6 @@ -- On receiving SDL.ActivateApp PoliciesManager must respond with "isPermissionsConsentNeeded:false" -- to HMI, consent for custom permissions is not appeared --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') diff --git a/test_scripts/Policies/user_consent_of_Policies/193_ATF_isPermissionsConsentNeeded_true.lua b/test_scripts/Policies/user_consent_of_Policies/193_ATF_isPermissionsConsentNeeded_true.lua index dad19b7f24..962d729244 100644 --- a/test_scripts/Policies/user_consent_of_Policies/193_ATF_isPermissionsConsentNeeded_true.lua +++ b/test_scripts/Policies/user_consent_of_Policies/193_ATF_isPermissionsConsentNeeded_true.lua @@ -19,10 +19,6 @@ -- On receiving SDL.ActivateApp PoliciesManager must respond with "isPermissionsConsentNeeded:true" to HMI, -- consent for custom permissions should appeared --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') @@ -69,4 +65,4 @@ function Test.Postcondition_Stop() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/user_consent_of_Policies/194_ATF_ActivateApp_isSDLAllowed_true.lua b/test_scripts/Policies/user_consent_of_Policies/194_ATF_ActivateApp_isSDLAllowed_true.lua index 1b13d968c6..eed9b4c07b 100644 --- a/test_scripts/Policies/user_consent_of_Policies/194_ATF_ActivateApp_isSDLAllowed_true.lua +++ b/test_scripts/Policies/user_consent_of_Policies/194_ATF_ActivateApp_isSDLAllowed_true.lua @@ -18,14 +18,13 @@ -- Expected result: -- PoliciesManager must respond with "isSDLAllowed: true" in the response to HMI without consent request --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -53,7 +52,7 @@ function Test:TestStep_ActivateApp1_isSDLAllowed_false() EXPECT_HMIRESPONSE(RequestId1) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,_data1) self.hmiConnection:SendResponse(_data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/user_consent_of_Policies/195_ATF_ActivateApp_isSDLAllowed_false.lua b/test_scripts/Policies/user_consent_of_Policies/195_ATF_ActivateApp_isSDLAllowed_false.lua index c93aa89c95..7ec27549b1 100644 --- a/test_scripts/Policies/user_consent_of_Policies/195_ATF_ActivateApp_isSDLAllowed_false.lua +++ b/test_scripts/Policies/user_consent_of_Policies/195_ATF_ActivateApp_isSDLAllowed_false.lua @@ -17,14 +17,12 @@ -- PoliciesManager must respond with 1)"isSDLAllowed:false", 2) "device" param containing the device`s name and ID previously sent by SDL via UpdateDeviceList -- in the response to HMI without consent request --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require ('user_modules/shared_testcases/commonSteps') local commonTestCases = require ('user_modules/shared_testcases/commonTestCases') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -38,8 +36,8 @@ require('mobile_session') --[[ Local variables ]] local mobile_session = require('mobile_session') -local device_id = config.deviceMAC -local server_address = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") +local device_id = utils.getDeviceMAC() +local server_address = utils.getDeviceName() --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") @@ -50,7 +48,7 @@ function Test:Precondition_UpdateDeviceList_on_device_connect() { deviceList = { { - id = config.deviceMAC, + id = utils.getDeviceMAC(), isSDLAllowed = false, name = server_address, transportType = "WIFI" @@ -97,7 +95,7 @@ function Test:ActivateApp_isSDLAllowed_false() EXPECT_HMIRESPONSE(RequestId1) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = server_address}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = server_address}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,_data1) self.hmiConnection:SendResponse(_data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/user_consent_of_Policies/196_ATF_UpdateDeviceList_isSDLAllowed_false.lua b/test_scripts/Policies/user_consent_of_Policies/196_ATF_UpdateDeviceList_isSDLAllowed_false.lua index 05a59f00f9..620dedb900 100644 --- a/test_scripts/Policies/user_consent_of_Policies/196_ATF_UpdateDeviceList_isSDLAllowed_false.lua +++ b/test_scripts/Policies/user_consent_of_Policies/196_ATF_UpdateDeviceList_isSDLAllowed_false.lua @@ -14,14 +14,12 @@ -- Expected result: -- PoliciesManager must provide "isSDLAllowed:false" param of "DeviceInfo" struct ONLY when sending "UpdateDeviceList" RPC to HMI --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require ('user_modules/shared_testcases/commonSteps') local commonTestCases = require ('user_modules/shared_testcases/commonTestCases') local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonPreconditions = require ('user_modules/shared_testcases/commonPreconditions') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -37,15 +35,14 @@ require('mobile_session') commonFunctions:newTestCasesGroup("Test") function Test:UpdateDeviceList_on_device_connect() - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") commonTestCases:DelayedExp(2000) self:connectMobile() EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", { deviceList = { { - id = config.deviceMAC, + id = utils.getDeviceMAC(), isSDLAllowed = false, - name = ServerAddress, + name = utils.getDeviceName(), transportType = "WIFI" }}}) :Do(function(_,data) @@ -63,4 +60,4 @@ function Test.Postcondition_StopSDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/user_consent_of_Policies/197_ATF_ActivateApp_isSDLAllowed_true.lua b/test_scripts/Policies/user_consent_of_Policies/197_ATF_ActivateApp_isSDLAllowed_true.lua index 33c408e9db..9b4266621b 100644 --- a/test_scripts/Policies/user_consent_of_Policies/197_ATF_ActivateApp_isSDLAllowed_true.lua +++ b/test_scripts/Policies/user_consent_of_Policies/197_ATF_ActivateApp_isSDLAllowed_true.lua @@ -21,14 +21,13 @@ -- Expected result: -- PoliciesManager must respond with "isSDLAllowed: true" in the response to HMI without consent request --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') -- local commonTestCases = require('user_modules/shared_testcases/commonTestCases') -- local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') @@ -59,7 +58,7 @@ function Test:ActivateApp1() EXPECT_HMIRESPONSE(RequestId1) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,_data1) self.hmiConnection:SendResponse(_data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/test_scripts/Policies/user_consent_of_Policies/198_ATF_GetUserFriendlyMessage_language_missed.lua b/test_scripts/Policies/user_consent_of_Policies/198_ATF_GetUserFriendlyMessage_language_missed.lua index ba9f2b3595..953c951d93 100644 --- a/test_scripts/Policies/user_consent_of_Policies/198_ATF_GetUserFriendlyMessage_language_missed.lua +++ b/test_scripts/Policies/user_consent_of_Policies/198_ATF_GetUserFriendlyMessage_language_missed.lua @@ -16,18 +16,14 @@ -- Expected result: -- English ("en-us") prompt must be returned to HMI --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local variables ]] -local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local language = testCasesForPolicyTableSnapshot:get_data_from_Preloaded_PT("consumer_friendly_messages.messages.DataConsent.languages.en-us.tts") local line1 = testCasesForPolicyTableSnapshot:get_data_from_Preloaded_PT("consumer_friendly_messages.messages.DataConsent.languages.en-us.line1") local line2 = testCasesForPolicyTableSnapshot:get_data_from_Preloaded_PT("consumer_friendly_messages.messages.DataConsent.languages.en-us.line2") @@ -65,7 +61,7 @@ function Test:Precondition_Activate_app_EN_US() :Do(function(_,_) -- Do not allow SDL to have again message GetUserFriendlyMessage self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = false, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = false}}) + {allowed = false, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = false}}) end) end diff --git a/test_scripts/Policies/user_consent_of_Policies/199_ATF_appPermissionsConsentNeeded_true.lua b/test_scripts/Policies/user_consent_of_Policies/199_ATF_appPermissionsConsentNeeded_true.lua index 4c4b1965c2..89f9a28dad 100644 --- a/test_scripts/Policies/user_consent_of_Policies/199_ATF_appPermissionsConsentNeeded_true.lua +++ b/test_scripts/Policies/user_consent_of_Policies/199_ATF_appPermissionsConsentNeeded_true.lua @@ -20,14 +20,11 @@ -- PoliciesManager must respond with the list of s that have the field "user_consent_prompt" in corresponding and -- are assigned to the specified application (section "" -> "groups") --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -43,7 +40,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_Activate_app() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] diff --git a/test_scripts/Policies/user_consent_of_Policies/200_ATF_Data_consent_prompt.lua b/test_scripts/Policies/user_consent_of_Policies/200_ATF_Data_consent_prompt.lua index 5a2c7c0e7e..4b62026c22 100644 --- a/test_scripts/Policies/user_consent_of_Policies/200_ATF_Data_consent_prompt.lua +++ b/test_scripts/Policies/user_consent_of_Policies/200_ATF_Data_consent_prompt.lua @@ -16,17 +16,11 @@ -- sub-sections of section which name corresponds to the value of messageCodes param of -- SDL.GetUserFriendlyMessage request --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') - ---[[ Local variables ]] -local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -50,7 +44,7 @@ function Test:GetUserFriendlyMessage_data_consent_prompt() { messages = { {messageCode = "DataConsent"}}}) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true}}) end) end end) diff --git a/test_scripts/Policies/user_consent_of_Policies/201_ATF_User_consents_permissions.lua b/test_scripts/Policies/user_consent_of_Policies/201_ATF_User_consents_permissions.lua index 11f965d5e9..16a9046925 100644 --- a/test_scripts/Policies/user_consent_of_Policies/201_ATF_User_consents_permissions.lua +++ b/test_scripts/Policies/user_consent_of_Policies/201_ATF_User_consents_permissions.lua @@ -20,16 +20,13 @@ -- Expected result: -- SDL must notify an application about the current permissions active on HMI via onPermissionsChange() notification --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -120,7 +117,6 @@ commonFunctions:newTestCasesGroup("Test") function Test:IsPermissionsConsentNeeded_false_on_app_activation() local is_test_passed = true - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) --Allow SDL functionality @@ -131,7 +127,7 @@ function Test:IsPermissionsConsentNeeded_false_on_app_activation() EXPECT_HMIRESPONSE( RequestId1, {result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true}}) end) end @@ -218,7 +214,7 @@ function Test:TestStep_trigger_user_request_update_from_HMI() end function Test:TestStep_verify_PermissionConsent() - local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.DrivingCharacteristics-3") + local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.DrivingCharacteristics-3") if(app_permission ~= true) then self:FailTestCase("DrivingCharacteristics-3 is not assigned to application, real: " ..app_permission) end diff --git a/test_scripts/Policies/user_consent_of_Policies/202_ATF_No_OnSDLConsentNeeded.lua b/test_scripts/Policies/user_consent_of_Policies/202_ATF_No_OnSDLConsentNeeded.lua index 68d675a988..d6a608ce90 100644 --- a/test_scripts/Policies/user_consent_of_Policies/202_ATF_No_OnSDLConsentNeeded.lua +++ b/test_scripts/Policies/user_consent_of_Policies/202_ATF_No_OnSDLConsentNeeded.lua @@ -23,7 +23,6 @@ -- SDL must NOT send the OnSDLConsentNeeded to HMI --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.application1.registerAppInterfaceParams.appHMIType = { "MEDIA" } --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/user_consent_of_Policies/203_ATF_Master_reset.lua b/test_scripts/Policies/user_consent_of_Policies/203_ATF_Master_reset.lua index b396d26930..bfbe53e7fe 100644 --- a/test_scripts/Policies/user_consent_of_Policies/203_ATF_Master_reset.lua +++ b/test_scripts/Policies/user_consent_of_Policies/203_ATF_Master_reset.lua @@ -15,14 +15,12 @@ -- Expected result: -- Policy Manager must revert Local Policy Table to the Preload Policy Table --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTableSnapshot = require ('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Preconditions ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -38,8 +36,6 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_CheckLocalPT() local hmi_app1_id = self.applications[config.application1.registerAppInterfaceParams.appName] - local ServerAddress = "127.0.0.1"--commonSteps:get_data_from_SDL_ini("ServerAddress") - local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) EXPECT_HMIRESPONSE(RequestId) @@ -49,13 +45,13 @@ function Test:TestStep_CheckLocalPT() EXPECT_HMIRESPONSE( RequestId1, {result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true}}) end) if ( commonSteps:file_exists('/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json')) then self:FailTestCase(" \27[31m /tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json is created \27[0m") else - testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID}, {config.deviceMAC},{hmi_app1_id}, "print") + testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID}, {utils.getDeviceMAC()},{hmi_app1_id}, "print") end end) end diff --git a/test_scripts/Policies/user_consent_of_Policies/204_ATF_App_group_order_preconsented.lua b/test_scripts/Policies/user_consent_of_Policies/204_ATF_App_group_order_preconsented.lua index 78a30f1294..2748097ff8 100644 --- a/test_scripts/Policies/user_consent_of_Policies/204_ATF_App_group_order_preconsented.lua +++ b/test_scripts/Policies/user_consent_of_Policies/204_ATF_App_group_order_preconsented.lua @@ -15,16 +15,13 @@ -- Expected result: -- App should have only "pre_DataConsent" groups allowed --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -258,11 +255,10 @@ local arrayRegisterNewApp = { commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_ConnectDevice() - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") commonTestCases:DelayedExp(2000) self:connectMobile() EXPECT_HMICALL("BasicCommunication.UpdateDeviceList", - { deviceList = { { id = config.deviceMAC, isSDLAllowed = false, name = ServerAddress, transportType = "WIFI" }}}) + { deviceList = { { id = utils.getDeviceMAC(), isSDLAllowed = false, name = utils.getDeviceName(), transportType = "WIFI" }}}) :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) diff --git a/test_scripts/Policies/user_consent_of_Policies/205_ATF_Consent_timestamp.lua b/test_scripts/Policies/user_consent_of_Policies/205_ATF_Consent_timestamp.lua index 642720c30f..1739b7bb51 100644 --- a/test_scripts/Policies/user_consent_of_Policies/205_ATF_Consent_timestamp.lua +++ b/test_scripts/Policies/user_consent_of_Policies/205_ATF_Consent_timestamp.lua @@ -17,15 +17,12 @@ -- Expected result: -- PoliciesManager must add a timestamp of user consent for the current mobile device into “time_stamp†field in the format of "TZ". --------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local Variables ]] local TimeToCheckSeconds = nil @@ -56,7 +53,7 @@ require('user_modules/AppTypes') --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_trigger_getting_device_consent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) local CurrentTimeSeconds = assert( io.popen( "date +%H:%M:%S" , 'r')) TimeToCheckSeconds = CurrentTimeSeconds:read( '*l' ) end @@ -71,7 +68,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:TimeStamp_in_userConsentRecords_table() local errorFlag = false local ErrorMessage = "" - local TimeStamp_InUserConsentRecordsTable = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records.device.time_stamp") + local TimeStamp_InUserConsentRecordsTable = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records.device.time_stamp") if type(TimeStamp_InUserConsentRecordsTable) ~= 'string' then self:FailTestCase("TimeStamp in user_consent_records came wrong") end diff --git a/test_scripts/Policies/user_consent_of_Policies/206_ATF_Permissions_before_device_consented.lua b/test_scripts/Policies/user_consent_of_Policies/206_ATF_Permissions_before_device_consented.lua index 3fd0e2ccd1..69bc95a8b0 100644 --- a/test_scripts/Policies/user_consent_of_Policies/206_ATF_Permissions_before_device_consented.lua +++ b/test_scripts/Policies/user_consent_of_Policies/206_ATF_Permissions_before_device_consented.lua @@ -29,18 +29,13 @@ -- HMI->SDL: SDL.ActivateApp{appID} -- SDL->HMI: SDL.ActivateApp_response{isSDLAllowed: false, params} ------------------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') - +local utils = require ('user_modules/utils') --[[ Local variables ]] -local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local pre_dataconsent = "129372391" --[[ General Precondition before ATF start ]] @@ -60,7 +55,7 @@ function Test:TestStep1_ActivateApp_on_unconsented_device() EXPECT_HMIRESPONSE(RequestId, {result = { code = 0, - device = { id = config.deviceMAC, name = ServerAddress }, + device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() }, isAppPermissionsRevoked = false, isAppRevoked = false, isSDLAllowed = false, method ="SDL.ActivateApp"}}) :Do(function(_,data) if data.result.isSDLAllowed ~= false then @@ -106,7 +101,7 @@ function Test:TestStep4_ActivateApp_again_on_unconsented_device() --Device is still not consented, isSDLAllowed should be "false" EXPECT_HMIRESPONSE(RequestId, {result = { code = 0, - device = { id = config.deviceMAC, name = ServerAddress }, + device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() }, isAppPermissionsRevoked = false, isAppRevoked = false, isSDLAllowed = false, method ="SDL.ActivateApp"}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Times(0) @@ -140,4 +135,4 @@ function Test.Postcondition_StopSDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/user_consent_of_Policies/207_ATF_HMILevel_before_data_consented.lua b/test_scripts/Policies/user_consent_of_Policies/207_ATF_HMILevel_before_data_consented.lua index 17dcf32412..9231e81b30 100644 --- a/test_scripts/Policies/user_consent_of_Policies/207_ATF_HMILevel_before_data_consented.lua +++ b/test_scripts/Policies/user_consent_of_Policies/207_ATF_HMILevel_before_data_consented.lua @@ -27,17 +27,11 @@ -- HMI->SDL: OnAllowSDLFunctionality {allowed: false, params} -- SDL->app: OnPermissionChanged{params}// "pre_DataConsent" sub-section of "app_policies" section of PT, app`s HMI level corresponds to one from "default_hmi" field ------------------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') - ---[[ Local variables ]] -local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -55,7 +49,7 @@ function Test:ActivateApp_on_unconsented_device() local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) EXPECT_HMIRESPONSE(RequestId, {result = { code = 0, - device = { id = config.deviceMAC, name = ServerAddress }, + device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() }, isAppPermissionsRevoked = false, isAppRevoked = false, isSDLAllowed = false, isPermissionsConsentNeeded = false, method ="SDL.ActivateApp"}}) :Do(function(_,data) --Consent for device is needed @@ -68,7 +62,7 @@ function Test:ActivateApp_on_unconsented_device() :Do(function() --Press "NO"on data consent self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = false, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress}}) + {allowed = false, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_NOTIFICATION("OnPermissionsChange", {}):Times(0) end) diff --git a/test_scripts/Policies/user_consent_of_Policies/208_ATF_No_consent_for_default_policies.lua b/test_scripts/Policies/user_consent_of_Policies/208_ATF_No_consent_for_default_policies.lua index ab252b6a57..f4590ff092 100644 --- a/test_scripts/Policies/user_consent_of_Policies/208_ATF_No_consent_for_default_policies.lua +++ b/test_scripts/Policies/user_consent_of_Policies/208_ATF_No_consent_for_default_policies.lua @@ -17,13 +17,11 @@ -- Expected result: -- PoliciesManager must not ask the User for consent for "default" permissions --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -35,7 +33,7 @@ local mobile_session = require('mobile_session') --[[ Precondition ]] function Test:Precondition_ActivateRegisteredApp() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_AddSession2() diff --git a/test_scripts/Policies/user_consent_of_Policies/209_ATF_Device_user_disallowed_after_consent.lua b/test_scripts/Policies/user_consent_of_Policies/209_ATF_Device_user_disallowed_after_consent.lua index 7bc6d63a8e..b98a5dc198 100644 --- a/test_scripts/Policies/user_consent_of_Policies/209_ATF_Device_user_disallowed_after_consent.lua +++ b/test_scripts/Policies/user_consent_of_Policies/209_ATF_Device_user_disallowed_after_consent.lua @@ -19,13 +19,11 @@ -- App must be rolled back to default group -- RPC from defult should be allowed --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local testCasesForPolicyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -40,7 +38,7 @@ require("user_modules/AppTypes") --[[ Precondition ]] function Test:Precondition_ActivateRegisteredApp() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_Check_App_assigned_BASE4() @@ -57,7 +55,7 @@ end function Test:Precondition_Disallow_device() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = false, source = "GUI", device = {id = config.deviceMAC , name = "127.0.0.1"}}) + {allowed = false, source = "GUI", device = {id = utils.getDeviceMAC() , name = utils.getDeviceName()}}) end --[[ Test ]] @@ -93,7 +91,7 @@ function Test:ActivateApp() local requestId2 = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", { language = "EN-US", messageCodes = { "DataConsent" } }) EXPECT_HMIRESPONSE(requestId2) :Do(function(_, _) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_, data2) self.hmiConnection:SendResponse(data2.id,"BasicCommunication.ActivateApp", "SUCCESS", { }) diff --git a/test_scripts/Policies/user_consent_of_Policies/210_ATF_User_consent_initing_after_PTU_FULL.lua b/test_scripts/Policies/user_consent_of_Policies/210_ATF_User_consent_initing_after_PTU_FULL.lua index f4d89d28f4..0b10479d1a 100644 --- a/test_scripts/Policies/user_consent_of_Policies/210_ATF_User_consent_initing_after_PTU_FULL.lua +++ b/test_scripts/Policies/user_consent_of_Policies/210_ATF_User_consent_initing_after_PTU_FULL.lua @@ -13,13 +13,11 @@ -- Policies Manager must notify HMI about 'user-consent-required' via SDL.OnAppPermissionChanged{appID, appPermissionsConsentNeeded: true} per application in FULL, -- that lacks the User`s permissions right after Policies Manager detects the user-unconsented permissions in Local PT --------------------------------------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Preconditions ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -30,7 +28,7 @@ require('cardinalities') require('user_modules/AppTypes') function Test:Precondition_Activate_app() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] @@ -78,4 +76,4 @@ function Test.Postcondition_StopSDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/user_consent_of_Policies/211_ATF_User_consent_initing_after_PTU_LIMITED.lua b/test_scripts/Policies/user_consent_of_Policies/211_ATF_User_consent_initing_after_PTU_LIMITED.lua index fe9688dd80..014d9165dc 100644 --- a/test_scripts/Policies/user_consent_of_Policies/211_ATF_User_consent_initing_after_PTU_LIMITED.lua +++ b/test_scripts/Policies/user_consent_of_Policies/211_ATF_User_consent_initing_after_PTU_LIMITED.lua @@ -15,13 +15,11 @@ -- Policies Manager must notify HMI about 'user-consent-required' via SDL.OnAppPermissionChanged{appID, appPermissionsConsentNeeded: true} per application in FULL, -- that lacks the User`s permissions right after Policies Manager detects the user-unconsented permissions in Local PT --------------------------------------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Preconditions ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -33,7 +31,7 @@ require('user_modules/AppTypes') function Test:Precondition_Activate_app() config.application1.registerAppInterfaceParams.isMediaApplication = true - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end function Test:Precondition_Switch_app_to_LIMITED() @@ -86,4 +84,4 @@ function Test.Postcondition_StopSDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/user_consent_of_Policies/212_ATF_Data_consent_device_not_in_LPT.lua b/test_scripts/Policies/user_consent_of_Policies/212_ATF_Data_consent_device_not_in_LPT.lua index da6fd7bbc6..074b4629a4 100644 --- a/test_scripts/Policies/user_consent_of_Policies/212_ATF_Data_consent_device_not_in_LPT.lua +++ b/test_scripts/Policies/user_consent_of_Policies/212_ATF_Data_consent_device_not_in_LPT.lua @@ -14,14 +14,11 @@ -- Expected result: -- PoliciesManager must initiate getting User`s data consent (that is, User`s permission for using the mobile device`s connection for Policy Table exchange) ---------------------------------------------------------------------------------------------------- - ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Preconditions ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -36,9 +33,8 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Test") function Test:Check_user_data_consent_is_requested() - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) - EXPECT_HMIRESPONSE(RequestId, {result = { code = 0, device = { id = config.deviceMAC, name = ServerAddress }, isSDLAllowed = false, isPermissionsConsentNeeded = false, method ="SDL.ActivateApp"}}) + EXPECT_HMIRESPONSE(RequestId, {result = { code = 0, device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() }, isSDLAllowed = false, isPermissionsConsentNeeded = false, method ="SDL.ActivateApp"}}) :Do(function(_,data) if data.result.isSDLAllowed ~= false then commonFunctions:userPrint(31, "Error: wrong behavior of SDL - device not from LPT, should be consented on HMI") @@ -47,7 +43,7 @@ function Test:Check_user_data_consent_is_requested() EXPECT_HMIRESPONSE(RequestIdGetMes) :Do(function() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) end) end end) diff --git a/test_scripts/Policies/user_consent_of_Policies/213_ATF_No_user_consent_prompt_in_group.lua b/test_scripts/Policies/user_consent_of_Policies/213_ATF_No_user_consent_prompt_in_group.lua index 93b010162e..2334e60bee 100644 --- a/test_scripts/Policies/user_consent_of_Policies/213_ATF_No_user_consent_prompt_in_group.lua +++ b/test_scripts/Policies/user_consent_of_Policies/213_ATF_No_user_consent_prompt_in_group.lua @@ -19,9 +19,7 @@ -- Expected result: -- PoliciesManager must apply such without asking User`s consent for it --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] @@ -29,6 +27,7 @@ local commonFunctions = require ('user_modules/shared_testcases/commonFunctions' local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -42,7 +41,6 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Test") function Test:TestStep1_PTU_lack_of_user_consent_prompt() - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) --Allow SDL functionality @@ -53,7 +51,7 @@ function Test:TestStep1_PTU_lack_of_user_consent_prompt() EXPECT_HMIRESPONSE( RequestId1, {result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true}}) end) end @@ -65,7 +63,7 @@ function Test:TestStep1_PTU_lack_of_user_consent_prompt() end function Test:TestStep_app_no_consent() - local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records."..config.application1.registerAppInterfaceParams.appID) + local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID) if(app_permission ~= nil) then self:FailTestCase("Consented gropus are assigned to application") end diff --git a/test_scripts/Policies/user_consent_of_Policies/214_ATF_User_consent_prompt_persists.lua b/test_scripts/Policies/user_consent_of_Policies/214_ATF_User_consent_prompt_persists.lua index 0e03ec8d9e..36e6191109 100644 --- a/test_scripts/Policies/user_consent_of_Policies/214_ATF_User_consent_prompt_persists.lua +++ b/test_scripts/Policies/user_consent_of_Policies/214_ATF_User_consent_prompt_persists.lua @@ -20,7 +20,6 @@ -- PoliciesManager must apply only after the User has consented it -> RPC should be allowed --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] @@ -29,6 +28,7 @@ local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +local utils = require ('user_modules/utils') --[[ Local variables ]] local allowed_rps = {} @@ -148,7 +148,6 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Preconditions") function Test:Precondition_IsPermissionsConsentNeeded_false_on_app_activation() Get_RPCs() - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) --Allow SDL functionality @@ -159,7 +158,7 @@ function Test:Precondition_IsPermissionsConsentNeeded_false_on_app_activation() EXPECT_HMIRESPONSE( RequestId1, {result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true}}) end) end @@ -176,7 +175,7 @@ function Test:Precondition_IsPermissionsConsentNeeded_false_on_app_activation() EXPECT_HMICALL("BasicCommunication.PolicyUpdate", {file = "/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json"}) :Do(function() - local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records."..config.application1.registerAppInterfaceParams.appID) + local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID) if(app_permission ~= nil) then self:FailTestCase("Consented gropus are assigned to application") end @@ -297,8 +296,8 @@ function Test:Precondition_PTU_user_consent_prompt_present() function Test.TestStep_verify_PermissionConsent() local is_test_passed = true - local app_permission_Location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Location-1") - local app_permission_Notifications = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Notifications") + local app_permission_Location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Location-1") + local app_permission_Notifications = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Notifications") if(app_permission_Location ~= nil) then commonFunctions:printError("Location-1 is assigned user_consent_records") is_test_passed = false diff --git a/test_scripts/Policies/user_consent_of_Policies/215_ATF_User_clears_all_applications.lua b/test_scripts/Policies/user_consent_of_Policies/215_ATF_User_clears_all_applications.lua index 473dcd4981..b8ccfac9a5 100644 --- a/test_scripts/Policies/user_consent_of_Policies/215_ATF_User_clears_all_applications.lua +++ b/test_scripts/Policies/user_consent_of_Policies/215_ATF_User_clears_all_applications.lua @@ -20,14 +20,12 @@ -- SDL->HMI: BC.UpdateDeviceList(device1, device2) -- HMI->SDL: BC.UpdateDeviceList(SUCCESS) -------------------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -47,7 +45,6 @@ local mobile = require('mobile_connection') local events = require('events') --[[ Local variables ]] -local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local deviceMAC2 = "54286cb92365be544aa7008b92854b9648072cf8d8b17b372fd0786bef69d7a2" local mobileHost = "1.0.0.1" @@ -61,8 +58,8 @@ function Test:Precondition_Connect_device1() { deviceList = { { - id = config.deviceMAC, - name = ServerAddress, + id = utils.getDeviceMAC(), + name = utils.getDeviceName(), transportType = "WIFI", isSDLAllowed = false } @@ -131,8 +128,8 @@ function Test:TestStep_Check_two_devices_visible_on_device2_connect() { deviceList = { { - id = config.deviceMAC, - name = ServerAddress, + id = utils.getDeviceMAC(), + name = utils.getDeviceName(), transportType = "WIFI", isSDLAllowed = false }, diff --git a/test_scripts/Policies/user_consent_of_Policies/216_ATF_User_consent_storage_in_LPT.lua b/test_scripts/Policies/user_consent_of_Policies/216_ATF_User_consent_storage_in_LPT.lua index a6a43b7391..aeca9ac0a4 100644 --- a/test_scripts/Policies/user_consent_of_Policies/216_ATF_User_consent_storage_in_LPT.lua +++ b/test_scripts/Policies/user_consent_of_Policies/216_ATF_User_consent_storage_in_LPT.lua @@ -27,13 +27,11 @@ -- PoliciesManager records the consent-related information in "device" subsection of "user_consent_records" subsection -- of "" section of "device_data" section in Local PT. --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -47,15 +45,14 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Test") function Test:TestStep1_Device_consent_on_activate_app() - local ServerAddress = commonFunctions:read_parameter_from_smart_device_link_ini("ServerAddress") local RequestIdActivate = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[config.application1.registerAppInterfaceParams.appName]}) - EXPECT_HMIRESPONSE(RequestIdActivate, {result = { code = 0, device = { id = config.deviceMAC, name = ServerAddress }, isSDLAllowed = false, method ="SDL.ActivateApp"}}) + EXPECT_HMIRESPONSE(RequestIdActivate, {result = { code = 0, device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() }, isSDLAllowed = false, method ="SDL.ActivateApp"}}) :Do(function() local RequestIdGetMes = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetMes, {result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = ServerAddress, isSDLAllowed = true }}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true }}) end) end) EXPECT_HMICALL("BasicCommunication.ActivateApp") @@ -66,7 +63,7 @@ end function Test:TestStep2_check_LocalPT_for_consent_storage() local test_fail = false - local data_consent = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records.device.consent_groups.DataConsent-2") + local data_consent = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records.device.consent_groups.DataConsent-2") print("data_consent = " ..tostring(data_consent)) if(data_consent ~= true) then @@ -84,4 +81,4 @@ function Test.Postcondition_StopSDL() StopSDL() end -return Test \ No newline at end of file +return Test diff --git a/test_scripts/Policies/user_consent_of_Policies/217_ATF_Consent_status_allowed_on_device_connect.lua b/test_scripts/Policies/user_consent_of_Policies/217_ATF_Consent_status_allowed_on_device_connect.lua index 6a53c385fe..721b04f2d7 100644 --- a/test_scripts/Policies/user_consent_of_Policies/217_ATF_Consent_status_allowed_on_device_connect.lua +++ b/test_scripts/Policies/user_consent_of_Policies/217_ATF_Consent_status_allowed_on_device_connect.lua @@ -14,14 +14,12 @@ -- SDL/PoliciesManager must provide the device`s DataConsent status (allowed) to HMI upon device`s connection-> -- SDL must request DataConsent status of the corresponding device from the PoliciesManager ------------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonFunctions:SDLForceStop() @@ -69,9 +67,9 @@ function Test:Check_device_connects_as_consented() { deviceList = { { - id = config.deviceMAC, + id = utils.getDeviceMAC(), isSDLAllowed = true, - name = "127.0.0.1", + name = utils.getDeviceName(), transportType = "WIFI" } } diff --git a/test_scripts/Policies/user_consent_of_Policies/218_ATF_Consent_status_not_allowed_on_device_connect.lua b/test_scripts/Policies/user_consent_of_Policies/218_ATF_Consent_status_not_allowed_on_device_connect.lua index 2702768086..4e52cc5183 100644 --- a/test_scripts/Policies/user_consent_of_Policies/218_ATF_Consent_status_not_allowed_on_device_connect.lua +++ b/test_scripts/Policies/user_consent_of_Policies/218_ATF_Consent_status_not_allowed_on_device_connect.lua @@ -7,28 +7,26 @@ -- 1. Used preconditions: -- Delete files and policy table from previous ignition cycle if any -- 2. Performed steps: --- Connect device +-- Connect device -- -- Expected result: -- SDL/PoliciesManager must provide the device`s DataConsent status (not allowed) to HMI upon device`s connection-> --- SDL must request DataConsent status of the corresponding device from the PoliciesManager +-- SDL must request DataConsent status of the corresponding device from the PoliciesManager ------------------------------------------------------------------------------------------------- --[[ General Settings for configuration ]] Test = require('user_modules/connecttest_resumption') require('cardinalities') ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +local utils = require ('user_modules/utils') require('user_modules/AppTypes') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFiles() -commonSteps:DeletePolicyTable() +commonSteps:DeletePolicyTable() --[[ Test ]] commonFunctions:newTestCasesGroup("Test") @@ -39,9 +37,9 @@ function Test:Check_device_connects_as_not_consented() { deviceList = { { - id = config.deviceMAC, + id = utils.getDeviceMAC(), isSDLAllowed = false, - name = "127.0.0.1", + name = utils.getDeviceName(), transportType = "WIFI" } } diff --git a/test_scripts/Policies/user_consent_of_Policies/219_ATF_Device_identifier_creation_upon_connect_no_apps.lua b/test_scripts/Policies/user_consent_of_Policies/219_ATF_Device_identifier_creation_upon_connect_no_apps.lua index 5dae8a13e4..7f548314f9 100644 --- a/test_scripts/Policies/user_consent_of_Policies/219_ATF_Device_identifier_creation_upon_connect_no_apps.lua +++ b/test_scripts/Policies/user_consent_of_Policies/219_ATF_Device_identifier_creation_upon_connect_no_apps.lua @@ -13,13 +13,11 @@ -- Expected result: -- SDL must add new device in deviceList of BasicCommunication.UpdateDeviceList --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFileAndPolicyTable() @@ -41,8 +39,8 @@ function Test:Test_Connect_device() { deviceList = { { - id = config.deviceMAC, - name = "127.0.0.1", + id = utils.getDeviceMAC(), + name = utils.getDeviceName(), transportType = "WIFI", isSDLAllowed = false } diff --git a/test_scripts/Policies/user_consent_of_Policies/220_ATF_Device_identifier_creation_upon_connect_with_apps.lua b/test_scripts/Policies/user_consent_of_Policies/220_ATF_Device_identifier_creation_upon_connect_with_apps.lua index d93529a973..be39413a58 100644 --- a/test_scripts/Policies/user_consent_of_Policies/220_ATF_Device_identifier_creation_upon_connect_with_apps.lua +++ b/test_scripts/Policies/user_consent_of_Policies/220_ATF_Device_identifier_creation_upon_connect_with_apps.lua @@ -15,15 +15,13 @@ -- Expected result: -- SDL must add new section in "device_data" section --------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" - --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local mobile_session = require('mobile_session') local testCasesForPolicyTable = require('user_modules/shared_testcases/testCasesForPolicyTable') +local utils = require ('user_modules/utils') --[[ Local variables ]] local pts_json = '/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json' @@ -47,8 +45,8 @@ function Test:Precondition_Connect_device() { deviceList = { { - id = config.deviceMAC, - name = "127.0.0.1", + id = utils.getDeviceMAC(), + name = utils.getDeviceName(), transportType = "WIFI", isSDLAllowed = false } @@ -72,8 +70,8 @@ function Test:Precondition_Register_app() { deviceInfo = { - name = "127.0.0.1", - id = config.deviceMAC, + name = utils.getDeviceName(), + id = utils.getDeviceMAC(), transportType = "WIFI" } } @@ -87,7 +85,7 @@ function Test:Precondition_Register_app() end function Test:Precondition_TriggerGettingDeviceConsent() - testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, config.deviceMAC) + testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end --[[ Test ]] @@ -103,7 +101,7 @@ function Test:Check_device_identifier_added_to_lpt() local data = json.decode(json_data) local deviceIdentificatorInPTS = next(data.policy_table.device_data, nil) - if (deviceIdentificatorInPTS == config.deviceMAC) then + if (deviceIdentificatorInPTS == utils.getDeviceMAC()) then commonFunctions:userPrint(33, "device_identifier ".. deviceIdentificatorInPTS.. " section is created") else self:FailTestCase("Test is FAILED. device_identifier section is not created.") diff --git a/test_scripts/Policies/user_consent_of_Policies/221_ATF_Factory_reset.lua b/test_scripts/Policies/user_consent_of_Policies/221_ATF_Factory_reset.lua index b3d914a8c4..d15a18a7c2 100644 --- a/test_scripts/Policies/user_consent_of_Policies/221_ATF_Factory_reset.lua +++ b/test_scripts/Policies/user_consent_of_Policies/221_ATF_Factory_reset.lua @@ -14,10 +14,7 @@ -- Expected result: -- Policy Manager must clear all user consent records in "user_consent_records" section of the LocalPT, other content of the LocalPT must be unchanged --------------------------------------------------------------------------------------------------------------------------------------------------------- ---[[ General Settings for configuration ]] - --[[ General configuration parameters ]] -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" config.defaultProtocolVersion = 2 config.ExitOnCrash = false @@ -28,6 +25,7 @@ local testCasesForPolicyTableSnapshot = require ('user_modules/shared_testcases/ local testCasesForPolicyTable = require ('user_modules/shared_testcases/testCasesForPolicyTable') local mobile_session = require('mobile_session') local sdl = require('SDL') +local utils = require ('user_modules/utils') --[[ Local Functions ]] @@ -94,7 +92,7 @@ function Test:Precondition_Activate_app_To_Trigger_PTU() EXPECT_HMIRESPONSE( RequestId1, {result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1", isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true}}) local request_id_list_of_permissions = self.hmiConnection:SendRequest("SDL.GetListOfPermissions", { appID = self.applications[config.application1.registerAppInterfaceParams.appName] }) EXPECT_HMIRESPONSE(request_id_list_of_permissions) @@ -194,7 +192,7 @@ function Test:Precondition_Activate_app_To_Trigger_PTU_after_reset() EXPECT_HMIRESPONSE( RequestId1, {result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1", isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName(), isSDLAllowed = true}}) end) end) @@ -219,8 +217,8 @@ function Test:Check_no_user_consent_records_in_PT() self:FailTestCase(config.pathToSDL .."sdl_preloaded_pt.json ".."is not created") else testCasesForPolicyTableSnapshot:extract_pts({self.applications[config.application1.registerAppInterfaceParams.appName]}) - local app_consent_location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Location-1") - local app_consent_notifications = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..config.deviceMAC..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Notifications") + local app_consent_location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Location-1") + local app_consent_notifications = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Notifications") if(app_consent_location == true) then commonFunctions:printError("Error: user_consent_records.consent_groups.Location was not reset in LPT") diff --git a/test_scripts/Policies/user_consent_of_Policies/222_ATF_Device_HashID_In_LPT.lua b/test_scripts/Policies/user_consent_of_Policies/222_ATF_Device_HashID_In_LPT.lua index 0b84dbe053..108facba61 100644 --- a/test_scripts/Policies/user_consent_of_Policies/222_ATF_Device_HashID_In_LPT.lua +++ b/test_scripts/Policies/user_consent_of_Policies/222_ATF_Device_HashID_In_LPT.lua @@ -6,14 +6,13 @@ -- Before storing the number in the policy table, Policy manager must hash the number using SHA-256. SDL must store the hashed device identifier -- (BTMAC for Bluetoth connection or Serial number of USB connected device) in section of Local Policy Table -- 1. Used preconditions: --- a) Start SDL, HMI and register app via Wifi (MAC address - 127.0.0.1) +-- a) Start SDL, HMI and register app via Wifi -- 2. Performed steps -- a) Initiate PTU to verify device hash in policy shapshot -- -- Expected result: -- a) Hash of device is present in snapshot --------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] --ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 @@ -21,6 +20,7 @@ config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') local commonSteps = require ('user_modules/shared_testcases/commonSteps') +local utils = require ('user_modules/utils') --[[ General Precondition before ATF start ]] commonSteps:DeleteLogsFiles() @@ -52,8 +52,8 @@ function Test:Precondition_Get_List_Of_Connected_Devices() { deviceList = { { - - name = "127.0.0.1", + id = utils.getDeviceMAC(), + name = utils.getDeviceName(), transportType = "WIFI", isSDLAllowed = false } @@ -74,7 +74,7 @@ function Test:Initiate_PTU_And_Check_DeviceHashId_In_PTS() local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = MACHash, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = MACHash, name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data1) self.hmiConnection:SendResponse(data1.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/user_modules/common_steps.lua b/user_modules/common_steps.lua index 7de684aba9..461aaa0d79 100644 --- a/user_modules/common_steps.lua +++ b/user_modules/common_steps.lua @@ -1,3 +1,4 @@ +local utils = require ('user_modules/utils') -------------------------------------------------------------------------------- -- This scripts contains common steps(Tests) that are used often in many scripts --[[ Note: functions in this script are designed based on bellow data structure of mobile connection, sessions, applications, application's parameter and HMI app ID @@ -197,7 +198,7 @@ function CommonSteps:ActivateApplication(test_case_name, app_name, expected_leve -- if application is disallowed, HMI has to send SDL.OnAllowSDLFunctionality notification to allow before activation -- If isSDLAllowed is false, consent for sending policy table through specified device is required. if data.result.isSDLAllowed ~= true then - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data) self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) diff --git a/user_modules/shared_testcases/commonSteps.lua b/user_modules/shared_testcases/commonSteps.lua index f1373b21fe..78294caaff 100644 --- a/user_modules/shared_testcases/commonSteps.lua +++ b/user_modules/shared_testcases/commonSteps.lua @@ -24,6 +24,7 @@ local commonSteps = {} local mobile_session = require('mobile_session') local config = require('config') local SDLConfig = require('user_modules/shared_testcases/SmartDeviceLinkConfigurations') +local utils = require ('user_modules/utils') --------------------------------------------------------------------------------------------- @@ -548,7 +549,7 @@ function commonSteps:ActivateAppInSpecificLevel(test, HMIAppID) :Do(function(_,_) --hmi side: send request SDL.OnAllowSDLFunctionality test.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) + {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) --hmi side: expect BasicCommunication.ActivateApp request EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_,data2) @@ -560,4 +561,4 @@ function commonSteps:ActivateAppInSpecificLevel(test, HMIAppID) end) end -return commonSteps \ No newline at end of file +return commonSteps diff --git a/user_modules/shared_testcases/testCasesForExternalUCS.lua b/user_modules/shared_testcases/testCasesForExternalUCS.lua index 19fc3c1f01..0b79e8e557 100644 --- a/user_modules/shared_testcases/testCasesForExternalUCS.lua +++ b/user_modules/shared_testcases/testCasesForExternalUCS.lua @@ -8,13 +8,14 @@ local commonPreconditions = require('user_modules/shared_testcases/commonPrecond local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local json = require("modules/json") local sdl = require('SDL') +local utils = require ('user_modules/utils') -local utils = { } +local m = { } -- [[ Variables ]] - utils.HMIAppIds = { } - utils.pts = nil + m.HMIAppIds = { } + m.pts = nil -- [[ Functions ]] @@ -22,7 +23,7 @@ local utils = { } --! @parameters: --! file - input file --]] - function utils.createTableFromJsonFile(file) + function m.createTableFromJsonFile(file) local f = io.open(file, "r") local content = f:read("*all") f:close() @@ -34,7 +35,7 @@ local utils = { } --! table - input table --! file - output file --]] - function utils.createJsonFileFromTable(table, file) + function m.createJsonFileFromTable(table, file) local f = io.open(file, "w") f:write(json.encode(table)) f:close() @@ -44,7 +45,7 @@ local utils = { } --! @parameters: --! expStatus - expected status of SDL (0 - STOPPED, 1 - RUNNING) --]] - function utils.checkSDLStatus(test, expStatus) + function m.checkSDLStatus(test, expStatus) local actStatus = sdl:CheckStatusSDL() print("SDL status: " .. tostring(actStatus)) if actStatus ~= expStatus then @@ -56,7 +57,7 @@ local utils = { } --[[@removeLPT: Delete Local Policy Table --! @parameters: NO --]] - function utils.removeLPT() + function m.removeLPT() local data = { "AppStorageFolder", "AppInfoStorage" } for _, v in pairs(data) do os.execute("rm -rf " .. commonPreconditions:GetPathToSDL() @@ -67,7 +68,7 @@ local utils = { } --[[@removePTS: Delete Policy Table Snapshot --! @parameters: NO --]] - function utils.removePTS() + function m.removePTS() local filePath = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") os.execute("rm -rf " .. filePath) @@ -78,19 +79,19 @@ local utils = { } --]] local function updatePTU() local appId = config.application1.registerAppInterfaceParams.appID - utils.pts.policy_table.consumer_friendly_messages.messages = nil - utils.pts.policy_table.device_data = nil - utils.pts.policy_table.module_meta = nil - utils.pts.policy_table.usage_and_error_counts = nil - utils.pts.policy_table.app_policies[appId] = { + m.pts.policy_table.consumer_friendly_messages.messages = nil + m.pts.policy_table.device_data = nil + m.pts.policy_table.module_meta = nil + m.pts.policy_table.usage_and_error_counts = nil + m.pts.policy_table.app_policies[appId] = { keep_context = false, steal_focus = false, priority = "NONE", default_hmi = "NONE" } - utils.pts.policy_table.app_policies[appId]["groups"] = { "Base-4", "Base-6" } - utils.pts.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null - utils.pts.policy_table.module_config.preloaded_pt = nil + m.pts.policy_table.app_policies[appId]["groups"] = { "Base-4", "Base-6" } + m.pts.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + m.pts.policy_table.module_config.preloaded_pt = nil end --[[@ptu: Perform Policy Table Update process @@ -106,7 +107,7 @@ local utils = { } :Do(function() test.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }) - utils.createJsonFileFromTable(utils.pts, ptu_file_name) + m.createJsonFileFromTable(m.pts, ptu_file_name) EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATING" }, { status = status }):Times(2) test.mobileSession1:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) :Do(function() @@ -128,7 +129,7 @@ local utils = { } --! @parameters: --! id - session number (1, 2 etc.) (mandatory) --]] - function utils.startSession(test, id) + function m.startSession(test, id) test["mobileSession"..id] = mobile_session.MobileSession(test, test.mobileConnection) test["mobileSession"..id]:StartService(7) end @@ -137,13 +138,13 @@ local utils = { } --! @parameters: --! id - application number (1, 2 etc.), equals to session number (mandatory) --]] - function utils.registerApp(test, id) + function m.registerApp(test, id) local RAIParams = config["application"..id].registerAppInterfaceParams local corId = test["mobileSession"..id]:SendRPC("RegisterAppInterface", RAIParams) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = RAIParams.appName } }) :Do(function(_, d) - utils.HMIAppIds[RAIParams.appID] = d.params.application.appID + m.HMIAppIds[RAIParams.appID] = d.params.application.appID end) test["mobileSession"..id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() @@ -163,9 +164,9 @@ local utils = { } --! updateFunc - function to update specific sections in PTU file --! that has to be passed as an input parameter --]] - function utils.activateApp(test, id, status, updateFunc) + function m.activateApp(test, id, status, updateFunc) local appId = config["application"..id].registerAppInterfaceParams.appID - local reqId = test.hmiConnection:SendRequest("SDL.ActivateApp", { appID = utils.HMIAppIds[appId] }) + local reqId = test.hmiConnection:SendRequest("SDL.ActivateApp", { appID = m.HMIAppIds[appId] }) EXPECT_HMIRESPONSE(reqId) :Do(function(_, d1) if d1.result.isSDLAllowed ~= true then @@ -174,7 +175,7 @@ local utils = { } EXPECT_HMIRESPONSE(reqId2) :Do(function() test.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - { allowed = true, source = "GUI", device = { id = config.deviceMAC, name = "127.0.0.1" } }) + { allowed = true, source = "GUI", device = { id = utils.getDeviceMAC(), name = utils.getDeviceName() } }) EXPECT_HMICALL("BasicCommunication.ActivateApp") :Do(function(_, d2) test.hmiConnection:SendResponse(d2.id,"BasicCommunication.ActivateApp", "SUCCESS", { }) @@ -187,12 +188,12 @@ local utils = { } EXPECT_HMICALL("BasicCommunication.PolicyUpdate") :Do(function(exp, d) if(exp.occurences == 1) then - utils.pts = utils.createTableFromJsonFile(d.params.file) + m.pts = m.createTableFromJsonFile(d.params.file) if status then test.hmiConnection:SendResponse(d.id, d.method, "SUCCESS", { }) updatePTU() if updateFunc then - updateFunc(utils.pts) + updateFunc(m.pts) end ptu(test, status) end @@ -207,20 +208,20 @@ local utils = { } --! updateFunc - function to update specific sections in PreloadedPT file --! that has to be passed as an input parameter --]] - function utils.updatePreloadedPT(updateFunc) + function m.updatePreloadedPT(updateFunc) local preloadedFile = commonPreconditions:GetPathToSDL() .. "sdl_preloaded_pt.json" - local preloadedTable = utils.createTableFromJsonFile(preloadedFile) + local preloadedTable = m.createTableFromJsonFile(preloadedFile) preloadedTable.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null if updateFunc then updateFunc(preloadedTable) end - utils.createJsonFileFromTable(preloadedTable, preloadedFile) + m.createJsonFileFromTable(preloadedTable, preloadedFile) end --[[@ignitionOff: Perform Igninition Off --! @parameters: NO --]] - function utils.ignitionOff(test) + function m.ignitionOff(test) if sdl:CheckStatusSDL() == sdl.RUNNING then test.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete") @@ -231,4 +232,4 @@ local utils = { } end end -return utils +return m diff --git a/user_modules/shared_testcases/testCasesForPolicyTable.lua b/user_modules/shared_testcases/testCasesForPolicyTable.lua index d963347be5..1d5c48822f 100644 --- a/user_modules/shared_testcases/testCasesForPolicyTable.lua +++ b/user_modules/shared_testcases/testCasesForPolicyTable.lua @@ -11,6 +11,7 @@ local commonPreconditions = require('user_modules/shared_testcases/commonPrecond local commonSteps = require('user_modules/shared_testcases/commonSteps') local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') local json = require('json') +local utils = require ('user_modules/utils') --Policy template local PolicyTableTemplate = "user_modules/shared_testcases/PolicyTables/DefaultPolicyTableWith_group1.json" @@ -897,7 +898,7 @@ end -- But this should be checked in appropriate scripts function testCasesForPolicyTable:flow_SUCCEESS_EXTERNAL_PROPRIETARY(self, app_id, device_id, hmi_app_id, ptu_file_path, ptu_file_name, ptu_file) if (app_id == nil) then app_id = config.application1.registerAppInterfaceParams.appID end - if (device_id == nil) then device_id = config.deviceMAC end + if (device_id == nil) then device_id = utils.getDeviceMAC() end if (hmi_app_id == nil) then hmi_app_id = self.applications[config.application1.registerAppInterfaceParams.appName] end if (ptu_file_path == nil) then ptu_file_path = "files/" end if (ptu_file_name == nil) then ptu_file_name = "PolicyTableUpdate" end @@ -966,7 +967,7 @@ function testCasesForPolicyTable:trigger_user_request_update_from_HMI(self) :Do(function(_,data) testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID }, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {hmi_app1_id}) local timeout_after_x_seconds = testCasesForPolicyTableSnapshot:get_data_from_PTS("module_config.timeout_after_x_seconds") @@ -1001,7 +1002,6 @@ function testCasesForPolicyTable:trigger_getting_device_consent(self, app_name, testCasesForPolicyTable.time_trigger = 0 testCasesForPolicyTable.time_onstatusupdate = 0 testCasesForPolicyTable.time_policyupdate = 0 - local ServerAddress = "127.0.0.1"--commonSteps:get_data_from_SDL_ini("ServerAddress") local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications[app_name]}) @@ -1015,14 +1015,14 @@ function testCasesForPolicyTable:trigger_getting_device_consent(self, app_name, testCasesForPolicyTable.time_trigger = timestamp() self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", - {allowed = true, source = "GUI", device = {id = device_ID, name = ServerAddress, isSDLAllowed = true}}) + {allowed = true, source = "GUI", device = {id = device_ID, name = utils.getDeviceName(), isSDLAllowed = true}}) end) EXPECT_HMICALL("BasicCommunication.PolicyUpdate", {file = "/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json"}) :Do(function(_,data) testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID }, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {hmi_app1_id}) local timeout_after_x_seconds = testCasesForPolicyTableSnapshot:get_data_from_PTS("module_config.timeout_after_x_seconds") @@ -1077,7 +1077,7 @@ function testCasesForPolicyTable:trigger_PTU_user_press_button_HMI(self, execute :Do(function(_,data) testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID }, - {config.deviceMAC}, + {utils.getDeviceMAC()}, {hmi_app1_id}) local timeout_after_x_seconds = testCasesForPolicyTableSnapshot:get_data_from_PTS("module_config.timeout_after_x_seconds") From e5b390252fb17ef1735bd1d661c30a7d82fc5b99 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 19 Mar 2018 01:47:59 +0200 Subject: [PATCH 333/681] Update Policy scripts regarding URL changes in PreloadedPT --- .../Policies/build_options/ptu_18269.json | 3 +- .../003_ATF_HP_User_Consent_Yes.lua | 2 +- .../004_ATF_HP_User_Consent_NO.lua | 2 +- ...Id_policies_And_RequestType_Validation.lua | 2 +- ...6_ATF_Steal_focus_validation_false_PTU.lua | 2 +- ...007_ATF_StealFocus_validation_true_PTU.lua | 2 +- ...f_Failed_Nickname_Validation_After_PTU.lua | 2 +- .../029_ATF_OnPermissionsChange_After_PTU.lua | 2 +- ...41_ATF_Got_PTU_from_mobile_application.lua | 7 +--- .../144_ATF_PTU_validation_failure.lua | 1 - ...able_Update_Trigger_After_N_Kilometers.lua | 2 +- ...licy_Table_Update_Trigger_After_N_Days.lua | 2 +- ...anager_Changes_Status_To_UPDATE_NEEDED.lua | 3 +- .../156_ATF_PTU_OnStatusUpdate_Trigger.lua | 2 +- ...ies_Manager_Changes_Status_To_UPDATING.lua | 2 +- ...F_Default_Policy_For_The_App_After_PTU.lua | 2 +- ...egister_NewApp_not_exist_inLocalPT_PTU.lua | 4 +- ...r_NewApp_not_exist_inLocalPT_FinishPTU.lua | 6 +-- ...t_exist_inLocalPT_start_PTU_for_NewApp.lua | 8 ++-- ...vi_App_Registration_And_No_Certificate.lua | 2 +- ...TF_PTU_request_after_N_ignition_cycles.lua | 2 +- ...6_ATF_OnPolicyUpdate_initiation_of_PTU.lua | 2 +- ...ATF_Get_Status_Update_Request_from_HMI.lua | 2 +- ...ation_rules_request_type_array_omitted.lua | 2 +- ...quest_type_array_has_one_invalid_value.lua | 2 +- ...pe_array_has_only_one_value_is_invalid.lua | 2 +- ...oaded_pt_parameter_trigger_in_local_pt.lua | 2 +- ...idation_rules_optional_parameters_type.lua | 2 +- ...idation_rules_required_parameters_type.lua | 2 +- ...ATF_pt_update_validation_rules_general.lua | 2 +- ...dation_rules_consumer_friendly_message.lua | 2 +- ..._Validate_default_hmi_default_policies.lua | 2 +- ...e_preconsented_groups_default_policies.lua | 2 +- ...2_ATF_Validate_groups_default_policies.lua | 2 +- ...TF_Validate_default_hmi_appId_policies.lua | 2 +- ...278_ATF_Validate_groups_appID_policies.lua | 2 +- ...PT_Exchanged_X_Days_After_Epoch_In_PTS.lua | 2 +- ...Store_pt_exchanged_at_odometer_x_in_PT.lua | 2 +- ...ATF_Validate_appHMIType_appID_policies.lua | 2 +- ...299_ATF_Memory_Kb_Constraints_Ignoring.lua | 2 +- ...s_update_app_registration_language_vui.lua | 2 +- ...HP_Validation_Count_Of_User_Selections.lua | 2 +- ...nt_of_run_attempts_while_revoked_in_PT.lua | 4 +- ..._Status_Appid_Gets_Null_In_Case_Of_PTU.lua | 2 +- ...MI_Status_Value_Of_AppId_In_PT_Is_Null.lua | 2 +- ...eivedPolicyUpdate_from_HMI_PROPRIETARY.lua | 10 ++++- ...nd_GetURLs_Request_fromHMI_PROPRIETARY.lua | 2 +- ...gh_The_URLs_During_Retry_Sequence_HTTP.lua | 13 ++++-- .../108_ATF_PTU_Trigger_days_PROPRIETARY.lua | 10 ++++- ...ATF_PTU_Trigger_kilometers_PROPRIETARY.lua | 2 +- ...temRequest_from_app_to_HMI_PROPRIETARY.lua | 10 ++++- ..._exist_inLocalPT_FinishPTU_PROPRIETARY.lua | 13 +++++- ...calPT_start_PTU_for_NewApp_PROPRIETARY.lua | 14 +++++-- ..._ATF_HP_Device_Data_Section_Validation.lua | 40 +++++++++++++------ .../189_ATF_isAppPermissionsRevoked_true.lua | 4 +- ...9_ATF_appPermissionsConsentNeeded_true.lua | 2 +- ...TF_User_consent_initing_after_PTU_FULL.lua | 2 +- ...User_consent_initing_after_PTU_LIMITED.lua | 2 +- .../214_ATF_User_consent_prompt_persists.lua | 2 +- .../shared_testcases/commonFunctions.lua | 16 ++++++++ .../testCasesForPolicyAppIdManagament.lua | 12 +----- .../testCasesForPolicyTable.lua | 4 +- ...cies_External_Consent_common_functions.lua | 2 +- 63 files changed, 164 insertions(+), 106 deletions(-) diff --git a/files/jsons/Policies/build_options/ptu_18269.json b/files/jsons/Policies/build_options/ptu_18269.json index 297744e375..5bfb400162 100644 --- a/files/jsons/Policies/build_options/ptu_18269.json +++ b/files/jsons/Policies/build_options/ptu_18269.json @@ -1239,8 +1239,7 @@ "0000001": [ "http://policies.domain1.ford.com/api/policies", "http://policies.domain2.ford.com/api/policies", - "http://policies.domain3.ford.com/api/policies", - "http://policies.domain4.ford.com/api/policies" + "http://policies.domain3.ford.com/api/policies" ] }, "lock_screen_icon_url": { diff --git a/test_scripts/Policies/App_Permissions/003_ATF_HP_User_Consent_Yes.lua b/test_scripts/Policies/App_Permissions/003_ATF_HP_User_Consent_Yes.lua index 5d580e18e5..3fa5923832 100644 --- a/test_scripts/Policies/App_Permissions/003_ATF_HP_User_Consent_Yes.lua +++ b/test_scripts/Policies/App_Permissions/003_ATF_HP_User_Consent_Yes.lua @@ -169,7 +169,7 @@ end function Test:Precondition_UpdatePolicyWithPTU() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { diff --git a/test_scripts/Policies/App_Permissions/004_ATF_HP_User_Consent_NO.lua b/test_scripts/Policies/App_Permissions/004_ATF_HP_User_Consent_NO.lua index fa0f3d3e8b..19e34c905c 100644 --- a/test_scripts/Policies/App_Permissions/004_ATF_HP_User_Consent_NO.lua +++ b/test_scripts/Policies/App_Permissions/004_ATF_HP_User_Consent_NO.lua @@ -143,7 +143,7 @@ end function Test:Precondition_UpdatePolicyWithPTU() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { diff --git a/test_scripts/Policies/App_Permissions/005_ATF_DISALLOWED_app_Id_policies_And_RequestType_Validation.lua b/test_scripts/Policies/App_Permissions/005_ATF_DISALLOWED_app_Id_policies_And_RequestType_Validation.lua index d2e9ae04a4..9447bd7ed8 100644 --- a/test_scripts/Policies/App_Permissions/005_ATF_DISALLOWED_app_Id_policies_And_RequestType_Validation.lua +++ b/test_scripts/Policies/App_Permissions/005_ATF_DISALLOWED_app_Id_policies_And_RequestType_Validation.lua @@ -128,7 +128,7 @@ end function Test:Preconditions_Update_Policy_With_RequestType_PROPRIETARY_For_Current_App() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { diff --git a/test_scripts/Policies/App_Permissions/006_ATF_Steal_focus_validation_false_PTU.lua b/test_scripts/Policies/App_Permissions/006_ATF_Steal_focus_validation_false_PTU.lua index 02c69778dd..ebd40e44e3 100644 --- a/test_scripts/Policies/App_Permissions/006_ATF_Steal_focus_validation_false_PTU.lua +++ b/test_scripts/Policies/App_Permissions/006_ATF_Steal_focus_validation_false_PTU.lua @@ -88,7 +88,7 @@ end function Test:Preconditions_Update_Policy_With_Steal_Focus_FalseValue_for_Current_App() EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATING" }, { status = "UP_TO_DATE" }):Times(2) local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { diff --git a/test_scripts/Policies/App_Permissions/007_ATF_StealFocus_validation_true_PTU.lua b/test_scripts/Policies/App_Permissions/007_ATF_StealFocus_validation_true_PTU.lua index dfb9da6d3c..42929dfb84 100644 --- a/test_scripts/Policies/App_Permissions/007_ATF_StealFocus_validation_true_PTU.lua +++ b/test_scripts/Policies/App_Permissions/007_ATF_StealFocus_validation_true_PTU.lua @@ -95,7 +95,7 @@ function Test:Preconditions_Update_Policy_With_Steal_Focus_FalseValue_for_Curren .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATING" }, { status = "UP_TO_DATE" }):Times(2) local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", diff --git a/test_scripts/Policies/App_Permissions/024_ATF_APP_UNAUTHORIZED_If_Failed_Nickname_Validation_After_PTU.lua b/test_scripts/Policies/App_Permissions/024_ATF_APP_UNAUTHORIZED_If_Failed_Nickname_Validation_After_PTU.lua index 1029fb2743..989c480755 100644 --- a/test_scripts/Policies/App_Permissions/024_ATF_APP_UNAUTHORIZED_If_Failed_Nickname_Validation_After_PTU.lua +++ b/test_scripts/Policies/App_Permissions/024_ATF_APP_UNAUTHORIZED_If_Failed_Nickname_Validation_After_PTU.lua @@ -172,7 +172,7 @@ function Test:TestStep_Update_PT_With_Another_NickName_For_Current_App_And_Check EXPECT_HMICALL("BasicCommunication.PolicyUpdate") :Do(function(_,_) local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest",{requestType = "PROPRIETARY", fileName = "filename"}) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) diff --git a/test_scripts/Policies/App_Permissions/029_ATF_OnPermissionsChange_After_PTU.lua b/test_scripts/Policies/App_Permissions/029_ATF_OnPermissionsChange_After_PTU.lua index 63620cb798..87131ee106 100644 --- a/test_scripts/Policies/App_Permissions/029_ATF_OnPermissionsChange_After_PTU.lua +++ b/test_scripts/Policies/App_Permissions/029_ATF_OnPermissionsChange_After_PTU.lua @@ -66,7 +66,7 @@ end function Test:TestStep_Update_Policy_With_New_Permissions_And_Check_Them_In_OnPermissionsChange() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { diff --git a/test_scripts/Policies/Policy_Table_Update/141_ATF_Got_PTU_from_mobile_application.lua b/test_scripts/Policies/Policy_Table_Update/141_ATF_Got_PTU_from_mobile_application.lua index 1ff4926e20..55064a78d9 100644 --- a/test_scripts/Policies/Policy_Table_Update/141_ATF_Got_PTU_from_mobile_application.lua +++ b/test_scripts/Policies/Policy_Table_Update/141_ATF_Got_PTU_from_mobile_application.lua @@ -70,13 +70,8 @@ function Test:TestStep_Sending_PTS_to_mobile_application() local RequestId_GetUrls = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) EXPECT_HMIRESPONSE(RequestId_GetUrls,{result = {code = 0, method = "SDL.GetURLS", urls = endpoints} } ) :Do(function(_,_) - if(#endpoints == 0) then - endpoints[1]={} - endpoints[1].url = "http://policies.telematics.ford.com/api/policies" - end - self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest",{ fileName = "PolicyTableUpdate", requestType = "PROPRIETARY", url = endpoints[1].url}) - EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY", fileType = "JSON", url = endpoints[1].url }) + EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY", fileType = "JSON" }) :Do(function(_,_) local CorIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", {requestType = "PROPRIETARY", fileName = "PolicyTableUpdate"}, "files/ptu.json") diff --git a/test_scripts/Policies/Policy_Table_Update/144_ATF_PTU_validation_failure.lua b/test_scripts/Policies/Policy_Table_Update/144_ATF_PTU_validation_failure.lua index 17b46d6f28..74272af529 100644 --- a/test_scripts/Policies/Policy_Table_Update/144_ATF_PTU_validation_failure.lua +++ b/test_scripts/Policies/Policy_Table_Update/144_ATF_PTU_validation_failure.lua @@ -76,7 +76,6 @@ function Test:TestStep_PTU_validation_failure() local RequestId_GetUrls = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) EXPECT_HMIRESPONSE(RequestId_GetUrls,{result = {code = 0, method = "SDL.GetURLS", urls = endpoints} } ) :Do(function(_,_) - if(#endpoints == 0) then endpoints[1].url = "http://policies.telematics.ford.com/api/policies" end self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest",{ fileName = "PolicyTableUpdate", requestType = "PROPRIETARY", url = endpoints[1].url}) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY", fileType = "JSON", url = endpoints[1].url }) :Do(function(_,_) diff --git a/test_scripts/Policies/Policy_Table_Update/147_ATF_Policy_Table_Update_Trigger_After_N_Kilometers.lua b/test_scripts/Policies/Policy_Table_Update/147_ATF_Policy_Table_Update_Trigger_After_N_Kilometers.lua index 47f99c7d56..631734072e 100644 --- a/test_scripts/Policies/Policy_Table_Update/147_ATF_Policy_Table_Update_Trigger_After_N_Kilometers.lua +++ b/test_scripts/Policies/Policy_Table_Update/147_ATF_Policy_Table_Update_Trigger_After_N_Kilometers.lua @@ -107,7 +107,7 @@ end function Test:Precondition_Update_Policy_With_New_Exchange_After_X_Kilometers_Value() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { diff --git a/test_scripts/Policies/Policy_Table_Update/149_ATF_Policy_Table_Update_Trigger_After_N_Days.lua b/test_scripts/Policies/Policy_Table_Update/149_ATF_Policy_Table_Update_Trigger_After_N_Days.lua index 972e661235..23665228ce 100644 --- a/test_scripts/Policies/Policy_Table_Update/149_ATF_Policy_Table_Update_Trigger_After_N_Days.lua +++ b/test_scripts/Policies/Policy_Table_Update/149_ATF_Policy_Table_Update_Trigger_After_N_Days.lua @@ -90,7 +90,7 @@ end function Test:Precondition_Update_Policy_With_Exchange_After_X_Days_Value() currentSystemDaysAfterEpoch = getSystemDaysAfterEpoch() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest",{requestType = "PROPRIETARY", fileName = "filename"}) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) diff --git a/test_scripts/Policies/Policy_Table_Update/155_ATF_PTU_Policies_Manager_Changes_Status_To_UPDATE_NEEDED.lua b/test_scripts/Policies/Policy_Table_Update/155_ATF_PTU_Policies_Manager_Changes_Status_To_UPDATE_NEEDED.lua index 76543f6dd7..e66d844af7 100644 --- a/test_scripts/Policies/Policy_Table_Update/155_ATF_PTU_Policies_Manager_Changes_Status_To_UPDATE_NEEDED.lua +++ b/test_scripts/Policies/Policy_Table_Update/155_ATF_PTU_Policies_Manager_Changes_Status_To_UPDATE_NEEDED.lua @@ -53,7 +53,6 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_ChangeStatus_Update_Needed() local time_update_needed = {} local time_system_request = {} - local endpoints = { { url = "http://policies.telematics.ford.com/api/policies" } } local is_test_fail = false local timeout_pts = testCasesForPolicyTableSnapshot:get_data_from_PTS("module_config.timeout_after_x_seconds") local seconds_between_retries = {} @@ -79,7 +78,7 @@ function Test:TestStep_ChangeStatus_Update_Needed() end local RequestId_GetUrls = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestId_GetUrls,{result = {code = 0, method = "SDL.GetURLS", urls = endpoints} } ) + EXPECT_HMIRESPONSE(RequestId_GetUrls) :Do(function(_,_) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest",{ requestType = "PROPRIETARY", fileName = "PolicyTableUpdate" }) diff --git a/test_scripts/Policies/Policy_Table_Update/156_ATF_PTU_OnStatusUpdate_Trigger.lua b/test_scripts/Policies/Policy_Table_Update/156_ATF_PTU_OnStatusUpdate_Trigger.lua index 7a5d774b04..6cce6f8c79 100644 --- a/test_scripts/Policies/Policy_Table_Update/156_ATF_PTU_OnStatusUpdate_Trigger.lua +++ b/test_scripts/Policies/Policy_Table_Update/156_ATF_PTU_OnStatusUpdate_Trigger.lua @@ -78,7 +78,7 @@ end function Test:TestStep_PTU_Success() local RequestId_GetUrls = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestId_GetUrls,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}} }} ) + EXPECT_HMIRESPONSE(RequestId_GetUrls) :Do(function(_,_) EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATING"}, {status = "UP_TO_DATE"}):Times(2) diff --git a/test_scripts/Policies/Policy_Table_Update/157_ATF_PTU_Policies_Manager_Changes_Status_To_UPDATING.lua b/test_scripts/Policies/Policy_Table_Update/157_ATF_PTU_Policies_Manager_Changes_Status_To_UPDATING.lua index f41cfdfd21..c05b90920c 100644 --- a/test_scripts/Policies/Policy_Table_Update/157_ATF_PTU_Policies_Manager_Changes_Status_To_UPDATING.lua +++ b/test_scripts/Policies/Policy_Table_Update/157_ATF_PTU_Policies_Manager_Changes_Status_To_UPDATING.lua @@ -43,7 +43,7 @@ function Test:TestStep_CheckMessagesSequence() local is_test_fail = false local message_number = 1 local RequestId_GetUrls = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestId_GetUrls,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}} }} ) + EXPECT_HMIRESPONSE(RequestId_GetUrls) :Do(function(_,_) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = "PolicyTableUpdate"}) diff --git a/test_scripts/Policies/Policy_Table_Update/160_ATF_Default_Policy_For_The_App_After_PTU.lua b/test_scripts/Policies/Policy_Table_Update/160_ATF_Default_Policy_For_The_App_After_PTU.lua index 64ae56ecee..fed15386cc 100644 --- a/test_scripts/Policies/Policy_Table_Update/160_ATF_Default_Policy_For_The_App_After_PTU.lua +++ b/test_scripts/Policies/Policy_Table_Update/160_ATF_Default_Policy_For_The_App_After_PTU.lua @@ -113,7 +113,7 @@ end function Test:TestStep_Update_Policy_With_New_Permission_In_Default_Section() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = "filename"}) diff --git a/test_scripts/Policies/Policy_Table_Update/163_P_ATF_Register_NewApp_not_exist_inLocalPT_PTU.lua b/test_scripts/Policies/Policy_Table_Update/163_P_ATF_Register_NewApp_not_exist_inLocalPT_PTU.lua index 7cc8c0e4fb..0eb61055f4 100644 --- a/test_scripts/Policies/Policy_Table_Update/163_P_ATF_Register_NewApp_not_exist_inLocalPT_PTU.lua +++ b/test_scripts/Policies/Policy_Table_Update/163_P_ATF_Register_NewApp_not_exist_inLocalPT_PTU.lua @@ -67,10 +67,10 @@ function Test:Precondition_PolicyUpdateStarted() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) EXPECT_HMIRESPONSE(RequestIdGetURLS) - :Do(function(_,_) + :Do(function(_, data) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest",{ requestType = "PROPRIETARY", - url = "http://policies.telematics.ford.com/api/policies", + url = data.result.urls[1].url, appID = self.applications [config.application1.registerAppInterfaceParams.appName], fileName = "sdl_snapshot.json" }) diff --git a/test_scripts/Policies/Policy_Table_Update/164_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU.lua b/test_scripts/Policies/Policy_Table_Update/164_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU.lua index c5ae25db58..c9b7510c82 100644 --- a/test_scripts/Policies/Policy_Table_Update/164_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU.lua +++ b/test_scripts/Policies/Policy_Table_Update/164_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU.lua @@ -70,12 +70,12 @@ end function Test:Precondition_PolicyUpdateStarted() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) - :Do(function(_,_) + EXPECT_HMIRESPONSE(RequestIdGetURLS) + :Do(function(_, data) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", - url = "http://policies.telematics.ford.com/api/policies", + url = data.result.urls[1].url, appID = self.applications [config.application1.registerAppInterfaceParams.appName], fileName = "sdl_snapshot.json" }) diff --git a/test_scripts/Policies/Policy_Table_Update/165_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp.lua b/test_scripts/Policies/Policy_Table_Update/165_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp.lua index d923e9b6e0..467e554e99 100644 --- a/test_scripts/Policies/Policy_Table_Update/165_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp.lua +++ b/test_scripts/Policies/Policy_Table_Update/165_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp.lua @@ -72,12 +72,12 @@ end function Test:Precondition_PolicyUpdateStarted() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) - :Do(function(_,_) + EXPECT_HMIRESPONSE(RequestIdGetURLS) + :Do(function(_, data) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", - url = "http://policies.telematics.ford.com/api/policies", + url = data.result.urls[1].url, appID = self.applications [config.application1.registerAppInterfaceParams.appName], fileName = "sdl_snapshot.json" }) @@ -167,7 +167,7 @@ end function Test:TestStep_Start_New_PolicyUpdate_For_SecondApplication() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATING"}, {status = "UP_TO_DATE"}):Times(2) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { diff --git a/test_scripts/Policies/Policy_Table_Update/170_ATF_PTU_Trigger_On_Navi_App_Registration_And_No_Certificate.lua b/test_scripts/Policies/Policy_Table_Update/170_ATF_PTU_Trigger_On_Navi_App_Registration_And_No_Certificate.lua index 21ac723089..214008a9dc 100644 --- a/test_scripts/Policies/Policy_Table_Update/170_ATF_PTU_Trigger_On_Navi_App_Registration_And_No_Certificate.lua +++ b/test_scripts/Policies/Policy_Table_Update/170_ATF_PTU_Trigger_On_Navi_App_Registration_And_No_Certificate.lua @@ -56,7 +56,7 @@ end function Test:Precondition_UpdatePolicyWithPTU() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest",{requestType = "PROPRIETARY", fileName = "filename"}) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) diff --git a/test_scripts/Policies/Policy_Table_Update/172_ATF_PTU_request_after_N_ignition_cycles.lua b/test_scripts/Policies/Policy_Table_Update/172_ATF_PTU_request_after_N_ignition_cycles.lua index bbdb9fd533..0feb36d21a 100644 --- a/test_scripts/Policies/Policy_Table_Update/172_ATF_PTU_request_after_N_ignition_cycles.lua +++ b/test_scripts/Policies/Policy_Table_Update/172_ATF_PTU_request_after_N_ignition_cycles.lua @@ -61,7 +61,7 @@ function Test:Precondition_Activate_App_Consent_Device_And_Update_Policy() EXPECT_HMICALL("BasicCommunication.PolicyUpdate") :Do(function(_,_) local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest",{requestType = "PROPRIETARY", fileName = "filename"}) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) diff --git a/test_scripts/Policies/Related_HMI_API/186_ATF_OnPolicyUpdate_initiation_of_PTU.lua b/test_scripts/Policies/Related_HMI_API/186_ATF_OnPolicyUpdate_initiation_of_PTU.lua index a51a373ae1..d6a96bc371 100644 --- a/test_scripts/Policies/Related_HMI_API/186_ATF_OnPolicyUpdate_initiation_of_PTU.lua +++ b/test_scripts/Policies/Related_HMI_API/186_ATF_OnPolicyUpdate_initiation_of_PTU.lua @@ -94,7 +94,7 @@ function Test:Precondtion_Activate_App_Consent_Update() EXPECT_HMICALL("BasicCommunication.PolicyUpdate") :Do(function(_,_) local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest",{requestType = "PROPRIETARY", fileName = "filename"}) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) diff --git a/test_scripts/Policies/Related_HMI_API/187_ATF_Get_Status_Update_Request_from_HMI.lua b/test_scripts/Policies/Related_HMI_API/187_ATF_Get_Status_Update_Request_from_HMI.lua index 7b25d3ee18..5e68eb40df 100644 --- a/test_scripts/Policies/Related_HMI_API/187_ATF_Get_Status_Update_Request_from_HMI.lua +++ b/test_scripts/Policies/Related_HMI_API/187_ATF_Get_Status_Update_Request_from_HMI.lua @@ -68,7 +68,7 @@ function Test:Test_2_UPDATING() local policy_file_name = "PolicyTableUpdate" local ptu_file = "files/ptu_general.json" local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(requestId, { result = { code = 0, method = "SDL.GetURLS", urls = {{ url = "http://policies.telematics.ford.com/api/policies" }}}}) + EXPECT_HMIRESPONSE(requestId) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", {requestType = "PROPRIETARY", fileName = policy_file_name}) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) :Do(function() diff --git a/test_scripts/Policies/Validation_of_PolicyTables/224_ATF_pt_update_validation_rules_request_type_array_omitted.lua b/test_scripts/Policies/Validation_of_PolicyTables/224_ATF_pt_update_validation_rules_request_type_array_omitted.lua index f4032796ce..bbfaf550d1 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/224_ATF_pt_update_validation_rules_request_type_array_omitted.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/224_ATF_pt_update_validation_rules_request_type_array_omitted.lua @@ -193,7 +193,7 @@ function Test:updatePolicyInDifferentSessions(PTName, appName, mobileSession) local iappID = self.applications[appName] local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,_) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { diff --git a/test_scripts/Policies/Validation_of_PolicyTables/225_ATF_pt_update_validation_rules_request_type_array_has_one_invalid_value.lua b/test_scripts/Policies/Validation_of_PolicyTables/225_ATF_pt_update_validation_rules_request_type_array_has_one_invalid_value.lua index 55aec7e3e3..e43a3265cc 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/225_ATF_pt_update_validation_rules_request_type_array_has_one_invalid_value.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/225_ATF_pt_update_validation_rules_request_type_array_has_one_invalid_value.lua @@ -132,7 +132,7 @@ function Test:updatePolicyInDifferentSessions(PTName, appName, mobileSession) local iappID = self.applications[appName] local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,_) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { diff --git a/test_scripts/Policies/Validation_of_PolicyTables/226_ATF_pt_update_validation_rules_request_type_array_has_only_one_value_is_invalid.lua b/test_scripts/Policies/Validation_of_PolicyTables/226_ATF_pt_update_validation_rules_request_type_array_has_only_one_value_is_invalid.lua index ec867a8950..079c92b9b9 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/226_ATF_pt_update_validation_rules_request_type_array_has_only_one_value_is_invalid.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/226_ATF_pt_update_validation_rules_request_type_array_has_only_one_value_is_invalid.lua @@ -175,7 +175,7 @@ function Test:updatePolicyInDifferentSessions(PTName, appName, mobileSession) local iappID = self.applications[appName] local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,_) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { diff --git a/test_scripts/Policies/Validation_of_PolicyTables/245_ATF_preloaded_pt_parameter_trigger_in_local_pt.lua b/test_scripts/Policies/Validation_of_PolicyTables/245_ATF_preloaded_pt_parameter_trigger_in_local_pt.lua index 753b873508..25ad67fee9 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/245_ATF_preloaded_pt_parameter_trigger_in_local_pt.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/245_ATF_preloaded_pt_parameter_trigger_in_local_pt.lua @@ -139,7 +139,7 @@ function Test:updatePolicyTable(pathToPolicyFile) local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(requestId, {result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(requestId) :Do(function(_, _) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { diff --git a/test_scripts/Policies/Validation_of_PolicyTables/266_ATF_pt_update_validation_rules_optional_parameters_type.lua b/test_scripts/Policies/Validation_of_PolicyTables/266_ATF_pt_update_validation_rules_optional_parameters_type.lua index 4782e5de8e..076412dc57 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/266_ATF_pt_update_validation_rules_optional_parameters_type.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/266_ATF_pt_update_validation_rules_optional_parameters_type.lua @@ -68,7 +68,7 @@ function Test:updatePolicyInDifferentSessions(_, appName, mobileSession) local iappID = self.applications[appName] local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,_) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = "PolicyTableUpdate"} ) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/267_ATF_pt_update_validation_rules_required_parameters_type.lua b/test_scripts/Policies/Validation_of_PolicyTables/267_ATF_pt_update_validation_rules_required_parameters_type.lua index d20c39fe7b..6d6309e15d 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/267_ATF_pt_update_validation_rules_required_parameters_type.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/267_ATF_pt_update_validation_rules_required_parameters_type.lua @@ -155,7 +155,7 @@ function Test:updatePolicyInDifferentSessions(_, appName, mobileSession) local iappID = self.applications[appName] local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,_) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = "PolicyTableUpdate"} ) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/268_ATF_pt_update_validation_rules_general.lua b/test_scripts/Policies/Validation_of_PolicyTables/268_ATF_pt_update_validation_rules_general.lua index dee8cc4cbb..23859e4e0c 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/268_ATF_pt_update_validation_rules_general.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/268_ATF_pt_update_validation_rules_general.lua @@ -43,7 +43,7 @@ local ptuAppRegistered = "files/ptu_app.json" function Test:updatePolicyInDifferentSessions(_, appName, mobileSession) local iappID = self.applications[appName] local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,_) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = "PolicyTableUpdate"} ) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/269_ATF_pt_update_validation_rules_consumer_friendly_message.lua b/test_scripts/Policies/Validation_of_PolicyTables/269_ATF_pt_update_validation_rules_consumer_friendly_message.lua index d4455aa92a..bd6a6f0464 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/269_ATF_pt_update_validation_rules_consumer_friendly_message.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/269_ATF_pt_update_validation_rules_consumer_friendly_message.lua @@ -172,7 +172,7 @@ function Test:updatePolicyInDifferentSessions(PTName, appName, mobileSession) local iappID = self.applications[appName] local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,_) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = "PolicyTableUpdate"} ) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/270_ATF_Validate_default_hmi_default_policies.lua b/test_scripts/Policies/Validation_of_PolicyTables/270_ATF_Validate_default_hmi_default_policies.lua index ca54c264df..c2974e33ab 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/270_ATF_Validate_default_hmi_default_policies.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/270_ATF_Validate_default_hmi_default_policies.lua @@ -58,7 +58,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_Validate_default_hmi_in_default_upon_PTU() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,data) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = "filename" } ) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/271_ATF_Validate_preconsented_groups_default_policies.lua b/test_scripts/Policies/Validation_of_PolicyTables/271_ATF_Validate_preconsented_groups_default_policies.lua index 068fba1d5f..41f98150b0 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/271_ATF_Validate_preconsented_groups_default_policies.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/271_ATF_Validate_preconsented_groups_default_policies.lua @@ -57,7 +57,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_Validate_preconsented_groups_in_default_upon_PTU() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,data) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { diff --git a/test_scripts/Policies/Validation_of_PolicyTables/272_ATF_Validate_groups_default_policies.lua b/test_scripts/Policies/Validation_of_PolicyTables/272_ATF_Validate_groups_default_policies.lua index c4aa108680..7e815fd160 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/272_ATF_Validate_groups_default_policies.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/272_ATF_Validate_groups_default_policies.lua @@ -56,7 +56,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_Validate_groups_in_default_upon_PTU() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,data) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { diff --git a/test_scripts/Policies/Validation_of_PolicyTables/273_ATF_Validate_default_hmi_appId_policies.lua b/test_scripts/Policies/Validation_of_PolicyTables/273_ATF_Validate_default_hmi_appId_policies.lua index 0e98440c84..031863a33b 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/273_ATF_Validate_default_hmi_appId_policies.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/273_ATF_Validate_default_hmi_appId_policies.lua @@ -79,7 +79,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_Validate_default_hmi_upon_PTU() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,data) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { diff --git a/test_scripts/Policies/Validation_of_PolicyTables/278_ATF_Validate_groups_appID_policies.lua b/test_scripts/Policies/Validation_of_PolicyTables/278_ATF_Validate_groups_appID_policies.lua index 552358c07b..feaf9c59f0 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/278_ATF_Validate_groups_appID_policies.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/278_ATF_Validate_groups_appID_policies.lua @@ -77,7 +77,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_Validate_groups_from_appId_upon_PTU() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,data) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { diff --git a/test_scripts/Policies/Validation_of_PolicyTables/282_ATF_PT_Exchanged_X_Days_After_Epoch_In_PTS.lua b/test_scripts/Policies/Validation_of_PolicyTables/282_ATF_PT_Exchanged_X_Days_After_Epoch_In_PTS.lua index 5e41cabfea..edb27420f7 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/282_ATF_PT_Exchanged_X_Days_After_Epoch_In_PTS.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/282_ATF_PT_Exchanged_X_Days_After_Epoch_In_PTS.lua @@ -79,7 +79,7 @@ function Test:Precondition_Activate_App_Consent_Device_And_Update_Policy() days_after_epoch_prev = getDaysAfterEpochFromPTS(pathToSnapshot) local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest",{requestType = "PROPRIETARY", fileName = "filename"}) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/283_ATF_Store_pt_exchanged_at_odometer_x_in_PT.lua b/test_scripts/Policies/Validation_of_PolicyTables/283_ATF_Store_pt_exchanged_at_odometer_x_in_PT.lua index f676583ff2..5f22a64e6a 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/283_ATF_Store_pt_exchanged_at_odometer_x_in_PT.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/283_ATF_Store_pt_exchanged_at_odometer_x_in_PT.lua @@ -60,7 +60,7 @@ end function Test:Precondition_PolicyUpdateRAI() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = "filename"}) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/287_ATF_Validate_appHMIType_appID_policies.lua b/test_scripts/Policies/Validation_of_PolicyTables/287_ATF_Validate_appHMIType_appID_policies.lua index 8aa5099f10..e2092b6634 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/287_ATF_Validate_appHMIType_appID_policies.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/287_ATF_Validate_appHMIType_appID_policies.lua @@ -78,7 +78,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_Validate_appHMIType_from_appId_upon_PTU() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,data) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { diff --git a/test_scripts/Policies/Validation_of_PolicyTables/299_ATF_Memory_Kb_Constraints_Ignoring.lua b/test_scripts/Policies/Validation_of_PolicyTables/299_ATF_Memory_Kb_Constraints_Ignoring.lua index 6aa3b91790..908988aca5 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/299_ATF_Memory_Kb_Constraints_Ignoring.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/299_ATF_Memory_Kb_Constraints_Ignoring.lua @@ -74,7 +74,7 @@ end function Test:Precondition_Update_Policy_With_memory_kb_Param() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest",{requestType = "PROPRIETARY", fileName = "filename"}) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/301_ATF_usage_and_error_counts_update_app_registration_language_vui.lua b/test_scripts/Policies/Validation_of_PolicyTables/301_ATF_usage_and_error_counts_update_app_registration_language_vui.lua index 45e06d4023..08efda3fd1 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/301_ATF_usage_and_error_counts_update_app_registration_language_vui.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/301_ATF_usage_and_error_counts_update_app_registration_language_vui.lua @@ -280,7 +280,7 @@ function Test:updatePolicyInDifferentSessions(PTName, appName, mobileSession) local iappID = self.applications[appName] local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,_) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = "PolicyTableUpdate"} ) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/304_ATF_HP_Validation_Count_Of_User_Selections.lua b/test_scripts/Policies/Validation_of_PolicyTables/304_ATF_HP_Validation_Count_Of_User_Selections.lua index 1b73cd8b72..760f98686d 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/304_ATF_HP_Validation_Count_Of_User_Selections.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/304_ATF_HP_Validation_Count_Of_User_Selections.lua @@ -38,7 +38,7 @@ commonSteps:DeletePolicyTable() --[[ Local Variables ]] local appID = config.application1.registerAppInterfaceParams["appID"] -local countAppActivation +local countAppActivation = 0 --[[ Preconditions ]] function Test:Precondition_Activate_App_Consent_Device() diff --git a/test_scripts/Policies/Validation_of_PolicyTables/306_ATF_Update_count_of_run_attempts_while_revoked_in_PT.lua b/test_scripts/Policies/Validation_of_PolicyTables/306_ATF_Update_count_of_run_attempts_while_revoked_in_PT.lua index 16208cb518..d875138de4 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/306_ATF_Update_count_of_run_attempts_while_revoked_in_PT.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/306_ATF_Update_count_of_run_attempts_while_revoked_in_PT.lua @@ -80,7 +80,7 @@ function Test:TestStep_PTU_appPermissionsConsentNeeded_true() end end) local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,_) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = "filename"}) @@ -126,7 +126,7 @@ function Test:Precondition_PTU_revoke_app() end) HMIAppID = self.applications[config.application1.registerAppInterfaceParams.appName] local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = "filename"}) diff --git a/test_scripts/Policies/appID_Management/043_ATF_HMI_Status_Appid_Gets_Null_In_Case_Of_PTU.lua b/test_scripts/Policies/appID_Management/043_ATF_HMI_Status_Appid_Gets_Null_In_Case_Of_PTU.lua index 94ab4bf7f9..b84f69bdeb 100644 --- a/test_scripts/Policies/appID_Management/043_ATF_HMI_Status_Appid_Gets_Null_In_Case_Of_PTU.lua +++ b/test_scripts/Policies/appID_Management/043_ATF_HMI_Status_Appid_Gets_Null_In_Case_Of_PTU.lua @@ -86,7 +86,7 @@ function Test:TestStep_UpdatePolicy() EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATING" }, { status = "UP_TO_DATE" }):Times(2) local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(requestId, {result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(requestId) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }) diff --git a/test_scripts/Policies/appID_Management/044_ATF_HMI_Status_Value_Of_AppId_In_PT_Is_Null.lua b/test_scripts/Policies/appID_Management/044_ATF_HMI_Status_Value_Of_AppId_In_PT_Is_Null.lua index 97b681e125..b0b32d4658 100644 --- a/test_scripts/Policies/appID_Management/044_ATF_HMI_Status_Value_Of_AppId_In_PT_Is_Null.lua +++ b/test_scripts/Policies/appID_Management/044_ATF_HMI_Status_Value_Of_AppId_In_PT_Is_Null.lua @@ -84,7 +84,7 @@ function Test:Precondition_UpdatePolicy() EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATING" }, { status = "UP_TO_DATE" }):Times(2) local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(requestId, {result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(requestId) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }) diff --git a/test_scripts/Policies/build_options/088_ATF_Apply_UpdatedPT_after_OnReceivedPolicyUpdate_from_HMI_PROPRIETARY.lua b/test_scripts/Policies/build_options/088_ATF_Apply_UpdatedPT_after_OnReceivedPolicyUpdate_from_HMI_PROPRIETARY.lua index 3f6339d7df..b22f3d6260 100644 --- a/test_scripts/Policies/build_options/088_ATF_Apply_UpdatedPT_after_OnReceivedPolicyUpdate_from_HMI_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/088_ATF_Apply_UpdatedPT_after_OnReceivedPolicyUpdate_from_HMI_PROPRIETARY.lua @@ -65,7 +65,15 @@ function Test:TestStep_Update_Policy() local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS, { + result = { + code = 0, + method = "SDL.GetURLS", + urls = { + { url = commonFunctions.getURLs("0x07")[1] } + } + } + }) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", {requestType = "PROPRIETARY", fileName = policy_file_path .. "sdl_snapshot.json"}) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) diff --git a/test_scripts/Policies/build_options/089_ATF_Check_SDL_respond_GetURLs_Request_fromHMI_PROPRIETARY.lua b/test_scripts/Policies/build_options/089_ATF_Check_SDL_respond_GetURLs_Request_fromHMI_PROPRIETARY.lua index 862a1c55c8..5149ec6136 100644 --- a/test_scripts/Policies/build_options/089_ATF_Check_SDL_respond_GetURLs_Request_fromHMI_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/089_ATF_Check_SDL_respond_GetURLs_Request_fromHMI_PROPRIETARY.lua @@ -71,7 +71,7 @@ function Test:RegisterApp() local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) EXPECT_HMIRESPONSE(requestId) :ValidIf(function(_, d) - local r_expected = "http://policies.telematics.ford.com/api/policies" + local r_expected = commonFunctions.getURLs("0x07")[1] local r_actual = d.result.urls[1].url if r_expected ~= r_actual then local msg = table.concat({"\nExpected: ", r_expected, "\nActual: ", tostring(r_actual)}) diff --git a/test_scripts/Policies/build_options/097_ATF_PTU_Cycleing_Through_The_URLs_During_Retry_Sequence_HTTP.lua b/test_scripts/Policies/build_options/097_ATF_PTU_Cycleing_Through_The_URLs_During_Retry_Sequence_HTTP.lua index d3aaa80412..0ac042164e 100644 --- a/test_scripts/Policies/build_options/097_ATF_PTU_Cycleing_Through_The_URLs_During_Retry_Sequence_HTTP.lua +++ b/test_scripts/Policies/build_options/097_ATF_PTU_Cycleing_Through_The_URLs_During_Retry_Sequence_HTTP.lua @@ -28,11 +28,11 @@ local ptu_file = "files/jsons/Policies/build_options/ptu_18269.json" local sequence = { } local attempts = 16 local r_expected = { - "http://policies.telematics.ford.com/api/policies", + commonFunctions.getURLs("0x07")[1], "http://policies.domain1.ford.com/api/policies", "http://policies.domain2.ford.com/api/policies", - "http://policies.domain3.ford.com/api/policies", -"http://policies.domain4.ford.com/api/policies"} + "http://policies.domain3.ford.com/api/policies" +} local r_actual = { } --[[ Local Functions ]] @@ -123,7 +123,12 @@ function Test.ShowSequence() print("--------------------------------------------------") end -for i = 1, 3 do +-- function Test.print() +-- print_table(r_expected) +-- print_table(r_actual) +-- end + +for i = 1, 4 do Test["ValidateResult" .. i] = function(self) if(r_actual[i] ~= nil) then if r_expected[i] ~= r_actual[i] then diff --git a/test_scripts/Policies/build_options/108_ATF_PTU_Trigger_days_PROPRIETARY.lua b/test_scripts/Policies/build_options/108_ATF_PTU_Trigger_days_PROPRIETARY.lua index 1781432267..342d554fbf 100644 --- a/test_scripts/Policies/build_options/108_ATF_PTU_Trigger_days_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/108_ATF_PTU_Trigger_days_PROPRIETARY.lua @@ -68,7 +68,15 @@ end function Test:Precondition_Update_Policy_With_Exchange_After_X_Days_Value() currentSystemDaysAfterEpoch = getSystemDaysAfterEpoch() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS, { + result = { + code = 0, + method = "SDL.GetURLS", + urls = { + { url = commonFunctions.getURLs("0x07")[1] } + } + } + }) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest",{requestType = "PROPRIETARY", fileName = "filename"}) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) diff --git a/test_scripts/Policies/build_options/110_ATF_PTU_Trigger_kilometers_PROPRIETARY.lua b/test_scripts/Policies/build_options/110_ATF_PTU_Trigger_kilometers_PROPRIETARY.lua index 95f14011fa..be6a534501 100644 --- a/test_scripts/Policies/build_options/110_ATF_PTU_Trigger_kilometers_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/110_ATF_PTU_Trigger_kilometers_PROPRIETARY.lua @@ -107,7 +107,7 @@ end function Test:Precondition_Update_Policy_With_New_Exchange_After_X_Kilometers_Value() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { diff --git a/test_scripts/Policies/build_options/112_ATF_transfer_SystemRequest_from_app_to_HMI_PROPRIETARY.lua b/test_scripts/Policies/build_options/112_ATF_transfer_SystemRequest_from_app_to_HMI_PROPRIETARY.lua index 6c47e00eff..f01e3d4efc 100644 --- a/test_scripts/Policies/build_options/112_ATF_transfer_SystemRequest_from_app_to_HMI_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/112_ATF_transfer_SystemRequest_from_app_to_HMI_PROPRIETARY.lua @@ -38,7 +38,15 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_Update_Policy() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS, { + result = { + code = 0, + method = "SDL.GetURLS", + urls = { + { url = commonFunctions.getURLs("0x07")[1] } + } + } + }) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", {requestType = "PROPRIETARY", fileName = testData.fileName}) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) diff --git a/test_scripts/Policies/build_options/114_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua b/test_scripts/Policies/build_options/114_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua index b70ebe4724..e2b4ea7925 100644 --- a/test_scripts/Policies/build_options/114_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/114_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua @@ -62,11 +62,20 @@ commonSteps:DeleteLogsFileAndPolicyTable() commonFunctions:newTestCasesGroup ("Preconditions") function Test:Precondition_PolicyUpdateStarted() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) :Do(function(_,_) + EXPECT_HMIRESPONSE(RequestIdGetURLS, { + result = { + code = 0, + method = "SDL.GetURLS", + urls = { + { url = commonFunctions.getURLs("0x07")[1] } + } + } + }) + :Do(function(_,_) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", - url = "http://policies.telematics.ford.com/api/policies", + url = commonFunctions.getURLs("0x07")[1], appID = self.applications ["Test Application"], fileName = "sdl_snapshot.json" }) diff --git a/test_scripts/Policies/build_options/115_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp_PROPRIETARY.lua b/test_scripts/Policies/build_options/115_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp_PROPRIETARY.lua index 3faf128056..911fbe3454 100644 --- a/test_scripts/Policies/build_options/115_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/115_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp_PROPRIETARY.lua @@ -95,15 +95,23 @@ function Test:Precondition_RegisterApp_trigger() end function Test:Precondition_PolicyUpdateStarted() - local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" + local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS, { + result = { + code = 0, + method = "SDL.GetURLS", + urls = { + { url = commonFunctions.getURLs("0x07")[1] } + } + } + }) :Do(function(_,_) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", - url = "http://policies.telematics.ford.com/api/policies", + url = commonFunctions.getURLs("0x07")[1], appID = self.applications ["Test Application"], fileName = policy_file_path .. "sdl_snapshot.json" } diff --git a/test_scripts/Policies/user_consent_of_Policies/188_ATF_HP_Device_Data_Section_Validation.lua b/test_scripts/Policies/user_consent_of_Policies/188_ATF_HP_Device_Data_Section_Validation.lua index d79d83554e..e165a2fc49 100644 --- a/test_scripts/Policies/user_consent_of_Policies/188_ATF_HP_Device_Data_Section_Validation.lua +++ b/test_scripts/Policies/user_consent_of_Policies/188_ATF_HP_Device_Data_Section_Validation.lua @@ -70,18 +70,32 @@ local function GetCurrentTimeStampGroupConsent() end local function GetDataFromSnapshot(pathToFile) + local function getData(pTable, pKey) + if pTable then + return pTable[pKey] + end + return nil + end + local function getTableData(pTable, pKey) + if pTable and pTable[pKey] then + return next(pTable[pKey], nil) + end + return nil + end local file = io.open(pathToFile, "r") local json_data = file:read("*all") -- may be abbreviated to "*a"; file:close() local json = require("modules/json") local data = json.decode(json_data) + local ucr = data.policy_table.device_data[MACHash].user_consent_records local res = { - deviceConsentTimeStamp = data.policy_table.device_data[MACHash].user_consent_records.device.time_stamp, - deviceInput = data.policy_table.device_data[MACHash].user_consent_records.device.input, - deviceGroups = next(data.policy_table.device_data[MACHash].user_consent_records.device.consent_groups, nil), - inputOfAppIdConsent = data.policy_table.device_data[MACHash].user_consent_records[appID].input, - groupUserconsentTimeStamp = data.policy_table.device_data[MACHash].user_consent_records[appID].time_stamp, - userConsentGroup = next(data.policy_table.device_data[MACHash].user_consent_records[appID].consent_groups, nil)} + deviceConsentTimeStamp = getData(ucr.device, "time_stamp"), + deviceInput = getData(ucr.device, "input"), + deviceGroups = getTableData(ucr.device, "consent_groups"), + inputOfAppIdConsent = getData(ucr[appID], "input"), + groupUserconsentTimeStamp = getData(ucr[appID], "time_stamp"), + userConsentGroup = getTableData(ucr[appID], "consent_groups") + } return res end @@ -126,7 +140,7 @@ function Test:Precondition_Activate_App_Consent_Device_Make_PTU_Consent_Group() EXPECT_HMICALL("BasicCommunication.PolicyUpdate") :Do(function(_,_) local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest",{requestType = "PROPRIETARY", fileName = "filename"}) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) @@ -191,16 +205,16 @@ function Test:Validate_Snapshot_Values() groupUserconsentTimeStamp = consentGroupSystemTimeStamp, userConsentGroup = "Location-1" } - + local msg = "" local result = true - for k,v in pairs(valuesFromPTS) do - if v ~= verificationValues[k] then - -- local stringLog = "Wrong value from snapshot " .. k .. "! Expected: " .. verificationValues[k] .. " Actual: " .. v - print("Wrong value from snapshot " .. k .. "! Expected: " .. verificationValues[k] .. " Actual: " .. v) + for k, v in pairs(verificationValues) do + if v ~= valuesFromPTS[k] then + if string.len(msg) > 0 then msg = msg .. "\n" end + msg = msg .. "Wrong value from snapshot " .. k .. "! Expected: " .. v .. " Actual: " .. tostring(valuesFromPTS[k]) result = false end end - return result + return result, msg end) end diff --git a/test_scripts/Policies/user_consent_of_Policies/189_ATF_isAppPermissionsRevoked_true.lua b/test_scripts/Policies/user_consent_of_Policies/189_ATF_isAppPermissionsRevoked_true.lua index ac5a10f5e5..997d638144 100644 --- a/test_scripts/Policies/user_consent_of_Policies/189_ATF_isAppPermissionsRevoked_true.lua +++ b/test_scripts/Policies/user_consent_of_Policies/189_ATF_isAppPermissionsRevoked_true.lua @@ -55,7 +55,7 @@ end function Test:TestStep_PTU_appPermissionsConsentNeeded_true() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,_) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = "filename"}) @@ -126,7 +126,7 @@ end function Test:Precondition_PTU_revoke_app_group() HMIAppID = self.applications[config.application1.registerAppInterfaceParams.appName] local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = "filename"}) diff --git a/test_scripts/Policies/user_consent_of_Policies/199_ATF_appPermissionsConsentNeeded_true.lua b/test_scripts/Policies/user_consent_of_Policies/199_ATF_appPermissionsConsentNeeded_true.lua index 89f9a28dad..9b318a192a 100644 --- a/test_scripts/Policies/user_consent_of_Policies/199_ATF_appPermissionsConsentNeeded_true.lua +++ b/test_scripts/Policies/user_consent_of_Policies/199_ATF_appPermissionsConsentNeeded_true.lua @@ -48,7 +48,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_PTU_appPermissionsConsentNeeded_true() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,_) EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATING"}, {status = "UP_TO_DATE"}):Times(2) :Do(function(_,data) diff --git a/test_scripts/Policies/user_consent_of_Policies/210_ATF_User_consent_initing_after_PTU_FULL.lua b/test_scripts/Policies/user_consent_of_Policies/210_ATF_User_consent_initing_after_PTU_FULL.lua index 0b10479d1a..1a1baa13ed 100644 --- a/test_scripts/Policies/user_consent_of_Policies/210_ATF_User_consent_initing_after_PTU_FULL.lua +++ b/test_scripts/Policies/user_consent_of_Policies/210_ATF_User_consent_initing_after_PTU_FULL.lua @@ -36,7 +36,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:OnAppPermissionChanged_to_FULL_upon_PTU() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest",{ requestType = "PROPRIETARY", fileName = "filename"} ) diff --git a/test_scripts/Policies/user_consent_of_Policies/211_ATF_User_consent_initing_after_PTU_LIMITED.lua b/test_scripts/Policies/user_consent_of_Policies/211_ATF_User_consent_initing_after_PTU_LIMITED.lua index 014d9165dc..3c304cf906 100644 --- a/test_scripts/Policies/user_consent_of_Policies/211_ATF_User_consent_initing_after_PTU_LIMITED.lua +++ b/test_scripts/Policies/user_consent_of_Policies/211_ATF_User_consent_initing_after_PTU_LIMITED.lua @@ -44,7 +44,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:OnAppPermissionChanged_to_LIMITED_upon_PTU() local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest",{ requestType = "PROPRIETARY", fileName = "filename"} ) diff --git a/test_scripts/Policies/user_consent_of_Policies/214_ATF_User_consent_prompt_persists.lua b/test_scripts/Policies/user_consent_of_Policies/214_ATF_User_consent_prompt_persists.lua index 36e6191109..112dd386b7 100644 --- a/test_scripts/Policies/user_consent_of_Policies/214_ATF_User_consent_prompt_persists.lua +++ b/test_scripts/Policies/user_consent_of_Policies/214_ATF_User_consent_prompt_persists.lua @@ -197,7 +197,7 @@ end function Test:Precondition_PTU_user_consent_prompt_present() local is_test_passed = true local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest",{ requestType = "PROPRIETARY", fileName = "filename"}) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) diff --git a/user_modules/shared_testcases/commonFunctions.lua b/user_modules/shared_testcases/commonFunctions.lua index c5262caff8..87a103df81 100644 --- a/user_modules/shared_testcases/commonFunctions.lua +++ b/user_modules/shared_testcases/commonFunctions.lua @@ -1332,4 +1332,20 @@ function commonFunctions:pathJoin(...) return table.concat(args, "/") end +function commonFunctions.getURLs(pService) + local utils = require ('user_modules/utils') + local function getPathToSDL() + local pathToSDL = config.pathToSDL + if pathToSDL:sub(-1) ~= '/' then + pathToSDL = pathToSDL .. "/" + end + return pathToSDL + end + local fileName = getPathToSDL() .. commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + local tbl = utils.jsonFileToTable(fileName) + local url = tbl.policy_table.module_config.endpoints[pService].default + return url +end + + return commonFunctions diff --git a/user_modules/shared_testcases/testCasesForPolicyAppIdManagament.lua b/user_modules/shared_testcases/testCasesForPolicyAppIdManagament.lua index 5e7e37353c..c3be96d6a6 100644 --- a/user_modules/shared_testcases/testCasesForPolicyAppIdManagament.lua +++ b/user_modules/shared_testcases/testCasesForPolicyAppIdManagament.lua @@ -20,17 +20,7 @@ local commonFunctions = require("user_modules/shared_testcases/commonFunctions") function common:updatePolicyTable(test, file) EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATING" }, { status = "UP_TO_DATE" }):Times(2) local requestId = test.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(requestId, { - result = { - code = 0, - method = "SDL.GetURLS", - urls = { - { - url = "http://policies.telematics.ford.com/api/policies" - } - } - } - }) + EXPECT_HMIRESPONSE(requestId) :Do(function() local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") diff --git a/user_modules/shared_testcases/testCasesForPolicyTable.lua b/user_modules/shared_testcases/testCasesForPolicyTable.lua index 1d5c48822f..1ff3c9d587 100644 --- a/user_modules/shared_testcases/testCasesForPolicyTable.lua +++ b/user_modules/shared_testcases/testCasesForPolicyTable.lua @@ -308,7 +308,7 @@ function testCasesForPolicyTable:updatePolicy(PTName, iappID) local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) --hmi side: expect SDL.GetURLS response from HMI - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,_) --print("SDL.GetURLS response is received") --hmi side: sending BasicCommunication.OnSystemRequest request to SDL @@ -408,7 +408,7 @@ function testCasesForPolicyTable:updatePolicyInDifferentSessions(self, PTName, a local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) --hmi side: expect SDL.GetURLS response from HMI - EXPECT_HMIRESPONSE(RequestIdGetURLS,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function(_,_) --hmi side: sending BasicCommunication.OnSystemRequest request to SDL self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", diff --git a/user_modules/shared_testcases_custom/ATF_Policies_External_Consent_common_functions.lua b/user_modules/shared_testcases_custom/ATF_Policies_External_Consent_common_functions.lua index 344dc8ee63..a0b7d78b49 100644 --- a/user_modules/shared_testcases_custom/ATF_Policies_External_Consent_common_functions.lua +++ b/user_modules/shared_testcases_custom/ATF_Policies_External_Consent_common_functions.lua @@ -102,7 +102,7 @@ function external_consent_common_functions:UpdatePolicy(self, json_file_path, in --hmi side: sending SDL.GetURLS request local request_id_get_urls = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) --hmi side: expect SDL.GetURLS response from HMI - EXPECT_HMIRESPONSE(request_id_get_urls,{result = {code = 0, method = "SDL.GetURLS", urls = {{url = "http://policies.telematics.ford.com/api/policies"}}}}) + EXPECT_HMIRESPONSE(request_id_get_urls) :Do(function(_,data) --hmi side: sending BasicCommunication.OnSystemRequest request to SDL self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { From 50f14526a38b05a91f7f8a5b0be6209cecf74e82 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 16 Mar 2018 16:48:15 +0200 Subject: [PATCH 334/681] Allow automatic answer on BC.GetSystemTime request from SDL with current Date/Time --- .../4_5/Trigger_PTU_NO_Certificate/common.lua | 33 +++++++++++++++++++ user_modules/sequences/actions.lua | 4 +++ 2 files changed, 37 insertions(+) diff --git a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua index e4698b5e8a..ece1b7e148 100644 --- a/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua +++ b/test_scripts/Defects/4_5/Trigger_PTU_NO_Certificate/common.lua @@ -16,6 +16,39 @@ m.frameInfo = security.frameInfo m.delayedExp = utils.wait m.readFile = utils.readFile +local function registerGetSystemTimeNotification() + m.getHMIConnection():SendNotification("BasicCommunication.OnSystemTimeReady") + m.getHMIConnection():ExpectRequest("BasicCommunication.GetSystemTime") + :Do(function(_, d) + local function getSystemTime() + local dd = os.date("*t") + return { + millisecond = 0, + second = dd.sec, + minute = dd.min, + hour = dd.hour, + day = dd.day, + month = dd.month, + year = dd.year, + tz_hour = 2, + tz_minute = 0 + } + end + m.getHMIConnection():SendResponse(d.id, d.method, "SUCCESS", { systemTime = getSystemTime() }) + end) + :Times(AnyNumber()) + :Pin() +end + +local startOrig = m.start + +function m.start(pHMIParams) + startOrig(pHMIParams) + :Do(function() + registerGetSystemTimeNotification() + end) +end + function m.setForceProtectedServiceParam(pParamValue) m.setSDLIniParameter("ForceProtectedService", pParamValue) end diff --git a/user_modules/sequences/actions.lua b/user_modules/sequences/actions.lua index 23687cf56f..bc85e0cc81 100644 --- a/user_modules/sequences/actions.lua +++ b/user_modules/sequences/actions.lua @@ -256,6 +256,8 @@ end --! @return: none --]] function m.start(pHMIParams) + local event = events.Event() + event.matches = function(e1, e2) return e1 == e2 end test:runSDL() commonFunctions:waitForSDLStart(test) :Do(function() @@ -269,10 +271,12 @@ function m.start(pHMIParams) :Do(function() utils.cprint(35, "Mobile connected") allowSDL(test) + RAISE_EVENT(event, event) end) end) end) end) + return EXPECT_EVENT(event, "Start event") end --[[ @ExpectRequest: register expectation for request on HMI connection From b10c5be7ce8d2feded15d5f074e3e406e2a4c95e Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 16 Mar 2018 11:49:18 +0200 Subject: [PATCH 335/681] Initial scripts for GetSystemTime --- .../client_credential.pem | 95 ++++++++++++ .../client_credential_0312_17.pem | 95 ++++++++++++ .../client_credential_0316_21.pem | 95 ++++++++++++ .../client_credential_0321_26.pem | 95 ++++++++++++ .../spt_credential.pem | 95 ++++++++++++ .../spt_credential_0311_16.pem | 95 ++++++++++++ .../spt_credential_0317_22.pem | 95 ++++++++++++ .../spt_credential_0323_28.pem | 95 ++++++++++++ .../001_GetSystemTime_is_sent.lua | 52 +++++++ .../002_GetSystemTime_is_not_sent.lua | 51 +++++++ ...mTime_mobile_sdl_cer_are_not_valid_yet.lua | 70 +++++++++ ...e_mobile_sdl_cer_are_not_valid_already.lua | 70 +++++++++ ...cer_becomes_valid_sdl_cer_is_not_valid.lua | 70 +++++++++ ...ile_is_not_valid_sdl_cer_becomes_valid.lua | 70 +++++++++ ..._valid_sdl_cer_becomes_valid_after_PTU.lua | 77 ++++++++++ ...SystemTime_mobile_sdl_cer_become_valid.lua | 70 +++++++++ ..._mobile_sdl_cer_become_valid_after_PTU.lua | 77 ++++++++++ ...mTime_mobile_cer_expired_sdl_cer_valid.lua | 70 +++++++++ ...mobile_cer_not_valid_yet_sdl_cer_valid.lua | 70 +++++++++ ...mobile_cer_becomes_valid_sdl_cer_valid.lua | 70 +++++++++ ...bile_cer_not_valid_sdl_becomes_invalid.lua | 70 +++++++++ ...ecomes_valid_sdl_cer_becomes_not_valid.lua | 70 +++++++++ ...ime_mobile_cer_valid_sdl_cer_not_valid.lua | 72 +++++++++ ...mobile_cer_valid_sdl_cer_becomes_valid.lua | 65 +++++++++ ..._valid_sdl_cer_becomes_valid_after_PTU.lua | 72 +++++++++ ...er_becomes_not_valid_sdl_cer_not_valid.lua | 65 +++++++++ ...ecomes_not_valid_sdl_cer_becomes_valid.lua | 70 +++++++++ ...t_valid_sdl_cer_becomes_valid_with_PTU.lua | 77 ++++++++++ ...ystemTime_mobile_cer_and_sdl_cer_valid.lua | 65 +++++++++ ...er_becomes_not_valid_and_sdl_cer_valid.lua | 70 +++++++++ ...ecomes_yet_not_valid_and_sdl_cer_valid.lua | 70 +++++++++ ...er_valid_and_sdl_cer_becomes_not_valid.lua | 65 +++++++++ ..._mobile_cer_and_sdl_cer_become_expired.lua | 65 +++++++++ ...e_cer_and_sdl_cer_become_not_valid_yet.lua | 65 +++++++++ .../Policies/GetSystemTime/common.lua | 137 ++++++++++++++++++ test_sets/get_system_time.txt | 26 ++++ user_modules/dummy_connecttest.lua | 3 +- 37 files changed, 2703 insertions(+), 1 deletion(-) create mode 100644 files/Security/GetSystemTime_certificates/client_credential.pem create mode 100644 files/Security/GetSystemTime_certificates/client_credential_0312_17.pem create mode 100644 files/Security/GetSystemTime_certificates/client_credential_0316_21.pem create mode 100644 files/Security/GetSystemTime_certificates/client_credential_0321_26.pem create mode 100644 files/Security/GetSystemTime_certificates/spt_credential.pem create mode 100644 files/Security/GetSystemTime_certificates/spt_credential_0311_16.pem create mode 100644 files/Security/GetSystemTime_certificates/spt_credential_0317_22.pem create mode 100644 files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem create mode 100644 test_scripts/Policies/GetSystemTime/001_GetSystemTime_is_sent.lua create mode 100644 test_scripts/Policies/GetSystemTime/002_GetSystemTime_is_not_sent.lua create mode 100644 test_scripts/Policies/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua create mode 100644 test_scripts/Policies/GetSystemTime/004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua create mode 100644 test_scripts/Policies/GetSystemTime/005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua create mode 100644 test_scripts/Policies/GetSystemTime/006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua create mode 100644 test_scripts/Policies/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua create mode 100644 test_scripts/Policies/GetSystemTime/008_GetSystemTime_mobile_sdl_cer_become_valid.lua create mode 100644 test_scripts/Policies/GetSystemTime/009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua create mode 100644 test_scripts/Policies/GetSystemTime/010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua create mode 100644 test_scripts/Policies/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua create mode 100644 test_scripts/Policies/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua create mode 100644 test_scripts/Policies/GetSystemTime/013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua create mode 100644 test_scripts/Policies/GetSystemTime/014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua create mode 100644 test_scripts/Policies/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua create mode 100644 test_scripts/Policies/GetSystemTime/016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua create mode 100644 test_scripts/Policies/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua create mode 100644 test_scripts/Policies/GetSystemTime/018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua create mode 100644 test_scripts/Policies/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua create mode 100644 test_scripts/Policies/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua create mode 100644 test_scripts/Policies/GetSystemTime/021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua create mode 100644 test_scripts/Policies/GetSystemTime/022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua create mode 100644 test_scripts/Policies/GetSystemTime/023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua create mode 100644 test_scripts/Policies/GetSystemTime/024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua create mode 100644 test_scripts/Policies/GetSystemTime/025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua create mode 100644 test_scripts/Policies/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua create mode 100644 test_scripts/Policies/GetSystemTime/common.lua create mode 100644 test_sets/get_system_time.txt diff --git a/files/Security/GetSystemTime_certificates/client_credential.pem b/files/Security/GetSystemTime_certificates/client_credential.pem new file mode 100644 index 0000000000..b366980046 --- /dev/null +++ b/files/Security/GetSystemTime_certificates/client_credential.pem @@ -0,0 +1,95 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEAzJ8ye6Rj7jSxaqtYXTNhMwllqWPaX13ZFZLNq6tsefg61IiT +OQcrBcIQUO9Uo29JWHUQ81iM9kMCe5n371uSVGDvm5iROJYbn8Eh3dII54XCbct8 +CMHSF+46SQ6PJshUeWE5B3tG0u7K+vE3Pdav4G5Rg3bu7fyiWKt3FU39mMISxkTT +qT/B0Rn+/+vi//3DjnkY5dzT6Tl3WS4yngsKeLEvcl5t1nBwlvxy9740iswaXm3f +wroYooSVS6sZM5ShKdUWdM5HyDbQ+DNehhjg0wFXzvDsP9lE+2Zy/fR+0IRTNpDE +zkNJrm9gm2k9VEtqNNkYQJ8b8NO1HPerJu/nfwIDAQABAoIBAQCjoUsFhNhEzO5z +lsH7BfNclM8vPiKK0Mmgbtz5wwPkJZUmEHFq0UieOipCDqFocL3+dt8vOki/Rabe +oKmcR2YlA7+YddDrp14/ynoCoMtuGZD5rBdsCVKwwFjrwzDGmryytASe7v4b/8li +EzNRyDStDIsyzhETT0ukDLoV12BMnrcMIMnXOjcy+fpO2Q7lWPko1+/VtyzYwbcO +GdLvmpsFlxQtorj3X8QEVuP5DZzZHr+KXrMLeNvshTDxRXPOlO18podTcBzqj/KW +iwrrlF2t6GoIA1zmPK6vgc1xwaXQp6rsKFhbR4fCu7bnAQ8NmKCAKQNBKtokHaqK +MkEe/TbBAoGBAPPNhNawBhYeI73PQy0K1hXAdQ4AvGeitoKA8g/Cke88+RQZvXF8 +HITlo0pQTvP8ASEqlZnGHcn72dnhaVdi3zvNpmhWvKVyp18UqbM6/fvPtjkKqo3y +0KVa3a5g7VCYz/jVl4Qs/T7I3TXInWgyO7Pp4D+/vVe/VQ0ZbeFkGkvjAoGBANbb +30KwSTE+COh6ngOxCuzAI0M3yA4ZCCKbHNRht9BR3br08jxaNP5QG6YEPLIL5y89 +73+TvsboJ/1O3vtvhJtRsJhXZih51wy5JlNf5eYOjqWzceqVR/voq3vzMxE14VB5 +L6CCew57GwKtUhMyC7xEmE5uIjqaz5fqEzWSOsC1AoGBALvCg5NzbLyL6aq8fFes +CMQnu/5UwsRto3FOLR3GEu3UX18Dk8pacvxGfkM1Jhjw802/pgcPdNGhjF0oJCCQ +nKtJ7eZdJlukuRGYsDjALepIRWYYuNEpN1ahbChnrVxs034nwNCidUZtGy/YmKEu +Tpx4eaOe3ws85xt3ghAbL8VRAoGBAKBU+Pih5ixp12nsPkgQ8E8VXfsGADKM+WYh +i9TsiqdYv/aIXM8unYb9LnSnisduXHkDZdo03VM+4MCE/55vbGwe/IHiDmi76v8i +lvf2gu83A7mg+6wK8+mGiZj4Na5tH5LWq/TCCaQXt2M7BRkv6lP2eBVm2AIVjj4V +vXnnghJVAoGBAIOvCe3EFvMVF7uKLK6AnOj2bytnSMDcFy5nDSErwLGH1ldVD178 +11TBciP0HsdnWuKcI21OgkHknsUBXmJISASmdEXXoQdPkJpcDizJHDjOf5CT4DGo +tIq1bF7ZB9iZgvav4EvRzR4CP35dV3zLnMgW9Tlc2aKm4LItFu3G1QIt +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDsjCCApoCCQDxyGnVVnCS/DANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMC +VVMxETAPBgNVBAgMCE1pY2hpZ2FuMRAwDgYDVQQHDAdEZXRyb2l0MRQwEgYDVQQK +DAtGT1JEX0NMSUVOVDEYMBYGA1UECwwPRk9SRF9TRExfQ0xJRU5UMRQwEgYDVQQD +DAtGT1JEX0NMSUVOVDEeMBwGCSqGSIb3DQEJARYPc2FtcGxlQGZvcmQuY29tMB4X +DTEyMDMxNzEwMDQxOVoXDTI2MDMxNDEwMDQxOVowgZwxCzAJBgNVBAYTAlJVMQ8w +DQYDVQQIDAZSdXNzaWExFzAVBgNVBAcMDlN0LiBQZXRlcnNidXJnMQ8wDQYDVQQK +DAZMdXhvZnQxETAPBgNVBAsMCEhlYWRVbml0MQ8wDQYDVQQDDAZjbGllbnQxIDAe +BgkqhkiG9w0BCQEWEXNhbXBsZUBsdXhvZnQuY29tMQwwCgYDVQQFEwNTUFQwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMnzJ7pGPuNLFqq1hdM2EzCWWp +Y9pfXdkVks2rq2x5+DrUiJM5BysFwhBQ71Sjb0lYdRDzWIz2QwJ7mffvW5JUYO+b +mJE4lhufwSHd0gjnhcJty3wIwdIX7jpJDo8myFR5YTkHe0bS7sr68Tc91q/gblGD +du7t/KJYq3cVTf2YwhLGRNOpP8HRGf7/6+L//cOOeRjl3NPpOXdZLjKeCwp4sS9y +Xm3WcHCW/HL3vjSKzBpebd/CuhiihJVLqxkzlKEp1RZ0zkfINtD4M16GGODTAVfO +8Ow/2UT7ZnL99H7QhFM2kMTOQ0mub2CbaT1US2o02RhAnxvw07Uc96sm7+d/AgMB +AAEwDQYJKoZIhvcNAQELBQADggEBABF1RZtawNRTphALoEgOt+kXJqTg7P9h76l1 +3bD7a4EJGNWVyRQvleeFtKb+cfWX+6ge7MgNN2kHcid7PK5C1KXm5H54c8MJ/QUp +Es/+niQInBHJJkcIQyuZI0RVnabONRXiSG0aG2pIl+Hccuq1VDPWIZ0Ml91U/xFt +8j1vHpocPpK8B/sV14H8PvBJT7sY9hjhznOrhZoL7JOh/jjO81q4mAaXJ+zKCbGv +Bg+/GVbiZD1X/wzegecxJP0I9Tk65AZQK1jzUP6AJLmRqC3YLAmaRxU6qRp1E9Uq +0e5Evu4uExWHAWW4GdOTbqGqCbE+oMILxJXNkD4A8NvdQpTic98= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIJAIP3pt4QUWolMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEXMBUGA1UEBwwOU2lsaWNvbiBW +YWxsZXkxEzARBgNVBAoMCkNBY2VydC5vcmcxDzANBgNVBAsMBkNBY2VydDEUMBIG +A1UEAwwLc2VydmVyX3Jvb3QxIDAeBgkqhkiG9w0BCQEWEXNhbXBsZUBjYWNlcnQu +b3JnMB4XDTE4MDMxNDExMjU0NVoXDTQ1MDczMDExMjU0NVowgZkxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRcwFQYDVQQHDA5TaWxpY29uIFZhbGxl +eTETMBEGA1UECgwKQ0FjZXJ0Lm9yZzEPMA0GA1UECwwGQ0FjZXJ0MRQwEgYDVQQD +DAtzZXJ2ZXJfcm9vdDEgMB4GCSqGSIb3DQEJARYRc2FtcGxlQGNhY2VydC5vcmcw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPq17BwejsrvNl6I7cip7L +tQvX/p4EMCi0i2HsmlGD0J+Vpq9Ws3xokekOO8RITBfD5JDoX6ufZf28bc26X4Tp +G8if18juzrGZD38ALfeuoYAVymuBd4NF2xilwX+uqH5E4lkqBOZo3nQ/f1aTKQVT +6DZmr+V62GGaaMewaUOyZ0fZM4tS5ncuvSCMtuLHH5gy87e/lzj8Zbyek6ej2lUL +lwaCMOGCOoxhxUr8rorMefUOMZ4IzObSJ/y6XqWJe8yjSrAmyRHBmpGmCiMUnrkD +4FTY05Cyn2kncCHlYFL18C0utwTBYK1Gv8qampSD+e7ZWKTO1kEMrbZv3kwQdTfp +AgMBAAGjUDBOMB0GA1UdDgQWBBQ+EGb7hYQffkb6GXTWVMyqzz3joTAfBgNVHSME +GDAWgBQ+EGb7hYQffkb6GXTWVMyqzz3joTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBFH2QNBHlth/nOIzyxPEXAyvkWDZh2/hukXlK4zWvWyiLlJXr9 +t5goWFzjbqpsCfN3TOb+CDBd3RYhhdnhxXMYmydR77+SlzZ6Lx0YBz7zNV0OUKTK +5Pnlh8GAP7CjU8A0pHf3auAgmBsVmX7+uFQcuRFzvc1LCL6q6t7pM5HH+NvJs7K+ +C/nQB9yW7PWXatPjNVY2YY5YJi2EuUdCFFcAQOtI90Xa8xVtTONYHh/QS7/egVWh +vdsuKx0I6SvMXf2AlVV2NSzcIqps5h7flYAw5sBC7ETux6DV3PgbikLybgxzHlhU +NhCYi7/M9o+QdQKGFc+Pdeapkl8a4GuuR3ax +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDqDCCApACCQCpjnaAoaUGmjANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMC +VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFzAVBgNVBAcMDlNpbGljb24gVmFsbGV5 +MRMwEQYDVQQKDApDQWNlcnQub3JnMQ8wDQYDVQQLDAZDQWNlcnQxFDASBgNVBAMM +C3NlcnZlcl9yb290MSAwHgYJKoZIhvcNAQkBFhFzYW1wbGVAY2FjZXJ0Lm9yZzAe +Fw0xODAzMTQxMTI1NDVaFw0xODA0MDMxMTI1NDVaMIGRMQswCQYDVQQGEwJVUzER +MA8GA1UECAwITWljaGlnYW4xEDAOBgNVBAcMB0RldHJvaXQxFDASBgNVBAoMC0ZP +UkRfU0VSVkVSMRgwFgYDVQQLDA9GT1JEX1NETF9TRVJWRVIxDTALBgNVBAMMBEZP +UkQxHjAcBgkqhkiG9w0BCQEWD3NhbXBsZUBmb3JkLmNvbTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAMCzhMkEhaMy6DkmyTKOhKYJKGsM64SU+6N/TCkv +I3eaj2Vn38gJ57QSwowmF/PtnP0LMPNfUwSmWETHHTGx4hqnAEomhy+4OIpByagZ +LUg8oGXAp+Vx/YyIxTMz6QgACjUV8iHnJWf6SHq+zhGQpo3S9Y2mivOzpAJY1n2n +Ae/FqfNS61CYLBmIh42qt5wOMweiH1Ny+mYUpT7RFMSeDHiiBW4frnJSBKR1xLVW +Y41A70Kto3QZFnjPTZ2eXyXomt+iV+87VWDfAV/edndblVk4QylJO/uPUQzlSrv9 +oY/Y79AcdPjub6xA8Df/H33SNVtSyGvSKEaS5GP7mw6zF98CAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEApIRshx5Ev16JS0DNKYduKqf2N7c7HjGkWw9cdYXBFlkha5uf +2dRe5MMCQLW7q2783a1gBXKxCc4UHks8AeFxajC2KxyTdmmkQsQBQ5Ih6S00K10S +Kk8EIjJ0k4gQyB58vb38Vf494ZfR8avDmYEppdff4DRUdvAgwCRPk9NhEKXLwaZV +0ghqvgLeZ/cb5kiIJW3NHxN9acluSdQLYBdVrRP9MyLzmu13BhcCUgodz4eKxyqY +5PWNPuFCMQ5eVMYVINnZKtzupWISyX9mr1/SJ3evAiroD/6kxxyRQVxtmxLYw+aL +6PRbXGDzEJQvX5frg7WpZLvqsRq5m6KzdXGpXA== +-----END CERTIFICATE----- diff --git a/files/Security/GetSystemTime_certificates/client_credential_0312_17.pem b/files/Security/GetSystemTime_certificates/client_credential_0312_17.pem new file mode 100644 index 0000000000..5ed61d88e1 --- /dev/null +++ b/files/Security/GetSystemTime_certificates/client_credential_0312_17.pem @@ -0,0 +1,95 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEA52O/h2A+5zdPWUTsuEHeB535p19h+pY2HnYyDLX0HDzFyJP8 +zEA/bivjJlBgOEhdwWDbkliSAhlrs9Hl0XzT6oW9gaTM84REes4J15QrMIL5qp1Y +BTwA5d8TxBxzYMx3Fo01r2CHWo2tCyIjRIVmocqf/5/huWOx3Jezknm5sc2FkID6 +DtEG5c+fXaivj34drE4iJcJ0FKntdpcm7haVMClOvZ5JcdaSM0OR6hKK/ffZTTUB +Kb1ZACAUKjcgVlTXmyyiRXMITq8HBq/hfPg9fPmPIqQ7K31+R4+cfOvcLpc960zs +fhm7VwCt9AJaziKMHUsMeGaxz0rwx/E4E022jQIDAQABAoIBAQCuk92foAgVnu9p +JM2NP3TrPk9r7lUYIVj3pqmgWW+yFlALQ0xKNnclAkvBTocqL7889Xz0b4rJtrBB +3a2NXqbsnLccJ2DSogqgtO9MDWiAk3EXPtt4J4tt498f6W9Lqzh2dVf519SHh7j1 +W25MdnG2xA/vZ4uAui0ph/NeIiTudfhHnLe33eoBzuFfjF6EfZcKsxQiNQFs/Su1 +Xg3lC2tFvRDWonrq9Rwmhkq0m049my9xTpCwkc4le30H0ldhArfRg8vqPfLGY4vl +zTecqEo7lS2ukVejaKpaoUVKp22FHrG/mJt6LKjMCFSJj3/Y0WGGqzUTyC+ZhrqW +0bbuCqYBAoGBAPuXo/pzjKucLpXPwFpksgiGyZq+a80dn7r6VOvmGcePKLxuJ36M +YDTgJuVm+s6WNoTMgEjIm473OoY5Omn/1Fw9uwQpimAfixzQP/aOgdK+16oVSvdU +s76m5b9/AyA0tQ9bCN71tbEt6TjpQq3EsRx0GBzxgfQDDlD9zRiy0C7BAoGBAOtx +gEZ7SyO8ZXM43ZA8iMd+s83nAaRLI0sgecGoYB/JpzUMAamD/j5y4MaXS3QVSGGj +7sTUjbkjt6OQy4K+XqNqeNkhevlyQguxX4TS+0trmQ+PQ6IFkbXAuUWApOuVliSB +8YJ+6l3YB2ouMVps2j62v+ANRUrHaOknvGaJL8bNAoGBAMzdZKwKrRAMRC6/FX1F +o2aoAr/bsMI8DhXdw4q3OmSyINSWydgVDD3iDCoeWbogvNIUB528pFac3+3t6a/o +no5hwcgY31F4Pfm/ZWYqEnJ97fTUE9AkC50CH/B3xx7RbGHNmgKbh1B39wHdhusi +T6nAquXejhgY6O5wTDKBYF3BAoGBAJLn0x4nOA8oMjTeuoCRBNdVW2OSTBfzOiZa +MR6ArNmovUgAIdlfnnfgvhert0zLKsqhuw3dgkCO5LqOUi1WEz7r5FO27EBQ5pzd +I7iA3IOGs45d2dlymCRMCE4xorXMNE67NbIy9pFvhdDe2bSOTu7qoHZwUVgDbJZu +UMO5vbHRAoGBAJtSQxWs5sY+Kcwxs0ddryfrWuq2uSrBoexBgZDtNlP8tbJtHesT +cxMNca71R3mPdqcLtBBA1aeBXKNmrcrCMhmdyHe9nLutGuxxsBnDU4XZ6PMffskQ +zMhyWgNRR2vxa4DWVjY0lwqwCmpmmE2RShSruFlkNviL1VXLKRWHpE0G +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDsjCCApoCCQDxyGnVVnCS9jANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMC +VVMxETAPBgNVBAgMCE1pY2hpZ2FuMRAwDgYDVQQHDAdEZXRyb2l0MRQwEgYDVQQK +DAtGT1JEX0NMSUVOVDEYMBYGA1UECwwPRk9SRF9TRExfQ0xJRU5UMRQwEgYDVQQD +DAtGT1JEX0NMSUVOVDEeMBwGCSqGSIb3DQEJARYPc2FtcGxlQGZvcmQuY29tMB4X +DTEyMDMxNjA5MDEzM1oXDTE3MDMxNTA5MDEzM1owgZwxCzAJBgNVBAYTAlJVMQ8w +DQYDVQQIDAZSdXNzaWExFzAVBgNVBAcMDlN0LiBQZXRlcnNidXJnMQ8wDQYDVQQK +DAZMdXhvZnQxETAPBgNVBAsMCEhlYWRVbml0MQ8wDQYDVQQDDAZjbGllbnQxIDAe +BgkqhkiG9w0BCQEWEXNhbXBsZUBsdXhvZnQuY29tMQwwCgYDVQQFEwNTUFQwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDnY7+HYD7nN09ZROy4Qd4Hnfmn +X2H6ljYedjIMtfQcPMXIk/zMQD9uK+MmUGA4SF3BYNuSWJICGWuz0eXRfNPqhb2B +pMzzhER6zgnXlCswgvmqnVgFPADl3xPEHHNgzHcWjTWvYIdaja0LIiNEhWahyp// +n+G5Y7Hcl7OSebmxzYWQgPoO0Qblz59dqK+Pfh2sTiIlwnQUqe12lybuFpUwKU69 +nklx1pIzQ5HqEor999lNNQEpvVkAIBQqNyBWVNebLKJFcwhOrwcGr+F8+D18+Y8i +pDsrfX5Hj5x869wulz3rTOx+GbtXAK30AlrOIowdSwx4ZrHPSvDH8TgTTbaNAgMB +AAEwDQYJKoZIhvcNAQELBQADggEBAJrux1Z4ma3OmW6nCgUi/xBhkEyhBaAiynsH +uMXoOxgg9Ffz0MvaLJWSiXASmVIc85IJStO+tRRt/szI4KTMyFGWFYt+J5PaphKZ +7VaztlBwNMqNA2a/XQOOvUPblXY9MeDL4SdNmMsMH/Xz+YA7wRGbv2rpqb7BE37G +tmCv7rW6KQFIXGLkFuM5pvKL/5U1C3MEugoM4htD68nmir5dc7cDKbh0BEqGDWOw +QTRwWw4v5K+TX482wYMNEHRQo0wd7C/9lh9vugcM3oQMVNg+Vc5eisEh2KxjZ5dG +O+cKzijNcICwTZJXzs+v0K3oyiUq0IyXTEKP+I5jKmFIMuMTm4o= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIJAIP3pt4QUWolMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEXMBUGA1UEBwwOU2lsaWNvbiBW +YWxsZXkxEzARBgNVBAoMCkNBY2VydC5vcmcxDzANBgNVBAsMBkNBY2VydDEUMBIG +A1UEAwwLc2VydmVyX3Jvb3QxIDAeBgkqhkiG9w0BCQEWEXNhbXBsZUBjYWNlcnQu +b3JnMB4XDTE4MDMxNDExMjU0NVoXDTQ1MDczMDExMjU0NVowgZkxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRcwFQYDVQQHDA5TaWxpY29uIFZhbGxl +eTETMBEGA1UECgwKQ0FjZXJ0Lm9yZzEPMA0GA1UECwwGQ0FjZXJ0MRQwEgYDVQQD +DAtzZXJ2ZXJfcm9vdDEgMB4GCSqGSIb3DQEJARYRc2FtcGxlQGNhY2VydC5vcmcw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPq17BwejsrvNl6I7cip7L +tQvX/p4EMCi0i2HsmlGD0J+Vpq9Ws3xokekOO8RITBfD5JDoX6ufZf28bc26X4Tp +G8if18juzrGZD38ALfeuoYAVymuBd4NF2xilwX+uqH5E4lkqBOZo3nQ/f1aTKQVT +6DZmr+V62GGaaMewaUOyZ0fZM4tS5ncuvSCMtuLHH5gy87e/lzj8Zbyek6ej2lUL +lwaCMOGCOoxhxUr8rorMefUOMZ4IzObSJ/y6XqWJe8yjSrAmyRHBmpGmCiMUnrkD +4FTY05Cyn2kncCHlYFL18C0utwTBYK1Gv8qampSD+e7ZWKTO1kEMrbZv3kwQdTfp +AgMBAAGjUDBOMB0GA1UdDgQWBBQ+EGb7hYQffkb6GXTWVMyqzz3joTAfBgNVHSME +GDAWgBQ+EGb7hYQffkb6GXTWVMyqzz3joTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBFH2QNBHlth/nOIzyxPEXAyvkWDZh2/hukXlK4zWvWyiLlJXr9 +t5goWFzjbqpsCfN3TOb+CDBd3RYhhdnhxXMYmydR77+SlzZ6Lx0YBz7zNV0OUKTK +5Pnlh8GAP7CjU8A0pHf3auAgmBsVmX7+uFQcuRFzvc1LCL6q6t7pM5HH+NvJs7K+ +C/nQB9yW7PWXatPjNVY2YY5YJi2EuUdCFFcAQOtI90Xa8xVtTONYHh/QS7/egVWh +vdsuKx0I6SvMXf2AlVV2NSzcIqps5h7flYAw5sBC7ETux6DV3PgbikLybgxzHlhU +NhCYi7/M9o+QdQKGFc+Pdeapkl8a4GuuR3ax +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDqDCCApACCQCpjnaAoaUGmjANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMC +VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFzAVBgNVBAcMDlNpbGljb24gVmFsbGV5 +MRMwEQYDVQQKDApDQWNlcnQub3JnMQ8wDQYDVQQLDAZDQWNlcnQxFDASBgNVBAMM +C3NlcnZlcl9yb290MSAwHgYJKoZIhvcNAQkBFhFzYW1wbGVAY2FjZXJ0Lm9yZzAe +Fw0xODAzMTQxMTI1NDVaFw0xODA0MDMxMTI1NDVaMIGRMQswCQYDVQQGEwJVUzER +MA8GA1UECAwITWljaGlnYW4xEDAOBgNVBAcMB0RldHJvaXQxFDASBgNVBAoMC0ZP +UkRfU0VSVkVSMRgwFgYDVQQLDA9GT1JEX1NETF9TRVJWRVIxDTALBgNVBAMMBEZP +UkQxHjAcBgkqhkiG9w0BCQEWD3NhbXBsZUBmb3JkLmNvbTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAMCzhMkEhaMy6DkmyTKOhKYJKGsM64SU+6N/TCkv +I3eaj2Vn38gJ57QSwowmF/PtnP0LMPNfUwSmWETHHTGx4hqnAEomhy+4OIpByagZ +LUg8oGXAp+Vx/YyIxTMz6QgACjUV8iHnJWf6SHq+zhGQpo3S9Y2mivOzpAJY1n2n +Ae/FqfNS61CYLBmIh42qt5wOMweiH1Ny+mYUpT7RFMSeDHiiBW4frnJSBKR1xLVW +Y41A70Kto3QZFnjPTZ2eXyXomt+iV+87VWDfAV/edndblVk4QylJO/uPUQzlSrv9 +oY/Y79AcdPjub6xA8Df/H33SNVtSyGvSKEaS5GP7mw6zF98CAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEApIRshx5Ev16JS0DNKYduKqf2N7c7HjGkWw9cdYXBFlkha5uf +2dRe5MMCQLW7q2783a1gBXKxCc4UHks8AeFxajC2KxyTdmmkQsQBQ5Ih6S00K10S +Kk8EIjJ0k4gQyB58vb38Vf494ZfR8avDmYEppdff4DRUdvAgwCRPk9NhEKXLwaZV +0ghqvgLeZ/cb5kiIJW3NHxN9acluSdQLYBdVrRP9MyLzmu13BhcCUgodz4eKxyqY +5PWNPuFCMQ5eVMYVINnZKtzupWISyX9mr1/SJ3evAiroD/6kxxyRQVxtmxLYw+aL +6PRbXGDzEJQvX5frg7WpZLvqsRq5m6KzdXGpXA== +-----END CERTIFICATE----- diff --git a/files/Security/GetSystemTime_certificates/client_credential_0316_21.pem b/files/Security/GetSystemTime_certificates/client_credential_0316_21.pem new file mode 100644 index 0000000000..1c9d3fe8dd --- /dev/null +++ b/files/Security/GetSystemTime_certificates/client_credential_0316_21.pem @@ -0,0 +1,95 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA3vQ9fmVv7SFNYmuF6TSGkDa+SSMq90FqEEhgczlKwX6hUoDo +LV/m53Fr/urj4BoyN66auordj7WXaXfghR3h/GFqpZzKHRXwPo4iKpiBXhaVBeYq +LJcB6WNl3qcXT7bsS0TI0EJKXBEB0YpX3SL2vyKSHRxq5h6HW1g6MZgdcQ3AYhtf +9wLJmL0GPz1aFXK5lpaCj2fn054PE1Muk3XrSJzFWEXeYi0yogk6CtnfZEutAe5s +KwyvhNQdjlc183HufjU6U0d0V6DcGKYrNaIl+34uSjegJWtRxfmjCFP1B6XgrByT +OhAv3J/qlaZJwHWhKVswUdweNgGUypOba7zY+QIDAQABAoIBAQCdryIa1gU+MjJ3 +7FIOaL7PGlikg4Hs08/+6iGE/L05cqUII/GRveUiRZ668UfvhLeFmDEIxBQFgsou +psEdhNAC3qc9sFFmFtEOfRn/BFNixxfozyt+0+JfPZSbz5N2JoqihWh9mpTa3pBp +sa2I0iSvc/ThL+sPDAJxgUnPL6WLAXtNulqlY3skvHZV/J1gtKecWGL/k1ti4Xoj +i3hMG13tL4xlzkqqqYw1z2+UGDqn0E4Dy7ZgNyB0FckTOia5M7/H863OeZaUW4AI +tL0Q7ALTmd/7CjY82l+YtpIq8CUjWAwXYralR87f9iyJ8eXpuEc8SseHKMNqHZxi +zxdsuppNAoGBAP1P7qgjZawhsPb+HJaSkKN9xE7Zah5KXFd61bWOjLqdGeYCn9kX +86sic9jjbpGgCnLomCXVVK6A7NV2CnChp+eDiIZ3S/VgYui5SvVF8iVgak/ubQXF +O//2SzRuEz951guwhR2APp5vzxtOeLlxQVPCBpxc947tTAEHl9hFnAufAoGBAOFR +2LiZ7K10tR7X883LH/FoPMX5ILzLCYq4dyITyVD3Qe80t1U4WdLK3thk623uycfG +vES2Id3Wbj+DEhl0v2PRdXqLpxNSRdoerq6iRpLkXWvy1HGQvBx9s5MeSSA9j4CX +5U1JM11BYFzW27wQtxbIZfiamwLjXcNYnKdXXFRnAoGAdgADO73pgerb5eLv7FBw +IkjW5qgu39dh9rpYzU+PTOscAmKcleOrdcAB2Tnw6tNzqp2hKpaa8QNL0BBBwr/7 +WESUl5cBAlgZGzIdse4YY8LrIzr8/GApmA3icJUKUFpwFFfxWpHAGcwZ3S2L3U7d +0Kekrrg79g+ihSRFXtDmZR8CgYB9IaMmAfW67tGXa37ujxwSST1XBN/1eRy3eXJP +7oUi/e4UFkaqgT0BH8Fak9Fbn/1XgTsVPcDZHjjj9LqcgIW5vZ1sjRogVNSOKfQA +8AYZldF8HcN1vld5yyVrUqpxyT5kv/aMUVbBN4l4hapKa04CzRA0XEgx9msgDZoS +JSYViQKBgDv09d0mD+OmRho+NYipg9b0SFvhBVXgFN0A8aHnaMOvqilOTBi1vM6v +M9JzgECXGtTpdJsShijKmupvgP2gMFsZ2sFtdvz+zjJthbJSvpQI2IYgVHZSnevg +dc07CINHj12an7VA4QoJmj2YWO5ciJBKo+bAODmQALEDLQYb5Gor +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDsjCCApoCCQDxyGnVVnCS7DANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMC +VVMxETAPBgNVBAgMCE1pY2hpZ2FuMRAwDgYDVQQHDAdEZXRyb2l0MRQwEgYDVQQK +DAtGT1JEX0NMSUVOVDEYMBYGA1UECwwPRk9SRF9TRExfQ0xJRU5UMRQwEgYDVQQD +DAtGT1JEX0NMSUVOVDEeMBwGCSqGSIb3DQEJARYPc2FtcGxlQGZvcmQuY29tMB4X +DTE2MDMxNDEyMTQyNVoXDTIxMDMxMzEyMTQyNVowgZwxCzAJBgNVBAYTAlJVMQ8w +DQYDVQQIDAZSdXNzaWExFzAVBgNVBAcMDlN0LiBQZXRlcnNidXJnMQ8wDQYDVQQK +DAZMdXhvZnQxETAPBgNVBAsMCEhlYWRVbml0MQ8wDQYDVQQDDAZjbGllbnQxIDAe +BgkqhkiG9w0BCQEWEXNhbXBsZUBsdXhvZnQuY29tMQwwCgYDVQQFEwNTUFQwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDe9D1+ZW/tIU1ia4XpNIaQNr5J +Iyr3QWoQSGBzOUrBfqFSgOgtX+bncWv+6uPgGjI3rpq6it2PtZdpd+CFHeH8YWql +nModFfA+jiIqmIFeFpUF5ioslwHpY2XepxdPtuxLRMjQQkpcEQHRilfdIva/IpId +HGrmHodbWDoxmB1xDcBiG1/3AsmYvQY/PVoVcrmWloKPZ+fTng8TUy6TdetInMVY +Rd5iLTKiCToK2d9kS60B7mwrDK+E1B2OVzXzce5+NTpTR3RXoNwYpis1oiX7fi5K +N6Ala1HF+aMIU/UHpeCsHJM6EC/cn+qVpknAdaEpWzBR3B42AZTKk5trvNj5AgMB +AAEwDQYJKoZIhvcNAQELBQADggEBAGVo/VHEXp8BSSfTFrcye0gI/CvIGPCSVQGv +3uzPMuwyk383dd/lEOXnlS3ohkAVu249Z0xIIHr4rm+ZKFUf11kBu4JaToGiC8r/ +lpY0Z6hcfWQ2SaVeZQoh202uGZJ++/NLjnsscERzyi7HG8s58VsWV9l7dWR/CM0n +pf7C4WeZHMbt1b+WPZCNQfyXgEK4aFq0fmP936JaOaR0ZszFLBrapyURT+R1kgPz +zTg2KysR/Tf6zEKHJ+MDwF47jyxtyvbtWaSImkemmpRqvOByAwLlwqbYoW00PYPp +E3O1pN5QwZMsYFTdOAbmKN1hf4/N5ISJ4LZx/KtXzT9y/NwMnKA= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIJAIP3pt4QUWolMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEXMBUGA1UEBwwOU2lsaWNvbiBW +YWxsZXkxEzARBgNVBAoMCkNBY2VydC5vcmcxDzANBgNVBAsMBkNBY2VydDEUMBIG +A1UEAwwLc2VydmVyX3Jvb3QxIDAeBgkqhkiG9w0BCQEWEXNhbXBsZUBjYWNlcnQu +b3JnMB4XDTE4MDMxNDExMjU0NVoXDTQ1MDczMDExMjU0NVowgZkxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRcwFQYDVQQHDA5TaWxpY29uIFZhbGxl +eTETMBEGA1UECgwKQ0FjZXJ0Lm9yZzEPMA0GA1UECwwGQ0FjZXJ0MRQwEgYDVQQD +DAtzZXJ2ZXJfcm9vdDEgMB4GCSqGSIb3DQEJARYRc2FtcGxlQGNhY2VydC5vcmcw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPq17BwejsrvNl6I7cip7L +tQvX/p4EMCi0i2HsmlGD0J+Vpq9Ws3xokekOO8RITBfD5JDoX6ufZf28bc26X4Tp +G8if18juzrGZD38ALfeuoYAVymuBd4NF2xilwX+uqH5E4lkqBOZo3nQ/f1aTKQVT +6DZmr+V62GGaaMewaUOyZ0fZM4tS5ncuvSCMtuLHH5gy87e/lzj8Zbyek6ej2lUL +lwaCMOGCOoxhxUr8rorMefUOMZ4IzObSJ/y6XqWJe8yjSrAmyRHBmpGmCiMUnrkD +4FTY05Cyn2kncCHlYFL18C0utwTBYK1Gv8qampSD+e7ZWKTO1kEMrbZv3kwQdTfp +AgMBAAGjUDBOMB0GA1UdDgQWBBQ+EGb7hYQffkb6GXTWVMyqzz3joTAfBgNVHSME +GDAWgBQ+EGb7hYQffkb6GXTWVMyqzz3joTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBFH2QNBHlth/nOIzyxPEXAyvkWDZh2/hukXlK4zWvWyiLlJXr9 +t5goWFzjbqpsCfN3TOb+CDBd3RYhhdnhxXMYmydR77+SlzZ6Lx0YBz7zNV0OUKTK +5Pnlh8GAP7CjU8A0pHf3auAgmBsVmX7+uFQcuRFzvc1LCL6q6t7pM5HH+NvJs7K+ +C/nQB9yW7PWXatPjNVY2YY5YJi2EuUdCFFcAQOtI90Xa8xVtTONYHh/QS7/egVWh +vdsuKx0I6SvMXf2AlVV2NSzcIqps5h7flYAw5sBC7ETux6DV3PgbikLybgxzHlhU +NhCYi7/M9o+QdQKGFc+Pdeapkl8a4GuuR3ax +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDqDCCApACCQCpjnaAoaUGmjANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMC +VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFzAVBgNVBAcMDlNpbGljb24gVmFsbGV5 +MRMwEQYDVQQKDApDQWNlcnQub3JnMQ8wDQYDVQQLDAZDQWNlcnQxFDASBgNVBAMM +C3NlcnZlcl9yb290MSAwHgYJKoZIhvcNAQkBFhFzYW1wbGVAY2FjZXJ0Lm9yZzAe +Fw0xODAzMTQxMTI1NDVaFw0xODA0MDMxMTI1NDVaMIGRMQswCQYDVQQGEwJVUzER +MA8GA1UECAwITWljaGlnYW4xEDAOBgNVBAcMB0RldHJvaXQxFDASBgNVBAoMC0ZP +UkRfU0VSVkVSMRgwFgYDVQQLDA9GT1JEX1NETF9TRVJWRVIxDTALBgNVBAMMBEZP +UkQxHjAcBgkqhkiG9w0BCQEWD3NhbXBsZUBmb3JkLmNvbTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAMCzhMkEhaMy6DkmyTKOhKYJKGsM64SU+6N/TCkv +I3eaj2Vn38gJ57QSwowmF/PtnP0LMPNfUwSmWETHHTGx4hqnAEomhy+4OIpByagZ +LUg8oGXAp+Vx/YyIxTMz6QgACjUV8iHnJWf6SHq+zhGQpo3S9Y2mivOzpAJY1n2n +Ae/FqfNS61CYLBmIh42qt5wOMweiH1Ny+mYUpT7RFMSeDHiiBW4frnJSBKR1xLVW +Y41A70Kto3QZFnjPTZ2eXyXomt+iV+87VWDfAV/edndblVk4QylJO/uPUQzlSrv9 +oY/Y79AcdPjub6xA8Df/H33SNVtSyGvSKEaS5GP7mw6zF98CAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEApIRshx5Ev16JS0DNKYduKqf2N7c7HjGkWw9cdYXBFlkha5uf +2dRe5MMCQLW7q2783a1gBXKxCc4UHks8AeFxajC2KxyTdmmkQsQBQ5Ih6S00K10S +Kk8EIjJ0k4gQyB58vb38Vf494ZfR8avDmYEppdff4DRUdvAgwCRPk9NhEKXLwaZV +0ghqvgLeZ/cb5kiIJW3NHxN9acluSdQLYBdVrRP9MyLzmu13BhcCUgodz4eKxyqY +5PWNPuFCMQ5eVMYVINnZKtzupWISyX9mr1/SJ3evAiroD/6kxxyRQVxtmxLYw+aL +6PRbXGDzEJQvX5frg7WpZLvqsRq5m6KzdXGpXA== +-----END CERTIFICATE----- diff --git a/files/Security/GetSystemTime_certificates/client_credential_0321_26.pem b/files/Security/GetSystemTime_certificates/client_credential_0321_26.pem new file mode 100644 index 0000000000..9e215a2bb3 --- /dev/null +++ b/files/Security/GetSystemTime_certificates/client_credential_0321_26.pem @@ -0,0 +1,95 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAu7gDfGpLP9MAyKMse1xnCpSbGaA2Rm8C2SDs7Yw9zG4t16b9 +o3v/eokMtTAWOCPbtBN92HmR/q7rkxfHEBKxuTAbPvqG7/rEqht0dRSu3/0QFyvc +OSdR49Onnpj3taZIG+KiwId5sch6a12VeZfCF1zlRxQOHed98ijMSxC3Gbj4rVVE +y2FAfDQNS3M38XwsVwk4fCAKZXz19vxKgevQX12dq5w/0Lds+WVB/68Yyvq8Gq99 +UskFolwo72ysLc1brk8wP0BQVv6WkIcGisZ5F3MSmJrenBRzB2GHRBoRjTb3ERZY +wpHKBBjH8yQpmMwVWAXGMsORKklET4FMNg0nCQIDAQABAoIBAApGORKfMr0sjFdu +7ulVlmIy3gZaCX5zZwGBVtZtnZhJ04KBJlLDX6lSRPrJxf2OoODLTFED3mTFKCml +3IRZsZaENomM5sPNwuPYmtgpqKSj0jSiduw95bKFjCAXGT+8+SdlkSjegV+krGah ++aNtFfd3YykvxNIIMJGHgB7/rDXhHNQhbDc7pIGTAzH7mu9oa8F+QOb00PtJFtg3 ++BAPPDD5DKrguTpMAZIGGfiAlFgFIMiOg4S9hE8yMmHOont/sExV3dKCh2XJa1Kb +A/BarXVaGTginVgRsGapJS2IvLWd4dbMowDIjh8izjAWBDEBzsKUWwaNr5p71XqJ +BSCvNg0CgYEA65apdalqKqSt8y6zR8AMzjAbctzAUDncdg5pdu2GyJcsnh8NVgP/ +bs17yMtMoaY86Srl32BQJIwbeMduRW53lCFUnBoKLFwyq5ew3Tuh+fg93qQ67nAn +fKfxo2JjLC1l2HyzoEg4k9zqyLJQYLJKNFLax8rIR5CIqEHDMPSrB0MCgYEAy/ua +uizAgbxwIwijU0CKMNbH6xOC2FonhSr1uT4Wpkb/IxiOVbU4wG9zSXy2nsgkd2SY +3eAgvDWwsid+M8fQ1XdFXKo3yePB6xzs0Vs7NIoUHlAqu/PBiV4dCt84++bN8lqK +/JrsmE6m3240CqEjC+Kd/0Tjgq79NFQToWDndcMCgYBPQcCA9R3iesSKq4tk+BdW +xph1bA7G7rBchzyz5fUSRsmb6JZz+aRVgovCYaLGP0b+qo/rNlu/7+LOH0nZ0fAo +xY3RdnE1u07Qq5e01fsIPZuS621oChM+vMFuVgtHMX6x9kH4ClP+arQSEOs5nMGa +GMXBsVbvvJA9CuK/9ZAUQQKBgQCObivW7aKptCtUuxZX7kvP2FkV0rTdXu4TdTDI +3QqxpgdGuUHBpN1wuSF14agebL/RwiNfYb1Zzd+INj1P6KjwNOzwzEZSKT9hbPwL +HznS8Mslc3KzdHvh8B41VjKS6dFJ9WDxCzhDDUBF6Mxb07IF/YG3GaIGwSs6G67t +Ux2rQwKBgAZSYpxFHQXsTAS929L5huqvGX2s0SuWEOzP0CSzt1fpb52gXVGj7Qle +pDvDs4Q7ZCbsf2BlUqT4b2Zc4u2bzXqUsJOSazGDqJ26ypl5RQfZY+FRnhnB1AGm +2jyP8EmKcpcWe/HQrW5bEoPrZFC+2za3DG6hgGQEmA2ALEhujh66 +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDsjCCApoCCQDxyGnVVnCS8DANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMC +VVMxETAPBgNVBAgMCE1pY2hpZ2FuMRAwDgYDVQQHDAdEZXRyb2l0MRQwEgYDVQQK +DAtGT1JEX0NMSUVOVDEYMBYGA1UECwwPRk9SRF9TRExfQ0xJRU5UMRQwEgYDVQQD +DAtGT1JEX0NMSUVOVDEeMBwGCSqGSIb3DQEJARYPc2FtcGxlQGZvcmQuY29tMB4X +DTIxMDMxMzEyMTY1M1oXDTI2MDMxMjEyMTY1M1owgZwxCzAJBgNVBAYTAlJVMQ8w +DQYDVQQIDAZSdXNzaWExFzAVBgNVBAcMDlN0LiBQZXRlcnNidXJnMQ8wDQYDVQQK +DAZMdXhvZnQxETAPBgNVBAsMCEhlYWRVbml0MQ8wDQYDVQQDDAZjbGllbnQxIDAe +BgkqhkiG9w0BCQEWEXNhbXBsZUBsdXhvZnQuY29tMQwwCgYDVQQFEwNTUFQwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7uAN8aks/0wDIoyx7XGcKlJsZ +oDZGbwLZIOztjD3Mbi3Xpv2je/96iQy1MBY4I9u0E33YeZH+ruuTF8cQErG5MBs+ ++obv+sSqG3R1FK7f/RAXK9w5J1Hj06eemPe1pkgb4qLAh3mxyHprXZV5l8IXXOVH +FA4d533yKMxLELcZuPitVUTLYUB8NA1LczfxfCxXCTh8IAplfPX2/EqB69BfXZ2r +nD/Qt2z5ZUH/rxjK+rwar31SyQWiXCjvbKwtzVuuTzA/QFBW/paQhwaKxnkXcxKY +mt6cFHMHYYdEGhGNNvcRFljCkcoEGMfzJCmYzBVYBcYyw5EqSURPgUw2DScJAgMB +AAEwDQYJKoZIhvcNAQELBQADggEBAA/lC4Ut2zYNLOQAE28wBwI5Q9BTDpnJ/GlX +ztdmFBPbq70lXs0M8mFhx32cTowuP/8uLc50R1e1pHlWrjAkP7GZCWUdTbB89eE+ +Nv6BLs2HOObztTdfVy0KfAhRc5gBXDxLLB9ksUUdlmcm1cOytC1jyvXFnu2/wR2t +afIMrI6qRD+yKhNh9cSCl0vJadCHuhEq5IfsFqgZeiHxDwwYmlddS0yxHsn5iT1r +avzGgOOcFhOoA5NbJB0S6P6ZDfubPWqgcZ8rf+QCKo8zri+Vr9evTP5MkwDWRJys +5w0z19UVk0ZwHQsrhg++g99Xvx6MPWBrnzDyEXxG30Y8JevXrAc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIJAIP3pt4QUWolMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEXMBUGA1UEBwwOU2lsaWNvbiBW +YWxsZXkxEzARBgNVBAoMCkNBY2VydC5vcmcxDzANBgNVBAsMBkNBY2VydDEUMBIG +A1UEAwwLc2VydmVyX3Jvb3QxIDAeBgkqhkiG9w0BCQEWEXNhbXBsZUBjYWNlcnQu +b3JnMB4XDTE4MDMxNDExMjU0NVoXDTQ1MDczMDExMjU0NVowgZkxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRcwFQYDVQQHDA5TaWxpY29uIFZhbGxl +eTETMBEGA1UECgwKQ0FjZXJ0Lm9yZzEPMA0GA1UECwwGQ0FjZXJ0MRQwEgYDVQQD +DAtzZXJ2ZXJfcm9vdDEgMB4GCSqGSIb3DQEJARYRc2FtcGxlQGNhY2VydC5vcmcw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPq17BwejsrvNl6I7cip7L +tQvX/p4EMCi0i2HsmlGD0J+Vpq9Ws3xokekOO8RITBfD5JDoX6ufZf28bc26X4Tp +G8if18juzrGZD38ALfeuoYAVymuBd4NF2xilwX+uqH5E4lkqBOZo3nQ/f1aTKQVT +6DZmr+V62GGaaMewaUOyZ0fZM4tS5ncuvSCMtuLHH5gy87e/lzj8Zbyek6ej2lUL +lwaCMOGCOoxhxUr8rorMefUOMZ4IzObSJ/y6XqWJe8yjSrAmyRHBmpGmCiMUnrkD +4FTY05Cyn2kncCHlYFL18C0utwTBYK1Gv8qampSD+e7ZWKTO1kEMrbZv3kwQdTfp +AgMBAAGjUDBOMB0GA1UdDgQWBBQ+EGb7hYQffkb6GXTWVMyqzz3joTAfBgNVHSME +GDAWgBQ+EGb7hYQffkb6GXTWVMyqzz3joTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBFH2QNBHlth/nOIzyxPEXAyvkWDZh2/hukXlK4zWvWyiLlJXr9 +t5goWFzjbqpsCfN3TOb+CDBd3RYhhdnhxXMYmydR77+SlzZ6Lx0YBz7zNV0OUKTK +5Pnlh8GAP7CjU8A0pHf3auAgmBsVmX7+uFQcuRFzvc1LCL6q6t7pM5HH+NvJs7K+ +C/nQB9yW7PWXatPjNVY2YY5YJi2EuUdCFFcAQOtI90Xa8xVtTONYHh/QS7/egVWh +vdsuKx0I6SvMXf2AlVV2NSzcIqps5h7flYAw5sBC7ETux6DV3PgbikLybgxzHlhU +NhCYi7/M9o+QdQKGFc+Pdeapkl8a4GuuR3ax +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDqDCCApACCQCpjnaAoaUGmjANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMC +VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFzAVBgNVBAcMDlNpbGljb24gVmFsbGV5 +MRMwEQYDVQQKDApDQWNlcnQub3JnMQ8wDQYDVQQLDAZDQWNlcnQxFDASBgNVBAMM +C3NlcnZlcl9yb290MSAwHgYJKoZIhvcNAQkBFhFzYW1wbGVAY2FjZXJ0Lm9yZzAe +Fw0xODAzMTQxMTI1NDVaFw0xODA0MDMxMTI1NDVaMIGRMQswCQYDVQQGEwJVUzER +MA8GA1UECAwITWljaGlnYW4xEDAOBgNVBAcMB0RldHJvaXQxFDASBgNVBAoMC0ZP +UkRfU0VSVkVSMRgwFgYDVQQLDA9GT1JEX1NETF9TRVJWRVIxDTALBgNVBAMMBEZP +UkQxHjAcBgkqhkiG9w0BCQEWD3NhbXBsZUBmb3JkLmNvbTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAMCzhMkEhaMy6DkmyTKOhKYJKGsM64SU+6N/TCkv +I3eaj2Vn38gJ57QSwowmF/PtnP0LMPNfUwSmWETHHTGx4hqnAEomhy+4OIpByagZ +LUg8oGXAp+Vx/YyIxTMz6QgACjUV8iHnJWf6SHq+zhGQpo3S9Y2mivOzpAJY1n2n +Ae/FqfNS61CYLBmIh42qt5wOMweiH1Ny+mYUpT7RFMSeDHiiBW4frnJSBKR1xLVW +Y41A70Kto3QZFnjPTZ2eXyXomt+iV+87VWDfAV/edndblVk4QylJO/uPUQzlSrv9 +oY/Y79AcdPjub6xA8Df/H33SNVtSyGvSKEaS5GP7mw6zF98CAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEApIRshx5Ev16JS0DNKYduKqf2N7c7HjGkWw9cdYXBFlkha5uf +2dRe5MMCQLW7q2783a1gBXKxCc4UHks8AeFxajC2KxyTdmmkQsQBQ5Ih6S00K10S +Kk8EIjJ0k4gQyB58vb38Vf494ZfR8avDmYEppdff4DRUdvAgwCRPk9NhEKXLwaZV +0ghqvgLeZ/cb5kiIJW3NHxN9acluSdQLYBdVrRP9MyLzmu13BhcCUgodz4eKxyqY +5PWNPuFCMQ5eVMYVINnZKtzupWISyX9mr1/SJ3evAiroD/6kxxyRQVxtmxLYw+aL +6PRbXGDzEJQvX5frg7WpZLvqsRq5m6KzdXGpXA== +-----END CERTIFICATE----- diff --git a/files/Security/GetSystemTime_certificates/spt_credential.pem b/files/Security/GetSystemTime_certificates/spt_credential.pem new file mode 100644 index 0000000000..9b59d8d7fb --- /dev/null +++ b/files/Security/GetSystemTime_certificates/spt_credential.pem @@ -0,0 +1,95 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAu4KiIgfAGfM7gcc1n8836HMIC605p0aNntOBXD0RszjjKj11 +ecArf3rgtsVJxEVbSY8kcCNL8HGkXpVE/ZYWu2RqmWIccRwDFuFZv6al6Xrg41p7 +1TAoN6oqcOlD6WC6xGYqSqjVBDeive/VtF5lyNw0nBs4k9Bx+xS21G8r9Bx9rrlD +NMdISF76C0j2JT7ovPdOuwSwSjfAAtidlqrMo/LQXdNOAX9mFuq7tAgeE3vLmm4v +l+I7RCMZ3mppoPTw2b83HVJaZATwZgYlMd4NKhDlzBxawBY/UaRZjcY7i9z0QJHu +BP+zRIOjd29JmdLhwoEnyggoHeFjJAsUxdkycQIDAQABAoIBAQCDTxnHBvJpucFk +QmK1BOG78EIkGyySjX/DR44BT+rDPQUnoV5Q4lgTr7MJiuL7hS5GNu1ncfBN8ucO +LS3g/2fv1oQn4WLVeq5XKXw2D7eD5z7xN34cbtrbEFkkNNYP6mMgAgN/wPdbOrLG +m9tlse1JWZul7hISwRfwojLeVPPMv6tgahfB3t9EbiAc1v6v/vcK7ROFSbDScuLP +FAAWOj0dMdVx+u7Z3GMvLvSamKo7FasAnOwx9Sbx5fY/glZnDJv/xd8pS620Jyqd +pExY9uIRgn2aPvrXbfcK5PCHi6LnuXefJynVVNVG/qtgPeuGd+ACm7PweGbSo86t +aItevmy5AoGBAOo+NE7AAoNBayZ0+0k4Pq3tZuHvUNr9HM4JsszJHw6mxjbNC9hE +7wziBs+8qPsBDAMZ2+XJFSILvtoYH1I5yhyC3nQbWD25jMC90FINQdChBwDqgh7q +abYkE96suGJSMVS0Zk3elxsI6gxffJv4c6aavGp4dUJwf22h8bMDMCzjAoGBAMzt +OcXQAAN405rDdRIKHtBndFH2kZsFTlLJU/ZMJNpLleB2v++fyQbo/oqey8J+pAEv +XcWXaiCZi55K2OuBypc5UJ6CbJRfS2avkXYdtXz7bjzD5s2tN6DEuBOMWDZ+g0wk +CNuICx0rnQ7FhOcxoqrTXNyTwuUUh2FqL0nHVfebAoGAQEr6iHLjPauDAXcyUZKC +gbKbfn/1LWYztcmrrdG2GItl9Dyrd5zUEDEptXMO3nYXGfLLDHL4vfODWtEsJ6F8 ++/5fmHa47Zg0LeLrftnsqprIFVRIirvEcB3O5lt58GKm75zkR5NE3kLAGs1KonS7 +KYtnE8IkTSwbjbfZY00IuAkCgYAlYcTfK9FE0N6w5aTOdKAoXibe6L6o66/c9DLn +w/4ZAB7IAoGCwcAXDZuZR9xdj2J1gOF3MObAKaJJbtfhJh0BtwfY0mviKPwFMFO1 +mzfHI8p5NTc+H7H9FsWJc1mIH03uLsia21dDq/gLgMZ8shY9WS8gYaf0x+jmQUt9 +BurMrwKBgAXTH967KW5wNXEZQozgHEIHnU7DsTWfjIP/0HeziNzND0IZzhqyX0iQ +Yg4i5AljQKLVyszitV9BAg/AqFooIqX/qjykTaadM5IsOsAProkQL4Pkk8ov4jx7 +4D2FlvbpZ5CFW9DNkB/KeEQ53bsJbR8FTrR9sDIOjxRLyDlCI6th +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDqTCCApECCQDFtoVyxnOs6jANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UEBhMC +VVMxETAPBgNVBAgMCE1pY2hpZ2FuMRAwDgYDVQQHDAdEZXRyb2l0MRQwEgYDVQQK +DAtGT1JEX1NFUlZFUjEYMBYGA1UECwwPRk9SRF9TRExfU0VSVkVSMQ0wCwYDVQQD +DARGT1JEMR4wHAYJKoZIhvcNAQkBFg9zYW1wbGVAZm9yZC5jb20wHhcNMTIwMzE3 +MTAwNDE4WhcNMjYwMzE0MTAwNDE4WjCBmjELMAkGA1UEBhMCUlUxDzANBgNVBAgM +BlJ1c3NpYTEXMBUGA1UEBwwOU3QuIFBldGVyc2J1cmcxDzANBgNVBAoMBkx1eG9m +dDEPMA0GA1UECwwGTW9iaWxlMQ8wDQYDVQQDDAZzZXJ2ZXIxIDAeBgkqhkiG9w0B +CQEWEXNhbXBsZUBsdXhvZnQuY29tMQwwCgYDVQQFEwNTUFQwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC7gqIiB8AZ8zuBxzWfzzfocwgLrTmnRo2e04Fc +PRGzOOMqPXV5wCt/euC2xUnERVtJjyRwI0vwcaRelUT9lha7ZGqZYhxxHAMW4Vm/ +pqXpeuDjWnvVMCg3qipw6UPpYLrEZipKqNUEN6K979W0XmXI3DScGziT0HH7FLbU +byv0HH2uuUM0x0hIXvoLSPYlPui89067BLBKN8AC2J2Wqsyj8tBd004Bf2YW6ru0 +CB4Te8uabi+X4jtEIxneammg9PDZvzcdUlpkBPBmBiUx3g0qEOXMHFrAFj9RpFmN +xjuL3PRAke4E/7NEg6N3b0mZ0uHCgSfKCCgd4WMkCxTF2TJxAgMBAAEwDQYJKoZI +hvcNAQELBQADggEBAHonEpso9no3n9hhRGi2STGabICRs4brMmfOngsr1EWHZQrh +eRexYJVIJZUrj4SIYnt6DmMlLaMQTGJXwZ4ZrXYwC7KwCEm2QHBV7IoAQFy6by/m +b9CpDhTtaFH1+oHy+ILuwVrt64rHZMcM6gqqtfiGrSoVpp7zcpoC/BIrq6oFm6BH +GLkVWK/0mtZY8DgxZqO2E3SUJt9Ch8uyUWpvAG+Y2srb9ZP+hwHWb6u3KlZmqS3x +brx66FQRt/Al+eir6ssx8FxuiMpZnasSrIsefbZzOrveLiQrlQ2KEq8r1y95U6gZ +6OBIAAVM6T8I/uXSKJQAx6zrFdK+Epbw0P79Bj8= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIJAJOyycRs95twMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEXMBUGA1UEBwwOU2lsaWNvbiBW +YWxsZXkxEzARBgNVBAoMCkNBY2VydC5vcmcxDzANBgNVBAsMBkNBY2VydDEUMBIG +A1UEAwwLY2xpZW50X3Jvb3QxIDAeBgkqhkiG9w0BCQEWEXNhbXBsZUBjYWNlcnQu +b3JnMB4XDTE4MDMxNDExMjU0NVoXDTQ1MDczMDExMjU0NVowgZkxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRcwFQYDVQQHDA5TaWxpY29uIFZhbGxl +eTETMBEGA1UECgwKQ0FjZXJ0Lm9yZzEPMA0GA1UECwwGQ0FjZXJ0MRQwEgYDVQQD +DAtjbGllbnRfcm9vdDEgMB4GCSqGSIb3DQEJARYRc2FtcGxlQGNhY2VydC5vcmcw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD2OsoeJefNo6+e06B1ytTS +NZu78/975ACCGgntwGOrDX9rS4GW3kZfxcn5Do7jsiQuMZbQ6lcT5HdTJ/SaEXlX +he78d+Tw9BF70LfwFOPhvnRxxSdcCtUMqYL64ZjmO0JHub0bFBt50dtzajWnzq7O +EKGo4E2qFpo4+DC8lTqtaCpjK9MW3kOwZw7as+RYf57X/HMCRWG9vjABPUJ85Tvp +iBmKVCAgVPsdiQPp1NKgBIBWbekZV0/SeoNnZixc1S/J0q+MSECO1YNwNar89fJv +2XXkslvDfJxz/GjPqtBOGu7LyvcobTctedqdea62lPUf+FnK0WNqfjq0Q/J2ALeN +AgMBAAGjUDBOMB0GA1UdDgQWBBTvvVyK2AKsYwfnbn2zHN6/nnwJWjAfBgNVHSME +GDAWgBTvvVyK2AKsYwfnbn2zHN6/nnwJWjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQB+shDSEVbiSbN130mZ17al9Tmul94hwZh9sPzeY0CbB5ImII7e +lbWKF5ScALIStrdGSGk+EUKgwfx7zBLj61LQajskyu717Q4IYPp7fn/6kN2eyrxW +GndLdn4AhMBAYNNYcK1r1Ji0lLJqoZF0ouAsEAW1AWPSDlB+St8kqGqhmEn3Race ++EC+noa/gc8Ot+x7VtRkL4z8Oo/nbbGBNqu5Qxm7zdz4lh5jcHEXQOq6EbWSqv+U +evanWYFVceiTqXGf9Aw7exAgTGH+Sr1d01g8r57kUYFetukY+UFRvCYJs8e7ER/O ++RQhR87cysNPZefar2oAj2d/berFh2B1a4TA +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDrzCCApcCCQChM2uDQRBkRDANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMC +VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFzAVBgNVBAcMDlNpbGljb24gVmFsbGV5 +MRMwEQYDVQQKDApDQWNlcnQub3JnMQ8wDQYDVQQLDAZDQWNlcnQxFDASBgNVBAMM +C2NsaWVudF9yb290MSAwHgYJKoZIhvcNAQkBFhFzYW1wbGVAY2FjZXJ0Lm9yZzAe +Fw0xODAzMTQxMTI1NDVaFw0xODA0MDMxMTI1NDVaMIGYMQswCQYDVQQGEwJVUzER +MA8GA1UECAwITWljaGlnYW4xEDAOBgNVBAcMB0RldHJvaXQxFDASBgNVBAoMC0ZP +UkRfQ0xJRU5UMRgwFgYDVQQLDA9GT1JEX1NETF9DTElFTlQxFDASBgNVBAMMC0ZP +UkRfQ0xJRU5UMR4wHAYJKoZIhvcNAQkBFg9zYW1wbGVAZm9yZC5jb20wggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDocPnd6WI6P8ahHu9UI3RxWzbKL3Bj +zbEEoVS1RGGiqJcTT99l9JWxYcnXkT2+K24cKKhgZe+yLhs1NZKDu2FxpBL6Tylq +/GgLIl5q7VUhjwLOGpHAY2v3qt4OmkaSMYTW/OxGoH6COya3YJ476yE0TaKRwtX0 +AB2efjWdydSMQMcXPshzjKWas6s94cr0DWnXbhZG1yFJF1qAQ8AstSo5Dp/Wexl5 +4/Ia1uxwAlMAgzhAn/hv6iQEmSqrIXV+UAkkIDutn+ZnNmAHBp89XtSC28o2wOa0 +RZDaRhbZ0eHsgqFwO7sXp9ere2uKiEDP/fd3smwxQcj3sA3pKy2vQ2BlAgMBAAEw +DQYJKoZIhvcNAQELBQADggEBAKHQgzyuTOPvL58eqG4nh2kQrRsT4yXTyymKJYpV +kEy7VaNAXhM+YpVlxGtcNNb6d56m3Vl6riTgEgVoqnbhse9J6II86uu9lvEgZbgW +D4eBBhdLwY22sIxupJ1vDJ4SaPweois7ph9rUQjvtpWQQaT0lnbw51H/DCCT6lxz +TjeoFED1qjFP8rNaNqhmzjs0b2KFMDB+itD6JBAqITnaoweBnYhxUC4F0xhSDng2 +qm/2yiX3zmkPSIK1MDmDvg7nIIIbfJwW6xNfkbgbfl4q5eCBgAL38REsMT13mEia +U8i7rb5q4FAq6iUUFwZxtPRyUJGvNTvuZH+75Yu6JZb2tDk= +-----END CERTIFICATE----- diff --git a/files/Security/GetSystemTime_certificates/spt_credential_0311_16.pem b/files/Security/GetSystemTime_certificates/spt_credential_0311_16.pem new file mode 100644 index 0000000000..a8ea22827b --- /dev/null +++ b/files/Security/GetSystemTime_certificates/spt_credential_0311_16.pem @@ -0,0 +1,95 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEA6ofSUW8xNVsxIG2GkIS8bg4yO5O6ijCTp8dQiF7LXYX/mNV/ +7yj9n7RB4chuRwJ2zeedEezRPpLIeRyQZ5r604KfXzPPX4GQORUY0C9666lEpwp+ +nrYB0mn+ZM60z9yl4+2mwZczY3WXZc0/0dECuuj84RSGEBZRvSFldy38Ffe9r0uy +iKvIPAQit/xItElP9IY2Rz6MkBsMXIwvBZA2PFy5W1qdz7nXQbTgPtx/gRME1eau +679Q8WTSqlPxv9Wz+MpMjyTdziD9TVK0/k4+BDwUgTL+nn/LxxAVsyto5BHs3We4 +K9R4U2ELyst58s5nohvqv+YY5Gv3xfZ7jwKJ6QIDAQABAoIBAQDJ9F9FRIyJN5ec +JvRDKingU1UqPFHbgW0Egvt0ErzoMeUhRGfAF/oeNeitdhyQBS0srY9xyg185oS+ +1bv7m1b2H3sBTen6geUhYmtVii09FStK9ByIqo3zFNa9E8pbW9N17EU2Wu8jbDUM +squMD4FcVhi78SJoY+/K/yESeYSjnGVkypFThb78UigTjrNC27S7G3wsqFEGDSh1 +nNWyXFq4Glo9vj1QTa8xJSz8euDNxSoalB1mHJOgDGz8OR4Y3lgwgKhVa/vHao5A +QZGWTgAETq9LR9J4C/+9Wjzg4havJ8fZZ6+C+MIVb6iPoIPZE6gWlM3c3lW14AIz +GkyeE3ZJAoGBAP7olkRg24eN9vrsyhIWVP/pE8O1xUTIRJTPSrPCI63E8E7LIhi5 +KffWw+g16vCBltmX0g//LGIXTuglwfZ2bCh5IANm09xTcUfNI6ireARILIfgMPLP +5Uhe5xFjelr/NXwEG6RSQU+OnoVFgp6cHakNmxqtqQUjKoSBtwuEGC1TAoGBAOuI +5culzuFhrr6nP0h97tWwTaS6zliU0B0olLmorrG58pasc83dmZwfdxHPxN7XrxWo ++zoSmy5gAVW5pOfMi3sCka+x7WblFnBdPwjgaBxPmrcEGjLIhdjWPyAmXJ45NNkk +M8Sdy2whoKqv4mcl/cGJYqBcNxiCChkr0n7t0chTAoGBAMV6ww9uSiSWIwT6dQHW +MzufAiTYqV9EF32Bqkng2WtB6znfvSaSLKVIyLUZME3q10bzi1XBRk0n6YWH2uBp +lhk03UxFWVSTgGszzbBaRrxqfbU2RjWWQfbzLugVvTDKDlFpjVCcOOS9hKmS1EK0 +h3X0iHj+mLbWK5ZEN97AE0rpAoGAO2dmlas2908ctIcYBd+FKi3yFzbqLhsyNfhz +MjQiAz8juO67slNOl7qz3DErtQxu4yagXjAtJVAfZhCRT8kd8KNgPRDCEG5871AF +QubeOy20lq4ZMW+zmlHG0AP83gcNlip0SAWINbhxfjsn/d3uFy7gShOX7b12cIzF +5S9z9nMCgYEA6duZkj4Hz3PQ2306LYHupTT8lDmI7F/x448tBunJjvVlNhLYsVm8 ++V+Kc6XioCmwcO2L3hwLY53cSjjZX8FN5fpIXRoMzoC3j/vQUQnwhGcbGbHfK4Ys +ZE4PY2lKjntqndkF8u9fLrjdkk8lqu+gLVQdlklMv+bvyKbr51bg1d4= +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDqTCCApECCQDFtoVyxnOs5jANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UEBhMC +VVMxETAPBgNVBAgMCE1pY2hpZ2FuMRAwDgYDVQQHDAdEZXRyb2l0MRQwEgYDVQQK +DAtGT1JEX1NFUlZFUjEYMBYGA1UECwwPRk9SRF9TRExfU0VSVkVSMQ0wCwYDVQQD +DARGT1JEMR4wHAYJKoZIhvcNAQkBFg9zYW1wbGVAZm9yZC5jb20wHhcNMTEwMzE3 +MDkwMDEzWhcNMTYwMzE1MDkwMDEzWjCBmjELMAkGA1UEBhMCUlUxDzANBgNVBAgM +BlJ1c3NpYTEXMBUGA1UEBwwOU3QuIFBldGVyc2J1cmcxDzANBgNVBAoMBkx1eG9m +dDEPMA0GA1UECwwGTW9iaWxlMQ8wDQYDVQQDDAZzZXJ2ZXIxIDAeBgkqhkiG9w0B +CQEWEXNhbXBsZUBsdXhvZnQuY29tMQwwCgYDVQQFEwNTUFQwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDqh9JRbzE1WzEgbYaQhLxuDjI7k7qKMJOnx1CI +Xstdhf+Y1X/vKP2ftEHhyG5HAnbN550R7NE+ksh5HJBnmvrTgp9fM89fgZA5FRjQ +L3rrqUSnCn6etgHSaf5kzrTP3KXj7abBlzNjdZdlzT/R0QK66PzhFIYQFlG9IWV3 +LfwV972vS7KIq8g8BCK3/Ei0SU/0hjZHPoyQGwxcjC8FkDY8XLlbWp3PuddBtOA+ +3H+BEwTV5q7rv1DxZNKqU/G/1bP4ykyPJN3OIP1NUrT+Tj4EPBSBMv6ef8vHEBWz +K2jkEezdZ7gr1HhTYQvKy3nyzmeiG+q/5hjka/fF9nuPAonpAgMBAAEwDQYJKoZI +hvcNAQELBQADggEBAFBC7PzhU9VtOBugvscjp615zm9UEes5FciMPPmkLLOToySr +uutCNHXMEyCpCFECxnC5mBHyOoI3IGl6CYs8qF1WT8VKQHVm6xkYeXGDSyPg1B0g +/BoYEJub16dbQxkOugvCEaYlLxMrvIzbcUqJFHn7d6/iqUhUzG6NwFpKPFgbBqoj +cQ6AOG2+LmFzPuJS9Jq0XtQrtXLCeAO62ukRhzWSOqqhOeF2y+IObkelSpGBz/i0 +21wXtMWoQ9+tBThD8tIBgm2CMeFfATKUZM3OPU7lgIvZakih9c4sd9f6PNL+6aFG +QEzBsBbFy4gmejYKrNOuqLBGbywinKz2oNQbs5s= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIJAJOyycRs95twMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEXMBUGA1UEBwwOU2lsaWNvbiBW +YWxsZXkxEzARBgNVBAoMCkNBY2VydC5vcmcxDzANBgNVBAsMBkNBY2VydDEUMBIG +A1UEAwwLY2xpZW50X3Jvb3QxIDAeBgkqhkiG9w0BCQEWEXNhbXBsZUBjYWNlcnQu +b3JnMB4XDTE4MDMxNDExMjU0NVoXDTQ1MDczMDExMjU0NVowgZkxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRcwFQYDVQQHDA5TaWxpY29uIFZhbGxl +eTETMBEGA1UECgwKQ0FjZXJ0Lm9yZzEPMA0GA1UECwwGQ0FjZXJ0MRQwEgYDVQQD +DAtjbGllbnRfcm9vdDEgMB4GCSqGSIb3DQEJARYRc2FtcGxlQGNhY2VydC5vcmcw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD2OsoeJefNo6+e06B1ytTS +NZu78/975ACCGgntwGOrDX9rS4GW3kZfxcn5Do7jsiQuMZbQ6lcT5HdTJ/SaEXlX +he78d+Tw9BF70LfwFOPhvnRxxSdcCtUMqYL64ZjmO0JHub0bFBt50dtzajWnzq7O +EKGo4E2qFpo4+DC8lTqtaCpjK9MW3kOwZw7as+RYf57X/HMCRWG9vjABPUJ85Tvp +iBmKVCAgVPsdiQPp1NKgBIBWbekZV0/SeoNnZixc1S/J0q+MSECO1YNwNar89fJv +2XXkslvDfJxz/GjPqtBOGu7LyvcobTctedqdea62lPUf+FnK0WNqfjq0Q/J2ALeN +AgMBAAGjUDBOMB0GA1UdDgQWBBTvvVyK2AKsYwfnbn2zHN6/nnwJWjAfBgNVHSME +GDAWgBTvvVyK2AKsYwfnbn2zHN6/nnwJWjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQB+shDSEVbiSbN130mZ17al9Tmul94hwZh9sPzeY0CbB5ImII7e +lbWKF5ScALIStrdGSGk+EUKgwfx7zBLj61LQajskyu717Q4IYPp7fn/6kN2eyrxW +GndLdn4AhMBAYNNYcK1r1Ji0lLJqoZF0ouAsEAW1AWPSDlB+St8kqGqhmEn3Race ++EC+noa/gc8Ot+x7VtRkL4z8Oo/nbbGBNqu5Qxm7zdz4lh5jcHEXQOq6EbWSqv+U +evanWYFVceiTqXGf9Aw7exAgTGH+Sr1d01g8r57kUYFetukY+UFRvCYJs8e7ER/O ++RQhR87cysNPZefar2oAj2d/berFh2B1a4TA +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDrzCCApcCCQChM2uDQRBkRDANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMC +VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFzAVBgNVBAcMDlNpbGljb24gVmFsbGV5 +MRMwEQYDVQQKDApDQWNlcnQub3JnMQ8wDQYDVQQLDAZDQWNlcnQxFDASBgNVBAMM +C2NsaWVudF9yb290MSAwHgYJKoZIhvcNAQkBFhFzYW1wbGVAY2FjZXJ0Lm9yZzAe +Fw0xODAzMTQxMTI1NDVaFw0xODA0MDMxMTI1NDVaMIGYMQswCQYDVQQGEwJVUzER +MA8GA1UECAwITWljaGlnYW4xEDAOBgNVBAcMB0RldHJvaXQxFDASBgNVBAoMC0ZP +UkRfQ0xJRU5UMRgwFgYDVQQLDA9GT1JEX1NETF9DTElFTlQxFDASBgNVBAMMC0ZP +UkRfQ0xJRU5UMR4wHAYJKoZIhvcNAQkBFg9zYW1wbGVAZm9yZC5jb20wggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDocPnd6WI6P8ahHu9UI3RxWzbKL3Bj +zbEEoVS1RGGiqJcTT99l9JWxYcnXkT2+K24cKKhgZe+yLhs1NZKDu2FxpBL6Tylq +/GgLIl5q7VUhjwLOGpHAY2v3qt4OmkaSMYTW/OxGoH6COya3YJ476yE0TaKRwtX0 +AB2efjWdydSMQMcXPshzjKWas6s94cr0DWnXbhZG1yFJF1qAQ8AstSo5Dp/Wexl5 +4/Ia1uxwAlMAgzhAn/hv6iQEmSqrIXV+UAkkIDutn+ZnNmAHBp89XtSC28o2wOa0 +RZDaRhbZ0eHsgqFwO7sXp9ere2uKiEDP/fd3smwxQcj3sA3pKy2vQ2BlAgMBAAEw +DQYJKoZIhvcNAQELBQADggEBAKHQgzyuTOPvL58eqG4nh2kQrRsT4yXTyymKJYpV +kEy7VaNAXhM+YpVlxGtcNNb6d56m3Vl6riTgEgVoqnbhse9J6II86uu9lvEgZbgW +D4eBBhdLwY22sIxupJ1vDJ4SaPweois7ph9rUQjvtpWQQaT0lnbw51H/DCCT6lxz +TjeoFED1qjFP8rNaNqhmzjs0b2KFMDB+itD6JBAqITnaoweBnYhxUC4F0xhSDng2 +qm/2yiX3zmkPSIK1MDmDvg7nIIIbfJwW6xNfkbgbfl4q5eCBgAL38REsMT13mEia +U8i7rb5q4FAq6iUUFwZxtPRyUJGvNTvuZH+75Yu6JZb2tDk= +-----END CERTIFICATE----- diff --git a/files/Security/GetSystemTime_certificates/spt_credential_0317_22.pem b/files/Security/GetSystemTime_certificates/spt_credential_0317_22.pem new file mode 100644 index 0000000000..1147e22c48 --- /dev/null +++ b/files/Security/GetSystemTime_certificates/spt_credential_0317_22.pem @@ -0,0 +1,95 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEAymx326Wn7GT4kWX9ft8ZY2LJhA3khWhwDJAkH3A7YnlY9Bea +0R3yoi5W5e97csXk0ykHvgzxLhjnN/Il/BWPnN108O1AdahpnyMXXKQlcnnnrvz4 +Sgavr5vfQcgyAXW2KYlDUbQjq445iBcOFa23YiOccMroTo2T/ps5i7o23zJGqdgW +JV4j5sP+KpKSrPePgcTcX86fI/5epbvS+a9Rhtecqrc4h38A/24rjpUu7EqPP31u +KSZYTR9gbNHJL7R94eLyqJO/DBy+PBWIZdo5hYcirnUb5xz2lQOmheXhelbrtiNY +KOK84+ysX+MG6aDL6A5RjimMBwQVo4+1b+NJjQIDAQABAoIBAQCSCVkbZNLWMC5I +L42H54qYch+yHpe8S5Fy7tawu7aMH8G2MAVoUrPGn6nfrzufnPeuA87rJMknGZ5O +dWtEB4YZhIemfXPgroSs45MqKd4+TYaBb03tkg9ToR+bhMPW28Z1ButDWbPWRABr +lz55E1/W9Jwbn7ejXG7l47TLgqets32eUtC17GcnKtWco4BscVAU+BlPHzlIdTQQ +SJd/qNyqrZ2Spiz+n6EchB6VfyhDWj802Tg33NA+HGORfZ1Ztz2Wx8yE0LDO9brv +z2CIoYGpXrIs10c+SOV4T6CRAtIC4pXrUFouZc96PMKtFnwXoMLDvhU9DdslHbrT +ougW1O0dAoGBAPO9sfkat+QRUOO2KRksqvCLeOp8K2CBlaFpooEHltGxU+xGsCv6 +k69DeQekh9fclZwzWko0pilYjYeFf61P58QU20gBcTZMu1OpXYbjgylce5ZsxXQB +bgrWnCwxEIKGPzcIVPV4HUWexjCzV0feKaWOrUeiQ3KPQ/zjBACq9YnjAoGBANSa +ygkMKNALUsZh2GT5r97CRhW/cddVhuOuF0ZNpBvdRvWXWjNRpNzV8hShoqqIcMt7 +zWRDDDuQ5FUiEmG+6MKVP5GtnAO3fSDBUxWXW9TnyHA6gnNEDP4dI9zvhvsGtwxd +xL1eENzUFbLljFdEAlpUlo4eoE0HlIWIF0D/yfnPAoGBAIrzXG9HNQgWewelhB5u +4XBKAn+ik9Pra9Ld9p8aJXebYN10muAndGPY0jlyKWL8xGmMuO9Ovl8ZtW1JxLSX +teeJgEy3TcQH0E7sYX4RW2eL6oShs5rjaclR+SwUOHZAc+86l7xsYjubPR7sTliR +JSrVgKEytsKrO7YB8Pk0fM/DAoGBAL4GsEhP7vas+EpK0FDIf7J6MIxltkoCrvM3 ++qOi5+jj6fW/VycBdXrRW3OnWS5Vj4PA3z8bUoa3Je8V6holugOZxNzfsM/9pECv +qyRkSfdNSHFPSqPeEkLbJt/l097xDJFoCl48ApRumApzc/HX3saATqUuqJbRDKYh +kq9NMWkvAoGBANrJVA2O6UmvuUQVfR8oXqvDslttfGYmN2aAd/J3w3jt2tOWkhUO +1I1ov6LMaf2dv1+ElomK0hDNCeynschYwcS4PsT9h6fJkxwkQ89/Vt9BmC39tW/0 +KL58MOmMc2T62S816JlCsrLC3CoQjOtrkZDcZTQXfrCDIg8ad9dI2elF +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDqTCCApECCQDFtoVyxnOs4zANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UEBhMC +VVMxETAPBgNVBAgMCE1pY2hpZ2FuMRAwDgYDVQQHDAdEZXRyb2l0MRQwEgYDVQQK +DAtGT1JEX1NFUlZFUjEYMBYGA1UECwwPRk9SRF9TRExfU0VSVkVSMQ0wCwYDVQQD +DARGT1JEMR4wHAYJKoZIhvcNAQkBFg9zYW1wbGVAZm9yZC5jb20wHhcNMTcwMzE0 +MTIxNTMxWhcNMjIwMzEzMTIxNTMxWjCBmjELMAkGA1UEBhMCUlUxDzANBgNVBAgM +BlJ1c3NpYTEXMBUGA1UEBwwOU3QuIFBldGVyc2J1cmcxDzANBgNVBAoMBkx1eG9m +dDEPMA0GA1UECwwGTW9iaWxlMQ8wDQYDVQQDDAZzZXJ2ZXIxIDAeBgkqhkiG9w0B +CQEWEXNhbXBsZUBsdXhvZnQuY29tMQwwCgYDVQQFEwNTUFQwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDKbHfbpafsZPiRZf1+3xljYsmEDeSFaHAMkCQf +cDtieVj0F5rRHfKiLlbl73tyxeTTKQe+DPEuGOc38iX8FY+c3XTw7UB1qGmfIxdc +pCVyeeeu/PhKBq+vm99ByDIBdbYpiUNRtCOrjjmIFw4VrbdiI5xwyuhOjZP+mzmL +ujbfMkap2BYlXiPmw/4qkpKs94+BxNxfzp8j/l6lu9L5r1GG15yqtziHfwD/biuO +lS7sSo8/fW4pJlhNH2Bs0ckvtH3h4vKok78MHL48FYhl2jmFhyKudRvnHPaVA6aF +5eF6Vuu2I1go4rzj7Kxf4wbpoMvoDlGOKYwHBBWjj7Vv40mNAgMBAAEwDQYJKoZI +hvcNAQELBQADggEBAJ3LsGChd01u/Zlk0Vg1NmFb13Ootxj38eKnTSdUXToGQVrw +biIWLXPKFPP9ImO6tRXrQlMIMrjy/t4sznDL1+Ep5KA4oyIzy7IAUTpQh3iAwI3S +hMywsKls0vAbk3GOs4HoQNU0GMfKiPA6F8V0nXTcQRuUX+npRAqQCqqFOyTRMLiZ +vCs7otWmGNfJdypraj+LsUbjsv3OzolYLDBfK6SZwlQyzvenlKkWcuBdchrmnXB5 +I8Q59lEmOHpbuSVGgyguD26XmlDPZKc5AKBmfUiFppgNQkNuyNjclWFHpef01BH5 +W+kUP2IbXx5ZI3SiHjfnJvLSiu3SiIXKRrl0NoQ= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIJAJOyycRs95twMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEXMBUGA1UEBwwOU2lsaWNvbiBW +YWxsZXkxEzARBgNVBAoMCkNBY2VydC5vcmcxDzANBgNVBAsMBkNBY2VydDEUMBIG +A1UEAwwLY2xpZW50X3Jvb3QxIDAeBgkqhkiG9w0BCQEWEXNhbXBsZUBjYWNlcnQu +b3JnMB4XDTE4MDMxNDExMjU0NVoXDTQ1MDczMDExMjU0NVowgZkxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRcwFQYDVQQHDA5TaWxpY29uIFZhbGxl +eTETMBEGA1UECgwKQ0FjZXJ0Lm9yZzEPMA0GA1UECwwGQ0FjZXJ0MRQwEgYDVQQD +DAtjbGllbnRfcm9vdDEgMB4GCSqGSIb3DQEJARYRc2FtcGxlQGNhY2VydC5vcmcw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD2OsoeJefNo6+e06B1ytTS +NZu78/975ACCGgntwGOrDX9rS4GW3kZfxcn5Do7jsiQuMZbQ6lcT5HdTJ/SaEXlX +he78d+Tw9BF70LfwFOPhvnRxxSdcCtUMqYL64ZjmO0JHub0bFBt50dtzajWnzq7O +EKGo4E2qFpo4+DC8lTqtaCpjK9MW3kOwZw7as+RYf57X/HMCRWG9vjABPUJ85Tvp +iBmKVCAgVPsdiQPp1NKgBIBWbekZV0/SeoNnZixc1S/J0q+MSECO1YNwNar89fJv +2XXkslvDfJxz/GjPqtBOGu7LyvcobTctedqdea62lPUf+FnK0WNqfjq0Q/J2ALeN +AgMBAAGjUDBOMB0GA1UdDgQWBBTvvVyK2AKsYwfnbn2zHN6/nnwJWjAfBgNVHSME +GDAWgBTvvVyK2AKsYwfnbn2zHN6/nnwJWjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQB+shDSEVbiSbN130mZ17al9Tmul94hwZh9sPzeY0CbB5ImII7e +lbWKF5ScALIStrdGSGk+EUKgwfx7zBLj61LQajskyu717Q4IYPp7fn/6kN2eyrxW +GndLdn4AhMBAYNNYcK1r1Ji0lLJqoZF0ouAsEAW1AWPSDlB+St8kqGqhmEn3Race ++EC+noa/gc8Ot+x7VtRkL4z8Oo/nbbGBNqu5Qxm7zdz4lh5jcHEXQOq6EbWSqv+U +evanWYFVceiTqXGf9Aw7exAgTGH+Sr1d01g8r57kUYFetukY+UFRvCYJs8e7ER/O ++RQhR87cysNPZefar2oAj2d/berFh2B1a4TA +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDrzCCApcCCQChM2uDQRBkRDANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMC +VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFzAVBgNVBAcMDlNpbGljb24gVmFsbGV5 +MRMwEQYDVQQKDApDQWNlcnQub3JnMQ8wDQYDVQQLDAZDQWNlcnQxFDASBgNVBAMM +C2NsaWVudF9yb290MSAwHgYJKoZIhvcNAQkBFhFzYW1wbGVAY2FjZXJ0Lm9yZzAe +Fw0xODAzMTQxMTI1NDVaFw0xODA0MDMxMTI1NDVaMIGYMQswCQYDVQQGEwJVUzER +MA8GA1UECAwITWljaGlnYW4xEDAOBgNVBAcMB0RldHJvaXQxFDASBgNVBAoMC0ZP +UkRfQ0xJRU5UMRgwFgYDVQQLDA9GT1JEX1NETF9DTElFTlQxFDASBgNVBAMMC0ZP +UkRfQ0xJRU5UMR4wHAYJKoZIhvcNAQkBFg9zYW1wbGVAZm9yZC5jb20wggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDocPnd6WI6P8ahHu9UI3RxWzbKL3Bj +zbEEoVS1RGGiqJcTT99l9JWxYcnXkT2+K24cKKhgZe+yLhs1NZKDu2FxpBL6Tylq +/GgLIl5q7VUhjwLOGpHAY2v3qt4OmkaSMYTW/OxGoH6COya3YJ476yE0TaKRwtX0 +AB2efjWdydSMQMcXPshzjKWas6s94cr0DWnXbhZG1yFJF1qAQ8AstSo5Dp/Wexl5 +4/Ia1uxwAlMAgzhAn/hv6iQEmSqrIXV+UAkkIDutn+ZnNmAHBp89XtSC28o2wOa0 +RZDaRhbZ0eHsgqFwO7sXp9ere2uKiEDP/fd3smwxQcj3sA3pKy2vQ2BlAgMBAAEw +DQYJKoZIhvcNAQELBQADggEBAKHQgzyuTOPvL58eqG4nh2kQrRsT4yXTyymKJYpV +kEy7VaNAXhM+YpVlxGtcNNb6d56m3Vl6riTgEgVoqnbhse9J6II86uu9lvEgZbgW +D4eBBhdLwY22sIxupJ1vDJ4SaPweois7ph9rUQjvtpWQQaT0lnbw51H/DCCT6lxz +TjeoFED1qjFP8rNaNqhmzjs0b2KFMDB+itD6JBAqITnaoweBnYhxUC4F0xhSDng2 +qm/2yiX3zmkPSIK1MDmDvg7nIIIbfJwW6xNfkbgbfl4q5eCBgAL38REsMT13mEia +U8i7rb5q4FAq6iUUFwZxtPRyUJGvNTvuZH+75Yu6JZb2tDk= +-----END CERTIFICATE----- diff --git a/files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem b/files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem new file mode 100644 index 0000000000..8d17321818 --- /dev/null +++ b/files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem @@ -0,0 +1,95 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA0GwJPHONllxCz4kVX/fQsLqJ29s2lYLJUyPm+CTYzzg0kyvi +C/Z6NaAjU3BL/YfHbxrcOzbNvvxGwS0wOlX/YrcsltSbs9oCzQryJzAgihMpFwAY +NAahPQWAAjimkj/N5KiUjj5xZAS4s9mMoiYKKo7txV2/6yt776OQC0S6g8d+/Zar +f0Ov8z9XX0Eh2JLtRKUmKwkNgcAKrF2/+R0sU23F1GQk0JHPu2htzQiXjg9MzyQL +DZpCRXDsdnjBFlYPge5+9DoGP44aWoBg/AN2QH/Pe0E+Ndx3KIFRNJHbSTdsf4rU +0x4jCBN1i9AKhYTuXH/ZiLkl8IK5QgZ16Q2fRwIDAQABAoIBAQCHct6hwbrvT7A/ +ragNgUDHycLT9efITIHIHVn6Q//+01kfl/JEsf8EILk0fZN1BauvYfZkKR6XEt5s +ppBkKQVaww4gS7WQsYsGdCmhHB7ZfNBEWVRhYzmgLZXeW7Cs9Pg6tPAubRhF1ueu +QiCqNCyBMfgGPwH9tHnL6DExkY3hGzW1bwcZR23QqD8iSStc4gEt4k2IkaWalRQM +P5k1YUisj5Kw9c+D91joret8HE/Kp2NfAkfT4x9PHHP/dVY5ntn8MmEpNFExVQ40 +LWQm6YmnoUqV+ISQYNQacxUX8sP5QqgNGQwiwjCZnZMn7B0OXvM9DSi1y6dkFajy +gmPkMs5ZAoGBAPIMFoI8k2SxgYN7yvcJeDh15EaPb7gn+fZgTTMqaAGE9sNRPzO7 +hfkT99qVaDKA4tGmU84WwoBL4uP/Q8MSAiy25pAQZOAlrl7PCbV4q2LJuqGFMPeZ +L4Tf6Mi7v3/W9SAyfy5kg7M1gcRAchWB9+we8Z9RKUfcl4cqXb1F0NtlAoGBANxv +vPMlCnipKqPRbYOUgpy3sxtGweX3PKXUzaL5kp+mDcFxlYrlde7y8M++lD9uUq2+ +JPQPV7GEJ/KG+6P0FJWB+zNP0sETdYbriMvQAYBHqLSrpqc++qMmzYOH8Hoi9/TS +w5lUeRTdSPoaw2GOtaYv68dcEAHzdHFgrK4LF2M7AoGBAIBOEBBxc+BIh9Le6DQT +fPrQ43TTy/DeoA4N9l5M+Fz10qiuhMYzfU0PXK8ty9IZqCJh/MKeJfRERb1+LrlU +7notagKr7g0zbD8tmIPtt0vii1/bbp2RQjM5Tfg6LcTieYXbvrck6PsyPdt+Hftw +ra8oqAQ/zZYeROSNfKs8Ov5RAoGATU0Jz6Ifp+x6vXPFmazMmLR6pIgNmt02cVjM +u+gVGNMcY8e3DzwkPSUIeXF1f0Dq0W6qesOeluunLo9TU01Woo8wTfAiEf8G6cdS +81YAEMIQUTsYd/HH5srGqudS1yHIHhyC5xQOWdi3rK0R8vYekSag4gpQur5rCQ9D +vsy46N0CgYBkclvpzeigQi0p9zbkDw/IF/DdlXoatS7AIp3w9dzlhSTeXZpG/wiE +DmHEUzqmFApjFPVmmKcXQpOYJIMjknUqPjVysZLd9BwHMQlgJ/hzZ7lvlirU+nOn +9jjhElHIgPWXC6KcG3JvxQCNfAsOhZr4N1QI4Iyj5SQzQ+sUbQoPcg== +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDqTCCApECCQDFtoVyxnOs5TANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UEBhMC +VVMxETAPBgNVBAgMCE1pY2hpZ2FuMRAwDgYDVQQHDAdEZXRyb2l0MRQwEgYDVQQK +DAtGT1JEX1NFUlZFUjEYMBYGA1UECwwPRk9SRF9TRExfU0VSVkVSMQ0wCwYDVQQD +DARGT1JEMR4wHAYJKoZIhvcNAQkBFg9zYW1wbGVAZm9yZC5jb20wHhcNMjMwMzEz +MTIxNzQwWhcNMjgwMzExMTIxNzQwWjCBmjELMAkGA1UEBhMCUlUxDzANBgNVBAgM +BlJ1c3NpYTEXMBUGA1UEBwwOU3QuIFBldGVyc2J1cmcxDzANBgNVBAoMBkx1eG9m +dDEPMA0GA1UECwwGTW9iaWxlMQ8wDQYDVQQDDAZzZXJ2ZXIxIDAeBgkqhkiG9w0B +CQEWEXNhbXBsZUBsdXhvZnQuY29tMQwwCgYDVQQFEwNTUFQwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDQbAk8c42WXELPiRVf99Cwuonb2zaVgslTI+b4 +JNjPODSTK+IL9no1oCNTcEv9h8dvGtw7Ns2+/EbBLTA6Vf9ityyW1Juz2gLNCvIn +MCCKEykXABg0BqE9BYACOKaSP83kqJSOPnFkBLiz2YyiJgoqju3FXb/rK3vvo5AL +RLqDx379lqt/Q6/zP1dfQSHYku1EpSYrCQ2BwAqsXb/5HSxTbcXUZCTQkc+7aG3N +CJeOD0zPJAsNmkJFcOx2eMEWVg+B7n70OgY/jhpagGD8A3ZAf897QT413HcogVE0 +kdtJN2x/itTTHiMIE3WL0AqFhO5cf9mIuSXwgrlCBnXpDZ9HAgMBAAEwDQYJKoZI +hvcNAQELBQADggEBAJXFKBrVm9Ag34tW+vWinOioE5ZynuqrCgTl76z30eQJarP4 +c81rQYpSatbF0XtEv2yunWtwAvz9c2m0bxNb9Tnh1Orh6pZRB37EC1Vhg9tBoZH3 +xXmZpsj8cvfZJLmhH2f7ULmnci/nt88ZHk5Cylj57Mm3p6sLRR6IepGDRoR1sTi/ +u8On0Ix0VzfvJZ8lcuXfLRlP5WesOHLORhSRgUxshLlhUA6RuItxxEEsvpnIXjWX +R9V0WRmXuAySYTRzaJ+LqsSA8kl0aI5QZGxauGsOm4lpoxY/NucfDUwK7A+H91f5 +LjTcFC281tomoA9Ti/ShCC2UekwBdM1i1loDbjo= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIJAJOyycRs95twMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEXMBUGA1UEBwwOU2lsaWNvbiBW +YWxsZXkxEzARBgNVBAoMCkNBY2VydC5vcmcxDzANBgNVBAsMBkNBY2VydDEUMBIG +A1UEAwwLY2xpZW50X3Jvb3QxIDAeBgkqhkiG9w0BCQEWEXNhbXBsZUBjYWNlcnQu +b3JnMB4XDTE4MDMxNDExMjU0NVoXDTQ1MDczMDExMjU0NVowgZkxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRcwFQYDVQQHDA5TaWxpY29uIFZhbGxl +eTETMBEGA1UECgwKQ0FjZXJ0Lm9yZzEPMA0GA1UECwwGQ0FjZXJ0MRQwEgYDVQQD +DAtjbGllbnRfcm9vdDEgMB4GCSqGSIb3DQEJARYRc2FtcGxlQGNhY2VydC5vcmcw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD2OsoeJefNo6+e06B1ytTS +NZu78/975ACCGgntwGOrDX9rS4GW3kZfxcn5Do7jsiQuMZbQ6lcT5HdTJ/SaEXlX +he78d+Tw9BF70LfwFOPhvnRxxSdcCtUMqYL64ZjmO0JHub0bFBt50dtzajWnzq7O +EKGo4E2qFpo4+DC8lTqtaCpjK9MW3kOwZw7as+RYf57X/HMCRWG9vjABPUJ85Tvp +iBmKVCAgVPsdiQPp1NKgBIBWbekZV0/SeoNnZixc1S/J0q+MSECO1YNwNar89fJv +2XXkslvDfJxz/GjPqtBOGu7LyvcobTctedqdea62lPUf+FnK0WNqfjq0Q/J2ALeN +AgMBAAGjUDBOMB0GA1UdDgQWBBTvvVyK2AKsYwfnbn2zHN6/nnwJWjAfBgNVHSME +GDAWgBTvvVyK2AKsYwfnbn2zHN6/nnwJWjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQB+shDSEVbiSbN130mZ17al9Tmul94hwZh9sPzeY0CbB5ImII7e +lbWKF5ScALIStrdGSGk+EUKgwfx7zBLj61LQajskyu717Q4IYPp7fn/6kN2eyrxW +GndLdn4AhMBAYNNYcK1r1Ji0lLJqoZF0ouAsEAW1AWPSDlB+St8kqGqhmEn3Race ++EC+noa/gc8Ot+x7VtRkL4z8Oo/nbbGBNqu5Qxm7zdz4lh5jcHEXQOq6EbWSqv+U +evanWYFVceiTqXGf9Aw7exAgTGH+Sr1d01g8r57kUYFetukY+UFRvCYJs8e7ER/O ++RQhR87cysNPZefar2oAj2d/berFh2B1a4TA +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDrzCCApcCCQChM2uDQRBkRDANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMC +VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFzAVBgNVBAcMDlNpbGljb24gVmFsbGV5 +MRMwEQYDVQQKDApDQWNlcnQub3JnMQ8wDQYDVQQLDAZDQWNlcnQxFDASBgNVBAMM +C2NsaWVudF9yb290MSAwHgYJKoZIhvcNAQkBFhFzYW1wbGVAY2FjZXJ0Lm9yZzAe +Fw0xODAzMTQxMTI1NDVaFw0xODA0MDMxMTI1NDVaMIGYMQswCQYDVQQGEwJVUzER +MA8GA1UECAwITWljaGlnYW4xEDAOBgNVBAcMB0RldHJvaXQxFDASBgNVBAoMC0ZP +UkRfQ0xJRU5UMRgwFgYDVQQLDA9GT1JEX1NETF9DTElFTlQxFDASBgNVBAMMC0ZP +UkRfQ0xJRU5UMR4wHAYJKoZIhvcNAQkBFg9zYW1wbGVAZm9yZC5jb20wggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDocPnd6WI6P8ahHu9UI3RxWzbKL3Bj +zbEEoVS1RGGiqJcTT99l9JWxYcnXkT2+K24cKKhgZe+yLhs1NZKDu2FxpBL6Tylq +/GgLIl5q7VUhjwLOGpHAY2v3qt4OmkaSMYTW/OxGoH6COya3YJ476yE0TaKRwtX0 +AB2efjWdydSMQMcXPshzjKWas6s94cr0DWnXbhZG1yFJF1qAQ8AstSo5Dp/Wexl5 +4/Ia1uxwAlMAgzhAn/hv6iQEmSqrIXV+UAkkIDutn+ZnNmAHBp89XtSC28o2wOa0 +RZDaRhbZ0eHsgqFwO7sXp9ere2uKiEDP/fd3smwxQcj3sA3pKy2vQ2BlAgMBAAEw +DQYJKoZIhvcNAQELBQADggEBAKHQgzyuTOPvL58eqG4nh2kQrRsT4yXTyymKJYpV +kEy7VaNAXhM+YpVlxGtcNNb6d56m3Vl6riTgEgVoqnbhse9J6II86uu9lvEgZbgW +D4eBBhdLwY22sIxupJ1vDJ4SaPweois7ph9rUQjvtpWQQaT0lnbw51H/DCCT6lxz +TjeoFED1qjFP8rNaNqhmzjs0b2KFMDB+itD6JBAqITnaoweBnYhxUC4F0xhSDng2 +qm/2yiX3zmkPSIK1MDmDvg7nIIIbfJwW6xNfkbgbfl4q5eCBgAL38REsMT13mEia +U8i7rb5q4FAq6iUUFwZxtPRyUJGvNTvuZH+75Yu6JZb2tDk= +-----END CERTIFICATE----- diff --git a/test_scripts/Policies/GetSystemTime/001_GetSystemTime_is_sent.lua b/test_scripts/Policies/GetSystemTime/001_GetSystemTime_is_sent.lua new file mode 100644 index 0000000000..1d9fad5586 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/001_GetSystemTime_is_sent.lua @@ -0,0 +1,52 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) HMI sends BC.OnSystemTimeReady notification to SDL during initialization +-- 2) Mobile and sdl certificates are valid +-- 3) Mobile app starts secure service +-- SDL must: +-- 1) SDL requests GetSystemTime to HMI +-- 2) According to time from GetSystemTime response mobile and SDL certificates are valid +-- 4) start secure service, Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true +} + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, { pData, serviceId, 1 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/002_GetSystemTime_is_not_sent.lua b/test_scripts/Policies/GetSystemTime/002_GetSystemTime_is_not_sent.lua new file mode 100644 index 0000000000..e12e30604d --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/002_GetSystemTime_is_not_sent.lua @@ -0,0 +1,51 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) HMI does not send BC.OnSystemTimeReady notification to SDL during initialization +-- 2) Mobile and sdl certificates are valid +-- 3) Mobile app starts secure service +-- SDL must: +-- 1) SDL does not request GetSystemTime to HMI +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI without BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { false }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("Handshake without BC.GetSystemTime request from SDL", common.startServiceSecured, { pData, serviceId, 0 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua b/test_scripts/Policies/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua new file mode 100644 index 0000000000..ddbbc14e57 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile and sdl certificates are not up to date yet +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile and sdl certificates are not valid +-- SDL must: +-- 1) trigger PTU and receives one more time not up to date sdl certificate during update +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2019, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, + { pData, serviceId, 1, systemTime, ptUpdate }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua b/test_scripts/Policies/GetSystemTime/004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua new file mode 100644 index 0000000000..b8fe4df09f --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile and sdl certificates are expired +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile and sdl certificates are not valid +-- SDL must: +-- 1) trigger PTU and receives one more time expired certificate during update +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0311_16.pem" +config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0311_16.pem" +config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0311_16.pem" + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2019, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0312_17.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, + { pData, serviceId, 1, systemTime, ptUpdate }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua b/test_scripts/Policies/GetSystemTime/005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua new file mode 100644 index 0000000000..b47ff8087f --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile and sdl certificates are expired +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate becomes valid and sdl certificate is not valid +-- SDL must: +-- 1) trigger PTU and receives one more time expired certificate during update +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2025, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0312_17.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, + { pData, serviceId, 1, systemTime, ptUpdate }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua b/test_scripts/Policies/GetSystemTime/006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua new file mode 100644 index 0000000000..86d9077e9a --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile and sdl certificates are expired +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile is still not valid and sdl becomes valid +-- SDL must: +-- 1) not trigger PTU +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2022, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, + { pData, serviceId, 1, systemTime }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua b/test_scripts/Policies/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua new file mode 100644 index 0000000000..f833c8fcf8 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua @@ -0,0 +1,77 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile and sdl certificates are expired +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile and sdl are still not valid +-- SDL must: +-- 1) SDL triggers PTU and sdl certificate becomes valid +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2018, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdateWithNotValidCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +local function ptUpdateWithValidCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0316_21.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotValidCer }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, + { pData, serviceId, 1, systemTime, ptUpdateWithValidCer }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/008_GetSystemTime_mobile_sdl_cer_become_valid.lua b/test_scripts/Policies/GetSystemTime/008_GetSystemTime_mobile_sdl_cer_become_valid.lua new file mode 100644 index 0000000000..6518238888 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/008_GetSystemTime_mobile_sdl_cer_become_valid.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile and sdl certificates are expired +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile and sdl certificates become valid +-- SDL must: +-- 1) not trigger PTU +-- 2) start secure service, Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2024, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, + { pData, serviceId, 1, systemTime }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua b/test_scripts/Policies/GetSystemTime/009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua new file mode 100644 index 0000000000..b67c6fb13e --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua @@ -0,0 +1,77 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile and sdl certificates are expired +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate becomes valid and sdl are still not valid +-- SDL must: +-- 1) SDL triggers PTU and sdl certificate becomes valid +-- 2) start secure service, Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2024, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdateWithNotValidCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0312_17.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +local function ptUpdateWithValidCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotValidCer }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, + { pData, serviceId, 1, systemTime, ptUpdateWithValidCer }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua b/test_scripts/Policies/GetSystemTime/010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua new file mode 100644 index 0000000000..70946a15d7 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile certificate is expired and sdl certificates is up to date +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate is still not valid and sdl certificate is valid +-- SDL must: +-- 1) not trigger PTU +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0311_16.pem" +config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0311_16.pem" +config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0311_16.pem" + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2020, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0316_21.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, + { pData, serviceId, 1, systemTime }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua b/test_scripts/Policies/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua new file mode 100644 index 0000000000..577a7741a0 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile certificate is not up to date yet and sdl certificates is up to date +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate is still not valid and sdl certificates is valid +-- SDL must: +-- 1) not trigger PTU +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2020, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0316_21.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, + { pData, serviceId, 1, systemTime }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua b/test_scripts/Policies/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua new file mode 100644 index 0000000000..dab1d3c3f6 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile certificate is not up to date and sdl certificates is up to date +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate becomes valid and sdl certificate is still valid +-- SDL must: +-- 1) not trigger PTU +-- 2) start secure service, Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2025, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, + { pData, serviceId, 1, systemTime }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua b/test_scripts/Policies/GetSystemTime/013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua new file mode 100644 index 0000000000..a52a5833b9 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile certificate is not up to date and sdl certificates is up to date +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate is still not valid and sdl certificate becomes not valid +-- SDL must: +-- 1) trigger PTU +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2030, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, + { pData, serviceId, 1, systemTime, ptUpdate }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua b/test_scripts/Policies/GetSystemTime/014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua new file mode 100644 index 0000000000..93301514b4 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile certificate is not up to date and sdl certificates is up to date +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate becomes valid and sdl certificate becomes not valid +-- SDL must: +-- 1) trigger PTU +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" +config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2027, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, + { pData, serviceId, 1, systemTime, ptUpdate }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua b/test_scripts/Policies/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua new file mode 100644 index 0000000000..4efd7f8569 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua @@ -0,0 +1,72 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile certificate is up to date and sdl certificates is not up to date +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate is valid and sdl certificate is not valid yet +-- SDL must: +-- 1) trigger PTU +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2020, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdateWithNotActualCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +local function ptUpdateWithExpiredCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0312_17.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, + { pData, serviceId, 1, systemTime, ptUpdateWithExpiredCer }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua b/test_scripts/Policies/GetSystemTime/016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua new file mode 100644 index 0000000000..bd48ae4cc0 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua @@ -0,0 +1,65 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile certificate is up to date and sdl certificates is not up to date +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate is valid and sdl certificate becomes valid +-- SDL must: +-- 1) not trigger PTU +-- 2) start secure service, Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2023, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdateWithNotActualCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, + { pData, serviceId, 1, systemTime }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua b/test_scripts/Policies/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua new file mode 100644 index 0000000000..05ec2ae16f --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua @@ -0,0 +1,72 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile certificate is up to date and sdl certificates is not up to date +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate is valid and sdl certificate is not valid +-- SDL must: +-- 1) trigger PTU and sdl certificate becomes valid +-- 2) start secure service, Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2020, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdateWithNotActualCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +local function ptUpdateWithActualCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, + { pData, serviceId, 1, systemTime, ptUpdateWithActualCer }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua b/test_scripts/Policies/GetSystemTime/018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua new file mode 100644 index 0000000000..70248886b2 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua @@ -0,0 +1,65 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile certificate is up to date and sdl certificates is not up to date +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate becomes not valid and sdl certificate is still not valid +-- SDL must: +-- 1) trigger PTU +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2027, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdateWithNotActualCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0312_17.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, + { pData, serviceId, 1, systemTime, ptUpdateWithNotActualCer }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua b/test_scripts/Policies/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua new file mode 100644 index 0000000000..1f362c7f68 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile certificate is up to date and sdl certificates is not up to date +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate becomes not valid and sdl certificate becomes valid +-- SDL must: +-- 1) not trigger PTU +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0317_22.pem" +config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0317_22.pem" +config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0317_22.pem" + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2024, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdateWithNotActualCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, + { pData, serviceId, 1, systemTime }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua b/test_scripts/Policies/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua new file mode 100644 index 0000000000..9986700812 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua @@ -0,0 +1,77 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile certificate is up to date and sdl certificate is not up to date +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate becomes not valid and sdl certificate becomes valid +-- SDL must: +-- 1) trigger PTU +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0317_22.pem" +config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0317_22.pem" +config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0317_22.pem" + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2020, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdateWithNotActualCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0312_17.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +local function ptUpdateWithActualCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, + { pData, serviceId, 1, systemTime, ptUpdateWithActualCer }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua b/test_scripts/Policies/GetSystemTime/021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua new file mode 100644 index 0000000000..128ca57b4a --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua @@ -0,0 +1,65 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile and sdl certificates are up to date +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate and sdl certificate are still valid +-- SDL must: +-- 1) not trigger PTU +-- 2) start secure service, Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2020, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdateWithNotActualCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, + { pData, serviceId, 1, systemTime }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua b/test_scripts/Policies/GetSystemTime/022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua new file mode 100644 index 0000000000..ba756a0a61 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile and sdl certificates are up to date +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate becomes expired and sdl certificate is still valid +-- SDL must: +-- 1) not trigger PTU +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0317_22.pem" +config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0317_22.pem" +config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0317_22.pem" + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2024, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdateWithNotActualCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, + { pData, serviceId, 1, systemTime }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua b/test_scripts/Policies/GetSystemTime/023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua new file mode 100644 index 0000000000..20e3a42aaf --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile and sdl certificates are up to date +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate becomes not valid yet and sdl certificate is still valid +-- SDL must: +-- 1) not trigger PTU +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0317_22.pem" +config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0317_22.pem" +config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0317_22.pem" + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2015, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdateWithNotActualCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, + { pData, serviceId, 1, systemTime }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua b/test_scripts/Policies/GetSystemTime/024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua new file mode 100644 index 0000000000..69be7fa51f --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua @@ -0,0 +1,65 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile and sdl certificates are up to date +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate is valid and sdl certificate becomes not valid +-- SDL must: +-- 1) trigger PTU +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2023, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdateWithNotActualCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0316_21.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, + { pData, serviceId, 1, systemTime, ptUpdateWithNotActualCer }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua b/test_scripts/Policies/GetSystemTime/025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua new file mode 100644 index 0000000000..70216aece8 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua @@ -0,0 +1,65 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile and sdl certificates are up to date +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate and sdl certificate become expired +-- SDL must: +-- 1) trigger PTU +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2028, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdateWithNotActualCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, + { pData, serviceId, 1, systemTime, ptUpdateWithNotActualCer }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua b/test_scripts/Policies/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua new file mode 100644 index 0000000000..4152027ec8 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua @@ -0,0 +1,65 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile and sdl certificates are up to date +-- 3) SDL requests GetSystemTime +-- 4) According to time from GetSystemTime response mobile certificate and sdl certificate become not valid yet +-- SDL must: +-- 1) trigger PTU +-- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Policies/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +local systemTime = { + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 1, + year = 2011, + tz_hour = -3, + tz_minute = 10 +} + +--[[ Local Functions ]] +local function ptUpdateWithNotActualCer(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, + { pData, serviceId, 1, systemTime, ptUpdateWithNotActualCer }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/common.lua b/test_scripts/Policies/GetSystemTime/common.lua new file mode 100644 index 0000000000..e2cec25f69 --- /dev/null +++ b/test_scripts/Policies/GetSystemTime/common.lua @@ -0,0 +1,137 @@ +--------------------------------------------------------------------------------------------------- +-- Common module +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") +local security = require("user_modules/sequences/security") +local utils = require("user_modules/utils") +local test = require("user_modules/dummy_connecttest") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") + +--[[ General configuration parameters ]] +config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential.pem" +config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential.pem" +config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential.pem" + +--[[ Module ]] +local m = actions + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 +config.isCheckClientCertificate = false +config.application1.registerAppInterfaceParams.appName = "server" +config.application1.registerAppInterfaceParams.appID = "SPT" +m.appHMIType = "DEFAULT" +config.application1.registerAppInterfaceParams.appHMIType = { m.appHMIType } + +--[[ Variables ]] +m.frameInfo = security.frameInfo +m.delayedExp = utils.wait +m.readFile = utils.readFile + +--[[ Functions ]] +local function GetSystemTimeValue() + local dd = os.date("*t") + return { + millisecond = 0, + second = dd.sec, + minute = dd.min, + hour = dd.hour, + day = dd.day, + month = dd.month, + year = dd.year, + tz_hour = 2, + tz_minute = 0 + } +end + +function m.setForceProtectedServiceParam(pParamValue) + m.setSDLIniParameter("ForceProtectedService", pParamValue) +end + +function m.getAppID(pAppId) + return m.getConfigAppParams(pAppId).appID +end + +local function allowSDL(self) + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { + allowed = true, + source = "GUI", + device = { + id = utils.getDeviceMAC(), + name = utils.getDeviceName() + } + }) +end + +function m.start(pOnSystemTime, pHMIParams) + test:runSDL() + commonFunctions:waitForSDLStart(test) + :Do(function() + test:initHMI() + :Do(function() + utils.cprint(35, "HMI initialized") + test:initHMI_onReady(pHMIParams) + :Do(function() + utils.cprint(35, "HMI is ready") + if pOnSystemTime then + m.getHMIConnection():SendNotification("BasicCommunication.OnSystemTimeReady") + end + test:connectMobile() + :Do(function() + utils.cprint(35, "Mobile connected") + allowSDL(test) + end) + end) + end) + end) +end + +function m.ExpectHandshakeMessage(pMobSession, handshakeOccurences, pGetSystemTimeOccur, pTime) + if not pTime then + pTime = GetSystemTimeValue() + end + pMobSession:ExpectHandshakeMessage() + :Times(handshakeOccurences) + EXPECT_HMICALL("BasicCommunication.GetSystemTime") + :Do(function(_, d) + m.getHMIConnection():SendResponse(d.id, d.method, "SUCCESS", { systemTime = pTime }) + end) + :Times(pGetSystemTimeOccur) +end + +function m.startServiceSecured(pData, serviceId, pGetSystemTimeOccur, pTime) + m.getMobileSession():StartSecureService(serviceId) + m.getMobileSession():ExpectControlMessage(serviceId, pData) + + m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate") + :Times(0) + + local handshakeOccurences = 0 + if pData.encryption == true then handshakeOccurences = 1 end + m.ExpectHandshakeMessage(m.getMobileSession(), handshakeOccurences, pGetSystemTimeOccur, pTime) +end + +local function ExpNotDuringPTU() + m.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) +end + +function m.startServiceSecuredwithPTU(pData, serviceId, pGetSystemTimeOccur, pTime, pPTUpdateFunc) + m.getMobileSession():StartSecureService(serviceId) + m.getMobileSession():ExpectControlMessage(serviceId, pData) + + m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + :Do(function(e) + if e.occurences == 1 then + m.policyTableUpdate(pPTUpdateFunc, ExpNotDuringPTU) + end + end) + + local handshakeOccurences = 0 + if pData.encryption == true then handshakeOccurences = 1 end + m.ExpectHandshakeMessage(m.getMobileSession(), handshakeOccurences, pGetSystemTimeOccur, pTime) +end + +return m diff --git a/test_sets/get_system_time.txt b/test_sets/get_system_time.txt new file mode 100644 index 0000000000..a0e437154b --- /dev/null +++ b/test_sets/get_system_time.txt @@ -0,0 +1,26 @@ +./test_scripts/Policies/GetSystemTime/001_GetSystemTime_is_sent.lua +./test_scripts/Policies/GetSystemTime/002_GetSystemTime_is_not_sent.lua +./test_scripts/Policies/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua +./test_scripts/Policies/GetSystemTime/004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua +./test_scripts/Policies/GetSystemTime/005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua +./test_scripts/Policies/GetSystemTime/006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua +./test_scripts/Policies/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua +./test_scripts/Policies/GetSystemTime/008_GetSystemTime_mobile_sdl_cer_become_valid.lua +./test_scripts/Policies/GetSystemTime/009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua +./test_scripts/Policies/GetSystemTime/010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua +./test_scripts/Policies/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua +./test_scripts/Policies/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua +./test_scripts/Policies/GetSystemTime/013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua +./test_scripts/Policies/GetSystemTime/014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua +./test_scripts/Policies/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua +./test_scripts/Policies/GetSystemTime/016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua +./test_scripts/Policies/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua +./test_scripts/Policies/GetSystemTime/018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua +./test_scripts/Policies/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua +./test_scripts/Policies/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua +./test_scripts/Policies/GetSystemTime/021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua +./test_scripts/Policies/GetSystemTime/022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua +./test_scripts/Policies/GetSystemTime/023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua +./test_scripts/Policies/GetSystemTime/024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua +./test_scripts/Policies/GetSystemTime/025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua +./test_scripts/Policies/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua diff --git a/user_modules/dummy_connecttest.lua b/user_modules/dummy_connecttest.lua index ab2e7dd084..5d19454be4 100644 --- a/user_modules/dummy_connecttest.lua +++ b/user_modules/dummy_connecttest.lua @@ -331,7 +331,8 @@ function module:initHMI() "BasicCommunication.PlayTone", "BasicCommunication.OnSDLClose", "SDL.OnSDLConsentNeeded", - "BasicCommunication.OnResumeAudioSource" + "BasicCommunication.OnResumeAudioSource", + "BasicCommunication.OnSystemTimeReady" }) registerComponent("UI", { From 94c50c237831e6367ea3d3cd2dab24a3890fc32d Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 21 Mar 2018 13:29:06 +0200 Subject: [PATCH 336/681] Update according to review comments --- .../001_GetSystemTime_is_sent.lua | 9 ++-- .../002_GetSystemTime_is_not_sent.lua | 5 +- ...mTime_mobile_sdl_cer_are_not_valid_yet.lua | 7 ++- ...e_mobile_sdl_cer_are_not_valid_already.lua | 7 ++- ...cer_becomes_valid_sdl_cer_is_not_valid.lua | 7 ++- ...ile_is_not_valid_sdl_cer_becomes_valid.lua | 7 ++- ..._valid_sdl_cer_becomes_valid_after_PTU.lua | 8 ++- ...SystemTime_mobile_sdl_cer_become_valid.lua | 7 ++- ..._mobile_sdl_cer_become_valid_after_PTU.lua | 8 ++- ...mTime_mobile_cer_expired_sdl_cer_valid.lua | 7 ++- ...mobile_cer_not_valid_yet_sdl_cer_valid.lua | 7 ++- ...mobile_cer_becomes_valid_sdl_cer_valid.lua | 7 ++- ...bile_cer_not_valid_sdl_becomes_invalid.lua | 7 ++- ...ecomes_valid_sdl_cer_becomes_not_valid.lua | 7 ++- ...ime_mobile_cer_valid_sdl_cer_not_valid.lua | 8 ++- ...mobile_cer_valid_sdl_cer_becomes_valid.lua | 7 ++- ..._valid_sdl_cer_becomes_valid_after_PTU.lua | 8 ++- ...er_becomes_not_valid_sdl_cer_not_valid.lua | 7 ++- ...ecomes_not_valid_sdl_cer_becomes_valid.lua | 7 ++- ...t_valid_sdl_cer_becomes_valid_with_PTU.lua | 10 ++-- ...ystemTime_mobile_cer_and_sdl_cer_valid.lua | 7 ++- ...er_becomes_not_valid_and_sdl_cer_valid.lua | 7 ++- ...ecomes_yet_not_valid_and_sdl_cer_valid.lua | 7 ++- ...er_valid_and_sdl_cer_becomes_not_valid.lua | 7 ++- ..._mobile_cer_and_sdl_cer_become_expired.lua | 7 ++- ...e_cer_and_sdl_cer_become_not_valid_yet.lua | 7 ++- ...etSystemTime_without_response_from_HMI.lua | 52 ++++++++++++++++++ .../GetSystemTime/common.lua | 31 +++++++---- test_sets/get_system_time.txt | 53 ++++++++++--------- 29 files changed, 180 insertions(+), 145 deletions(-) rename test_scripts/{Policies => Security}/GetSystemTime/001_GetSystemTime_is_sent.lua (82%) rename test_scripts/{Policies => Security}/GetSystemTime/002_GetSystemTime_is_not_sent.lua (88%) rename test_scripts/{Policies => Security}/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua (88%) rename test_scripts/{Policies => Security}/GetSystemTime/004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua (88%) rename test_scripts/{Policies => Security}/GetSystemTime/005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua (87%) rename test_scripts/{Policies => Security}/GetSystemTime/006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua (87%) rename test_scripts/{Policies => Security}/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua (86%) rename test_scripts/{Policies => Security}/GetSystemTime/008_GetSystemTime_mobile_sdl_cer_become_valid.lua (87%) rename test_scripts/{Policies => Security}/GetSystemTime/009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua (85%) rename test_scripts/{Policies => Security}/GetSystemTime/010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua (86%) rename test_scripts/{Policies => Security}/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua (86%) rename test_scripts/{Policies => Security}/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua (86%) rename test_scripts/{Policies => Security}/GetSystemTime/013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua (86%) rename test_scripts/{Policies => Security}/GetSystemTime/014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua (86%) rename test_scripts/{Policies => Security}/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua (83%) rename test_scripts/{Policies => Security}/GetSystemTime/016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua (85%) rename test_scripts/{Policies => Security}/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua (84%) rename test_scripts/{Policies => Security}/GetSystemTime/018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua (84%) rename test_scripts/{Policies => Security}/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua (87%) rename test_scripts/{Policies => Security}/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua (85%) rename test_scripts/{Policies => Security}/GetSystemTime/021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua (85%) rename test_scripts/{Policies => Security}/GetSystemTime/022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua (86%) rename test_scripts/{Policies => Security}/GetSystemTime/023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua (86%) rename test_scripts/{Policies => Security}/GetSystemTime/024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua (85%) rename test_scripts/{Policies => Security}/GetSystemTime/025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua (85%) rename test_scripts/{Policies => Security}/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua (85%) create mode 100644 test_scripts/Security/GetSystemTime/027_GetSystemTime_without_response_from_HMI.lua rename test_scripts/{Policies => Security}/GetSystemTime/common.lua (82%) diff --git a/test_scripts/Policies/GetSystemTime/001_GetSystemTime_is_sent.lua b/test_scripts/Security/GetSystemTime/001_GetSystemTime_is_sent.lua similarity index 82% rename from test_scripts/Policies/GetSystemTime/001_GetSystemTime_is_sent.lua rename to test_scripts/Security/GetSystemTime/001_GetSystemTime_is_sent.lua index 1d9fad5586..ac4c3cc52d 100644 --- a/test_scripts/Policies/GetSystemTime/001_GetSystemTime_is_sent.lua +++ b/test_scripts/Security/GetSystemTime/001_GetSystemTime_is_sent.lua @@ -10,12 +10,12 @@ -- 2) Mobile and sdl certificates are valid -- 3) Mobile app starts secure service -- SDL must: --- 1) SDL requests GetSystemTime to HMI --- 2) According to time from GetSystemTime response mobile and SDL certificates are valid --- 4) start secure service, Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true +-- 1) Request GetSystemTime from HMI +-- 2) Mobile and SDL certificates are valid according to date/time from GetSystemTime response +-- 3) Start secure service: Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] @@ -33,7 +33,6 @@ local function ptUpdate(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/002_GetSystemTime_is_not_sent.lua b/test_scripts/Security/GetSystemTime/002_GetSystemTime_is_not_sent.lua similarity index 88% rename from test_scripts/Policies/GetSystemTime/002_GetSystemTime_is_not_sent.lua rename to test_scripts/Security/GetSystemTime/002_GetSystemTime_is_not_sent.lua index e12e30604d..6ddf4f9729 100644 --- a/test_scripts/Policies/GetSystemTime/002_GetSystemTime_is_not_sent.lua +++ b/test_scripts/Security/GetSystemTime/002_GetSystemTime_is_not_sent.lua @@ -11,10 +11,10 @@ -- 3) Mobile app starts secure service -- SDL must: -- 1) SDL does not request GetSystemTime to HMI --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] @@ -32,7 +32,6 @@ local function ptUpdate(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua b/test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua similarity index 88% rename from test_scripts/Policies/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua rename to test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua index ddbbc14e57..df4ed35988 100644 --- a/test_scripts/Policies/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua +++ b/test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile and sdl certificates are not up to date yet -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile and sdl certificates are not valid +-- 4) Mobile and sdl certificates are not valid according to date/time from GetSystemTime response -- SDL must: -- 1) trigger PTU and receives one more time not up to date sdl certificate during update --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ General configuration parameters ]] @@ -50,7 +50,6 @@ local function ptUpdate(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua b/test_scripts/Security/GetSystemTime/004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua similarity index 88% rename from test_scripts/Policies/GetSystemTime/004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua rename to test_scripts/Security/GetSystemTime/004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua index b8fe4df09f..1b5b2b898e 100644 --- a/test_scripts/Policies/GetSystemTime/004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua +++ b/test_scripts/Security/GetSystemTime/004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile and sdl certificates are expired -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile and sdl certificates are not valid +-- 4) Mobile and sdl certificates are not valid according to date/time from GetSystemTime response -- SDL must: -- 1) trigger PTU and receives one more time expired certificate during update --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ General configuration parameters ]] @@ -50,7 +50,6 @@ local function ptUpdate(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0312_17.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua b/test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua similarity index 87% rename from test_scripts/Policies/GetSystemTime/005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua rename to test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua index b47ff8087f..929bb90609 100644 --- a/test_scripts/Policies/GetSystemTime/005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua +++ b/test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile and sdl certificates are expired -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate becomes valid and sdl certificate is not valid +-- 4) Mobile certificate becomes valid and sdl certificate is not valid according to date/time from GetSystemTime response -- SDL must: -- 1) trigger PTU and receives one more time expired certificate during update --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ General configuration parameters ]] @@ -50,7 +50,6 @@ local function ptUpdate(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0312_17.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua b/test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua similarity index 87% rename from test_scripts/Policies/GetSystemTime/006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua rename to test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua index 86d9077e9a..d31840f2be 100644 --- a/test_scripts/Policies/GetSystemTime/006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua +++ b/test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile and sdl certificates are expired -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile is still not valid and sdl becomes valid +-- 4) Mobile is still not valid and sdl becomes valid according to date/time from GetSystemTime response -- SDL must: -- 1) not trigger PTU --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ General configuration parameters ]] @@ -50,7 +50,6 @@ local function ptUpdate(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua b/test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua similarity index 86% rename from test_scripts/Policies/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua rename to test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua index f833c8fcf8..2e18e4e96e 100644 --- a/test_scripts/Policies/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua +++ b/test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile and sdl certificates are expired -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile and sdl are still not valid +-- 4) Mobile and sdl are still not valid according to date/time from GetSystemTime response -- SDL must: -- 1) SDL triggers PTU and sdl certificate becomes valid --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ General configuration parameters ]] @@ -50,14 +50,12 @@ local function ptUpdateWithNotValidCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end local function ptUpdateWithValidCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0316_21.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/008_GetSystemTime_mobile_sdl_cer_become_valid.lua b/test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_sdl_cer_become_valid.lua similarity index 87% rename from test_scripts/Policies/GetSystemTime/008_GetSystemTime_mobile_sdl_cer_become_valid.lua rename to test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_sdl_cer_become_valid.lua index 6518238888..2c3579acd4 100644 --- a/test_scripts/Policies/GetSystemTime/008_GetSystemTime_mobile_sdl_cer_become_valid.lua +++ b/test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_sdl_cer_become_valid.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile and sdl certificates are expired -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile and sdl certificates become valid +-- 4) Mobile and sdl certificates become valid according to date/time from GetSystemTime response -- SDL must: -- 1) not trigger PTU --- 2) start secure service, Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true +-- 2) Start secure service: Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ General configuration parameters ]] @@ -50,7 +50,6 @@ local function ptUpdate(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua b/test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua similarity index 85% rename from test_scripts/Policies/GetSystemTime/009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua rename to test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua index b67c6fb13e..b7b65fe953 100644 --- a/test_scripts/Policies/GetSystemTime/009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua +++ b/test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile and sdl certificates are expired -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate becomes valid and sdl are still not valid +-- 4) Mobile certificate becomes valid and sdl are still not valid according to date/time from GetSystemTime response -- SDL must: -- 1) SDL triggers PTU and sdl certificate becomes valid --- 2) start secure service, Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true +-- 2) Start secure service: Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ General configuration parameters ]] @@ -50,14 +50,12 @@ local function ptUpdateWithNotValidCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0312_17.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end local function ptUpdateWithValidCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua similarity index 86% rename from test_scripts/Policies/GetSystemTime/010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua rename to test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua index 70946a15d7..5c926e4449 100644 --- a/test_scripts/Policies/GetSystemTime/010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile certificate is expired and sdl certificates is up to date -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate is still not valid and sdl certificate is valid +-- 4) Mobile certificate is still not valid and sdl certificate is valid according to date/time from GetSystemTime response -- SDL must: -- 1) not trigger PTU --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ General configuration parameters ]] @@ -50,7 +50,6 @@ local function ptUpdate(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0316_21.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua similarity index 86% rename from test_scripts/Policies/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua rename to test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua index 577a7741a0..e79a5b5200 100644 --- a/test_scripts/Policies/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile certificate is not up to date yet and sdl certificates is up to date -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate is still not valid and sdl certificates is valid +-- 4) Mobile certificate is still not valid and sdl certificates is valid according to date/time from GetSystemTime response -- SDL must: -- 1) not trigger PTU --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ General configuration parameters ]] @@ -50,7 +50,6 @@ local function ptUpdate(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0316_21.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua similarity index 86% rename from test_scripts/Policies/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua rename to test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua index dab1d3c3f6..4e3ad23b0d 100644 --- a/test_scripts/Policies/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile certificate is not up to date and sdl certificates is up to date -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate becomes valid and sdl certificate is still valid +-- 4) Mobile certificate becomes valid and sdl certificate is still valid according to date/time from GetSystemTime response -- SDL must: -- 1) not trigger PTU --- 2) start secure service, Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true +-- 2) Start secure service: Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ General configuration parameters ]] @@ -50,7 +50,6 @@ local function ptUpdate(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua b/test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua similarity index 86% rename from test_scripts/Policies/GetSystemTime/013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua rename to test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua index a52a5833b9..50f8d2c01f 100644 --- a/test_scripts/Policies/GetSystemTime/013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua +++ b/test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile certificate is not up to date and sdl certificates is up to date -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate is still not valid and sdl certificate becomes not valid +-- 4) Mobile certificate is still not valid and sdl certificate becomes not valid according to date/time from GetSystemTime response -- SDL must: -- 1) trigger PTU --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ General configuration parameters ]] @@ -50,7 +50,6 @@ local function ptUpdate(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua b/test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua similarity index 86% rename from test_scripts/Policies/GetSystemTime/014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua rename to test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua index 93301514b4..bc56ffff95 100644 --- a/test_scripts/Policies/GetSystemTime/014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua +++ b/test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile certificate is not up to date and sdl certificates is up to date -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate becomes valid and sdl certificate becomes not valid +-- 4) Mobile certificate becomes valid and sdl certificate becomes not valid according to date/time from GetSystemTime response -- SDL must: -- 1) trigger PTU --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ General configuration parameters ]] @@ -50,7 +50,6 @@ local function ptUpdate(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua b/test_scripts/Security/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua similarity index 83% rename from test_scripts/Policies/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua rename to test_scripts/Security/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua index 4efd7f8569..1f819270b7 100644 --- a/test_scripts/Policies/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua +++ b/test_scripts/Security/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile certificate is up to date and sdl certificates is not up to date -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate is valid and sdl certificate is not valid yet +-- 4) Mobile certificate is valid and sdl certificate is not valid yet according to date/time from GetSystemTime response -- SDL must: -- 1) trigger PTU --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] @@ -45,14 +45,12 @@ local function ptUpdateWithNotActualCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end local function ptUpdateWithExpiredCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0312_17.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua b/test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua similarity index 85% rename from test_scripts/Policies/GetSystemTime/016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua rename to test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua index bd48ae4cc0..e519cdb37e 100644 --- a/test_scripts/Policies/GetSystemTime/016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua +++ b/test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile certificate is up to date and sdl certificates is not up to date -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate is valid and sdl certificate becomes valid +-- 4) Mobile certificate is valid and sdl certificate becomes valid according to date/time from GetSystemTime response -- SDL must: -- 1) not trigger PTU --- 2) start secure service, Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true +-- 2) Start secure service: Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] @@ -45,7 +45,6 @@ local function ptUpdateWithNotActualCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua b/test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua similarity index 84% rename from test_scripts/Policies/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua rename to test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua index 05ec2ae16f..a902a245d5 100644 --- a/test_scripts/Policies/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua +++ b/test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile certificate is up to date and sdl certificates is not up to date -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate is valid and sdl certificate is not valid +-- 4) Mobile certificate is valid and sdl certificate is not valid according to date/time from GetSystemTime response -- SDL must: -- 1) trigger PTU and sdl certificate becomes valid --- 2) start secure service, Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true +-- 2) Start secure service: Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] @@ -45,14 +45,12 @@ local function ptUpdateWithNotActualCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end local function ptUpdateWithActualCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua b/test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua similarity index 84% rename from test_scripts/Policies/GetSystemTime/018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua rename to test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua index 70248886b2..4e2bc54b38 100644 --- a/test_scripts/Policies/GetSystemTime/018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua +++ b/test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile certificate is up to date and sdl certificates is not up to date -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate becomes not valid and sdl certificate is still not valid +-- 4) Mobile certificate becomes not valid and sdl certificate is still not valid according to date/time from GetSystemTime response -- SDL must: -- 1) trigger PTU --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] @@ -45,7 +45,6 @@ local function ptUpdateWithNotActualCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0312_17.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua b/test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua similarity index 87% rename from test_scripts/Policies/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua rename to test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua index 1f362c7f68..41138a48fe 100644 --- a/test_scripts/Policies/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua +++ b/test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile certificate is up to date and sdl certificates is not up to date -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate becomes not valid and sdl certificate becomes valid +-- 4) Mobile certificate becomes not valid and sdl certificate becomes valid according to date/time from GetSystemTime response -- SDL must: -- 1) not trigger PTU --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] @@ -50,7 +50,6 @@ local function ptUpdateWithNotActualCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua b/test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua similarity index 85% rename from test_scripts/Policies/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua rename to test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua index 9986700812..9df7e14b65 100644 --- a/test_scripts/Policies/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua +++ b/test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile certificate is up to date and sdl certificate is not up to date -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate becomes not valid and sdl certificate becomes valid +-- 4) Mobile certificate becomes not valid and sdl certificate becomes valid according to date/time from GetSystemTime response -- SDL must: -- 1) trigger PTU --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] @@ -40,7 +40,7 @@ local systemTime = { hour = 15, day = 20, month = 1, - year = 2020, + year = 2023, tz_hour = -3, tz_minute = 10 } @@ -50,14 +50,12 @@ local function ptUpdateWithNotActualCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0312_17.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end local function ptUpdateWithActualCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua similarity index 85% rename from test_scripts/Policies/GetSystemTime/021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua rename to test_scripts/Security/GetSystemTime/021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua index 128ca57b4a..1addcbee57 100644 --- a/test_scripts/Policies/GetSystemTime/021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile and sdl certificates are up to date -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate and sdl certificate are still valid +-- 4) Mobile certificate and sdl certificate are still valid according to date/time from GetSystemTime response -- SDL must: -- 1) not trigger PTU --- 2) start secure service, Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true +-- 2) Start secure service: Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] @@ -45,7 +45,6 @@ local function ptUpdateWithNotActualCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua similarity index 86% rename from test_scripts/Policies/GetSystemTime/022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua rename to test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua index ba756a0a61..bee9896aa8 100644 --- a/test_scripts/Policies/GetSystemTime/022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile and sdl certificates are up to date -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate becomes expired and sdl certificate is still valid +-- 4) Mobile certificate becomes expired and sdl certificate is still valid according to date/time from GetSystemTime response -- SDL must: -- 1) not trigger PTU --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] @@ -50,7 +50,6 @@ local function ptUpdateWithNotActualCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua similarity index 86% rename from test_scripts/Policies/GetSystemTime/023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua rename to test_scripts/Security/GetSystemTime/023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua index 20e3a42aaf..59a0a16cb0 100644 --- a/test_scripts/Policies/GetSystemTime/023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile and sdl certificates are up to date -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate becomes not valid yet and sdl certificate is still valid +-- 4) Mobile certificate becomes not valid yet and sdl certificate is still valid according to date/time from GetSystemTime response -- SDL must: -- 1) not trigger PTU --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] @@ -50,7 +50,6 @@ local function ptUpdateWithNotActualCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua b/test_scripts/Security/GetSystemTime/024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua similarity index 85% rename from test_scripts/Policies/GetSystemTime/024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua rename to test_scripts/Security/GetSystemTime/024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua index 69be7fa51f..a56c4307c1 100644 --- a/test_scripts/Policies/GetSystemTime/024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua +++ b/test_scripts/Security/GetSystemTime/024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile and sdl certificates are up to date -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate is valid and sdl certificate becomes not valid +-- 4) Mobile certificate is valid and sdl certificate becomes not valid according to date/time from GetSystemTime response -- SDL must: -- 1) trigger PTU --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] @@ -45,7 +45,6 @@ local function ptUpdateWithNotActualCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0316_21.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua b/test_scripts/Security/GetSystemTime/025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua similarity index 85% rename from test_scripts/Policies/GetSystemTime/025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua rename to test_scripts/Security/GetSystemTime/025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua index 70216aece8..4d806ba421 100644 --- a/test_scripts/Policies/GetSystemTime/025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua +++ b/test_scripts/Security/GetSystemTime/025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile and sdl certificates are up to date -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate and sdl certificate become expired +-- 4) Mobile certificate and sdl certificate become expired according to date/time from GetSystemTime response -- SDL must: -- 1) trigger PTU --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] @@ -45,7 +45,6 @@ local function ptUpdateWithNotActualCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Policies/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua b/test_scripts/Security/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua similarity index 85% rename from test_scripts/Policies/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua rename to test_scripts/Security/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua index 4152027ec8..196785e45d 100644 --- a/test_scripts/Policies/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua +++ b/test_scripts/Security/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua @@ -9,13 +9,13 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile and sdl certificates are up to date -- 3) SDL requests GetSystemTime --- 4) According to time from GetSystemTime response mobile certificate and sdl certificate become not valid yet +-- 4) Mobile certificate and sdl certificate become not valid yet according to date/time from GetSystemTime response -- SDL must: -- 1) trigger PTU --- 2) not start secure service, Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/Policies/GetSystemTime/common') +local common = require('test_scripts/Security/GetSystemTime/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] @@ -45,7 +45,6 @@ local function ptUpdateWithNotActualCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt - pTbl.policy_table.app_policies[common.getAppID()].AppHMIType = { common.appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/Security/GetSystemTime/027_GetSystemTime_without_response_from_HMI.lua b/test_scripts/Security/GetSystemTime/027_GetSystemTime_without_response_from_HMI.lua new file mode 100644 index 0000000000..c4cba09f50 --- /dev/null +++ b/test_scripts/Security/GetSystemTime/027_GetSystemTime_without_response_from_HMI.lua @@ -0,0 +1,52 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app starts secure RPC service +-- 2) Mobile and sdl certificates are up to date +-- 3) SDL requests GetSystemTime +-- 4) HMI does not respond +-- SDL must: +-- 1) wait default timeout +-- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Security/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 +local pData = { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false +} + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("Handshake without BC.GetSystemTime response from HMI", common.startServiceSecuredWithoutGetSTResp, + { pData, serviceId }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Policies/GetSystemTime/common.lua b/test_scripts/Security/GetSystemTime/common.lua similarity index 82% rename from test_scripts/Policies/GetSystemTime/common.lua rename to test_scripts/Security/GetSystemTime/common.lua index e2cec25f69..795fa6769c 100644 --- a/test_scripts/Policies/GetSystemTime/common.lua +++ b/test_scripts/Security/GetSystemTime/common.lua @@ -53,8 +53,8 @@ function m.getAppID(pAppId) return m.getConfigAppParams(pAppId).appID end -local function allowSDL(self) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { +local function allowSDL() + test.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { allowed = true, source = "GUI", device = { @@ -87,11 +87,11 @@ function m.start(pOnSystemTime, pHMIParams) end) end -function m.ExpectHandshakeMessage(pMobSession, handshakeOccurences, pGetSystemTimeOccur, pTime) +function m.ExpectHandshakeMessage(handshakeOccurences, pGetSystemTimeOccur, pTime) if not pTime then pTime = GetSystemTimeValue() end - pMobSession:ExpectHandshakeMessage() + m.getMobileSession():ExpectHandshakeMessage() :Times(handshakeOccurences) EXPECT_HMICALL("BasicCommunication.GetSystemTime") :Do(function(_, d) @@ -109,16 +109,16 @@ function m.startServiceSecured(pData, serviceId, pGetSystemTimeOccur, pTime) local handshakeOccurences = 0 if pData.encryption == true then handshakeOccurences = 1 end - m.ExpectHandshakeMessage(m.getMobileSession(), handshakeOccurences, pGetSystemTimeOccur, pTime) + m.ExpectHandshakeMessage(handshakeOccurences, pGetSystemTimeOccur, pTime) end local function ExpNotDuringPTU() m.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) end -function m.startServiceSecuredwithPTU(pData, serviceId, pGetSystemTimeOccur, pTime, pPTUpdateFunc) - m.getMobileSession():StartSecureService(serviceId) - m.getMobileSession():ExpectControlMessage(serviceId, pData) +function m.startServiceSecuredwithPTU(pData, pServiceId, pGetSystemTimeOccur, pTime, pPTUpdateFunc) + m.getMobileSession():StartSecureService(pServiceId) + m.getMobileSession():ExpectControlMessage(pServiceId, pData) m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) @@ -131,7 +131,20 @@ function m.startServiceSecuredwithPTU(pData, serviceId, pGetSystemTimeOccur, pTi local handshakeOccurences = 0 if pData.encryption == true then handshakeOccurences = 1 end - m.ExpectHandshakeMessage(m.getMobileSession(), handshakeOccurences, pGetSystemTimeOccur, pTime) + m.ExpectHandshakeMessage(handshakeOccurences, pGetSystemTimeOccur, pTime) +end + +function m.startServiceSecuredWithoutGetSTResp(pData, serviceId) + m.getMobileSession():StartSecureService(serviceId) + m.getMobileSession():ExpectControlMessage(serviceId, pData) + + m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate") + :Times(0) + + m.getMobileSession():ExpectHandshakeMessage() + :Times(0) + EXPECT_HMICALL("BasicCommunication.GetSystemTime") + end return m diff --git a/test_sets/get_system_time.txt b/test_sets/get_system_time.txt index a0e437154b..8b5d9d5f1d 100644 --- a/test_sets/get_system_time.txt +++ b/test_sets/get_system_time.txt @@ -1,26 +1,27 @@ -./test_scripts/Policies/GetSystemTime/001_GetSystemTime_is_sent.lua -./test_scripts/Policies/GetSystemTime/002_GetSystemTime_is_not_sent.lua -./test_scripts/Policies/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua -./test_scripts/Policies/GetSystemTime/004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua -./test_scripts/Policies/GetSystemTime/005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua -./test_scripts/Policies/GetSystemTime/006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua -./test_scripts/Policies/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua -./test_scripts/Policies/GetSystemTime/008_GetSystemTime_mobile_sdl_cer_become_valid.lua -./test_scripts/Policies/GetSystemTime/009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua -./test_scripts/Policies/GetSystemTime/010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua -./test_scripts/Policies/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua -./test_scripts/Policies/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua -./test_scripts/Policies/GetSystemTime/013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua -./test_scripts/Policies/GetSystemTime/014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua -./test_scripts/Policies/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua -./test_scripts/Policies/GetSystemTime/016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua -./test_scripts/Policies/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua -./test_scripts/Policies/GetSystemTime/018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua -./test_scripts/Policies/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua -./test_scripts/Policies/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua -./test_scripts/Policies/GetSystemTime/021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua -./test_scripts/Policies/GetSystemTime/022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua -./test_scripts/Policies/GetSystemTime/023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua -./test_scripts/Policies/GetSystemTime/024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua -./test_scripts/Policies/GetSystemTime/025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua -./test_scripts/Policies/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua +./test_scripts/Security/GetSystemTime/001_GetSystemTime_is_sent.lua +./test_scripts/Security/GetSystemTime/002_GetSystemTime_is_not_sent.lua +./test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua +./test_scripts/Security/GetSystemTime/004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua +./test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua +./test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua +./test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua +./test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_sdl_cer_become_valid.lua +./test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua +./test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua +./test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua +./test_scripts/Security/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua +./test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua +./test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua +./test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua +./test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua +./test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua +./test_scripts/Security/GetSystemTime/021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua +./test_scripts/Security/GetSystemTime/025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua +./test_scripts/Security/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua +./test_scripts/Security/GetSystemTime/027_GetSystemTime_without_response_from_HMI.lua From 3a8257f378c9bb79f012a1db301d8cff2fc5d223 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 22 Mar 2018 11:41:43 +0200 Subject: [PATCH 337/681] Update according to review comments --- .../Security/GetSystemTime/common.lua | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/test_scripts/Security/GetSystemTime/common.lua b/test_scripts/Security/GetSystemTime/common.lua index 795fa6769c..0e0d11133a 100644 --- a/test_scripts/Security/GetSystemTime/common.lua +++ b/test_scripts/Security/GetSystemTime/common.lua @@ -30,7 +30,7 @@ m.delayedExp = utils.wait m.readFile = utils.readFile --[[ Functions ]] -local function GetSystemTimeValue() +local function getSystemTimeValue() local dd = os.date("*t") return { millisecond = 0, @@ -87,12 +87,12 @@ function m.start(pOnSystemTime, pHMIParams) end) end -function m.ExpectHandshakeMessage(handshakeOccurences, pGetSystemTimeOccur, pTime) +function m.expectHandshakeMessage(pHandshakeOccurences, pGetSystemTimeOccur, pTime) if not pTime then - pTime = GetSystemTimeValue() + pTime = getSystemTimeValue() end m.getMobileSession():ExpectHandshakeMessage() - :Times(handshakeOccurences) + :Times(pHandshakeOccurences) EXPECT_HMICALL("BasicCommunication.GetSystemTime") :Do(function(_, d) m.getHMIConnection():SendResponse(d.id, d.method, "SUCCESS", { systemTime = pTime }) @@ -100,19 +100,19 @@ function m.ExpectHandshakeMessage(handshakeOccurences, pGetSystemTimeOccur, pTim :Times(pGetSystemTimeOccur) end -function m.startServiceSecured(pData, serviceId, pGetSystemTimeOccur, pTime) - m.getMobileSession():StartSecureService(serviceId) - m.getMobileSession():ExpectControlMessage(serviceId, pData) +function m.startServiceSecured(pData, pServiceId, pGetSystemTimeOccur, pTime) + m.getMobileSession():StartSecureService(pServiceId) + m.getMobileSession():ExpectControlMessage(pServiceId, pData) m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate") :Times(0) local handshakeOccurences = 0 if pData.encryption == true then handshakeOccurences = 1 end - m.ExpectHandshakeMessage(handshakeOccurences, pGetSystemTimeOccur, pTime) + m.expectHandshakeMessage(handshakeOccurences, pGetSystemTimeOccur, pTime) end -local function ExpNotDuringPTU() +local function expNotDuringPTU() m.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) end @@ -125,18 +125,18 @@ function m.startServiceSecuredwithPTU(pData, pServiceId, pGetSystemTimeOccur, pT :Times(3) :Do(function(e) if e.occurences == 1 then - m.policyTableUpdate(pPTUpdateFunc, ExpNotDuringPTU) + m.policyTableUpdate(pPTUpdateFunc, expNotDuringPTU) end end) local handshakeOccurences = 0 if pData.encryption == true then handshakeOccurences = 1 end - m.ExpectHandshakeMessage(handshakeOccurences, pGetSystemTimeOccur, pTime) + m.expectHandshakeMessage(handshakeOccurences, pGetSystemTimeOccur, pTime) end -function m.startServiceSecuredWithoutGetSTResp(pData, serviceId) - m.getMobileSession():StartSecureService(serviceId) - m.getMobileSession():ExpectControlMessage(serviceId, pData) +function m.startServiceSecuredWithoutGetSTResp(pData, pServiceId) + m.getMobileSession():StartSecureService(pServiceId) + m.getMobileSession():ExpectControlMessage(pServiceId, pData) m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate") :Times(0) From 0a3ee8a8fdda6a8c4c5fb6152d8f8b2670fddc06 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 28 Mar 2018 10:33:01 +0300 Subject: [PATCH 338/681] Add new functions to Utils module --- user_modules/utils.lua | 86 ++++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 19 deletions(-) diff --git a/user_modules/utils.lua b/user_modules/utils.lua index e15afb8931..d1adde254f 100644 --- a/user_modules/utils.lua +++ b/user_modules/utils.lua @@ -122,35 +122,83 @@ function m.protect(pTbl) return setmetatable({}, mt) end ---[[ @inheritObjects: copy objects from source module to target --- 'objects' means: tables, functions, fields --- Function is useful for 'inheriting' data of one module to another +--[[ @cprint: print color message to console --! @parameters: ---! pTargetObject - target module ---! pSourceObject - source module ---! @return: none +--! pColor - color code +--! pMsg - message +--]] +function m.cprint(pColor, ...) + print("\27[" .. tostring(pColor) .. "m" .. table.concat(table.pack(...), "\t") .. "\27[0m") +end + +--[[ @spairs: sorted iterator, allows to get items from table sorted by key +-- Usually used as a replacement of standard 'pairs' function +--! @parameters: +--! pTbl - table to iterate +--! @return: iterator --]] -function m.inheritObjects(pTargetObject, pSourceObject) - for k, v in pairs(pSourceObject) do - if type(v) == "table" then - pTargetObject[k] = m.cloneTable(v) - elseif type(v) == "function" then - pTargetObject[k] = function(...) - return v(...) +function m.spairs(pTbl) + local keys = {} + for k in pairs(pTbl) do + keys[#keys+1] = k + end + table.sort(keys, function(a, b) return tostring(a) < tostring(b) end) + local i = 0 + return function() + i = i + 1 + if keys[i] then + return keys[i], pTbl[keys[i]] + end + end +end + +--[[ @tableToString: convert table to string +--! @parameters: +--! pTbl - table to convert +--! @return: string +--]] +function m.tableToString(pTbl) + local s = "" + local function tPrint(tbl, level) + if not level then level = 0 end + for k, v in m.spairs(tbl) do + local indent = string.rep(" ", level * 4) + s = s .. indent .. "[" .. k .. "]: " + if type(v) == "table" then + s = s .. "{\n" + tPrint(v, level + 1) + s = s .. indent .. "}" + elseif type(v) == "string" then + s = s .. "'" .. tostring(v) .. "'" + else + s = s .. tostring(v) end - else - pTargetObject[k] = v + s = s .. "\n" end end + tPrint(pTbl) + return string.sub(s, 1, string.len(s) - 1) end ---[[ @cprint: print color message to console +--[[ @printTable: print table --! @parameters: --! pColor - color code ---! pMsg - message +--! pTbl - table to print +--! @return: none +--]] +function m.cprintTable(pColor, pTbl) + m.cprint(pColor, string.rep("-", 50)) + m.cprint(pColor, m.tableToString(pTbl)) + m.cprint(pColor, string.rep("-", 50)) +end + +--[[ @printTable: print table +--! @parameters: +--! pTbl - table to print +--! @return: none --]] -function m.cprint(pColor, pMsg) - print("\27[" .. tostring(pColor) .. "m" .. tostring(pMsg) .. "\27[0m") +function m.printTable(pTbl) + m.cprintTable(39, pTbl) end return m From d4bd2ea6a37099c6da8fc1f94c09b1c85a556567 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 28 Mar 2018 11:26:18 +0300 Subject: [PATCH 339/681] Added case for when GetSystemTime resp sends in 9 sec --- ...7_GetSystemTime_without_response_from_HMI.lua | 16 ++++++++++++---- test_scripts/Security/GetSystemTime/common.lua | 16 ++++++++++++++-- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/test_scripts/Security/GetSystemTime/027_GetSystemTime_without_response_from_HMI.lua b/test_scripts/Security/GetSystemTime/027_GetSystemTime_without_response_from_HMI.lua index c4cba09f50..6a9861bb07 100644 --- a/test_scripts/Security/GetSystemTime/027_GetSystemTime_without_response_from_HMI.lua +++ b/test_scripts/Security/GetSystemTime/027_GetSystemTime_without_response_from_HMI.lua @@ -20,13 +20,19 @@ local runner = require('user_modules/script_runner') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = {"NAVIGATION"} --[[ Local Variables ]] -local serviceId = 7 -local pData = { +local serviceIdNack = 7 +local pDataNack = { frameInfo = common.frameInfo.START_SERVICE_NACK, encryption = false } +local serviceIdAck = 10 +local pDataAck = { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true +} --[[ Local Functions ]] local function ptUpdate(pTbl) @@ -45,8 +51,10 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) -runner.Step("Handshake without BC.GetSystemTime response from HMI", common.startServiceSecuredWithoutGetSTResp, - { pData, serviceId }) +runner.Step("Handshake with response BC.GetSystemTime in 9 sec from HMI", common.startServiceSecuredWitTimeoutWithoutGetSTResp, + { pDataAck, serviceIdAck, 9500 }) +runner.Step("Handshake without BC.GetSystemTime response from HMI", common.startServiceSecuredWitTimeoutWithoutGetSTResp, + { pDataNack, serviceIdNack }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/common.lua b/test_scripts/Security/GetSystemTime/common.lua index 0e0d11133a..d7ef9e9083 100644 --- a/test_scripts/Security/GetSystemTime/common.lua +++ b/test_scripts/Security/GetSystemTime/common.lua @@ -134,16 +134,28 @@ function m.startServiceSecuredwithPTU(pData, pServiceId, pGetSystemTimeOccur, pT m.expectHandshakeMessage(handshakeOccurences, pGetSystemTimeOccur, pTime) end -function m.startServiceSecuredWithoutGetSTResp(pData, pServiceId) +function m.startServiceSecuredWitTimeoutWithoutGetSTResp(pData, pServiceId, pTimeout) m.getMobileSession():StartSecureService(pServiceId) m.getMobileSession():ExpectControlMessage(pServiceId, pData) + :Timeout(1100) m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate") :Times(0) + local handshakeOccurences = 0 + if pData.encryption == true then handshakeOccurences = 1 end m.getMobileSession():ExpectHandshakeMessage() - :Times(0) + :Times(handshakeOccurences) + EXPECT_HMICALL("BasicCommunication.GetSystemTime") + :Do(function(_,data) + if pTimeout then + local function GetSystemTimeResponse() + m.getHMIConnection():SendResponse(d.id, d.method, "SUCCESS", { systemTime = getSystemTimeValue() }) + end + RUN_AFTER(GetSystemTimeResponse, pTimeout) + end + end) end From 2c3fe68570f95c0815588c3dcb7ab7408622d3ef Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 28 Mar 2018 12:07:19 +0300 Subject: [PATCH 340/681] Updated timeout value --- test_scripts/Security/GetSystemTime/common.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/Security/GetSystemTime/common.lua b/test_scripts/Security/GetSystemTime/common.lua index d7ef9e9083..049e277e0e 100644 --- a/test_scripts/Security/GetSystemTime/common.lua +++ b/test_scripts/Security/GetSystemTime/common.lua @@ -137,7 +137,7 @@ end function m.startServiceSecuredWitTimeoutWithoutGetSTResp(pData, pServiceId, pTimeout) m.getMobileSession():StartSecureService(pServiceId) m.getMobileSession():ExpectControlMessage(pServiceId, pData) - :Timeout(1100) + :Timeout(11000) m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate") :Times(0) From 75f9bde8ef0e07ee82daa27004cb07597d8d2719 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 29 Mar 2018 14:38:49 +0300 Subject: [PATCH 341/681] Removed scripts related to not yet valid sdl sertif and HandShake expectations --- ...SystemTime_mobile_sdl_cer_are_expired.lua} | 0 ...mTime_mobile_sdl_cer_are_not_valid_yet.lua | 69 ----------------- ...er_becomes_valid_sdl_cer_is_not_valid.lua} | 0 ...le_is_not_valid_sdl_cer_becomes_valid.lua} | 0 ...ystemTime_mobile_sdl_cer_become_valid.lua} | 0 ..._valid_sdl_cer_becomes_valid_after_PTU.lua | 75 ------------------- ...mobile_sdl_cer_become_valid_after_PTU.lua} | 0 ...Time_mobile_cer_expired_sdl_cer_valid.lua} | 0 ...obile_cer_not_valid_yet_sdl_cer_valid.lua} | 0 ...obile_cer_becomes_valid_sdl_cer_valid.lua} | 0 ...ile_cer_not_valid_sdl_becomes_invalid.lua} | 0 ...comes_valid_sdl_cer_becomes_not_valid.lua} | 0 ...me_mobile_cer_valid_sdl_cer_not_valid.lua} | 2 +- ...obile_cer_valid_sdl_cer_becomes_valid.lua} | 0 ...r_becomes_not_valid_sdl_cer_not_valid.lua} | 0 ...comes_not_valid_sdl_cer_becomes_valid.lua} | 0 ..._valid_sdl_cer_becomes_valid_with_PTU.lua} | 0 ..._valid_sdl_cer_becomes_valid_after_PTU.lua | 70 ----------------- ...stemTime_mobile_cer_and_sdl_cer_valid.lua} | 0 ...r_becomes_not_valid_and_sdl_cer_valid.lua} | 0 ...comes_yet_not_valid_and_sdl_cer_valid.lua} | 0 ...r_valid_and_sdl_cer_becomes_not_valid.lua} | 0 ...mobile_cer_and_sdl_cer_become_expired.lua} | 0 ...tSystemTime_without_response_from_HMI.lua} | 16 +--- ...mTime_with_response_from_HMI_in_9_sec.lua} | 30 +++----- .../Security/GetSystemTime/common.lua | 24 +++--- test_sets/get_system_time.txt | 47 ++++++------ 27 files changed, 49 insertions(+), 284 deletions(-) rename test_scripts/Security/GetSystemTime/{004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua => 003_GetSystemTime_mobile_sdl_cer_are_expired.lua} (100%) delete mode 100644 test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua rename test_scripts/Security/GetSystemTime/{005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua => 004_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua} (100%) rename test_scripts/Security/GetSystemTime/{006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua => 005_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua} (100%) rename test_scripts/Security/GetSystemTime/{008_GetSystemTime_mobile_sdl_cer_become_valid.lua => 006_GetSystemTime_mobile_sdl_cer_become_valid.lua} (100%) delete mode 100644 test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua rename test_scripts/Security/GetSystemTime/{009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua => 007_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua} (100%) rename test_scripts/Security/GetSystemTime/{010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua => 008_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua} (100%) rename test_scripts/Security/GetSystemTime/{011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua => 009_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua} (100%) rename test_scripts/Security/GetSystemTime/{012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua => 010_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua} (100%) rename test_scripts/Security/GetSystemTime/{013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua => 011_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua} (100%) rename test_scripts/Security/GetSystemTime/{014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua => 012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua} (100%) rename test_scripts/Security/GetSystemTime/{015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua => 013_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua} (98%) rename test_scripts/Security/GetSystemTime/{016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua => 014_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua} (100%) rename test_scripts/Security/GetSystemTime/{018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua => 015_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua} (100%) rename test_scripts/Security/GetSystemTime/{019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua => 016_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua} (100%) rename test_scripts/Security/GetSystemTime/{020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua => 017_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua} (100%) delete mode 100644 test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua rename test_scripts/Security/GetSystemTime/{021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua => 018_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua} (100%) rename test_scripts/Security/GetSystemTime/{022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua => 019_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua} (100%) rename test_scripts/Security/GetSystemTime/{023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua => 020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua} (100%) rename test_scripts/Security/GetSystemTime/{024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua => 021_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua} (100%) rename test_scripts/Security/GetSystemTime/{025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua => 022_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua} (100%) rename test_scripts/Security/GetSystemTime/{027_GetSystemTime_without_response_from_HMI.lua => 023_GetSystemTime_without_response_from_HMI.lua} (76%) rename test_scripts/Security/GetSystemTime/{026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua => 024_GetSystemTime_with_response_from_HMI_in_9_sec.lua} (65%) diff --git a/test_scripts/Security/GetSystemTime/004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua b/test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_expired.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua rename to test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_expired.lua diff --git a/test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua b/test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua deleted file mode 100644 index df4ed35988..0000000000 --- a/test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua +++ /dev/null @@ -1,69 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- User story: TBD --- Use case: TBD --- --- Requirement summary: TBD --- --- Description: --- In case: --- 1) Mobile app starts secure RPC service --- 2) Mobile and sdl certificates are not up to date yet --- 3) SDL requests GetSystemTime --- 4) Mobile and sdl certificates are not valid according to date/time from GetSystemTime response --- SDL must: --- 1) trigger PTU and receives one more time not up to date sdl certificate during update --- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local common = require('test_scripts/Security/GetSystemTime/common') -local runner = require('user_modules/script_runner') - ---[[ General configuration parameters ]] -config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" -config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" -config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ Local Variables ]] -local serviceId = 7 -local pData = { - frameInfo = common.frameInfo.START_SERVICE_NACK, - encryption = false -} - -local systemTime = { - millisecond = 100, - second = 30, - minute = 29, - hour = 15, - day = 20, - month = 1, - year = 2019, - tz_hour = -3, - tz_minute = 10 -} - ---[[ Local Functions ]] -local function ptUpdate(pTbl) - local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" - local crt = common.readFile(filePath) - pTbl.policy_table.module_config.certificate = crt -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) - -runner.Title("Test") - -runner.Step("Register App", common.registerApp) -runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) -runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdate }) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua b/test_scripts/Security/GetSystemTime/004_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua rename to test_scripts/Security/GetSystemTime/004_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua diff --git a/test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua b/test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua rename to test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua diff --git a/test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_sdl_cer_become_valid.lua b/test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_sdl_cer_become_valid.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_sdl_cer_become_valid.lua rename to test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_sdl_cer_become_valid.lua diff --git a/test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua b/test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua deleted file mode 100644 index 2e18e4e96e..0000000000 --- a/test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua +++ /dev/null @@ -1,75 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- User story: TBD --- Use case: TBD --- --- Requirement summary: TBD --- --- Description: --- In case: --- 1) Mobile app starts secure RPC service --- 2) Mobile and sdl certificates are expired --- 3) SDL requests GetSystemTime --- 4) Mobile and sdl are still not valid according to date/time from GetSystemTime response --- SDL must: --- 1) SDL triggers PTU and sdl certificate becomes valid --- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local common = require('test_scripts/Security/GetSystemTime/common') -local runner = require('user_modules/script_runner') - ---[[ General configuration parameters ]] -config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" -config.serverPrivateKeyPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" -config.serverCAChainCertPath = "./files/Security/GetSystemTime_certificates/spt_credential_0323_28.pem" - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ Local Variables ]] -local serviceId = 7 -local pData = { - frameInfo = common.frameInfo.START_SERVICE_NACK, - encryption = false -} - -local systemTime = { - millisecond = 100, - second = 30, - minute = 29, - hour = 15, - day = 20, - month = 1, - year = 2018, - tz_hour = -3, - tz_minute = 10 -} - ---[[ Local Functions ]] -local function ptUpdateWithNotValidCer(pTbl) - local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" - local crt = common.readFile(filePath) - pTbl.policy_table.module_config.certificate = crt -end - -local function ptUpdateWithValidCer(pTbl) - local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0316_21.pem" - local crt = common.readFile(filePath) - pTbl.policy_table.module_config.certificate = crt -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) - -runner.Title("Test") - -runner.Step("Register App", common.registerApp) -runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotValidCer }) -runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdateWithValidCer }) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua b/test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua rename to test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua diff --git a/test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua rename to test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua diff --git a/test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua rename to test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua diff --git a/test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua rename to test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua diff --git a/test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua b/test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua rename to test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua diff --git a/test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua b/test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua rename to test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua diff --git a/test_scripts/Security/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua b/test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua similarity index 98% rename from test_scripts/Security/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua rename to test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua index 1f819270b7..07687b35b5 100644 --- a/test_scripts/Security/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua +++ b/test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua @@ -42,7 +42,7 @@ local systemTime = { --[[ Local Functions ]] local function ptUpdateWithNotActualCer(pTbl) - local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" + local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0312_17.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt end diff --git a/test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua b/test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua rename to test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua diff --git a/test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua b/test_scripts/Security/GetSystemTime/015_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua rename to test_scripts/Security/GetSystemTime/015_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua diff --git a/test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua b/test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua rename to test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua diff --git a/test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua b/test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua rename to test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua diff --git a/test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua b/test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua deleted file mode 100644 index a902a245d5..0000000000 --- a/test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua +++ /dev/null @@ -1,70 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- User story: TBD --- Use case: TBD --- --- Requirement summary: TBD --- --- Description: --- In case: --- 1) Mobile app starts secure RPC service --- 2) Mobile certificate is up to date and sdl certificates is not up to date --- 3) SDL requests GetSystemTime --- 4) Mobile certificate is valid and sdl certificate is not valid according to date/time from GetSystemTime response --- SDL must: --- 1) trigger PTU and sdl certificate becomes valid --- 2) Start secure service: Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local common = require('test_scripts/Security/GetSystemTime/common') -local runner = require('user_modules/script_runner') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ Local Variables ]] -local serviceId = 7 -local pData = { - frameInfo = common.frameInfo.START_SERVICE_ACK, - encryption = true -} - -local systemTime = { - millisecond = 100, - second = 30, - minute = 29, - hour = 15, - day = 20, - month = 1, - year = 2020, - tz_hour = -3, - tz_minute = 10 -} - ---[[ Local Functions ]] -local function ptUpdateWithNotActualCer(pTbl) - local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0321_26.pem" - local crt = common.readFile(filePath) - pTbl.policy_table.module_config.certificate = crt -end - -local function ptUpdateWithActualCer(pTbl) - local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" - local crt = common.readFile(filePath) - pTbl.policy_table.module_config.certificate = crt -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI with BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { true }) - -runner.Title("Test") - -runner.Step("Register App", common.registerApp) -runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) -runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdateWithActualCer }) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua rename to test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua diff --git a/test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua rename to test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua diff --git a/test_scripts/Security/GetSystemTime/023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua rename to test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua diff --git a/test_scripts/Security/GetSystemTime/024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua b/test_scripts/Security/GetSystemTime/021_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua rename to test_scripts/Security/GetSystemTime/021_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua diff --git a/test_scripts/Security/GetSystemTime/025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua b/test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua similarity index 100% rename from test_scripts/Security/GetSystemTime/025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua rename to test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua diff --git a/test_scripts/Security/GetSystemTime/027_GetSystemTime_without_response_from_HMI.lua b/test_scripts/Security/GetSystemTime/023_GetSystemTime_without_response_from_HMI.lua similarity index 76% rename from test_scripts/Security/GetSystemTime/027_GetSystemTime_without_response_from_HMI.lua rename to test_scripts/Security/GetSystemTime/023_GetSystemTime_without_response_from_HMI.lua index 6a9861bb07..ed395e93bd 100644 --- a/test_scripts/Security/GetSystemTime/027_GetSystemTime_without_response_from_HMI.lua +++ b/test_scripts/Security/GetSystemTime/023_GetSystemTime_without_response_from_HMI.lua @@ -20,19 +20,13 @@ local runner = require('user_modules/script_runner') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false -config.application1.registerAppInterfaceParams.appHMIType = {"NAVIGATION"} --[[ Local Variables ]] -local serviceIdNack = 7 -local pDataNack = { +local serviceId = 7 +local pData = { frameInfo = common.frameInfo.START_SERVICE_NACK, encryption = false } -local serviceIdAck = 10 -local pDataAck = { - frameInfo = common.frameInfo.START_SERVICE_ACK, - encryption = true -} --[[ Local Functions ]] local function ptUpdate(pTbl) @@ -50,11 +44,9 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) -runner.Step("Handshake with response BC.GetSystemTime in 9 sec from HMI", common.startServiceSecuredWitTimeoutWithoutGetSTResp, - { pDataAck, serviceIdAck, 9500 }) +runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake without BC.GetSystemTime response from HMI", common.startServiceSecuredWitTimeoutWithoutGetSTResp, - { pDataNack, serviceIdNack }) + { pData, serviceId }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua b/test_scripts/Security/GetSystemTime/024_GetSystemTime_with_response_from_HMI_in_9_sec.lua similarity index 65% rename from test_scripts/Security/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua rename to test_scripts/Security/GetSystemTime/024_GetSystemTime_with_response_from_HMI_in_9_sec.lua index 196785e45d..3a8bf6b23e 100644 --- a/test_scripts/Security/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua +++ b/test_scripts/Security/GetSystemTime/024_GetSystemTime_with_response_from_HMI_in_9_sec.lua @@ -9,10 +9,10 @@ -- 1) Mobile app starts secure RPC service -- 2) Mobile and sdl certificates are up to date -- 3) SDL requests GetSystemTime --- 4) Mobile certificate and sdl certificate become not valid yet according to date/time from GetSystemTime response +-- 4) HMI responds in 9 seconds -- SDL must: --- 1) trigger PTU --- 2) Not start secure service: Handshake is finished with frameInfo = START_SERVICE_NACK, encryption = false +-- 1) wait GetSystemTime default timeout +-- 2) Start secure service: Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/Security/GetSystemTime/common') @@ -24,24 +24,12 @@ runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local serviceId = 7 local pData = { - frameInfo = common.frameInfo.START_SERVICE_NACK, - encryption = false -} - -local systemTime = { - millisecond = 100, - second = 30, - minute = 29, - hour = 15, - day = 20, - month = 1, - year = 2011, - tz_hour = -3, - tz_minute = 10 + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true } --[[ Local Functions ]] -local function ptUpdateWithNotActualCer(pTbl) +local function ptUpdate(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt @@ -56,9 +44,9 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) -runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdateWithNotActualCer }) +runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("Handshake with response BC.GetSystemTime in 9 sec from HMI", common.startServiceSecuredWitTimeoutWithoutGetSTResp, + { pData, serviceId, 9500 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/common.lua b/test_scripts/Security/GetSystemTime/common.lua index 049e277e0e..910ec10495 100644 --- a/test_scripts/Security/GetSystemTime/common.lua +++ b/test_scripts/Security/GetSystemTime/common.lua @@ -87,12 +87,16 @@ function m.start(pOnSystemTime, pHMIParams) end) end -function m.expectHandshakeMessage(pHandshakeOccurences, pGetSystemTimeOccur, pTime) +function m.expectHandshakeMessage(pGetSystemTimeOccur, pTime) if not pTime then pTime = getSystemTimeValue() end + local handshakeOccurences = 1 + if pGetSystemTimeOccur == 0 then + handshakeOccurences = 0 + end m.getMobileSession():ExpectHandshakeMessage() - :Times(pHandshakeOccurences) + :Times(handshakeOccurences) EXPECT_HMICALL("BasicCommunication.GetSystemTime") :Do(function(_, d) m.getHMIConnection():SendResponse(d.id, d.method, "SUCCESS", { systemTime = pTime }) @@ -107,9 +111,7 @@ function m.startServiceSecured(pData, pServiceId, pGetSystemTimeOccur, pTime) m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate") :Times(0) - local handshakeOccurences = 0 - if pData.encryption == true then handshakeOccurences = 1 end - m.expectHandshakeMessage(handshakeOccurences, pGetSystemTimeOccur, pTime) + m.expectHandshakeMessage(pGetSystemTimeOccur, pTime) end local function expNotDuringPTU() @@ -129,21 +131,21 @@ function m.startServiceSecuredwithPTU(pData, pServiceId, pGetSystemTimeOccur, pT end end) - local handshakeOccurences = 0 - if pData.encryption == true then handshakeOccurences = 1 end - m.expectHandshakeMessage(handshakeOccurences, pGetSystemTimeOccur, pTime) + m.expectHandshakeMessage(pGetSystemTimeOccur, pTime) end function m.startServiceSecuredWitTimeoutWithoutGetSTResp(pData, pServiceId, pTimeout) m.getMobileSession():StartSecureService(pServiceId) m.getMobileSession():ExpectControlMessage(pServiceId, pData) - :Timeout(11000) + :Timeout(11500) m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate") :Times(0) local handshakeOccurences = 0 - if pData.encryption == true then handshakeOccurences = 1 end + if pTimeout then + handshakeOccurences = 1 + end m.getMobileSession():ExpectHandshakeMessage() :Times(handshakeOccurences) @@ -151,7 +153,7 @@ function m.startServiceSecuredWitTimeoutWithoutGetSTResp(pData, pServiceId, pTim :Do(function(_,data) if pTimeout then local function GetSystemTimeResponse() - m.getHMIConnection():SendResponse(d.id, d.method, "SUCCESS", { systemTime = getSystemTimeValue() }) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { systemTime = getSystemTimeValue() }) end RUN_AFTER(GetSystemTimeResponse, pTimeout) end diff --git a/test_sets/get_system_time.txt b/test_sets/get_system_time.txt index 8b5d9d5f1d..1d30b388b0 100644 --- a/test_sets/get_system_time.txt +++ b/test_sets/get_system_time.txt @@ -1,27 +1,24 @@ ./test_scripts/Security/GetSystemTime/001_GetSystemTime_is_sent.lua ./test_scripts/Security/GetSystemTime/002_GetSystemTime_is_not_sent.lua -./test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_not_valid_yet.lua -./test_scripts/Security/GetSystemTime/004_GetSystemTime_mobile_sdl_cer_are_not_valid_already.lua -./test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua -./test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua -./test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid_after_PTU.lua -./test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_sdl_cer_become_valid.lua -./test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua -./test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua -./test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua -./test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua -./test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua -./test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua -./test_scripts/Security/GetSystemTime/015_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua -./test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua -./test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid_after_PTU.lua -./test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua -./test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua -./test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua -./test_scripts/Security/GetSystemTime/021_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua -./test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua -./test_scripts/Security/GetSystemTime/023_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua -./test_scripts/Security/GetSystemTime/024_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua -./test_scripts/Security/GetSystemTime/025_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua -./test_scripts/Security/GetSystemTime/026_GetSystemTime_mobile_cer_and_sdl_cer_become_not_valid_yet.lua -./test_scripts/Security/GetSystemTime/027_GetSystemTime_without_response_from_HMI.lua +./test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_expired.lua +./test_scripts/Security/GetSystemTime/004_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua +./test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua +./test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_sdl_cer_become_valid.lua +./test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua +./test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua +./test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua +./test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua +./test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua +./test_scripts/Security/GetSystemTime/015_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua +./test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua +./test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua +./test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/021_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua +./test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua +./test_scripts/Security/GetSystemTime/023_GetSystemTime_without_response_from_HMI.lua +./test_scripts/Security/GetSystemTime/024_GetSystemTime_with_response_from_HMI_in_9_sec.lua From fa569ddf54ee3e7748622077821a5b27b2b41e0d Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 30 Mar 2018 14:13:35 +0300 Subject: [PATCH 342/681] Handshake is unsuccess in case expired cer after PTU --- ..._GetSystemTime_mobile_sdl_cer_are_expired.lua | 2 +- ...le_cer_becomes_valid_sdl_cer_is_not_valid.lua | 2 +- ..._mobile_cer_not_valid_sdl_becomes_invalid.lua | 2 +- ...r_becomes_valid_sdl_cer_becomes_not_valid.lua | 2 +- ...emTime_mobile_cer_valid_sdl_cer_not_valid.lua | 2 +- ...e_cer_becomes_not_valid_sdl_cer_not_valid.lua | 2 +- ...e_cer_valid_and_sdl_cer_becomes_not_valid.lua | 2 +- ...ime_mobile_cer_and_sdl_cer_become_expired.lua | 2 +- test_scripts/Security/GetSystemTime/common.lua | 16 ++++++++++------ 9 files changed, 18 insertions(+), 14 deletions(-) diff --git a/test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_expired.lua b/test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_expired.lua index 1b5b2b898e..99c775e374 100644 --- a/test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_expired.lua +++ b/test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_expired.lua @@ -63,7 +63,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdate }) + { pData, serviceId, 1, systemTime, ptUpdate, 0 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/004_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua b/test_scripts/Security/GetSystemTime/004_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua index 929bb90609..3faa6fddb5 100644 --- a/test_scripts/Security/GetSystemTime/004_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua +++ b/test_scripts/Security/GetSystemTime/004_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua @@ -63,7 +63,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdate }) + { pData, serviceId, 1, systemTime, ptUpdate, 0 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua b/test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua index 50f8d2c01f..5c044db5cf 100644 --- a/test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua +++ b/test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua @@ -63,7 +63,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdate }) + { pData, serviceId, 1, systemTime, ptUpdate, 0 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua b/test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua index bc56ffff95..6bfef82b6d 100644 --- a/test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua +++ b/test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua @@ -63,7 +63,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdate }) + { pData, serviceId, 1, systemTime, ptUpdate, 0 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua b/test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua index 07687b35b5..f02bea84f0 100644 --- a/test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua +++ b/test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua @@ -64,7 +64,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdateWithExpiredCer }) + { pData, serviceId, 1, systemTime, ptUpdateWithExpiredCer, 0 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/015_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua b/test_scripts/Security/GetSystemTime/015_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua index 4e2bc54b38..226f223817 100644 --- a/test_scripts/Security/GetSystemTime/015_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua +++ b/test_scripts/Security/GetSystemTime/015_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua @@ -58,7 +58,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdateWithNotActualCer }) + { pData, serviceId, 1, systemTime, ptUpdateWithNotActualCer, 0 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/021_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua b/test_scripts/Security/GetSystemTime/021_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua index a56c4307c1..c7c920a1ad 100644 --- a/test_scripts/Security/GetSystemTime/021_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua +++ b/test_scripts/Security/GetSystemTime/021_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua @@ -58,7 +58,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdateWithNotActualCer }) + { pData, serviceId, 1, systemTime, ptUpdateWithNotActualCer, 0 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua b/test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua index 4d806ba421..92448b0fed 100644 --- a/test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua +++ b/test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua @@ -58,7 +58,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdateWithNotActualCer }) + { pData, serviceId, 1, systemTime, ptUpdateWithNotActualCer, 0 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/common.lua b/test_scripts/Security/GetSystemTime/common.lua index 910ec10495..d8d6729da9 100644 --- a/test_scripts/Security/GetSystemTime/common.lua +++ b/test_scripts/Security/GetSystemTime/common.lua @@ -76,6 +76,10 @@ function m.start(pOnSystemTime, pHMIParams) utils.cprint(35, "HMI is ready") if pOnSystemTime then m.getHMIConnection():SendNotification("BasicCommunication.OnSystemTimeReady") + EXPECT_HMICALL("BasicCommunication.GetSystemTime") + :Do(function(_,data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { systemTime = getSystemTimeValue() }) + end) end test:connectMobile() :Do(function() @@ -87,16 +91,16 @@ function m.start(pOnSystemTime, pHMIParams) end) end -function m.expectHandshakeMessage(pGetSystemTimeOccur, pTime) +function m.expectHandshakeMessage(pGetSystemTimeOccur, pTime, pHandshakeOccurences) if not pTime then pTime = getSystemTimeValue() end - local handshakeOccurences = 1 + if not pHandshakeOccurences then pHandshakeOccurences = 1 end if pGetSystemTimeOccur == 0 then - handshakeOccurences = 0 + pHandshakeOccurences = pGetSystemTimeOccur end m.getMobileSession():ExpectHandshakeMessage() - :Times(handshakeOccurences) + :Times(pHandshakeOccurences) EXPECT_HMICALL("BasicCommunication.GetSystemTime") :Do(function(_, d) m.getHMIConnection():SendResponse(d.id, d.method, "SUCCESS", { systemTime = pTime }) @@ -118,7 +122,7 @@ local function expNotDuringPTU() m.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) end -function m.startServiceSecuredwithPTU(pData, pServiceId, pGetSystemTimeOccur, pTime, pPTUpdateFunc) +function m.startServiceSecuredwithPTU(pData, pServiceId, pGetSystemTimeOccur, pTime, pPTUpdateFunc, pHandshakeOccurences) m.getMobileSession():StartSecureService(pServiceId) m.getMobileSession():ExpectControlMessage(pServiceId, pData) @@ -131,7 +135,7 @@ function m.startServiceSecuredwithPTU(pData, pServiceId, pGetSystemTimeOccur, pT end end) - m.expectHandshakeMessage(pGetSystemTimeOccur, pTime) + m.expectHandshakeMessage(pGetSystemTimeOccur, pTime, pHandshakeOccurences) end function m.startServiceSecuredWitTimeoutWithoutGetSTResp(pData, pServiceId, pTimeout) From 20709394967bd109ec21cb058eae6719da2392f7 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 30 Mar 2018 16:03:58 +0300 Subject: [PATCH 343/681] Updated time in case with sending GetSystemTime response with delay --- ...etSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua | 4 ++-- .../006_GetSystemTime_mobile_sdl_cer_become_valid.lua | 4 ++-- .../008_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua | 4 ++-- ...9_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua | 4 ++-- ...0_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua | 4 ++-- ...GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua | 4 ++-- ...ime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua | 4 ++-- ...4_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua | 4 ++-- ...ime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua | 4 ++-- .../018_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua | 4 ++-- ...temTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua | 4 ++-- ...ime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua | 4 ++-- ...22_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua | 4 ++-- .../024_GetSystemTime_with_response_from_HMI_in_9_sec.lua | 4 ++-- 14 files changed, 28 insertions(+), 28 deletions(-) diff --git a/test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua b/test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua index d31840f2be..0d48462e4d 100644 --- a/test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua +++ b/test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua @@ -61,9 +61,9 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_sdl_cer_become_valid.lua b/test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_sdl_cer_become_valid.lua index 2c3579acd4..5aa7380ebb 100644 --- a/test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_sdl_cer_become_valid.lua +++ b/test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_sdl_cer_become_valid.lua @@ -61,9 +61,9 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua index 5c926e4449..b9cbc63a1b 100644 --- a/test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua @@ -61,9 +61,9 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua index e79a5b5200..5fd5518558 100644 --- a/test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua @@ -61,9 +61,9 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua index 4e3ad23b0d..afba0dc844 100644 --- a/test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua @@ -61,9 +61,9 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua b/test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua index 5c044db5cf..f5e9f9e955 100644 --- a/test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua +++ b/test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua @@ -61,9 +61,9 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdate, 0 }) + { pData, serviceId, 1, systemTime, ptUpdate, 0 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua b/test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua index 6bfef82b6d..462ee1a1c9 100644 --- a/test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua +++ b/test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua @@ -61,9 +61,9 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdate, 0 }) + { pData, serviceId, 1, systemTime, ptUpdate, 0 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua b/test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua index e519cdb37e..c2a8fb9d46 100644 --- a/test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua +++ b/test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua @@ -56,9 +56,9 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua b/test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua index 41138a48fe..31cf4b5e36 100644 --- a/test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua +++ b/test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua @@ -61,9 +61,9 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua index 1addcbee57..b844f447a2 100644 --- a/test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua @@ -56,9 +56,9 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua index bee9896aa8..e53415fd2c 100644 --- a/test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua @@ -61,9 +61,9 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua index 59a0a16cb0..8242787023 100644 --- a/test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua @@ -61,9 +61,9 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua b/test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua index 92448b0fed..e632ced9f8 100644 --- a/test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua +++ b/test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua @@ -56,9 +56,9 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdateWithNotActualCer, 0 }) + { pData, serviceId, 1, systemTime, ptUpdateWithNotActualCer, 0 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/024_GetSystemTime_with_response_from_HMI_in_9_sec.lua b/test_scripts/Security/GetSystemTime/024_GetSystemTime_with_response_from_HMI_in_9_sec.lua index 3a8bf6b23e..01eb43ff09 100644 --- a/test_scripts/Security/GetSystemTime/024_GetSystemTime_with_response_from_HMI_in_9_sec.lua +++ b/test_scripts/Security/GetSystemTime/024_GetSystemTime_with_response_from_HMI_in_9_sec.lua @@ -44,9 +44,9 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake with response BC.GetSystemTime in 9 sec from HMI", common.startServiceSecuredWitTimeoutWithoutGetSTResp, - { pData, serviceId, 9500 }) + { pData, serviceId, 8000 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) From 9e467845cfc81194399eb424d532e306c52e04fb Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Sat, 31 Mar 2018 16:11:33 +0300 Subject: [PATCH 344/681] Remove not required response --- test_scripts/Security/GetSystemTime/common.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test_scripts/Security/GetSystemTime/common.lua b/test_scripts/Security/GetSystemTime/common.lua index d8d6729da9..0d7af20c0a 100644 --- a/test_scripts/Security/GetSystemTime/common.lua +++ b/test_scripts/Security/GetSystemTime/common.lua @@ -76,10 +76,6 @@ function m.start(pOnSystemTime, pHMIParams) utils.cprint(35, "HMI is ready") if pOnSystemTime then m.getHMIConnection():SendNotification("BasicCommunication.OnSystemTimeReady") - EXPECT_HMICALL("BasicCommunication.GetSystemTime") - :Do(function(_,data) - m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { systemTime = getSystemTimeValue() }) - end) end test:connectMobile() :Do(function() From 8d84428f22173709145baeef70804e172bac1ad1 Mon Sep 17 00:00:00 2001 From: HSavynetska Date: Wed, 4 Apr 2018 15:55:47 +0300 Subject: [PATCH 345/681] Initial scripts for Icon Resumtion --- .../001_Mobile_app_First_Registration.lua | 32 +++++ ...gistration_with_param_iconResumed_true.lua | 55 ++++++++ .../003_Icon_resumption_by_disconnect.lua | 70 ++++++++++ ...emove_icon_and_reregistered_Mobile_app.lua | 59 +++++++++ ...conResumed_true_App2_iconResumed_false.lua | 55 ++++++++ ...iconResumed_true_App2_iconResumed_true.lua | 74 +++++++++++ ...nd_to_SetAppIcon_request_GENERIC_ERROR.lua | 65 +++++++++ ...eived_response_SetAppIcon_INVALID_DATA.lua | 52 ++++++++ ...eceived_response_SetAppIcon_DISALLOWED.lua | 62 +++++++++ ..._received_response_SetAppIcon_REJECTED.lua | 66 ++++++++++ ..._re_sets_custom_icon_iconResumed_true_.lua | 82 ++++++++++++ .../API/SetAppIcon/commonIconResumed.lua | 123 ++++++++++++++++++ 12 files changed, 795 insertions(+) create mode 100644 test_scripts/API/SetAppIcon/001_Mobile_app_First_Registration.lua create mode 100644 test_scripts/API/SetAppIcon/002_Mobile_app_registration_with_param_iconResumed_true.lua create mode 100644 test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua create mode 100644 test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua create mode 100644 test_scripts/API/SetAppIcon/005_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_false.lua create mode 100644 test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua create mode 100644 test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua create mode 100644 test_scripts/API/SetAppIcon/008_Mobile_App_received_response_SetAppIcon_INVALID_DATA.lua create mode 100644 test_scripts/API/SetAppIcon/009_Mobile_App_received_response_SetAppIcon_DISALLOWED.lua create mode 100644 test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua create mode 100644 test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua create mode 100644 test_scripts/API/SetAppIcon/commonIconResumed.lua diff --git a/test_scripts/API/SetAppIcon/001_Mobile_app_First_Registration.lua b/test_scripts/API/SetAppIcon/001_Mobile_app_First_Registration.lua new file mode 100644 index 0000000000..e1e87658b9 --- /dev/null +++ b/test_scripts/API/SetAppIcon/001_Mobile_app_First_Registration.lua @@ -0,0 +1,32 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0041-appicon-resumption.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) SDL, HMI are started. +-- 2) Mobile app registers first time. +-- SDL does: +-- 1) Successfully register application and respond with result code "SUCCESS" and "iconResumed" = false" to mobile application. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/SetAppIcon/commonIconResumed') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SetAppIcon/002_Mobile_app_registration_with_param_iconResumed_true.lua b/test_scripts/API/SetAppIcon/002_Mobile_app_registration_with_param_iconResumed_true.lua new file mode 100644 index 0000000000..44c4de5526 --- /dev/null +++ b/test_scripts/API/SetAppIcon/002_Mobile_app_registration_with_param_iconResumed_true.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0041-appicon-resumption.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) SDL, HMI are started. +-- 2) Mobile application is registered and sets custom icon via sending PutFile and valid SetAppIcon request. +-- 3) Mobile app is re-registered. +-- SDL does: +-- 1) Successfully register application. +-- 2) Successful process PutFile and SetAppIcon requests. +-- 3) Respond with result code "SUCCESS" and "iconResumed" = true for RAI request. +-- 4) Send to HMI OnAppRegistered notification "icon" and notify that apps icon exists. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/SetAppIcon/commonIconResumed') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + syncFileName = "icon.png" +} +local requestUiParams = { + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(requestParams.syncFileName) + } +} +local allParams = { + requestParams = requestParams, + requestUiParams = requestUiParams +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false }) +runner.Step("Upload icon file", common.putFile) +runner.Step("SetAppIcon", common.setAppIcon, { allParams } ) +runner.Step("App unregistration", common.unregisterAppInterface, { 1 }) +runner.Step("App registration with iconResumed = true", common.registerAppWOPTU, { 1, true, true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua b/test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua new file mode 100644 index 0000000000..5822a5909e --- /dev/null +++ b/test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0041-appicon-resumption.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) SDL, HMI are started. +-- 2) Mobile application is registered and sets custom icon via sending PutFile and valid SetAppIcon request. +-- 3) Mobile application is unregistered. +-- 4) Mobile app is re-registered. +-- SDL does: +-- 1) Respond with result code "SUCCESS" and "iconResumed" = true for RAI request. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/SetAppIcon/commonIconResumed') +local test = require("user_modules/dummy_connecttest") +local mobile_session = require('mobile_session') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + syncFileName = "icon.png" +} +local requestUiParams = { + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(requestParams.syncFileName) + } +} +local allParams = { + requestParams = requestParams, + requestUiParams = requestUiParams +} + +local function CloseConnection() + test.mobileConnection:Close() + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = true }) +end + +local function OpenConnection() + test.mobileSession[1] = mobile_session.MobileSession( + test, + test.mobileConnection, + config.application1.registerAppInterfaceParams) + test.mobileConnection:Connect() + test.mobileSession[1]:StartRPC() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false }) +runner.Step("Upload icon file", common.putFile) +runner.Step("SetAppIcon", common.setAppIcon, { allParams } ) +runner.Step("Disconnect mobile app", CloseConnection) +runner.Step("Connect mobile app", OpenConnection) +runner.Step("App registration with iconResumed = true", common.registerAppWOPTU, { 1, true, true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua b/test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua new file mode 100644 index 0000000000..629db3eafd --- /dev/null +++ b/test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua @@ -0,0 +1,59 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0041-appicon-resumption.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) SDL, HMI are started. +-- 2) Mobile application is registered and sets custom icon via sending PutFile and valid SetAppIcon request. +-- 3) Mobile application is unregistered. +-- 4) Remove Icon for mobile app from the file system +-- 5) Mobile app is re-registered, mobile app is registered. +-- SDL does: +-- 1) SDL respond with result code "SUCCESS" and "iconResumed" = false for RAI request. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/SetAppIcon/commonIconResumed') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + syncFileName = "icon.png" +} +local requestUiParams = { + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(requestParams.syncFileName) + } +} +local allParams = { + requestParams = requestParams, + requestUiParams = requestUiParams +} + +local function IconRemove(pFile) + os.remove(common.getPathToFileInStorage(pFile)) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false }) +runner.Step("Upload icon file", common.putFile) +runner.Step("SetAppIcon", common.setAppIcon, { allParams } ) +runner.Step("App unregistration", common.unregisterAppInterface, { 1 }) +runner.Step("Remove Icon for mobile app from the file system", IconRemove, { "icon.png"}) +runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false, true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SetAppIcon/005_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_false.lua b/test_scripts/API/SetAppIcon/005_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_false.lua new file mode 100644 index 0000000000..0571d19016 --- /dev/null +++ b/test_scripts/API/SetAppIcon/005_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_false.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0041-appicon-resumption.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) SDL, HMI are started. +-- 2) App1 set custom icon via putfile and SetAppIcon requests and is re-registered with resuming custom icon( "iconResumed" = true). +-- 3) Mobile App2 registered. +-- SDL does: +-- 1) Register App1 successfully registered and sets its app icon, +-- respond to RAI with result code "SUCCESS", "iconResumed" = true +-- 2) Register an App 2 with default icon, "iconResumed" = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/SetAppIcon/commonIconResumed') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + syncFileName = "icon.png" +} +local requestUiParams = { + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(requestParams.syncFileName) + } +} +local allParams = { + requestParams = requestParams, + requestUiParams = requestUiParams +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("App1 registration with iconResumed = false", common.registerAppWOPTU, { 1, false }) +runner.Step("Upload icon file", common.putFile) +runner.Step("SetAppIcon", common.setAppIcon, { allParams } ) +runner.Step("App1 unregistration", common.unregisterAppInterface, { 1 }) +runner.Step("App1 registration with iconResumed = true", common.registerAppWOPTU, { 1, true, true }) +runner.Step("App2 registration with iconResumed = false", common.registerAppWOPTU, { 2, false }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua b/test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua new file mode 100644 index 0000000000..16f3ea543d --- /dev/null +++ b/test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua @@ -0,0 +1,74 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0041-appicon-resumption.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) SDL, HMI are started. +-- 2) App1 set custom icon via putfile and SetAppIcon requests. +-- 3) App2 set custom icon via putfile and SetAppIcon requests. +-- 4) Two app are re-registered. +-- SDL does: +-- 1) Register an App 1 successfully, respond to RAI with result code "SUCCESS", "iconResumed" = true. +-- 2) Register an App 2 successfully, respond to RAI with result code "SUCCESS", "iconResumed" = true. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/SetAppIcon/commonIconResumed') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + syncFileName = "icon.png" +} + +local requestUiParamsApp1 = { + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(requestParams.syncFileName) + } +} +local requestUiParamsApp2 = { + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(requestParams.syncFileName, 2) + } +} + +local allParamsApp1 = { + requestParams = requestParams, + requestUiParams = requestUiParamsApp1 +} +local allParamsApp2 = { + requestParams = requestParams, + requestUiParams = requestUiParamsApp2 +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("App1 registration with iconResumed = false", common.registerAppWOPTU, { 1, false }) +runner.Step("Upload icon file", common.putFile) +runner.Step("SetAppIcon", common.setAppIcon, { allParamsApp1 } ) + +runner.Step("App2 registration with iconResumed = false", common.registerAppWOPTU, { 2, false }) +runner.Step("Upload icon file", common.putFile, {nil, nil, 2}) +runner.Step("SetAppIcon", common.setAppIcon, { allParamsApp2, 2 } ) + +runner.Step("App1 unregistration", common.unregisterAppInterface, { 1 }) +runner.Step("App2 unregistration", common.unregisterAppInterface, { 2 }) + +runner.Step("App1 registration with iconResumed = true", common.registerAppWOPTU, { 1, true, true }) +runner.Step("App2 registration with iconResumed = true", common.registerAppWOPTU, { 2, true, true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua b/test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua new file mode 100644 index 0000000000..0b28e47aeb --- /dev/null +++ b/test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua @@ -0,0 +1,65 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0041-appicon-resumption.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) SDL, HMI are started. +-- 2) Mobile app is registered. Sends PutFile and SetAppIcon requests. +-- 3) HMI is not respond to SetAppIcon request. Mobile App received response SetAppIcon(GENERIC_ERROR). +-- 4) App is re-registered. +-- SDL does: +-- 1) Register an app successfully, respond to RAI with result code "SUCCESS", "iconResumed" = false. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/SetAppIcon/commonIconResumed') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + syncFileName = "icon.png" +} +local requestUiParams = { + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(requestParams.syncFileName) + } +} +local allParams = { + requestParams = requestParams, + requestUiParams = requestUiParams +} + +local function setAppIcon_GENERIC_ERROR(params, pAppId) + if not pAppId then pAppId = 1 end + local mobSession = common.getMobileSession(pAppId) + local cid = mobSession:SendRPC("SetAppIcon", params.requestParams) + params.requestUiParams.appID = common.getHMIAppId() + EXPECT_HMICALL("UI.SetAppIcon", params.requestUiParams) + :Do(function() + -- HMI does not respond + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false }) +runner.Step("Upload icon file", common.putFile) +runner.Step("HMI does not respond", setAppIcon_GENERIC_ERROR, { allParams }) +runner.Step("App unregistration", common.unregisterAppInterface, { 1 }) +runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false,true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SetAppIcon/008_Mobile_App_received_response_SetAppIcon_INVALID_DATA.lua b/test_scripts/API/SetAppIcon/008_Mobile_App_received_response_SetAppIcon_INVALID_DATA.lua new file mode 100644 index 0000000000..a6ff51a5c1 --- /dev/null +++ b/test_scripts/API/SetAppIcon/008_Mobile_App_received_response_SetAppIcon_INVALID_DATA.lua @@ -0,0 +1,52 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0041-appicon-resumption.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) SDL, HMI are started. +-- 2) Mobile app is registered. Sends PutFile and invalid SetAppIcon requests. +-- 3) Mobile App received response SetAppIcon(INVALID_DATA). Custom Icon is not set. +-- 4) App is re-registered. +-- SDL does: +-- 1) Successfully register application. +-- 2) Register an app successfully, respond to RAI with result code "SUCCESS", "iconResumed" = false. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/SetAppIcon/commonIconResumed') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + syncFileName = "123" --invalid type of parameter +} + +local function setAppIcon_INVALID_DATA(params) + local mobSession = common.getMobileSession() + local cid = mobSession:SendRPC("SetAppIcon", params) + EXPECT_HMICALL("UI.SetAppIcon", params.requestUiParams) + :Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false }) +runner.Step("Upload icon file", common.putFile) +runner.Step("Gets_INVALID_DATA", setAppIcon_INVALID_DATA, { requestParams } ) +runner.Step("App unregistration", common.unregisterAppInterface, { 1 }) +runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false, true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SetAppIcon/009_Mobile_App_received_response_SetAppIcon_DISALLOWED.lua b/test_scripts/API/SetAppIcon/009_Mobile_App_received_response_SetAppIcon_DISALLOWED.lua new file mode 100644 index 0000000000..956b2a7d48 --- /dev/null +++ b/test_scripts/API/SetAppIcon/009_Mobile_App_received_response_SetAppIcon_DISALLOWED.lua @@ -0,0 +1,62 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0041-appicon-resumption.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) SDL, HMI are started. +-- 2) SetAppIcon does not exist in app's assigned policies after PTU. +-- 3) Mobile app is registered. Sends PutFile and valid SetAppIcon requests. +-- 4) Mobile app received response SetAppIcon(DISALLOWED) +-- 5) Mobile app is re-registered. +-- SDL does: +-- 1) Register an app successfully, respond to RAI with result code "SUCCESS", "iconResumed" = false. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/SetAppIcon/commonIconResumed') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + syncFileName = "icon.png" +} + +--[[ Local Functions ]] +local function setAppIcon_DISALLOWED(params) + local mobSession = common.getMobileSession() + local cid = mobSession:SendRPC("SetAppIcon", params) + EXPECT_HMICALL("UI.SetAppIcon") + :Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function updatePTU(tbl) + local CustomGroup = commonFunctions:cloneTable(tbl.policy_table.functional_groupings["Base-4"]) + CustomGroup.rpcs.SetAppIcon = nil + tbl.policy_table.functional_groupings.GroupWithoutSetAppIcon = CustomGroup + tbl.policy_table.app_policies[common.getConfigAppParams().appID].groups = {"GroupWithoutSetAppIcon"} +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("App registration", common.registerApp, { 1 }) +runner.Step("PTU without permissions for SetAppIcon", common.policyTableUpdate, { updatePTU }) +runner.Step("Upload icon file", common.putFile) +runner.Step("Mobile App received response SetAppIcon(DISALLOWED)", setAppIcon_DISALLOWED, { requestParams } ) +runner.Step("App unregistration", common.unregisterAppInterface, { 1 }) +runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false, true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua b/test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua new file mode 100644 index 0000000000..d7b6cf3984 --- /dev/null +++ b/test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua @@ -0,0 +1,66 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0041-appicon-resumption.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) SDL, HMI are started. +-- 2) Mobile app is registered. Sends PutFile and valid SetAppIcon requests. +-- 3) HMI responds with REJECTED resultCode to SetAppIcon request. Mobile App received response SetAppIcon(REJECTED). +-- 4) App is re-registered. +-- SDL does: +-- 1) Register an app successfully, respond to RAI with result code "SUCCESS", "iconResumed" = true. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/SetAppIcon/commonIconResumed') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + syncFileName = "icon.png" +} +local requestUiParams = { + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(requestParams.syncFileName) + } +} +local allParams = { + requestParams = requestParams, + requestUiParams = requestUiParams +} + +--[[ Local Functions ]] +local function setAppIcon_resultCode_REJECTED(params) + local mobSession = common.getMobileSession() + local cid = mobSession:SendRPC("SetAppIcon", params.requestParams) + params.requestUiParams.appID = common.getHMIAppId() + EXPECT_HMICALL("UI.SetAppIcon", params.requestUiParams) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "REJECTED", {}) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false }) +runner.Step("Upload icon file", common.putFile) +runner.Step("SetAppIcon", common.setAppIcon, { allParams } ) +runner.Step("Mobile App received response SetAppIcon(REJECTED)", setAppIcon_resultCode_REJECTED, { allParams } ) +runner.Step("App unregistration", common.unregisterAppInterface, { 1 }) +runner.Step("App registration with iconResumed = true", common.registerAppWOPTU, { 1, true, true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua b/test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua new file mode 100644 index 0000000000..3ce5dc0464 --- /dev/null +++ b/test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua @@ -0,0 +1,82 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0041-appicon-resumption.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) SDL, HMI are started. +-- 2) Mobile application is registered and sets custom icon via sending PutFile and valid SetAppIcon request. +-- 3) App re-sets custom icon via sending PutFile and valid SetAppIcon request. +-- 4) App is re-registered. +-- SDL does: +-- 1) Successfully register application +-- 2) Successful processes PutFile and SetAppIcon requests. +-- 3) Respons with result code "SUCCESS" and "iconResumed" = true for RAI request. Corresponding custom icon is resumed. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/SetAppIcon/commonIconResumed') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams1 = { + syncFileName = "icon.png" +} + +local requestParams2 = { + syncFileName = "action.png" +} + +local requestUiParams1 = { + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(requestParams1.syncFileName) + } +} + +local requestUiParams2 = { + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(requestParams2.syncFileName) + } +} + +local allParamsSet1 = { + requestParams = requestParams1, + requestUiParams = requestUiParams1 +} + +local allParamsSet2 = { + requestParams = requestParams2, + requestUiParams = requestUiParams2 +} + +local PutFileParams = { + syncFileName = "action.png", + fileType = "GRAPHIC_PNG", + } + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false }) +runner.Step("Upload icon file1", common.putFile) +runner.Step("SetAppIcon1", common.setAppIcon, { allParamsSet1 } ) + +runner.Step("Upload icon file2", common.putFile, {PutFileParams}) +runner.Step("SetAppIcon2", common.setAppIcon, { allParamsSet2 } ) + +runner.Step("App unregistration", common.unregisterAppInterface, { 1 }) +runner.Step("App registration with iconResumed = true", common.registerAppWOPTU, { 1, true, true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SetAppIcon/commonIconResumed.lua b/test_scripts/API/SetAppIcon/commonIconResumed.lua new file mode 100644 index 0000000000..fea40fda89 --- /dev/null +++ b/test_scripts/API/SetAppIcon/commonIconResumed.lua @@ -0,0 +1,123 @@ +--------------------------------------------------------------------------------------------------- +-- Common module +--------------------------------------------------------------------------------------------------- +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 2 + +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") +local utils = require("user_modules/utils") +local test = require("user_modules/dummy_connecttest") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') + +--[[ Module ]] +local m = actions + +--[[ Variables ]] +-- local ptuTable = {} +local hmiAppIds = {} + +--[[ @registerAppWOPTU: register mobile application +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! pIconResumed - apps icon was resumed at system or is not resumed +--! pReconnection - re-register mobile application +--! @return: none +--]] +function m.registerAppWOPTU(pAppId, pIconResumed, pReconnection) + if not pAppId then pAppId = 1 end + local mobSession = m.getMobileSession(pAppId) + local function RegisterApp() + local corId = mobSession:SendRPC("RegisterAppInterface", + config["application" .. pAppId].registerAppInterfaceParams) + test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[m.getConfigAppParams(pAppId).appID] = d1.params.application.appID + end) + mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS", iconResumed = pIconResumed }) + :Do(function() + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + mobSession:ExpectNotification("OnPermissionsChange") + end) + end + if pReconnection == true then + RegisterApp() + else + mobSession:StartService(7) + :Do(function() + RegisterApp() + end) + end +end + +--Description: unregisterAppInterface successfully + --pAppId - application number (1, 2, etc.) +function m.unregisterAppInterface(pAppId) + if not pAppId then pAppId = 1 end + local mobSession = m.getMobileSession(pAppId) + local corId = mobSession:SendRPC("UnregisterAppInterface", { }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", + { appID = m.getHMIAppId(pAppId), unexpectedDisconnect = false }) + mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) +end + +--Description: Set all parameter for PutFile +local function putFileAllParams() + local temp = { + syncFileName = "icon.png", + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false, + offset = 0, + length = 11600 + } + return temp +end + +--Description: PutFile successfully + --paramsSend: Parameters will be sent to SDL + --file: path to file will be used to send to SDL + --pAppId - application number (1, 2, etc.) +function m.putFile(paramsSend, file, pAppId) + if paramsSend then + paramsSend = paramsSend + else paramsSend = putFileAllParams() + end + if not pAppId then pAppId = 1 end + local mobSession = m.getMobileSession(pAppId) + local cid + if file ~= nil then + cid = mobSession:SendRPC("PutFile",paramsSend, file) + else + cid = mobSession:SendRPC("PutFile",paramsSend, "files/icon.png") + end + + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +function m.getPathToFileInStorage(fileName, pAppId) + if not pAppId then pAppId = 1 end + return commonPreconditions:GetPathToSDL() .. "storage/" + .. m.getConfigAppParams( pAppId ).appID .. "_" + .. utils.getDeviceMAC() .. "/" .. fileName +end + +--Description: setAppIcon successfully + --params - Parameters will be sent to SDL + --pAppId - application number (1, 2, etc.) +function m.setAppIcon(params, pAppId) + if not pAppId then pAppId = 1 end + local mobSession = m.getMobileSession(pAppId) + local cid = mobSession:SendRPC("SetAppIcon", params.requestParams) + params.requestUiParams.appID = m.getHMIAppId() + EXPECT_HMICALL("UI.SetAppIcon", params.requestUiParams) + :Do(function(_, data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +return m From 548047945e3f53b7af6aa8ed5414f6b6dfd088ac Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 4 Apr 2018 18:57:33 +0300 Subject: [PATCH 346/681] Added expectation icon value in OnAppRegistered --- ..._re_sets_custom_icon_iconResumed_true_.lua | 2 +- .../API/SetAppIcon/commonIconResumed.lua | 30 +++++++++++++------ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua b/test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua index 3ce5dc0464..701abef886 100644 --- a/test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua +++ b/test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua @@ -76,7 +76,7 @@ runner.Step("Upload icon file2", common.putFile, {PutFileParams}) runner.Step("SetAppIcon2", common.setAppIcon, { allParamsSet2 } ) runner.Step("App unregistration", common.unregisterAppInterface, { 1 }) -runner.Step("App registration with iconResumed = true", common.registerAppWOPTU, { 1, true, true }) +runner.Step("App registration with iconResumed = true", common.registerAppWOPTU, { 1, true, true, "action.png" }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SetAppIcon/commonIconResumed.lua b/test_scripts/API/SetAppIcon/commonIconResumed.lua index fea40fda89..5a14c32835 100644 --- a/test_scripts/API/SetAppIcon/commonIconResumed.lua +++ b/test_scripts/API/SetAppIcon/commonIconResumed.lua @@ -18,6 +18,13 @@ local m = actions -- local ptuTable = {} local hmiAppIds = {} +function m.getPathToFileInStorage(fileName, pAppId) + if not pAppId then pAppId = 1 end + return commonPreconditions:GetPathToSDL() .. "storage/" + .. m.getConfigAppParams( pAppId ).appID .. "_" + .. utils.getDeviceMAC() .. "/" .. fileName +end + --[[ @registerAppWOPTU: register mobile application --! @parameters: --! pAppId - application number (1, 2, etc.) @@ -25,14 +32,26 @@ local hmiAppIds = {} --! pReconnection - re-register mobile application --! @return: none --]] -function m.registerAppWOPTU(pAppId, pIconResumed, pReconnection) +function m.registerAppWOPTU(pAppId, pIconResumed, pReconnection, pIconValue) if not pAppId then pAppId = 1 end + if pIconResumed == true then + if not pIconValue then + pIconValue = m.getPathToFileInStorage("icon.png") + else + pIconValue = m.getPathToFileInStorage(pIconValue) + end + else + pIconValue = "" + end local mobSession = m.getMobileSession(pAppId) local function RegisterApp() local corId = mobSession:SendRPC("RegisterAppInterface", config["application" .. pAppId].registerAppInterfaceParams) test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", - { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) + { application = { + appName = config["application" .. pAppId].registerAppInterfaceParams.appName, + icon = pIconValue + }}) :Do(function(_, d1) hmiAppIds[m.getConfigAppParams(pAppId).appID] = d1.params.application.appID end) @@ -98,13 +117,6 @@ function m.putFile(paramsSend, file, pAppId) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end -function m.getPathToFileInStorage(fileName, pAppId) - if not pAppId then pAppId = 1 end - return commonPreconditions:GetPathToSDL() .. "storage/" - .. m.getConfigAppParams( pAppId ).appID .. "_" - .. utils.getDeviceMAC() .. "/" .. fileName -end - --Description: setAppIcon successfully --params - Parameters will be sent to SDL --pAppId - application number (1, 2, etc.) From cf479ae02c7f291c12e23f52c7821acf48d0631c Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 5 Apr 2018 15:02:25 +0300 Subject: [PATCH 347/681] Check absence of icon paramter in case iconResumption = false --- test_scripts/API/SetAppIcon/commonIconResumed.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test_scripts/API/SetAppIcon/commonIconResumed.lua b/test_scripts/API/SetAppIcon/commonIconResumed.lua index 5a14c32835..160d13283a 100644 --- a/test_scripts/API/SetAppIcon/commonIconResumed.lua +++ b/test_scripts/API/SetAppIcon/commonIconResumed.lua @@ -40,8 +40,6 @@ function m.registerAppWOPTU(pAppId, pIconResumed, pReconnection, pIconValue) else pIconValue = m.getPathToFileInStorage(pIconValue) end - else - pIconValue = "" end local mobSession = m.getMobileSession(pAppId) local function RegisterApp() @@ -55,6 +53,13 @@ function m.registerAppWOPTU(pAppId, pIconResumed, pReconnection, pIconValue) :Do(function(_, d1) hmiAppIds[m.getConfigAppParams(pAppId).appID] = d1.params.application.appID end) + :ValidIf(function(_,data) + if false == pIconResumed and + data.params.application.icon then + return false, "BC.OnAppRegistered notification contains unexpected icon value " + end + return true + end) mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS", iconResumed = pIconResumed }) :Do(function() mobSession:ExpectNotification("OnHMIStatus", From 35bb9a5fd82a28283db8f15077f638ec7283d67d Mon Sep 17 00:00:00 2001 From: HSavynetska Date: Fri, 6 Apr 2018 12:21:42 +0300 Subject: [PATCH 348/681] Update test scripts for app_icon_resumption --- ...gistration_with_param_iconResumed_true.lua | 12 ++-- .../003_Icon_resumption_by_disconnect.lua | 30 ++------ ...emove_icon_and_reregistered_Mobile_app.lua | 12 ++-- ...conResumed_true_App2_iconResumed_false.lua | 12 ++-- ...iconResumed_true_App2_iconResumed_true.lua | 31 ++++---- ...nd_to_SetAppIcon_request_GENERIC_ERROR.lua | 12 ++-- ..._received_response_SetAppIcon_REJECTED.lua | 12 ++-- .../API/SetAppIcon/commonIconResumed.lua | 72 ++++++++++++++----- .../Smoke/Registration/003_Register_App.lua | 2 +- 9 files changed, 104 insertions(+), 91 deletions(-) diff --git a/test_scripts/API/SetAppIcon/002_Mobile_app_registration_with_param_iconResumed_true.lua b/test_scripts/API/SetAppIcon/002_Mobile_app_registration_with_param_iconResumed_true.lua index 44c4de5526..c45fb9ede8 100644 --- a/test_scripts/API/SetAppIcon/002_Mobile_app_registration_with_param_iconResumed_true.lua +++ b/test_scripts/API/SetAppIcon/002_Mobile_app_registration_with_param_iconResumed_true.lua @@ -25,19 +25,17 @@ local common = require('test_scripts/API/SetAppIcon/commonIconResumed') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local requestParams = { - syncFileName = "icon.png" +local allParams = { + requestParams = { + syncFileName = "icon.png" + } } -local requestUiParams = { + requestUiParams = { syncFileName = { imageType = "DYNAMIC", value = common.getPathToFileInStorage(requestParams.syncFileName) } } -local allParams = { - requestParams = requestParams, - requestUiParams = requestUiParams -} --[[ Scenario ]] runner.Title("Preconditions") diff --git a/test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua b/test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua index 5822a5909e..54410682f2 100644 --- a/test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua +++ b/test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua @@ -25,33 +25,17 @@ local mobile_session = require('mobile_session') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local requestParams = { - syncFileName = "icon.png" +local allParams = { + requestParams = { + syncFileName = "icon.png" + } } -local requestUiParams = { + requestUiParams = { syncFileName = { imageType = "DYNAMIC", value = common.getPathToFileInStorage(requestParams.syncFileName) } } -local allParams = { - requestParams = requestParams, - requestUiParams = requestUiParams -} - -local function CloseConnection() - test.mobileConnection:Close() - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = true }) -end - -local function OpenConnection() - test.mobileSession[1] = mobile_session.MobileSession( - test, - test.mobileConnection, - config.application1.registerAppInterfaceParams) - test.mobileConnection:Connect() - test.mobileSession[1]:StartRPC() -end --[[ Scenario ]] runner.Title("Preconditions") @@ -62,8 +46,8 @@ runner.Title("Test") runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false }) runner.Step("Upload icon file", common.putFile) runner.Step("SetAppIcon", common.setAppIcon, { allParams } ) -runner.Step("Disconnect mobile app", CloseConnection) -runner.Step("Connect mobile app", OpenConnection) +runner.Step("Disconnect mobile app", common.CloseConnection) +runner.Step("Connect mobile app", common.OpenConnection) runner.Step("App registration with iconResumed = true", common.registerAppWOPTU, { 1, true, true }) runner.Title("Postconditions") diff --git a/test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua b/test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua index 629db3eafd..c1cb442f01 100644 --- a/test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua +++ b/test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua @@ -24,19 +24,17 @@ local common = require('test_scripts/API/SetAppIcon/commonIconResumed') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local requestParams = { - syncFileName = "icon.png" +local allParams = { + requestParams = { + syncFileName = "icon.png" + } } -local requestUiParams = { + requestUiParams = { syncFileName = { imageType = "DYNAMIC", value = common.getPathToFileInStorage(requestParams.syncFileName) } } -local allParams = { - requestParams = requestParams, - requestUiParams = requestUiParams -} local function IconRemove(pFile) os.remove(common.getPathToFileInStorage(pFile)) diff --git a/test_scripts/API/SetAppIcon/005_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_false.lua b/test_scripts/API/SetAppIcon/005_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_false.lua index 0571d19016..605ec0484b 100644 --- a/test_scripts/API/SetAppIcon/005_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_false.lua +++ b/test_scripts/API/SetAppIcon/005_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_false.lua @@ -24,19 +24,17 @@ local common = require('test_scripts/API/SetAppIcon/commonIconResumed') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local requestParams = { - syncFileName = "icon.png" +local allParams = { + requestParams = { + syncFileName = "icon.png" + } } -local requestUiParams = { + requestUiParams = { syncFileName = { imageType = "DYNAMIC", value = common.getPathToFileInStorage(requestParams.syncFileName) } } -local allParams = { - requestParams = requestParams, - requestUiParams = requestUiParams -} --[[ Scenario ]] runner.Title("Preconditions") diff --git a/test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua b/test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua index 16f3ea543d..a336c97ef4 100644 --- a/test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua +++ b/test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua @@ -24,30 +24,29 @@ local common = require('test_scripts/API/SetAppIcon/commonIconResumed') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local requestParams = { - syncFileName = "icon.png" -} - -local requestUiParamsApp1 = { - syncFileName = { - imageType = "DYNAMIC", - value = common.getPathToFileInStorage(requestParams.syncFileName) +local allParamsApp1 = { + requestParams1 = { + syncFileName = "icon.png" } } -local requestUiParamsApp2 = { + requestUiParams1 = { syncFileName = { imageType = "DYNAMIC", - value = common.getPathToFileInStorage(requestParams.syncFileName, 2) + value = common.getPathToFileInStorage(requestParams1.syncFileName) } } -local allParamsApp1 = { - requestParams = requestParams, - requestUiParams = requestUiParamsApp1 -} + local allParamsApp2 = { - requestParams = requestParams, - requestUiParams = requestUiParamsApp2 + requestParams2 = { + syncFileName = "action.png" + } +} + requestUiParams2 = { + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(requestParams2.syncFileName) + } } --[[ Scenario ]] diff --git a/test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua b/test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua index 0b28e47aeb..f259fc126f 100644 --- a/test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua +++ b/test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua @@ -23,19 +23,17 @@ local common = require('test_scripts/API/SetAppIcon/commonIconResumed') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local requestParams = { - syncFileName = "icon.png" +local allParams = { + requestParams = { + syncFileName = "icon.png" + } } -local requestUiParams = { + requestUiParams = { syncFileName = { imageType = "DYNAMIC", value = common.getPathToFileInStorage(requestParams.syncFileName) } } -local allParams = { - requestParams = requestParams, - requestUiParams = requestUiParams -} local function setAppIcon_GENERIC_ERROR(params, pAppId) if not pAppId then pAppId = 1 end diff --git a/test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua b/test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua index d7b6cf3984..90ba6a3bdf 100644 --- a/test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua +++ b/test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua @@ -23,19 +23,17 @@ local common = require('test_scripts/API/SetAppIcon/commonIconResumed') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local requestParams = { - syncFileName = "icon.png" +local allParams = { + requestParams = { + syncFileName = "icon.png" + } } -local requestUiParams = { + requestUiParams = { syncFileName = { imageType = "DYNAMIC", value = common.getPathToFileInStorage(requestParams.syncFileName) } } -local allParams = { - requestParams = requestParams, - requestUiParams = requestUiParams -} --[[ Local Functions ]] local function setAppIcon_resultCode_REJECTED(params) diff --git a/test_scripts/API/SetAppIcon/commonIconResumed.lua b/test_scripts/API/SetAppIcon/commonIconResumed.lua index 160d13283a..4d32d312fe 100644 --- a/test_scripts/API/SetAppIcon/commonIconResumed.lua +++ b/test_scripts/API/SetAppIcon/commonIconResumed.lua @@ -15,10 +15,14 @@ local commonPreconditions = require('user_modules/shared_testcases/commonPrecond local m = actions --[[ Variables ]] --- local ptuTable = {} local hmiAppIds = {} -function m.getPathToFileInStorage(fileName, pAppId) +--[[ @getPathToFileInStorage: Return app file from storage +--! @parameters: +--! pFile - Path to file will be used to send to SDL +--! pAppId - application number (1, 2, etc.) +--]] +function m.getPathToFileInStorage(pFileName, pAppId) if not pAppId then pAppId = 1 end return commonPreconditions:GetPathToSDL() .. "storage/" .. m.getConfigAppParams( pAppId ).appID .. "_" @@ -30,6 +34,7 @@ end --! pAppId - application number (1, 2, etc.) --! pIconResumed - apps icon was resumed at system or is not resumed --! pReconnection - re-register mobile application +--! pIconValue - --! @return: none --]] function m.registerAppWOPTU(pAppId, pIconResumed, pReconnection, pIconValue) @@ -77,8 +82,10 @@ function m.registerAppWOPTU(pAppId, pIconResumed, pReconnection, pIconValue) end end ---Description: unregisterAppInterface successfully - --pAppId - application number (1, 2, etc.) +--[[ @unregisterAppInterface: Mobile application successfully unregistered +--! @parameters: +--! pAppId - Application number (1, 2, etc.) +--]] function m.unregisterAppInterface(pAppId) if not pAppId then pAppId = 1 end local mobSession = m.getMobileSession(pAppId) @@ -88,8 +95,11 @@ function m.unregisterAppInterface(pAppId) mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) end ---Description: Set all parameter for PutFile -local function putFileAllParams() +--[[ @putFileAllParams: Set all parameter for PutFile +--! @parameters: none +--! @return: none +--]] +local function getPutFileAllParams() local temp = { syncFileName = "icon.png", fileType = "GRAPHIC_PNG", @@ -101,11 +111,13 @@ local function putFileAllParams() return temp end ---Description: PutFile successfully - --paramsSend: Parameters will be sent to SDL - --file: path to file will be used to send to SDL - --pAppId - application number (1, 2, etc.) -function m.putFile(paramsSend, file, pAppId) +--[[ @PutFile: File downloaded successfully +--! @parameters: +--! pFile - Path to file will be used to send to SDL +--! pAppId - Application number (1, 2, etc.) +--! @return: none +--]] +function m.putFile(paramsSend, pFile, pAppId) if paramsSend then paramsSend = paramsSend else paramsSend = putFileAllParams() @@ -114,17 +126,22 @@ function m.putFile(paramsSend, file, pAppId) local mobSession = m.getMobileSession(pAppId) local cid if file ~= nil then - cid = mobSession:SendRPC("PutFile",paramsSend, file) + cid = mobSession:SendRPC("PutFile", paramsSend, file) else - cid = mobSession:SendRPC("PutFile",paramsSend, "files/icon.png") + cid = mobSession:SendRPC("PutFile", paramsSend, "files/icon.png") end mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end ---Description: setAppIcon successfully - --params - Parameters will be sent to SDL - --pAppId - application number (1, 2, etc.) + + +--[[ @setAppIcon: Icon set successfully +--! @parameters: +--! params - Parameters will be sent to SDL +--! pAppId - Application number (1, 2, etc.) +--! @return: m +--]] function m.setAppIcon(params, pAppId) if not pAppId then pAppId = 1 end local mobSession = m.getMobileSession(pAppId) @@ -138,3 +155,26 @@ function m.setAppIcon(params, pAppId) end return m + +--[[ @CloseConnection: Close mobile connection successfully +--! @parameters: none +--! @return: none +--]] +function m.CloseConnection() + test.mobileConnection:Close() + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = true }) +end + + +--[[ @OpenConnection: return Mobile connection object +--! @parameters: none +--! return: none +--]] +function m.OpenConnection() + test.mobileSession[1] = mobile_session.MobileSession( + test, + test.mobileConnection, + config.application1.registerAppInterfaceParams) + test.mobileConnection:Connect() + test.mobileSession[1]:StartRPC() +end diff --git a/test_scripts/Smoke/Registration/003_Register_App.lua b/test_scripts/Smoke/Registration/003_Register_App.lua index 8f837a5a59..88fdc85711 100644 --- a/test_scripts/Smoke/Registration/003_Register_App.lua +++ b/test_scripts/Smoke/Registration/003_Register_App.lua @@ -78,4 +78,4 @@ function Test.Stop_SDL() StopSDL() end -return Test \ No newline at end of file +return Test From 1b9f7c09e1e22749389fae7313c4e12ad9fafb0f Mon Sep 17 00:00:00 2001 From: HSavynetska Date: Fri, 6 Apr 2018 12:32:37 +0300 Subject: [PATCH 349/681] Added test set for app_icon_resumption --- test_sets/app_ico_resumption.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test_sets/app_ico_resumption.txt diff --git a/test_sets/app_ico_resumption.txt b/test_sets/app_ico_resumption.txt new file mode 100644 index 0000000000..77f17c42a9 --- /dev/null +++ b/test_sets/app_ico_resumption.txt @@ -0,0 +1,13 @@ +./test_scripts/API/SetAppIcon/001_Mobile_app_First_Registration.lua +./test_scripts/API/SetAppIcon/002_Mobile_app_registration_with_param_iconResumed_true.lua +./test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua +./test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua +./test_scripts/API/SetAppIcon/005_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_false.lua +./test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua +./test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua +./test_scripts/API/SetAppIcon/008_Mobile_App_received_response_SetAppIcon_INVALID_DATA.lua +./test_scripts/API/SetAppIcon/009_Mobile_App_received_response_SetAppIcon_DISALLOWED.lua +./test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua +./test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua + + From dd41900aff8e71a0128a39041d50db39b1731cff Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 6 Apr 2018 13:31:07 +0300 Subject: [PATCH 350/681] Update acoording to review, icon from resumption in storage --- ...gistration_with_param_iconResumed_true.lua | 16 ++-- .../003_Icon_resumption_by_disconnect.lua | 17 ++-- ...emove_icon_and_reregistered_Mobile_app.lua | 21 ++--- ...conResumed_true_App2_iconResumed_false.lua | 15 ++-- ...iconResumed_true_App2_iconResumed_true.lua | 40 +++++---- ...nd_to_SetAppIcon_request_GENERIC_ERROR.lua | 15 ++-- ..._received_response_SetAppIcon_REJECTED.lua | 15 ++-- ..._re_sets_custom_icon_iconResumed_true_.lua | 2 +- .../API/SetAppIcon/commonIconResumed.lua | 85 ++++++++++--------- ...resumption.txt => app_icon_resumption.txt} | 2 - 10 files changed, 121 insertions(+), 107 deletions(-) rename test_sets/{app_ico_resumption.txt => app_icon_resumption.txt} (99%) diff --git a/test_scripts/API/SetAppIcon/002_Mobile_app_registration_with_param_iconResumed_true.lua b/test_scripts/API/SetAppIcon/002_Mobile_app_registration_with_param_iconResumed_true.lua index c45fb9ede8..0f2868200d 100644 --- a/test_scripts/API/SetAppIcon/002_Mobile_app_registration_with_param_iconResumed_true.lua +++ b/test_scripts/API/SetAppIcon/002_Mobile_app_registration_with_param_iconResumed_true.lua @@ -25,18 +25,18 @@ local common = require('test_scripts/API/SetAppIcon/commonIconResumed') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] +local iconValue = "icon.png" local allParams = { - requestParams = { - syncFileName = "icon.png" - } -} + requestParams = { + syncFileName = iconValue + }, requestUiParams = { - syncFileName = { - imageType = "DYNAMIC", - value = common.getPathToFileInStorage(requestParams.syncFileName) + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(iconValue) + } } } - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) diff --git a/test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua b/test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua index 54410682f2..96817e944a 100644 --- a/test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua +++ b/test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua @@ -18,22 +18,21 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/API/SetAppIcon/commonIconResumed') -local test = require("user_modules/dummy_connecttest") -local mobile_session = require('mobile_session') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] +local iconValue = "icon.png" local allParams = { - requestParams = { - syncFileName = "icon.png" - } -} + requestParams = { + syncFileName = iconValue + }, requestUiParams = { - syncFileName = { - imageType = "DYNAMIC", - value = common.getPathToFileInStorage(requestParams.syncFileName) + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(iconValue) + } } } diff --git a/test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua b/test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua index c1cb442f01..438528424a 100644 --- a/test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua +++ b/test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua @@ -24,20 +24,21 @@ local common = require('test_scripts/API/SetAppIcon/commonIconResumed') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] +local iconValue = "icon.png" local allParams = { - requestParams = { - syncFileName = "icon.png" - } -} + requestParams = { + syncFileName = iconValue + }, requestUiParams = { - syncFileName = { - imageType = "DYNAMIC", - value = common.getPathToFileInStorage(requestParams.syncFileName) + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(iconValue) + } } } -local function IconRemove(pFile) - os.remove(common.getPathToFileInStorage(pFile)) +local function IconRemove(pAppId) + os.remove(common.getIconValueForResumtion(pAppId)) end --[[ Scenario ]] @@ -50,7 +51,7 @@ runner.Step("App registration with iconResumed = false", common.registerAppWOPTU runner.Step("Upload icon file", common.putFile) runner.Step("SetAppIcon", common.setAppIcon, { allParams } ) runner.Step("App unregistration", common.unregisterAppInterface, { 1 }) -runner.Step("Remove Icon for mobile app from the file system", IconRemove, { "icon.png"}) +runner.Step("Remove Icon for mobile app from the file system", IconRemove, { 1 }) runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false, true }) runner.Title("Postconditions") diff --git a/test_scripts/API/SetAppIcon/005_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_false.lua b/test_scripts/API/SetAppIcon/005_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_false.lua index 605ec0484b..a985a30c0e 100644 --- a/test_scripts/API/SetAppIcon/005_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_false.lua +++ b/test_scripts/API/SetAppIcon/005_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_false.lua @@ -24,15 +24,16 @@ local common = require('test_scripts/API/SetAppIcon/commonIconResumed') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] +local iconValue = "icon.png" local allParams = { - requestParams = { - syncFileName = "icon.png" - } -} + requestParams = { + syncFileName = iconValue + }, requestUiParams = { - syncFileName = { - imageType = "DYNAMIC", - value = common.getPathToFileInStorage(requestParams.syncFileName) + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(iconValue) + } } } diff --git a/test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua b/test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua index a336c97ef4..02c0066ea9 100644 --- a/test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua +++ b/test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua @@ -24,29 +24,35 @@ local common = require('test_scripts/API/SetAppIcon/commonIconResumed') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] +local IconValueForApp1 = "icon.png" local allParamsApp1 = { - requestParams1 = { - syncFileName = "icon.png" + requestParams = { + syncFileName = IconValueForApp1 + }, + requestUiParams = { + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(IconValueForApp1) + } } } - requestUiParams1 = { - syncFileName = { - imageType = "DYNAMIC", - value = common.getPathToFileInStorage(requestParams1.syncFileName) - } -} - +local IconValueForApp2 = "action.png" local allParamsApp2 = { - requestParams2 = { - syncFileName = "action.png" + requestParams = { + syncFileName = IconValueForApp2 + }, + requestUiParams = { + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(IconValueForApp2, 2) + } } } - requestUiParams2 = { - syncFileName = { - imageType = "DYNAMIC", - value = common.getPathToFileInStorage(requestParams2.syncFileName) - } + +local PutFileParams = { + syncFileName = IconValueForApp2, + fileType = "GRAPHIC_PNG", } --[[ Scenario ]] @@ -60,7 +66,7 @@ runner.Step("Upload icon file", common.putFile) runner.Step("SetAppIcon", common.setAppIcon, { allParamsApp1 } ) runner.Step("App2 registration with iconResumed = false", common.registerAppWOPTU, { 2, false }) -runner.Step("Upload icon file", common.putFile, {nil, nil, 2}) +runner.Step("Upload icon file", common.putFile, {PutFileParams, nil, 2}) runner.Step("SetAppIcon", common.setAppIcon, { allParamsApp2, 2 } ) runner.Step("App1 unregistration", common.unregisterAppInterface, { 1 }) diff --git a/test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua b/test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua index f259fc126f..15dcb4cf26 100644 --- a/test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua +++ b/test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua @@ -23,15 +23,16 @@ local common = require('test_scripts/API/SetAppIcon/commonIconResumed') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] +local iconValue = "icon.png" local allParams = { - requestParams = { - syncFileName = "icon.png" - } -} + requestParams = { + syncFileName = iconValue + }, requestUiParams = { - syncFileName = { - imageType = "DYNAMIC", - value = common.getPathToFileInStorage(requestParams.syncFileName) + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(iconValue) + } } } diff --git a/test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua b/test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua index 90ba6a3bdf..cdf3296f13 100644 --- a/test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua +++ b/test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua @@ -23,15 +23,16 @@ local common = require('test_scripts/API/SetAppIcon/commonIconResumed') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] +local iconValue = "icon.png" local allParams = { - requestParams = { - syncFileName = "icon.png" - } -} + requestParams = { + syncFileName = iconValue + }, requestUiParams = { - syncFileName = { - imageType = "DYNAMIC", - value = common.getPathToFileInStorage(requestParams.syncFileName) + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(iconValue) + } } } diff --git a/test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua b/test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua index 701abef886..3ce5dc0464 100644 --- a/test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua +++ b/test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua @@ -76,7 +76,7 @@ runner.Step("Upload icon file2", common.putFile, {PutFileParams}) runner.Step("SetAppIcon2", common.setAppIcon, { allParamsSet2 } ) runner.Step("App unregistration", common.unregisterAppInterface, { 1 }) -runner.Step("App registration with iconResumed = true", common.registerAppWOPTU, { 1, true, true, "action.png" }) +runner.Step("App registration with iconResumed = true", common.registerAppWOPTU, { 1, true, true }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SetAppIcon/commonIconResumed.lua b/test_scripts/API/SetAppIcon/commonIconResumed.lua index 4d32d312fe..40c27a480f 100644 --- a/test_scripts/API/SetAppIcon/commonIconResumed.lua +++ b/test_scripts/API/SetAppIcon/commonIconResumed.lua @@ -10,6 +10,7 @@ local actions = require("user_modules/sequences/actions") local utils = require("user_modules/utils") local test = require("user_modules/dummy_connecttest") local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local mobile_session = require('mobile_session') --[[ Module ]] local m = actions @@ -17,16 +18,28 @@ local m = actions --[[ Variables ]] local hmiAppIds = {} ---[[ @getPathToFileInStorage: Return app file from storage +--[[ @getPathToFileInStorage: Get path of app icon from storage --! @parameters: ---! pFile - Path to file will be used to send to SDL +--! pFileName - Name of file --! pAppId - application number (1, 2, etc.) +--! @return: app icon path --]] function m.getPathToFileInStorage(pFileName, pAppId) if not pAppId then pAppId = 1 end return commonPreconditions:GetPathToSDL() .. "storage/" .. m.getConfigAppParams( pAppId ).appID .. "_" - .. utils.getDeviceMAC() .. "/" .. fileName + .. utils.getDeviceMAC() .. "/" .. pFileName +end + +--[[ @getIconValueForResumtion: Get path of app icon from storage +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: app icon path +--]] +function m.getIconValueForResumtion (pAppId) + if not pAppId then pAppId = 1 end + return commonPreconditions:GetPathToSDL() .. "storage/" + .. m.getConfigAppParams( pAppId ).appID end --[[ @registerAppWOPTU: register mobile application @@ -34,18 +47,12 @@ end --! pAppId - application number (1, 2, etc.) --! pIconResumed - apps icon was resumed at system or is not resumed --! pReconnection - re-register mobile application ---! pIconValue - --! @return: none --]] -function m.registerAppWOPTU(pAppId, pIconResumed, pReconnection, pIconValue) +function m.registerAppWOPTU(pAppId, pIconResumed, pReconnection) if not pAppId then pAppId = 1 end - if pIconResumed == true then - if not pIconValue then - pIconValue = m.getPathToFileInStorage("icon.png") - else - pIconValue = m.getPathToFileInStorage(pIconValue) - end - end + local pIconValue + if pIconResumed == true then pIconValue = m.getIconValueForResumtion(pAppId) end local mobSession = m.getMobileSession(pAppId) local function RegisterApp() local corId = mobSession:SendRPC("RegisterAppInterface", @@ -61,7 +68,7 @@ function m.registerAppWOPTU(pAppId, pIconResumed, pReconnection, pIconValue) :ValidIf(function(_,data) if false == pIconResumed and data.params.application.icon then - return false, "BC.OnAppRegistered notification contains unexpected icon value " + return false, "BC.OnAppRegistered notification contains unexpected parameter: icon " end return true end) @@ -82,9 +89,10 @@ function m.registerAppWOPTU(pAppId, pIconResumed, pReconnection, pIconValue) end end ---[[ @unregisterAppInterface: Mobile application successfully unregistered +--[[ @unregisterAppInterface: Mobile application unregistration --! @parameters: --! pAppId - Application number (1, 2, etc.) +--! @return: none --]] function m.unregisterAppInterface(pAppId) if not pAppId then pAppId = 1 end @@ -95,9 +103,9 @@ function m.unregisterAppInterface(pAppId) mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) end ---[[ @putFileAllParams: Set all parameter for PutFile ---! @parameters: none ---! @return: none +--[[ @getPutFileAllParams: get all parameter for PutFile +--! @parameters: none +--! @return: parameters for PutFile --]] local function getPutFileAllParams() local temp = { @@ -111,62 +119,59 @@ local function getPutFileAllParams() return temp end ---[[ @PutFile: File downloaded successfully +--[[ @putFile: Successful processing PutFile RPC --! @parameters: ---! pFile - Path to file will be used to send to SDL +--! pParamsSend - parameters for PutFile RPC +--! pFile - file will be used to send to SDL --! pAppId - Application number (1, 2, etc.) --! @return: none --]] -function m.putFile(paramsSend, pFile, pAppId) - if paramsSend then - paramsSend = paramsSend - else paramsSend = putFileAllParams() +function m.putFile(pParamsSend, pFile, pAppId) + if pParamsSend then + pParamsSend = pParamsSend + else pParamsSend = getPutFileAllParams() end if not pAppId then pAppId = 1 end local mobSession = m.getMobileSession(pAppId) local cid - if file ~= nil then - cid = mobSession:SendRPC("PutFile", paramsSend, file) + if pFile ~= nil then + cid = mobSession:SendRPC("PutFile", pParamsSend, pFile) else - cid = mobSession:SendRPC("PutFile", paramsSend, "files/icon.png") + cid = mobSession:SendRPC("PutFile", pParamsSend, "files/icon.png") end mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end - - ---[[ @setAppIcon: Icon set successfully +--[[ @setAppIcon: Successful Processing of SetAppIcon RPC --! @parameters: ---! params - Parameters will be sent to SDL +--! pParams - Parameters for SetAppIcon RPC --! pAppId - Application number (1, 2, etc.) ---! @return: m +--! @return: none --]] -function m.setAppIcon(params, pAppId) +function m.setAppIcon(pParams, pAppId) if not pAppId then pAppId = 1 end local mobSession = m.getMobileSession(pAppId) - local cid = mobSession:SendRPC("SetAppIcon", params.requestParams) - params.requestUiParams.appID = m.getHMIAppId() - EXPECT_HMICALL("UI.SetAppIcon", params.requestUiParams) + local cid = mobSession:SendRPC("SetAppIcon", pParams.requestParams) + pParams.requestUiParams.appID = m.getHMIAppId() + EXPECT_HMICALL("UI.SetAppIcon", pParams.requestUiParams) :Do(function(_, data) m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) end) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end -return m - --[[ @CloseConnection: Close mobile connection successfully --! @parameters: none --! @return: none --]] function m.CloseConnection() - test.mobileConnection:Close() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = true }) + test.mobileConnection:Close() end ---[[ @OpenConnection: return Mobile connection object +--[[ @OpenConnection: Open mobile connection successfully --! @parameters: none --! return: none --]] @@ -178,3 +183,5 @@ function m.OpenConnection() test.mobileConnection:Connect() test.mobileSession[1]:StartRPC() end + +return m diff --git a/test_sets/app_ico_resumption.txt b/test_sets/app_icon_resumption.txt similarity index 99% rename from test_sets/app_ico_resumption.txt rename to test_sets/app_icon_resumption.txt index 77f17c42a9..849342489f 100644 --- a/test_sets/app_ico_resumption.txt +++ b/test_sets/app_icon_resumption.txt @@ -9,5 +9,3 @@ ./test_scripts/API/SetAppIcon/009_Mobile_App_received_response_SetAppIcon_DISALLOWED.lua ./test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua ./test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua - - From a1ab2542cc56b496df5ffb70d7645da333b93a05 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 6 Apr 2018 14:46:01 +0300 Subject: [PATCH 351/681] Minor fixes --- .../003_Icon_resumption_by_disconnect.lua | 4 +- ...emove_icon_and_reregistered_Mobile_app.lua | 6 +- ...iconResumed_true_App2_iconResumed_true.lua | 6 +- ...nd_to_SetAppIcon_request_GENERIC_ERROR.lua | 2 +- ...eceived_response_SetAppIcon_DISALLOWED.lua | 2 +- ..._received_response_SetAppIcon_REJECTED.lua | 6 +- ..._re_sets_custom_icon_iconResumed_true.lua} | 6 +- .../API/SetAppIcon/commonIconResumed.lua | 57 ++++++++++--------- test_sets/app_icon_resumption.txt | 2 +- 9 files changed, 46 insertions(+), 45 deletions(-) rename test_scripts/API/SetAppIcon/{011_App_re_sets_custom_icon_iconResumed_true_.lua => 011_App_re_sets_custom_icon_iconResumed_true.lua} (95%) diff --git a/test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua b/test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua index 96817e944a..5cf41f4ad4 100644 --- a/test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua +++ b/test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua @@ -45,8 +45,8 @@ runner.Title("Test") runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false }) runner.Step("Upload icon file", common.putFile) runner.Step("SetAppIcon", common.setAppIcon, { allParams } ) -runner.Step("Disconnect mobile app", common.CloseConnection) -runner.Step("Connect mobile app", common.OpenConnection) +runner.Step("Disconnect mobile app", common.closeConnection) +runner.Step("Connect mobile app", common.openConnection) runner.Step("App registration with iconResumed = true", common.registerAppWOPTU, { 1, true, true }) runner.Title("Postconditions") diff --git a/test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua b/test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua index 438528424a..a0750fd9de 100644 --- a/test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua +++ b/test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua @@ -37,8 +37,8 @@ local allParams = { } } -local function IconRemove(pAppId) - os.remove(common.getIconValueForResumtion(pAppId)) +local function removeIcon(pAppId) + os.remove(common.getIconValueForResumption(pAppId)) end --[[ Scenario ]] @@ -51,7 +51,7 @@ runner.Step("App registration with iconResumed = false", common.registerAppWOPTU runner.Step("Upload icon file", common.putFile) runner.Step("SetAppIcon", common.setAppIcon, { allParams } ) runner.Step("App unregistration", common.unregisterAppInterface, { 1 }) -runner.Step("Remove Icon for mobile app from the file system", IconRemove, { 1 }) +runner.Step("Remove Icon for mobile app from the file system", removeIcon, { 1 }) runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false, true }) runner.Title("Postconditions") diff --git a/test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua b/test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua index 02c0066ea9..e71d0ee6cd 100644 --- a/test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua +++ b/test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua @@ -51,8 +51,8 @@ local allParamsApp2 = { } local PutFileParams = { - syncFileName = IconValueForApp2, - fileType = "GRAPHIC_PNG", + syncFileName = IconValueForApp2, + fileType = "GRAPHIC_PNG", } --[[ Scenario ]] @@ -66,7 +66,7 @@ runner.Step("Upload icon file", common.putFile) runner.Step("SetAppIcon", common.setAppIcon, { allParamsApp1 } ) runner.Step("App2 registration with iconResumed = false", common.registerAppWOPTU, { 2, false }) -runner.Step("Upload icon file", common.putFile, {PutFileParams, nil, 2}) +runner.Step("Upload icon file", common.putFile, { PutFileParams, nil, 2 }) runner.Step("SetAppIcon", common.setAppIcon, { allParamsApp2, 2 } ) runner.Step("App1 unregistration", common.unregisterAppInterface, { 1 }) diff --git a/test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua b/test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua index 15dcb4cf26..2535455675 100644 --- a/test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua +++ b/test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua @@ -58,7 +58,7 @@ runner.Step("App registration with iconResumed = false", common.registerAppWOPTU runner.Step("Upload icon file", common.putFile) runner.Step("HMI does not respond", setAppIcon_GENERIC_ERROR, { allParams }) runner.Step("App unregistration", common.unregisterAppInterface, { 1 }) -runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false,true }) +runner.Step("App registration with iconResumed = false", common.registerAppWOPTU, { 1, false, true }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SetAppIcon/009_Mobile_App_received_response_SetAppIcon_DISALLOWED.lua b/test_scripts/API/SetAppIcon/009_Mobile_App_received_response_SetAppIcon_DISALLOWED.lua index 956b2a7d48..6020ebae36 100644 --- a/test_scripts/API/SetAppIcon/009_Mobile_App_received_response_SetAppIcon_DISALLOWED.lua +++ b/test_scripts/API/SetAppIcon/009_Mobile_App_received_response_SetAppIcon_DISALLOWED.lua @@ -42,7 +42,7 @@ local function updatePTU(tbl) local CustomGroup = commonFunctions:cloneTable(tbl.policy_table.functional_groupings["Base-4"]) CustomGroup.rpcs.SetAppIcon = nil tbl.policy_table.functional_groupings.GroupWithoutSetAppIcon = CustomGroup - tbl.policy_table.app_policies[common.getConfigAppParams().appID].groups = {"GroupWithoutSetAppIcon"} + tbl.policy_table.app_policies[common.getConfigAppParams().appID].groups = { "GroupWithoutSetAppIcon" } end --[[ Scenario ]] diff --git a/test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua b/test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua index cdf3296f13..707175db34 100644 --- a/test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua +++ b/test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua @@ -42,9 +42,9 @@ local function setAppIcon_resultCode_REJECTED(params) local cid = mobSession:SendRPC("SetAppIcon", params.requestParams) params.requestUiParams.appID = common.getHMIAppId() EXPECT_HMICALL("UI.SetAppIcon", params.requestUiParams) - :Do(function(_,data) - common.getHMIConnection():SendResponse(data.id, data.method, "REJECTED", {}) - end) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "REJECTED", {}) + end) mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) end diff --git a/test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua b/test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true.lua similarity index 95% rename from test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua rename to test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true.lua index 3ce5dc0464..053e291d7e 100644 --- a/test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua +++ b/test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true.lua @@ -58,8 +58,8 @@ local allParamsSet2 = { } local PutFileParams = { - syncFileName = "action.png", - fileType = "GRAPHIC_PNG", + syncFileName = "action.png", + fileType = "GRAPHIC_PNG", } --[[ Scenario ]] @@ -72,7 +72,7 @@ runner.Step("App registration with iconResumed = false", common.registerAppWOPTU runner.Step("Upload icon file1", common.putFile) runner.Step("SetAppIcon1", common.setAppIcon, { allParamsSet1 } ) -runner.Step("Upload icon file2", common.putFile, {PutFileParams}) +runner.Step("Upload icon file2", common.putFile, { PutFileParams }) runner.Step("SetAppIcon2", common.setAppIcon, { allParamsSet2 } ) runner.Step("App unregistration", common.unregisterAppInterface, { 1 }) diff --git a/test_scripts/API/SetAppIcon/commonIconResumed.lua b/test_scripts/API/SetAppIcon/commonIconResumed.lua index 40c27a480f..cda2c45a0c 100644 --- a/test_scripts/API/SetAppIcon/commonIconResumed.lua +++ b/test_scripts/API/SetAppIcon/commonIconResumed.lua @@ -27,19 +27,18 @@ local hmiAppIds = {} function m.getPathToFileInStorage(pFileName, pAppId) if not pAppId then pAppId = 1 end return commonPreconditions:GetPathToSDL() .. "storage/" - .. m.getConfigAppParams( pAppId ).appID .. "_" - .. utils.getDeviceMAC() .. "/" .. pFileName + .. m.getConfigAppParams(pAppId).appID .. "_" + .. utils.getDeviceMAC() .. "/" .. pFileName end ---[[ @getIconValueForResumtion: Get path of app icon from storage +--[[ @getIconValueForResumption: Get path of app icon from storage --! @parameters: --! pAppId - application number (1, 2, etc.) --! @return: app icon path --]] -function m.getIconValueForResumtion (pAppId) +function m.getIconValueForResumption(pAppId) if not pAppId then pAppId = 1 end - return commonPreconditions:GetPathToSDL() .. "storage/" - .. m.getConfigAppParams( pAppId ).appID + return commonPreconditions:GetPathToSDL() .. "storage/" .. m.getConfigAppParams(pAppId).appID end --[[ @registerAppWOPTU: register mobile application @@ -52,16 +51,17 @@ end function m.registerAppWOPTU(pAppId, pIconResumed, pReconnection) if not pAppId then pAppId = 1 end local pIconValue - if pIconResumed == true then pIconValue = m.getIconValueForResumtion(pAppId) end + if pIconResumed == true then pIconValue = m.getIconValueForResumption(pAppId) end local mobSession = m.getMobileSession(pAppId) local function RegisterApp() local corId = mobSession:SendRPC("RegisterAppInterface", config["application" .. pAppId].registerAppInterfaceParams) - test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", - { application = { - appName = config["application" .. pAppId].registerAppInterfaceParams.appName, - icon = pIconValue - }}) + test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", { + application = { + appName = config["application" .. pAppId].registerAppInterfaceParams.appName, + icon = pIconValue + } + }) :Do(function(_, d1) hmiAppIds[m.getConfigAppParams(pAppId).appID] = d1.params.application.appID end) @@ -74,18 +74,19 @@ function m.registerAppWOPTU(pAppId, pIconResumed, pReconnection) end) mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS", iconResumed = pIconResumed }) :Do(function() - mobSession:ExpectNotification("OnHMIStatus", - { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + mobSession:ExpectNotification("OnHMIStatus", { + hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" + }) mobSession:ExpectNotification("OnPermissionsChange") - end) + end) end if pReconnection == true then RegisterApp() else mobSession:StartService(7) :Do(function() - RegisterApp() - end) + RegisterApp() + end) end end @@ -98,8 +99,9 @@ function m.unregisterAppInterface(pAppId) if not pAppId then pAppId = 1 end local mobSession = m.getMobileSession(pAppId) local corId = mobSession:SendRPC("UnregisterAppInterface", { }) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", - { appID = m.getHMIAppId(pAppId), unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { + appID = m.getHMIAppId(pAppId), unexpectedDisconnect = false + }) mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) end @@ -108,7 +110,7 @@ end --! @return: parameters for PutFile --]] local function getPutFileAllParams() - local temp = { + return { syncFileName = "icon.png", fileType = "GRAPHIC_PNG", persistentFile = false, @@ -116,7 +118,6 @@ local function getPutFileAllParams() offset = 0, length = 11600 } - return temp end --[[ @putFile: Successful processing PutFile RPC @@ -129,7 +130,8 @@ end function m.putFile(pParamsSend, pFile, pAppId) if pParamsSend then pParamsSend = pParamsSend - else pParamsSend = getPutFileAllParams() + else + pParamsSend = getPutFileAllParams() end if not pAppId then pAppId = 1 end local mobSession = m.getMobileSession(pAppId) @@ -137,7 +139,7 @@ function m.putFile(pParamsSend, pFile, pAppId) if pFile ~= nil then cid = mobSession:SendRPC("PutFile", pParamsSend, pFile) else - cid = mobSession:SendRPC("PutFile", pParamsSend, "files/icon.png") + cid = mobSession:SendRPC("PutFile", pParamsSend, "files/icon_png.png") end mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) @@ -161,21 +163,20 @@ function m.setAppIcon(pParams, pAppId) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end ---[[ @CloseConnection: Close mobile connection successfully +--[[ @closeConnection: Close mobile connection successfully --! @parameters: none --! @return: none --]] -function m.CloseConnection() +function m.closeConnection() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = true }) test.mobileConnection:Close() end - ---[[ @OpenConnection: Open mobile connection successfully +--[[ @openConnection: Open mobile connection successfully --! @parameters: none --! return: none --]] -function m.OpenConnection() +function m.openConnection() test.mobileSession[1] = mobile_session.MobileSession( test, test.mobileConnection, diff --git a/test_sets/app_icon_resumption.txt b/test_sets/app_icon_resumption.txt index 849342489f..30c77e4e31 100644 --- a/test_sets/app_icon_resumption.txt +++ b/test_sets/app_icon_resumption.txt @@ -8,4 +8,4 @@ ./test_scripts/API/SetAppIcon/008_Mobile_App_received_response_SetAppIcon_INVALID_DATA.lua ./test_scripts/API/SetAppIcon/009_Mobile_App_received_response_SetAppIcon_DISALLOWED.lua ./test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua -./test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true_.lua +./test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true.lua From 652a7297a056c9b4eee14b1e5a5db1b4e8d5aa56 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 11 Apr 2018 15:40:30 +0300 Subject: [PATCH 352/681] Update service IDs in endpoints --- .../129_ATF_HMI_sends_GetURLs_one_app_registered.lua | 2 +- .../130_ATF_HMI_sends_GetURLs_no_app_registered.lua | 3 +-- .../136_ATF_Define_urls_PTS_will_sent_hmi.lua | 2 +- ...ATF_merge_preloaded_pt_into_local_pt_module_config.lua | 8 ++++---- .../260_ATF_local_pt_from_preloaded_pt_master_reset.lua | 4 ++-- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/test_scripts/Policies/Policy_Table_Update/129_ATF_HMI_sends_GetURLs_one_app_registered.lua b/test_scripts/Policies/Policy_Table_Update/129_ATF_HMI_sends_GetURLs_one_app_registered.lua index e079421d67..53fa7fc2fc 100644 --- a/test_scripts/Policies/Policy_Table_Update/129_ATF_HMI_sends_GetURLs_one_app_registered.lua +++ b/test_scripts/Policies/Policy_Table_Update/129_ATF_HMI_sends_GetURLs_one_app_registered.lua @@ -93,7 +93,7 @@ function Test:TestStep_PTU_GetURLs_AppRegistered() for _, value in pairs(sevices_table) do policy_endpoints[#policy_endpoints + 1] = { found = false, service = value } --TODO(istoimenova): Should be updated when policy defect is fixed - if ( value == "4" or value == "7" or value == "1") then + if ( value == "0x04" or value == "0x07" or value == "0x01") then policy_endpoints[#policy_endpoints].found = true end end diff --git a/test_scripts/Policies/Policy_Table_Update/130_ATF_HMI_sends_GetURLs_no_app_registered.lua b/test_scripts/Policies/Policy_Table_Update/130_ATF_HMI_sends_GetURLs_no_app_registered.lua index 50e79ce4e8..c46bdfc787 100644 --- a/test_scripts/Policies/Policy_Table_Update/130_ATF_HMI_sends_GetURLs_no_app_registered.lua +++ b/test_scripts/Policies/Policy_Table_Update/130_ATF_HMI_sends_GetURLs_no_app_registered.lua @@ -118,11 +118,10 @@ function Test:TestStep_PTU_DB_GetURLs_NoAppRegistered() local policy_endpoints = {} local sevices_table = commonFunctions:get_data_policy_sql(config.pathToSDL.."/storage/policy.sqlite", "select service from endpoint") - for _, value in pairs(sevices_table) do policy_endpoints[#policy_endpoints + 1] = { found = false, service = value } --TODO(istoimenova): Should be updated when policy defect is fixed - if ( value == "4" or value == "7") then + if ( value == "0x04" or value == "0x07") then policy_endpoints[#policy_endpoints].found = true end end diff --git a/test_scripts/Policies/Policy_Table_Update/136_ATF_Define_urls_PTS_will_sent_hmi.lua b/test_scripts/Policies/Policy_Table_Update/136_ATF_Define_urls_PTS_will_sent_hmi.lua index 3d10aebaec..23254f5d35 100644 --- a/test_scripts/Policies/Policy_Table_Update/136_ATF_Define_urls_PTS_will_sent_hmi.lua +++ b/test_scripts/Policies/Policy_Table_Update/136_ATF_Define_urls_PTS_will_sent_hmi.lua @@ -53,7 +53,7 @@ function Test:TestStep_PTU_GetURLs_AppRegistered() for _, value in pairs(sevices_table) do policy_endpoints[#policy_endpoints + 1] = { found = false, service = value } --TODO(istoimenova): Should be updated when policy defect is fixed - if ( value == "4" or value == "7" or value == "1") then + if ( value == "0x04" or value == "0x07" or value == "0x01") then policy_endpoints[#policy_endpoints].found = true end end diff --git a/test_scripts/Policies/Validation_of_PolicyTables/257_ATF_merge_preloaded_pt_into_local_pt_module_config.lua b/test_scripts/Policies/Validation_of_PolicyTables/257_ATF_merge_preloaded_pt_into_local_pt_module_config.lua index b4a326cfdd..2e1634b819 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/257_ATF_merge_preloaded_pt_into_local_pt_module_config.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/257_ATF_merge_preloaded_pt_into_local_pt_module_config.lua @@ -364,8 +364,8 @@ function Test:TestStep_VerifyInitialLocalPT() expectedValues = {"NONE|"..tostring(TESTED_DATA[1].module_config.notifications_per_minute_by_priority.NONE)} }, { query = 'select * from seconds_between_retry', expectedValues = {"0|"..tostring(TESTED_DATA[1].module_config.seconds_between_retries[1])} }, - { query = 'select * from endpoint where service is 4', - expectedValues = {"4|http://ivsu.software.ford.com/api/getsoftwareupdates|default"} } + { query = 'select * from endpoint where service is "0x04"', + expectedValues = {"0x04|http://ivsu.software.ford.com/api/getsoftwareupdates|default"} } } if not self.checkLocalPT(checks) then @@ -452,8 +452,8 @@ function Test:Test_NewLocalPT() expectedValues = {"NONE|"..tostring(TESTED_DATA[2].module_config.notifications_per_minute_by_priority.NONE)} }, { query = 'select * from seconds_between_retry', expectedValues = {"0|"..tostring(TESTED_DATA[2].module_config.seconds_between_retries[1])} }, - { query = 'select * from endpoint where service is 4', - expectedValues = {"4|http://policies.telematics.ford.com/api/policies|default"} } + { query = 'select * from endpoint where service is "0x04"', + expectedValues = {"0x04|http://policies.telematics.ford.com/api/policies|default"} } } if not self.checkLocalPT(checks) then diff --git a/test_scripts/Policies/Validation_of_PolicyTables/260_ATF_local_pt_from_preloaded_pt_master_reset.lua b/test_scripts/Policies/Validation_of_PolicyTables/260_ATF_local_pt_from_preloaded_pt_master_reset.lua index a1cd259cd1..eca07dea23 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/260_ATF_local_pt_from_preloaded_pt_master_reset.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/260_ATF_local_pt_from_preloaded_pt_master_reset.lua @@ -273,8 +273,8 @@ function Test:CheckLocalPT() expectedValues = {"NONE|"..tostring(TESTED_DATA[1].module_config.notifications_per_minute_by_priority.NONE)} }, { query = 'select * from seconds_between_retry', expectedValues = {"0|"..tostring(TESTED_DATA[1].module_config.seconds_between_retries[1])} }, - { query = 'select * from endpoint where service is 4', - expectedValues = {"4|http://ivsu.software.ford.com/api/getsoftwareupdates|default"} }, + { query = 'select * from endpoint where service is "0x04"', + expectedValues = {"0x04|http://ivsu.software.ford.com/api/getsoftwareupdates|default"} }, } if not self.checkLocalPT(checks) then From 0fd4b71892a406354df607be4d67d9617ff26044 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 11 Apr 2018 15:40:39 +0300 Subject: [PATCH 353/681] Move BC.PolicyUpdate expectation to App activation step --- ...TF_pt_update_validation_rules_optional_parameters_type.lua | 3 +-- ...TF_pt_update_validation_rules_required_parameters_type.lua | 3 +-- .../268_ATF_pt_update_validation_rules_general.lua | 3 +-- ...F_pt_update_validation_rules_consumer_friendly_message.lua | 4 +--- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/266_ATF_pt_update_validation_rules_optional_parameters_type.lua b/test_scripts/Policies/Validation_of_PolicyTables/266_ATF_pt_update_validation_rules_optional_parameters_type.lua index 076412dc57..81c8047f42 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/266_ATF_pt_update_validation_rules_optional_parameters_type.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/266_ATF_pt_update_validation_rules_optional_parameters_type.lua @@ -99,8 +99,6 @@ function Test:updatePolicyInDifferentSessions(_, appName, mobileSession) EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATING"}, {status = "UPDATE_NEEDED"}):Times(2) - - EXPECT_HMICALL("BasicCommunication.PolicyUpdate") end --[[ Test ]] @@ -108,6 +106,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:TestStep_ActivateAppInFULL() activateAppInSpecificLevel(self) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") end function Test:TestStep_UpdatePolicy_ExpectOnAppPermissionChangedWithAppID() diff --git a/test_scripts/Policies/Validation_of_PolicyTables/267_ATF_pt_update_validation_rules_required_parameters_type.lua b/test_scripts/Policies/Validation_of_PolicyTables/267_ATF_pt_update_validation_rules_required_parameters_type.lua index 6d6309e15d..7f00e51027 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/267_ATF_pt_update_validation_rules_required_parameters_type.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/267_ATF_pt_update_validation_rules_required_parameters_type.lua @@ -186,8 +186,6 @@ function Test:updatePolicyInDifferentSessions(_, appName, mobileSession) EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATING"}, {status = "UPDATE_NEEDED"}):Times(2) - - EXPECT_HMICALL("BasicCommunication.PolicyUpdate") end local function constructPathToDatabase() @@ -366,6 +364,7 @@ function Test:Precondition_ActivateAppInFULL() HMIAppId = self.applications[config.application1.registerAppInterfaceParams.appName] activateAppInSpecificLevel(self,HMIAppId,"FULL") TestData:store("Store LocalPT before PTU", constructPathToDatabase(), "beforePTU_policy.sqlite" ) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") end --[[ Test ]] diff --git a/test_scripts/Policies/Validation_of_PolicyTables/268_ATF_pt_update_validation_rules_general.lua b/test_scripts/Policies/Validation_of_PolicyTables/268_ATF_pt_update_validation_rules_general.lua index 23859e4e0c..2868cb6501 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/268_ATF_pt_update_validation_rules_general.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/268_ATF_pt_update_validation_rules_general.lua @@ -74,8 +74,6 @@ function Test:updatePolicyInDifferentSessions(_, appName, mobileSession) EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATING"}, {status = "UPDATE_NEEDED"}):Times(2) - - EXPECT_HMICALL("BasicCommunication.PolicyUpdate") end --[[ Preconditions ]] @@ -85,6 +83,7 @@ function Test:ActivateApp() HMIAppId = self.applications[config.application1.registerAppInterfaceParams.appName] commonSteps:ActivateAppInSpecificLevel(Test, HMIAppId) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") end --[[ Test ]] diff --git a/test_scripts/Policies/Validation_of_PolicyTables/269_ATF_pt_update_validation_rules_consumer_friendly_message.lua b/test_scripts/Policies/Validation_of_PolicyTables/269_ATF_pt_update_validation_rules_consumer_friendly_message.lua index bd6a6f0464..82ba3004d9 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/269_ATF_pt_update_validation_rules_consumer_friendly_message.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/269_ATF_pt_update_validation_rules_consumer_friendly_message.lua @@ -203,9 +203,6 @@ function Test:updatePolicyInDifferentSessions(PTName, appName, mobileSession) EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATING"}, {status = "UPDATE_NEEDED"}):Times(2) - - EXPECT_HMICALL("BasicCommunication.PolicyUpdate") - end local function constructPathToDatabase() @@ -391,6 +388,7 @@ commonFunctions:newTestCasesGroup("Test") function Test:ActivateAppInFULL() HMIAppId = self.applications[config.application1.registerAppInterfaceParams.appName] activateAppInSpecificLevel(self,HMIAppId,"FULL") + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") end function Test:UpdatePolicy_ExpectOnAppPermissionChangedWithAppID() From 1c557ec7bffd66bcb479193a148ec1ef8d323976 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 11 Apr 2018 17:16:32 +0300 Subject: [PATCH 354/681] Fix issue in cloneTable function --- user_modules/utils.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_modules/utils.lua b/user_modules/utils.lua index d1adde254f..b568e3cf0e 100644 --- a/user_modules/utils.lua +++ b/user_modules/utils.lua @@ -66,7 +66,7 @@ function m.cloneTable(pTbl) local copy = {} for k, v in pairs(pTbl) do if type(v) == 'table' then - v = m:cloneTable(v) + v = m.cloneTable(v) end copy[k] = v end From 24d951c172a3aeb77b534ef4f702e77f2048f64d Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 29 Mar 2018 15:22:18 +0300 Subject: [PATCH 355/681] Initial scripts for Template images feature --- .../Image_template/001_isTemplate_is_true.lua | 33 ++++ .../002_isTemplate_is_false.lua | 33 ++++ .../003_isTemplate_is_absent.lua | 33 ++++ .../004_isTemplate_invalid_type.lua | 33 ++++ .../Image_template/commonImageTemplate.lua | 184 ++++++++++++++++++ test_sets/template_images.txt | 4 + 6 files changed, 320 insertions(+) create mode 100644 test_scripts/Image_template/001_isTemplate_is_true.lua create mode 100644 test_scripts/Image_template/002_isTemplate_is_false.lua create mode 100644 test_scripts/Image_template/003_isTemplate_is_absent.lua create mode 100644 test_scripts/Image_template/004_isTemplate_invalid_type.lua create mode 100644 test_scripts/Image_template/commonImageTemplate.lua create mode 100644 test_sets/template_images.txt diff --git a/test_scripts/Image_template/001_isTemplate_is_true.lua b/test_scripts/Image_template/001_isTemplate_is_true.lua new file mode 100644 index 0000000000..c3b3dfadf9 --- /dev/null +++ b/test_scripts/Image_template/001_isTemplate_is_true.lua @@ -0,0 +1,33 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- Mobile application sends request with isTemplate = true +-- SDL must: +-- send request to HMI with isTemplate = true +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Image_template/commonImageTemplate') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Adding PNG file via PutFile", common.putFile) +runner.Step("AddCommand with isTemplate = true", common.addCommand, { true }) +runner.Step("Alert with isTemplate = true in SoftButtons", common.alert, { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Image_template/002_isTemplate_is_false.lua b/test_scripts/Image_template/002_isTemplate_is_false.lua new file mode 100644 index 0000000000..e0c8a1cee7 --- /dev/null +++ b/test_scripts/Image_template/002_isTemplate_is_false.lua @@ -0,0 +1,33 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- Mobile application sends request with isTemplate = false +-- SDL must: +-- send isTemplate = false to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Image_template/commonImageTemplate') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Adding PNG file via PutFile", common.putFile) +runner.Step("AddCommand with isTemplate = false", common.addCommand, { false }) +runner.Step("Alert with isTemplate = false in SoftButtons", common.alert, { false }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Image_template/003_isTemplate_is_absent.lua b/test_scripts/Image_template/003_isTemplate_is_absent.lua new file mode 100644 index 0000000000..c6848bde15 --- /dev/null +++ b/test_scripts/Image_template/003_isTemplate_is_absent.lua @@ -0,0 +1,33 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- Mobile application sends request without +-- SDL must: +-- send request to HMI without isTemplate +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Image_template/commonImageTemplate') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Adding PNG file via PutFile", common.putFile) +runner.Step("AddCommand without isTemplate", common.addCommand) +runner.Step("Alert without isTemplate in SoftButtons", common.alert) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Image_template/004_isTemplate_invalid_type.lua b/test_scripts/Image_template/004_isTemplate_invalid_type.lua new file mode 100644 index 0000000000..20d33ee7e0 --- /dev/null +++ b/test_scripts/Image_template/004_isTemplate_invalid_type.lua @@ -0,0 +1,33 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- Mobile application sends request with wrong type of isTemplate +-- SDL must: +-- respond with INVALID_DATA resultCode to mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Image_template/commonImageTemplate') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Adding PNG file via PutFile", common.putFile) +runner.Step("AddCommand with isTemplate = 123", common.rpcInvalidData, { 123, "AddCommand" } ) +runner.Step("Alert with isTemplate = '123' in SoftButtons", common.rpcInvalidData, { "123", "Alert" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Image_template/commonImageTemplate.lua b/test_scripts/Image_template/commonImageTemplate.lua new file mode 100644 index 0000000000..548aa3bb6d --- /dev/null +++ b/test_scripts/Image_template/commonImageTemplate.lua @@ -0,0 +1,184 @@ +--------------------------------------------------------------------------------------------------- +-- Common module +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local utils = require("user_modules/utils") + +--[[ Module ]] +local m = actions + +--[[ Local variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +--[[ Functions ]] +local function addCommandParams() + local requestParams = { + cmdID = 11, + menuParams = { + position = 0, + menuName ="Commandpositive" + }, + cmdIcon = { + value ="icon.png", + imageType ="DYNAMIC" + } + } + local responseUiParams = { + cmdID = requestParams.cmdID, + cmdIcon = commonFunctions:cloneTable(requestParams.cmdIcon), + menuParams = requestParams.menuParams + } + responseUiParams.cmdIcon.value = m.getPathToFileInStorage("icon.png") + local params = { + requestParams = requestParams, + responseUiParams = responseUiParams, + } + return params +end + +local function alertParams() + local requestParams = { + alertText1 = "alertText1", + alertText2 = "alertText2", + softButtons = { + { + type = "BOTH", + text = "Close", + image = { + value = "icon.png", + imageType = "DYNAMIC", + }, + isHighlighted = true, + softButtonID = 3, + systemAction = "DEFAULT_ACTION", + } + } +} + +local responseUiParamsAlert = { + alertStrings = { + { + fieldName = requestParams.alertText1, + fieldText = requestParams.alertText1 + }, + { + fieldName = requestParams.alertText2, + fieldText = requestParams.alertText2 + } + }, + alertType = "UI", + softButtons = commonFunctions:cloneTable(requestParams.softButtons) + } + responseUiParamsAlert.softButtons[1].image.value = m.getPathToFileInStorage("icon.png") + local params = { + requestParams = requestParams, + responseUiParams = responseUiParamsAlert, + } + return params +end + +function m.getPathToFileInStorage(pFileName) + return commonPreconditions:GetPathToSDL() .. "storage/" + .. config["application1"].registerAppInterfaceParams.appID .. "_" + .. utils.getDeviceMAC() .. "/" .. pFileName +end + +function m.putFile(pParams) + if not pParams then pParams = putFileParams end + local mobileSession = m.getMobileSession(); + local cid = mobileSession:SendRPC("PutFile", pParams.requestParams, pParams.filePath) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +function m.addCommand(pIsTemplate, pParams) + if not pParams then pParams = addCommandParams() end + if pIsTemplate == true or pIsTemplate == false then + pParams.requestParams.cmdIcon.isTemplate = pIsTemplate + pParams.responseUiParams.cmdIcon.isTemplate = pIsTemplate + end + local mobSession = m.getMobileSession() + local hmiConnection = m.getHMIConnection() + local cid = mobSession:SendRPC("AddCommand", pParams.requestParams) + pParams.responseUiParams.appID = m.getHMIAppId() + EXPECT_HMICALL("UI.AddCommand", pParams.responseUiParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_, data) + if pIsTemplate == nil and data.params.cmdIcon.isTemplate then + return false, " isTemplate paramter is present in UI.AddCommand, isTemplate was not send in mobile request " + end + return true + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + mobSession:ExpectNotification("OnHashChange") +end + +function m.rpcInvalidData(pIsTemplate, pRpc) + local params + if "AddCommand" == pRpc then + params = addCommandParams() + params.requestParams.cmdIcon.isTemplate = pIsTemplate + else + params = alertParams() + params.requestParams.softButtons[1].image.isTemplate = pIsTemplate + end + local mobSession = m.getMobileSession() + local cid = mobSession:SendRPC(pRpc, params.requestParams) + EXPECT_HMICALL("UI." .. pRpc) + :Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function sendOnSystemContext(pCtx) + m.getHMIConnection():SendNotification("UI.OnSystemContext", + { + appID = m.getHMIAppId(), + systemContext = pCtx + }) +end + +function m.alert(pIsTemplate, pParams) + if not pParams then pParams = alertParams() end + local mobSession = m.getMobileSession() + if pIsTemplate then + pParams.requestParams.softButtons[1].image.isTemplate = pIsTemplate + pParams.responseUiParams.softButtons[1].image.isTemplate = pIsTemplate + end + local responseDelay = 3000 + local cid = mobSession:SendRPC("Alert", pParams.requestParams) + EXPECT_HMICALL("UI.Alert", pParams.responseUiParams) + :Do(function(_,data) + sendOnSystemContext("ALERT") + local alertId = data.id + local function alertResponse() + m.getHMIConnection():SendResponse(alertId, "UI.Alert", "SUCCESS", { }) + sendOnSystemContext("MAIN") + end + RUN_AFTER(alertResponse, responseDelay) + end) + :ValidIf(function(_, data) + if pIsTemplate == nil and data.params.softButtons[1].image.isTemplate then + return false, " isTemplate paramter is present in UI.Alert, isTemplate was not send in mobile request " + end + return true + end) + mobSession:ExpectNotification("OnHMIStatus", + { systemContext = "ALERT"}, + { systemContext = "MAIN"}) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +return m diff --git a/test_sets/template_images.txt b/test_sets/template_images.txt new file mode 100644 index 0000000000..528cf5318c --- /dev/null +++ b/test_sets/template_images.txt @@ -0,0 +1,4 @@ +./test_scripts/Image_template/001_isTemplate_is_true.lua +./test_scripts/Image_template/002_isTemplate_is_false.lua +./test_scripts/Image_template/003_isTemplate_is_absent.lua +./test_scripts/Image_template/004_isTemplate_invalid_type.lua From 58cb7d3bf9ed90ebe8a4f732a63c0051e099c197 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Mon, 16 Apr 2018 17:27:01 +0300 Subject: [PATCH 356/681] Expanded coverage with STATIC image type and not PNG file type --- .../Image_template/001_isTemplate_is_true.lua | 2 +- .../002_isTemplate_is_false.lua | 2 +- .../003_isTemplate_is_absent.lua | 2 +- .../004_isTemplate_invalid_type.lua | 2 +- ..._isTemplate_is_true_with_not_png_image.lua | 60 +++++++++++++++++++ ...6_isTemplate_is_true_with_STATIC_image.lua | 44 ++++++++++++++ .../Image_template/commonImageTemplate.lua | 24 ++++++-- test_sets/template_images.txt | 2 + 8 files changed, 128 insertions(+), 10 deletions(-) create mode 100644 test_scripts/Image_template/005_isTemplate_is_true_with_not_png_image.lua create mode 100644 test_scripts/Image_template/006_isTemplate_is_true_with_STATIC_image.lua diff --git a/test_scripts/Image_template/001_isTemplate_is_true.lua b/test_scripts/Image_template/001_isTemplate_is_true.lua index c3b3dfadf9..a048a2f57c 100644 --- a/test_scripts/Image_template/001_isTemplate_is_true.lua +++ b/test_scripts/Image_template/001_isTemplate_is_true.lua @@ -23,9 +23,9 @@ runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) +runner.Step("Adding PNG file via PutFile", common.putFile) runner.Title("Test") -runner.Step("Adding PNG file via PutFile", common.putFile) runner.Step("AddCommand with isTemplate = true", common.addCommand, { true }) runner.Step("Alert with isTemplate = true in SoftButtons", common.alert, { true }) diff --git a/test_scripts/Image_template/002_isTemplate_is_false.lua b/test_scripts/Image_template/002_isTemplate_is_false.lua index e0c8a1cee7..619eb8d913 100644 --- a/test_scripts/Image_template/002_isTemplate_is_false.lua +++ b/test_scripts/Image_template/002_isTemplate_is_false.lua @@ -23,9 +23,9 @@ runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) +runner.Step("Adding PNG file via PutFile", common.putFile) runner.Title("Test") -runner.Step("Adding PNG file via PutFile", common.putFile) runner.Step("AddCommand with isTemplate = false", common.addCommand, { false }) runner.Step("Alert with isTemplate = false in SoftButtons", common.alert, { false }) diff --git a/test_scripts/Image_template/003_isTemplate_is_absent.lua b/test_scripts/Image_template/003_isTemplate_is_absent.lua index c6848bde15..69f3da93ae 100644 --- a/test_scripts/Image_template/003_isTemplate_is_absent.lua +++ b/test_scripts/Image_template/003_isTemplate_is_absent.lua @@ -23,9 +23,9 @@ runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) +runner.Step("Adding PNG file via PutFile", common.putFile) runner.Title("Test") -runner.Step("Adding PNG file via PutFile", common.putFile) runner.Step("AddCommand without isTemplate", common.addCommand) runner.Step("Alert without isTemplate in SoftButtons", common.alert) diff --git a/test_scripts/Image_template/004_isTemplate_invalid_type.lua b/test_scripts/Image_template/004_isTemplate_invalid_type.lua index 20d33ee7e0..ef0ace5190 100644 --- a/test_scripts/Image_template/004_isTemplate_invalid_type.lua +++ b/test_scripts/Image_template/004_isTemplate_invalid_type.lua @@ -23,9 +23,9 @@ runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) +runner.Step("Adding PNG file via PutFile", common.putFile) runner.Title("Test") -runner.Step("Adding PNG file via PutFile", common.putFile) runner.Step("AddCommand with isTemplate = 123", common.rpcInvalidData, { 123, "AddCommand" } ) runner.Step("Alert with isTemplate = '123' in SoftButtons", common.rpcInvalidData, { "123", "Alert" }) diff --git a/test_scripts/Image_template/005_isTemplate_is_true_with_not_png_image.lua b/test_scripts/Image_template/005_isTemplate_is_true_with_not_png_image.lua new file mode 100644 index 0000000000..b864aa6319 --- /dev/null +++ b/test_scripts/Image_template/005_isTemplate_is_true_with_not_png_image.lua @@ -0,0 +1,60 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- Mobile application sends request with isTemplate = true and not png image +-- SDL must: +-- send request with received paramters to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Image_template/commonImageTemplate') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local fileName = "action.jpeg" + +local putFileParams = { + requestParams = { + syncFileName = fileName, + fileType = "GRAPHIC_JPEG", + }, + filePath = "files/" .. fileName +} + +local pathToFile = common.getPathToFileInStorage(fileName) + +local paramsAlert = common.alertParams() +paramsAlert.requestParams.softButtons[1].image.value = fileName +paramsAlert.requestParams.softButtons[1].image.isTemplate = true +paramsAlert.responseUiParams.softButtons[1].image.value = pathToFile +paramsAlert.responseUiParams.softButtons[1].image.isTemplate = true + +local paramsAddCommand = common.addCommandParams() +paramsAddCommand.requestParams.cmdIcon.value = fileName +paramsAddCommand.requestParams.cmdIcon.isTemplate = true +paramsAddCommand.responseUiParams.cmdIcon.value = pathToFile +paramsAddCommand.responseUiParams.cmdIcon.isTemplate = true + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Adding JPEG file via PutFile", common.putFile, { putFileParams }) +runner.Step("AddCommand with isTemplate = true with jpeg icon", common.rpcWithCustomResultCode, + { "AddCommand", paramsAddCommand, "WARNINGS", true }) +runner.Step("Alert with isTemplate = true and jpeg icon in SoftButtons", common.rpcWithCustomResultCode, + { "Alert", paramsAlert, "WARNINGS", true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Image_template/006_isTemplate_is_true_with_STATIC_image.lua b/test_scripts/Image_template/006_isTemplate_is_true_with_STATIC_image.lua new file mode 100644 index 0000000000..7774c95d6f --- /dev/null +++ b/test_scripts/Image_template/006_isTemplate_is_true_with_STATIC_image.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- Mobile application sends request with isTemplate = true and STATIC image type +-- SDL must: +-- send request with received paramters to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Image_template/commonImageTemplate') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local fileName = "icon.png" + +local paramsAddCommand = common.addCommandParams() +paramsAddCommand.requestParams.cmdIcon.imageType = "STATIC" +paramsAddCommand.requestParams.cmdIcon.value = fileName +paramsAddCommand.requestParams.cmdIcon.isTemplate = true +paramsAddCommand.responseUiParams.cmdIcon.value = fileName +paramsAddCommand.responseUiParams.cmdIcon.isTemplate = true +paramsAddCommand.responseUiParams.cmdIcon.imageType = "STATIC" + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("Adding PNG file via PutFile", common.putFile) + +runner.Title("Test") +runner.Step("AddCommand with isTemplate = true with STATIC image type", common.rpcWithCustomResultCode, + { "AddCommand", paramsAddCommand, "UNSUPPORTED_RESOURCE", true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Image_template/commonImageTemplate.lua b/test_scripts/Image_template/commonImageTemplate.lua index 548aa3bb6d..da231fe400 100644 --- a/test_scripts/Image_template/commonImageTemplate.lua +++ b/test_scripts/Image_template/commonImageTemplate.lua @@ -22,7 +22,7 @@ local putFileParams = { } --[[ Functions ]] -local function addCommandParams() +function m.addCommandParams() local requestParams = { cmdID = 11, menuParams = { @@ -47,7 +47,7 @@ local function addCommandParams() return params end -local function alertParams() +function m.alertParams() local requestParams = { alertText1 = "alertText1", alertText2 = "alertText2", @@ -103,7 +103,7 @@ function m.putFile(pParams) end function m.addCommand(pIsTemplate, pParams) - if not pParams then pParams = addCommandParams() end + if not pParams then pParams = m.addCommandParams() end if pIsTemplate == true or pIsTemplate == false then pParams.requestParams.cmdIcon.isTemplate = pIsTemplate pParams.responseUiParams.cmdIcon.isTemplate = pIsTemplate @@ -129,10 +129,10 @@ end function m.rpcInvalidData(pIsTemplate, pRpc) local params if "AddCommand" == pRpc then - params = addCommandParams() + params = m.addCommandParams() params.requestParams.cmdIcon.isTemplate = pIsTemplate else - params = alertParams() + params = m.alertParams() params.requestParams.softButtons[1].image.isTemplate = pIsTemplate end local mobSession = m.getMobileSession() @@ -151,7 +151,7 @@ local function sendOnSystemContext(pCtx) end function m.alert(pIsTemplate, pParams) - if not pParams then pParams = alertParams() end + if not pParams then pParams = m.alertParams() end local mobSession = m.getMobileSession() if pIsTemplate then pParams.requestParams.softButtons[1].image.isTemplate = pIsTemplate @@ -181,4 +181,16 @@ function m.alert(pIsTemplate, pParams) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) end +function m.rpcWithCustomResultCode(pRPC, pParams, pResultCode, pSuccess) + local mobSession = m.getMobileSession() + local hmiConnection = m.getHMIConnection() + local cid = mobSession:SendRPC(pRPC, pParams.requestParams) + pParams.responseUiParams.appID = m.getHMIAppId() + EXPECT_HMICALL("UI." .. pRPC, pParams.responseUiParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, pResultCode, {}) + end) + mobSession:ExpectResponse(cid, { success = pSuccess, resultCode = pResultCode}) +end + return m diff --git a/test_sets/template_images.txt b/test_sets/template_images.txt index 528cf5318c..b3e6680665 100644 --- a/test_sets/template_images.txt +++ b/test_sets/template_images.txt @@ -2,3 +2,5 @@ ./test_scripts/Image_template/002_isTemplate_is_false.lua ./test_scripts/Image_template/003_isTemplate_is_absent.lua ./test_scripts/Image_template/004_isTemplate_invalid_type.lua +./test_scripts/Image_template/005_isTemplate_is_true_with_not_png_image.lua +./test_scripts/Image_template/006_isTemplate_is_true_with_STATIC_image.lua From abd95832386c9a304da6c18ba3bde6e66e7600a7 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 18 Apr 2018 19:47:49 +0300 Subject: [PATCH 357/681] Fix issue in cloneTable function regarding empty arrays --- user_modules/utils.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/user_modules/utils.lua b/user_modules/utils.lua index b568e3cf0e..3184ab0b9e 100644 --- a/user_modules/utils.lua +++ b/user_modules/utils.lua @@ -62,6 +62,8 @@ end function m.cloneTable(pTbl) if pTbl == nil then return {} + elseif pTbl == json.EMPTY_ARRAY then + return pTbl end local copy = {} for k, v in pairs(pTbl) do From 111d23b6249da03b132b675984565376c8d33d61 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 13 Apr 2018 14:52:10 +0300 Subject: [PATCH 358/681] Initial scripts for expanded proprietary data exchange feature --- ...quest_with_OEM_SPECIFIC_requestSubType.lua | 45 ++++ ...quest_with_OEM_SPECIFIC_requestSubType.lua | 45 ++++ ...stSubType_with_requestType_PROPRIETARY.lua | 31 +++ ...4_requestSubType_with_requestType_HTTP.lua | 48 +++++ ..._requestSubType_with_empty_array_in_pt.lua | 60 ++++++ ...uestSubType_with_array_of_values_in_pt.lua | 71 ++++++ ...emRequest_without_requestSubType_in_pt.lua | 71 ++++++ ...List_with_value_list_in_requestSubType.lua | 41 ++++ ...ist_with_empty_array_in_requestSubType.lua | 39 ++++ ...d_UpdateAppList_without_requestSubType.lua | 38 ++++ ...mRequest_OEM_SPECIFIC_type_not_allowed.lua | 48 +++++ .../commonDataExchange.lua | 204 ++++++++++++++++++ .../expanded_proprietary_data_exchange.txt | 11 + 13 files changed, 752 insertions(+) create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/001_SystemRequest_with_OEM_SPECIFIC_requestSubType.lua create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/002_onSystemRequest_with_OEM_SPECIFIC_requestSubType.lua create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/003_requestSubType_with_requestType_PROPRIETARY.lua create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/004_requestSubType_with_requestType_HTTP.lua create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_pt.lua create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_pt.lua create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_pt.lua create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_UpdateAppList_with_value_list_in_requestSubType.lua create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_UpdateAppList_with_empty_array_in_requestSubType.lua create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_UpdateAppList_without_requestSubType.lua create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/011_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua create mode 100644 test_sets/expanded_proprietary_data_exchange.txt diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/001_SystemRequest_with_OEM_SPECIFIC_requestSubType.lua b/test_scripts/API/Expanded_proprietary_data_exchange/001_SystemRequest_with_OEM_SPECIFIC_requestSubType.lua new file mode 100644 index 0000000000..2cdeaba6c8 --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/001_SystemRequest_with_OEM_SPECIFIC_requestSubType.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: Mobile application sends SystemRequest only with requestType = "OEM_SPECIFIC" or with +-- requestType = "OEM_SPECIFIC" and requestSubType +-- SDL does: resend request with received parameters to HMI and successful process response from HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local usedFile = "./files/action.png" +local params = { + requestType = "OEM_SPECIFIC", + requestSubType = "SomeSubType", + fileName = "action.png" +} + +local paramsWithoutSubType = { + requestType = "OEM_SPECIFIC", + fileName = "action.png" +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerApp) + +runner.Title("Test") +runner.Step("SystemRequest with request type OEM_SPECIFIC", common.systemRequest, {paramsWithoutSubType, usedFile}) +runner.Step("SystemRequest with request type OEM_SPECIFIC and requestSubType", common.systemRequest, {params, usedFile}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/002_onSystemRequest_with_OEM_SPECIFIC_requestSubType.lua b/test_scripts/API/Expanded_proprietary_data_exchange/002_onSystemRequest_with_OEM_SPECIFIC_requestSubType.lua new file mode 100644 index 0000000000..209926735a --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/002_onSystemRequest_with_OEM_SPECIFIC_requestSubType.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: HMI sends onSystemRequest only with requestType = "OEM_SPECIFIC" or with +-- requestType = "OEM_SPECIFIC" and requestSubType +-- SDL does: resend notification with received parameters to mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local params = { + requestType = "OEM_SPECIFIC", + requestSubType = "SomeSubType", + fileName = "action.png" +} + +local paramsWithoutSubType = { + requestType = "OEM_SPECIFIC", + requestSubType = "SomeSubType", + fileName = "action.png" +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerApp) + +runner.Title("Test") +runner.Step("onSystemRequest with request type OEM_SPECIFIC", common.onSystemRequest, {paramsWithoutSubType}) +runner.Step("onSystemRequest with request type OEM_SPECIFIC and with requestSubType", common.onSystemRequest, {params}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/003_requestSubType_with_requestType_PROPRIETARY.lua b/test_scripts/API/Expanded_proprietary_data_exchange/003_requestSubType_with_requestType_PROPRIETARY.lua new file mode 100644 index 0000000000..aa0d64cdf0 --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/003_requestSubType_with_requestType_PROPRIETARY.lua @@ -0,0 +1,31 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: SystemRequest and onSystemRequest with PROPRIETARY requestType contains requestSubType paramter during policy table update +-- SDL does: ignore received requestSubType and process received messages as usual +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerApp) + +runner.Title("Test") +runner.Step("onSystemRequest and SystemRequest with requestSubType in policy flow", common.policyTableUpdate, + { nil, nil, "SomeSubType" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/004_requestSubType_with_requestType_HTTP.lua b/test_scripts/API/Expanded_proprietary_data_exchange/004_requestSubType_with_requestType_HTTP.lua new file mode 100644 index 0000000000..418ef8f03b --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/004_requestSubType_with_requestType_HTTP.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: SDL reveives SystemRequest and on SystemRequest with requestType = HTTP and requestSubType +-- SDL does: ignore requestSubType and process messages as usual +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local usedFile = "./files/action.png" +local params = { + requestType = "HTTP", + requestSubType = "SomeSubType", + fileName = "action.png" +} + +local function systemRequest(pParams, pFile) + local mobSession = common.getMobileSession() + local cid = mobSession:SendRPC("SystemRequest", pParams, pFile) + if pParams.fileName then pParams.fileName = "/tmp/fs/mp/images/ivsu_cache/" .. pParams.fileName end + EXPECT_HMICALL("BasicCommunication.SystemRequest",pParams) + :Times(0) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerApp) + +runner.Title("Test") +runner.Step("SystemRequest with request type OEM_SPECIFIC", systemRequest, {params, usedFile}) +runner.Step("OnSystemRequest with request type OEM_SPECIFIC", common.onSystemRequest, {params}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_pt.lua b/test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_pt.lua new file mode 100644 index 0000000000..8ee571d736 --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_pt.lua @@ -0,0 +1,60 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1. PTU is performed with empty array in requestSubType +-- 2. SDL receives SystemRequest and onSystemRequest with requestSubType after ptu +-- SDL does: +-- 1. send OnAppPermissionChanged( requestSubType = [] ) to HMI during update +-- 2. successful process SystemRequest and resend onSystemRequest +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') +local json = require('modules/json') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local usedFile = "./files/action.png" +local params = { + requestType = "OEM_SPECIFIC", + requestSubType = "SomeSubType", + fileName = "action.png" +} + +--[[ Local Functions ]] +local function ptuFuncRPC(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].requestSubType = json.EMPTY_ARRAY +end + +local function policyUpdate() + common.policyTableUpdate(ptuFuncRPC) + EXPECT_HMICALL("SDL.OnAppPermissionChanged", { + appID = common.getConfigAppParams().appID, + requestSubType = json.EMPTY_ARRAY + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerApp) + +runner.Title("Test") +runner.Step("PTU with empty json in requestSubType section", policyUpdate) +runner.Step("SystemRequest with request type OEM_SPECIFIC and requestSubType", common.systemRequest, + {params, usedFile}) +runner.Step("onSystemRequest with request type OEM_SPECIFIC and with requestSubType", common.onSystemRequest, + {params}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_pt.lua b/test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_pt.lua new file mode 100644 index 0000000000..942a1f9971 --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_pt.lua @@ -0,0 +1,71 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1. PTU is performed with list of values in requestSubType +-- 2. SDL receives SystemRequest and onSystemRequest with requestSubType with value from list in pt +-- 3. SDL receives SystemRequest and onSystemRequest with requestSubType with value not from list in pt +-- SDL does: +-- 1. send OnAppPermissionChanged with list of values in requestSubType parameter to HMI during update +-- 2. successful process SystemRequest RPC and resend onSystemRequest to mobile application +-- 3. respond disallowed to SystemRequest and not resend onSystemRequest +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local usedFile = "./files/action.png" +local params = { + requestType = "OEM_SPECIFIC", + requestSubType = "TYPE1", + fileName = "action.png" +} +local unsuccessParams = { + requestType = "OEM_SPECIFIC", + requestSubType = "TYPE4", + fileName = "action.png" +} +local requestSubTypeArray = { "TYPE1", "TYPE2", "TYPE3" } + +--[[ Local Functions ]] +local function ptuFuncRPC(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].requestSubType = requestSubTypeArray +end + +local function policyUpdate() + common.policyTableUpdate(ptuFuncRPC) + EXPECT_HMICALL("SDL.OnAppPermissionChanged", { + appID = common.getConfigAppParams().appID, + requestSubType = requestSubTypeArray + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerApp) + +runner.Title("Test") +runner.Step("PTU with list of requestSubType", policyUpdate) +runner.Step("SystemRequest with not allowed requestSubType", common.unsuccessSystemRequest, + {unsuccessParams, usedFile}) +runner.Step("SystemRequest with allowed requestSubType", common.systemRequest, + {params, usedFile}) +runner.Step("onSystemRequest with not allowed requestSubType", common.unsuccessOnSystemRequest, + {unsuccessParams}) +runner.Step("onSystemRequest with allowed requestSubType", common.onSystemRequest, + {params}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_pt.lua b/test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_pt.lua new file mode 100644 index 0000000000..b5f1536897 --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_pt.lua @@ -0,0 +1,71 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1. PTU is performed without requestSubType +-- 2. SDL receives SystemRequest and onSystemRequest with requestSubType value +-- SDL does: +-- 1. send OnAppPermissionChanged without requestSubType parameter to HMI during update +-- 2. respond disallowed to SystemRequest request and not resend onSystemRequest to mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local usedFile = "./files/action.png" +local params = { + requestType = "OEM_SPECIFIC", + requestSubType = "someValue", + fileName = "action.png" +} + +local requestSubTypeArray = { "TYPE1", "TYPE2", "TYPE3" } + +--[[ Local Functions ]] +local function ptuFuncRPC(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].requestSubType = requestSubTypeArray +end + +local function ptuFuncWithoutRequestSubType(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].requestSubType = nil +end + +local function policyUpdate() + common.policyTableUpdate(ptuFuncWithoutRequestSubType) + EXPECT_HMICALL("SDL.OnAppPermissionChanged", { + appID = common.getConfigAppParams().appID, + }) + :ValidIf(function(_, data) + if data.params.requestSubType then + return false, "SDL.OnAppPermissionChanged notification contains unexpected requestSubType parameter" + end + return true + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerApp) +runner.Step("Policy table update", common.policyTableUpdate, {ptuFuncRPC}) + +runner.Title("Test") +runner.Step("PTU without requestSubType", policyUpdate) +runner.Step("SystemRequest with requestSubType", common.unsuccessSystemRequest, + {params, usedFile}) +runner.Step("onSystemRequest with requestSubType", common.unsuccessOnSystemRequest, + {params}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_UpdateAppList_with_value_list_in_requestSubType.lua b/test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_UpdateAppList_with_value_list_in_requestSubType.lua new file mode 100644 index 0000000000..d62c2b086c --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_UpdateAppList_with_value_list_in_requestSubType.lua @@ -0,0 +1,41 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: PT is updated with list of values for requestSubType for application App2 and App2 starts regisration +-- SDL does: send list of requestSubType values from PT in OnAppRegistered and UpdateAppList during registration +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestSubTypeArray = { "TYPE1", "TYPE2", "TYPE3" } + +--[[ Local Functions ]] +local function ptuFuncRPC(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = tbl.policy_table.app_policies.default + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID].requestSubType = requestSubTypeArray +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerApp) +runner.Step("Policy table update", common.policyTableUpdate, {ptuFuncRPC}) + +runner.Title("Test") +runner.Step("List of requestSubType in UpdateAppList and OnAppRegistered by app registration", common.registerAppWOPTU, + { 2, requestSubTypeArray }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_UpdateAppList_with_empty_array_in_requestSubType.lua b/test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_UpdateAppList_with_empty_array_in_requestSubType.lua new file mode 100644 index 0000000000..6891bfd438 --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_UpdateAppList_with_empty_array_in_requestSubType.lua @@ -0,0 +1,39 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: PT is updated with empty array for requestSubType for application App2 and App2 starts regisration +-- SDL does: send empty array from PT in OnAppRegistered and UpdateAppList during registration +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') +local json = require('modules/json') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function ptuFuncRPC(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = tbl.policy_table.app_policies.default + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID].requestSubType = json.EMPTY_ARRAY +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerApp) +runner.Step("Policy table update", common.policyTableUpdate, {ptuFuncRPC }) + +runner.Title("Test") +runner.Step("Empty array in requestSubType in UpdateAppList and OnAppRegistered by app registration", common.registerAppWOPTU, + { 2, json.EMPTY_ARRAY }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_UpdateAppList_without_requestSubType.lua b/test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_UpdateAppList_without_requestSubType.lua new file mode 100644 index 0000000000..f8da08a473 --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_UpdateAppList_without_requestSubType.lua @@ -0,0 +1,38 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: PT is updated without requestSubType for application App2 and App2 starts regisration +-- SDL does: not send requestSubType in OnAppRegistered and UpdateAppList during registration +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function ptuFuncRPC(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = tbl.policy_table.app_policies.default + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID].requestSubType = nil +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerApp) +runner.Step("Policy table update", common.policyTableUpdate, {ptuFuncRPC}) + +runner.Title("Test") +runner.Step("Empty array in requestSubType in UpdateAppList and OnAppRegistered by app registration", common.registerAppWOPTU, + { 2, nil, true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/011_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua b/test_scripts/API/Expanded_proprietary_data_exchange/011_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua new file mode 100644 index 0000000000..dd4e9e1f19 --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/011_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1. PT is updated with list of values without OEM_SPECIFIC in requestType for app +-- 2. Mobile app sends SystemRequest and HMI sends onSystemRequest to SDL with requestType = OEM_SPECIFIC +-- SDL does: respond DISALLOWED to SystemRequest and does not send onSystemRequest to mobile app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local usedFile = "./files/action.png" +local params = { + requestType = "OEM_SPECIFIC", + requestSubType = "SomeSubType", + fileName = "action.png" +} +--[[ Local Functions ]] +local function ptuFuncRPC(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].RequestType = { "HTTP", "PROPRIETARY" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerApp) +runner.Step("Policy table update", common.policyTableUpdate, {ptuFuncRPC}) + +runner.Title("Test") +runner.Step("SystemRequest with request type OEM_SPECIFIC", common.unsuccessSystemRequest, + {params, usedFile}) +runner.Step("onSystemRequest with request type OEM_SPECIFIC", common.unsuccessOnSystemRequest, + {params}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua b/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua new file mode 100644 index 0000000000..b24983a5d9 --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua @@ -0,0 +1,204 @@ +--------------------------------------------------------------------------------------------------- +-- Common module +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local utils = require("user_modules/utils") +local events = require("events") +local json = require("modules/json") + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 2 + +local m = actions +local ptuTable = {} +local hmiAppIds = {} + +function m.systemRequest(pParams, pFile) + local mobSession = m.getMobileSession() + local cid = mobSession:SendRPC("SystemRequest", pParams, pFile) + if pParams.fileName then pParams.fileName = "/tmp/fs/mp/images/ivsu_cache/" .. pParams.fileName end + EXPECT_HMICALL("BasicCommunication.SystemRequest",pParams) + :Do(function(_, data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +function m.unsuccessSystemRequest(pParams, pFile) + local mobSession = m.getMobileSession() + local cid = mobSession:SendRPC("SystemRequest", pParams, pFile) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +function m.onSystemRequest(pParams) + m.getHMIConnection():SendNotification("BasicCommunication.OnSystemRequest", pParams) + if pParams.fileName then pParams.fileName = nil end + m.getMobileSession():ExpectNotification("OnSystemRequest", pParams) +end + +function m.unsuccessOnSystemRequest(pParams) + m.getHMIConnection():SendNotification("BasicCommunication.OnSystemRequest", pParams) + m.getMobileSession():ExpectNotification("OnSystemRequest", pParams) + :Times(0) +end + +--[[ @getPTUFromPTS: create policy table update table (PTU) +--! @parameters: +--! pTbl - table with policy table snapshot (PTS) +--! @return: table with PTU +--]] +local function getPTUFromPTS(pTbl) + pTbl.policy_table.consumer_friendly_messages.messages = nil + pTbl.policy_table.device_data = nil + pTbl.policy_table.module_meta = nil + pTbl.policy_table.usage_and_error_counts = nil + pTbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + pTbl.policy_table.module_config.preloaded_pt = nil + pTbl.policy_table.module_config.preloaded_date = nil +end + +--[[ @policyTableUpdate: perform PTU +--! @parameters: +--! pPTUpdateFunc - function with additional updates (optional) +--! pExpNotificationFunc - function with specific expectations (optional) +--! @return: none +--]] +function m.policyTableUpdate(pPTUpdateFunc, pExpNotificationFunc, pRequestSubType) + if pExpNotificationFunc then + pExpNotificationFunc() + else + m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", { status = "UP_TO_DATE" }) + m.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) + end + local ptsFileName = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" + .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + local ptuFileName = os.tmpname() + local requestId = m.getHMIConnection():SendRequest("SDL.GetURLS", { service = 7 }) + m.getHMIConnection():ExpectResponse(requestId) + :Do(function() + m.getHMIConnection():SendNotification("BasicCommunication.OnSystemRequest", + { requestType = "PROPRIETARY", fileName = ptsFileName, requestSubType = pRequestSubType }) + getPTUFromPTS(ptuTable) + for i = 1, m.getAppsCount() do + ptuTable.policy_table.app_policies[m.getConfigAppParams(i).appID] = m.getAppDataForPTU(i) + end + if pPTUpdateFunc then + pPTUpdateFunc(ptuTable) + end + utils.tableToJsonFile(ptuTable, ptuFileName) + local event = events.Event() + event.matches = function(e1, e2) return e1 == e2 end + EXPECT_EVENT(event, "PTU event") + for id = 1, m.getAppsCount() do + local session = m.getMobileSession(id) + session:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY", requestSubType = pRequestSubType }) + :Do(function() + utils.cprint(35, "App ".. id .. " was used for PTU") + RAISE_EVENT(event, event, "PTU event") + local corIdSystemRequest = session:SendRPC("SystemRequest", + { requestType = "PROPRIETARY", requestSubType = pRequestSubType }, ptuFileName) + EXPECT_HMICALL("BasicCommunication.SystemRequest", { requestSubType = pRequestSubType }) + :Do(function(_, d3) + m.getHMIConnection():SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + m.getHMIConnection():SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = d3.params.fileName }) + end) + session:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + -- :Do(function() os.remove(ptuFileName) end) + end) + :Times(AtMost(1)) + end + end) +end + +--[[ @registerApp: register mobile application +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: none +--]] +function m.registerApp(pAppId) + if not pAppId then pAppId = 1 end + local mobSession = m.getMobileSession(pAppId) + mobSession:StartService(7) + :Do(function() + local corId = mobSession:SendRPC("RegisterAppInterface", m.getConfigAppParams(pAppId)) + m.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", { + application = { + appName = m.getConfigAppParams(pAppId).appName + } + }) + :Do(function(_, d1) + hmiAppIds[m.getConfigAppParams(pAppId).appID] = d1.params.application.appID + m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(2) + m.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") + :Do(function(_, d2) + m.getHMIConnection():SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptuTable = utils.jsonFileToTable(d2.params.file) + end) + end) + mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + mobSession:ExpectNotification("OnPermissionsChange") + end) + end) +end + +--[[ @registerAppWOPTU: register mobile application and do not perform PTU +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: none +--]] +function m.registerAppWOPTU(pAppId, pRequestSubType, pAbsenceCheck) + if not pAppId then pAppId = 1 end + local mobSession = m.getMobileSession(pAppId) + mobSession:StartService(7) + :Do(function() + local corId = mobSession:SendRPC("RegisterAppInterface", m.getConfigAppParams(pAppId)) + m.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", + { application = { + appName = m.getConfigAppParams(pAppId).appName, + requestSubType = pRequestSubType + } + }) + :ValidIf(function(_, data) + if pAbsenceCheck then + if data.params.application.requestSubType then + return false, "BC.OnAppRegistered notification contains unexpected requestSubType parameter" + end + end + return true + end) + :Do(function(_, d1) + hmiAppIds[m.getConfigAppParams(pAppId).appID] = d1.params.application.appID + EXPECT_HMICALL("BasicCommunication.UpdateAppList", { applications = { + { }, + { + appName = m.getConfigAppParams(pAppId).appName, + requestSubType = pRequestSubType + }}}) + :ValidIf(function(_, data) + if pAbsenceCheck then + if data.params.applications[2].requestSubType then + return false, "BC.UpdateAppList request contains unexpected requestSubType parameter" + end + end + return true + end) + end) + mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + mobSession:ExpectNotification("OnPermissionsChange") + end) + end) +end + +return m diff --git a/test_sets/expanded_proprietary_data_exchange.txt b/test_sets/expanded_proprietary_data_exchange.txt new file mode 100644 index 0000000000..422510416e --- /dev/null +++ b/test_sets/expanded_proprietary_data_exchange.txt @@ -0,0 +1,11 @@ +./test_scripts/API/Expanded_proprietary_data_exchange/001_SystemRequest_with_OEM_SPECIFIC_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/002_onSystemRequest_with_OEM_SPECIFIC_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/003_requestSubType_with_requestType_PROPRIETARY.lua +./test_scripts/API/Expanded_proprietary_data_exchange/004_requestSubType_with_requestType_HTTP.lua +./test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_pt.lua +./test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_pt.lua +./test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_pt.lua +./test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_UpdateAppList_with_value_list_in_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_UpdateAppList_with_empty_array_in_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_UpdateAppList_without_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/011_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua From a6b463ce92f11bdffc89998ddc07e4349bbfec2d Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 18 Apr 2018 14:23:33 +0300 Subject: [PATCH 359/681] Updated scripts according to new initilal SDL state, expanded list of scripts --- ..._requestSubType_with_empty_array_in_pt.lua | 18 ++++---- ...uestSubType_with_array_of_values_in_pt.lua | 8 ++-- ...emRequest_without_requestSubType_in_pt.lua | 35 +++++++--------- ...List_with_value_list_in_requestSubType.lua | 20 +++++++-- ...ist_with_empty_array_in_requestSubType.lua | 15 ++++++- ...d_UpdateAppList_without_requestSubType.lua | 16 ++++++- ...red_UpdateAppList_by_fist_registration.lua | 42 +++++++++++++++++++ ...Request_OEM_SPECIFIC_type_not_allowed.lua} | 0 .../commonDataExchange.lua | 33 +++------------ 9 files changed, 118 insertions(+), 69 deletions(-) create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_UpdateAppList_by_fist_registration.lua rename test_scripts/API/Expanded_proprietary_data_exchange/{011_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua => 012_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua} (100%) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_pt.lua b/test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_pt.lua index 8ee571d736..910cb3e71e 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_pt.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_pt.lua @@ -11,7 +11,7 @@ -- 1. PTU is performed with empty array in requestSubType -- 2. SDL receives SystemRequest and onSystemRequest with requestSubType after ptu -- SDL does: --- 1. send OnAppPermissionChanged( requestSubType = [] ) to HMI during update +-- 1. not send OnAppPermissionChanged() to HMI during update -- 2. successful process SystemRequest and resend onSystemRequest --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] @@ -32,25 +32,23 @@ local params = { --[[ Local Functions ]] local function ptuFuncRPC(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].requestSubType = json.EMPTY_ARRAY + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].RequestSubType = json.EMPTY_ARRAY end -local function policyUpdate() - common.policyTableUpdate(ptuFuncRPC) - EXPECT_HMICALL("SDL.OnAppPermissionChanged", { - appID = common.getConfigAppParams().appID, - requestSubType = json.EMPTY_ARRAY - }) +local function policyUpdate(pPtuFunc) + common.policyTableUpdate(pPtuFunc) + common.getHMIConnection():ExpectNotification("SDL.OnAppPermissionChanged") + :Times(0) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("App registration", common.registerApp) +runner.Step("App1 registration", common.registerApp) runner.Title("Test") -runner.Step("PTU with empty json in requestSubType section", policyUpdate) +runner.Step("PTU with empty json in requestSubType section", policyUpdate, { ptuFuncRPC, }) runner.Step("SystemRequest with request type OEM_SPECIFIC and requestSubType", common.systemRequest, {params, usedFile}) runner.Step("onSystemRequest with request type OEM_SPECIFIC and with requestSubType", common.onSystemRequest, diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_pt.lua b/test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_pt.lua index 942a1f9971..86ab41574f 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_pt.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_pt.lua @@ -39,14 +39,14 @@ local requestSubTypeArray = { "TYPE1", "TYPE2", "TYPE3" } --[[ Local Functions ]] local function ptuFuncRPC(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].requestSubType = requestSubTypeArray + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].RequestSubType = requestSubTypeArray end local function policyUpdate() common.policyTableUpdate(ptuFuncRPC) - EXPECT_HMICALL("SDL.OnAppPermissionChanged", { - appID = common.getConfigAppParams().appID, - requestSubType = requestSubTypeArray + common.getHMIConnection():ExpectNotification("SDL.OnAppPermissionChanged", { + appID = common.getHMIAppId(), + requestSubType = requestSubTypeArray }) end diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_pt.lua b/test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_pt.lua index b5f1536897..85e3f1b513 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_pt.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_pt.lua @@ -8,11 +8,11 @@ -- -- Description: -- In case: --- 1. PTU is performed without requestSubType +-- 1. PTU is performed without requestSubType and with requestType -- 2. SDL receives SystemRequest and onSystemRequest with requestSubType value -- SDL does: --- 1. send OnAppPermissionChanged without requestSubType parameter to HMI during update --- 2. respond disallowed to SystemRequest request and not resend onSystemRequest to mobile application +-- 1. send OnAppPermissionChanged without requestSubType and with requestType parameters to HMI during update +-- 2. process SystemRequest request successful and resend onSystemRequest to mobile application --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -29,27 +29,23 @@ local params = { fileName = "action.png" } -local requestSubTypeArray = { "TYPE1", "TYPE2", "TYPE3" } - --[[ Local Functions ]] local function ptuFuncRPC(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].requestSubType = requestSubTypeArray -end - -local function ptuFuncWithoutRequestSubType(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].requestSubType = nil + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].RequestType = { "PROPRIETARY", "OEM_SPECIFIC" } + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].RequestSubType = nil end local function policyUpdate() - common.policyTableUpdate(ptuFuncWithoutRequestSubType) - EXPECT_HMICALL("SDL.OnAppPermissionChanged", { - appID = common.getConfigAppParams().appID, + common.policyTableUpdate(ptuFuncRPC) + common.getHMIConnection():ExpectNotification("SDL.OnAppPermissionChanged", { + appID = common.getHMIAppId(), + requestType = { "PROPRIETARY", "OEM_SPECIFIC" }, }) :ValidIf(function(_, data) - if data.params.requestSubType then - return false, "SDL.OnAppPermissionChanged notification contains unexpected requestSubType parameter" - end - return true + if data.params.requestSubType then + return false, "SDL.OnAppPermissionChanged notification contains unexpected parameter requestSubType" + end + return true end) end @@ -58,13 +54,12 @@ runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerApp) -runner.Step("Policy table update", common.policyTableUpdate, {ptuFuncRPC}) runner.Title("Test") runner.Step("PTU without requestSubType", policyUpdate) -runner.Step("SystemRequest with requestSubType", common.unsuccessSystemRequest, +runner.Step("SystemRequest with requestSubType", common.systemRequest, {params, usedFile}) -runner.Step("onSystemRequest with requestSubType", common.unsuccessOnSystemRequest, +runner.Step("onSystemRequest with requestSubType", common.onSystemRequest, {params}) runner.Title("Postconditions") diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_UpdateAppList_with_value_list_in_requestSubType.lua b/test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_UpdateAppList_with_value_list_in_requestSubType.lua index d62c2b086c..213e25cce4 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_UpdateAppList_with_value_list_in_requestSubType.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_UpdateAppList_with_value_list_in_requestSubType.lua @@ -7,8 +7,10 @@ -- TBD -- -- Description: --- In case: PT is updated with list of values for requestSubType for application App2 and App2 starts regisration --- SDL does: send list of requestSubType values from PT in OnAppRegistered and UpdateAppList during registration +-- In case: +-- 1. PT is updated with list of values for requestSubType for application App2 and App2 starts regisration +-- SDL does: +-- 1. send list of requestSubType values from PT in OnAppRegistered and UpdateAppList during registration --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -20,10 +22,20 @@ runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local requestSubTypeArray = { "TYPE1", "TYPE2", "TYPE3" } +local applicationsParams = { + { + appName = common.getConfigAppParams(1).appName + }, + { + appName = common.getConfigAppParams(2).appName, + requestSubType = requestSubTypeArray + } +} + --[[ Local Functions ]] local function ptuFuncRPC(tbl) tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = tbl.policy_table.app_policies.default - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID].requestSubType = requestSubTypeArray + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID].RequestSubType = requestSubTypeArray end --[[ Scenario ]] @@ -35,7 +47,7 @@ runner.Step("Policy table update", common.policyTableUpdate, {ptuFuncRPC}) runner.Title("Test") runner.Step("List of requestSubType in UpdateAppList and OnAppRegistered by app registration", common.registerAppWOPTU, - { 2, requestSubTypeArray }) + { 2, requestSubTypeArray, applicationsParams }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_UpdateAppList_with_empty_array_in_requestSubType.lua b/test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_UpdateAppList_with_empty_array_in_requestSubType.lua index 6891bfd438..9eae9496db 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_UpdateAppList_with_empty_array_in_requestSubType.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_UpdateAppList_with_empty_array_in_requestSubType.lua @@ -18,10 +18,21 @@ local json = require('modules/json') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false +--[[ Local Variables ]] +local applicationsParams = { + { + appName = common.getConfigAppParams(1).appName + }, + { + appName = common.getConfigAppParams(2).appName, + requestSubType = json.EMPTY_ARRAY + } +} + --[[ Local Functions ]] local function ptuFuncRPC(tbl) tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = tbl.policy_table.app_policies.default - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID].requestSubType = json.EMPTY_ARRAY + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID].RequestSubType = json.EMPTY_ARRAY end --[[ Scenario ]] @@ -33,7 +44,7 @@ runner.Step("Policy table update", common.policyTableUpdate, {ptuFuncRPC }) runner.Title("Test") runner.Step("Empty array in requestSubType in UpdateAppList and OnAppRegistered by app registration", common.registerAppWOPTU, - { 2, json.EMPTY_ARRAY }) + { 2, json.EMPTY_ARRAY, applicationsParams }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_UpdateAppList_without_requestSubType.lua b/test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_UpdateAppList_without_requestSubType.lua index f8da08a473..9d04b68944 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_UpdateAppList_without_requestSubType.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_UpdateAppList_without_requestSubType.lua @@ -13,14 +13,26 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') +local json = require('modules/json') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false +--[[ Local Variables ]] +local applicationsParams = { + { + appName = common.getConfigAppParams(1).appName + }, + { + appName = common.getConfigAppParams(2).appName, + requestSubType = json.EMPTY_ARRAY + } +} + --[[ Local Functions ]] local function ptuFuncRPC(tbl) tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = tbl.policy_table.app_policies.default - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID].requestSubType = nil + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID].RequestSubType = nil end --[[ Scenario ]] @@ -32,7 +44,7 @@ runner.Step("Policy table update", common.policyTableUpdate, {ptuFuncRPC}) runner.Title("Test") runner.Step("Empty array in requestSubType in UpdateAppList and OnAppRegistered by app registration", common.registerAppWOPTU, - { 2, nil, true }) + { 2, json.EMPTY_ARRAY, applicationsParams }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_UpdateAppList_by_fist_registration.lua b/test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_UpdateAppList_by_fist_registration.lua new file mode 100644 index 0000000000..f9a4e14f1c --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_UpdateAppList_by_fist_registration.lua @@ -0,0 +1,42 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1. App registers first time, permissions are from preloaded_pt +-- SDL does: +-- 1. send empty array in requestSubType, requetsType in OnAppRegistered and UpdateAppList during registration +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') +local json = require('modules/json') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local applicationsParams = { + { + appName = common.getConfigAppParams(1).appName, + requestSubType = json.EMPTY_ARRAY, + requestType = json.EMPTY_ARRAY + } +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Empty array in requestSubType in UpdateAppList and OnAppRegistered by app registration", + common.registerAppWOPTU, { 1, json.EMPTY_ARRAY, applicationsParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/011_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua b/test_scripts/API/Expanded_proprietary_data_exchange/012_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua similarity index 100% rename from test_scripts/API/Expanded_proprietary_data_exchange/011_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua rename to test_scripts/API/Expanded_proprietary_data_exchange/012_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua b/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua index b24983a5d9..80d7d4c31b 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua @@ -42,7 +42,7 @@ end function m.unsuccessOnSystemRequest(pParams) m.getHMIConnection():SendNotification("BasicCommunication.OnSystemRequest", pParams) - m.getMobileSession():ExpectNotification("OnSystemRequest", pParams) + m.getMobileSession():ExpectNotification("OnSystemRequest") :Times(0) end @@ -107,7 +107,7 @@ function m.policyTableUpdate(pPTUpdateFunc, pExpNotificationFunc, pRequestSubTyp m.getHMIConnection():SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = d3.params.fileName }) end) session:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) - -- :Do(function() os.remove(ptuFileName) end) + :Do(function() os.remove(ptuFileName) end) end) :Times(AtMost(1)) end @@ -155,7 +155,7 @@ end --! pAppId - application number (1, 2, etc.) --! @return: none --]] -function m.registerAppWOPTU(pAppId, pRequestSubType, pAbsenceCheck) +function m.registerAppWOPTU(pAppId, pRequestSubType, pApplications) if not pAppId then pAppId = 1 end local mobSession = m.getMobileSession(pAppId) mobSession:StartService(7) @@ -167,31 +167,10 @@ function m.registerAppWOPTU(pAppId, pRequestSubType, pAbsenceCheck) requestSubType = pRequestSubType } }) - :ValidIf(function(_, data) - if pAbsenceCheck then - if data.params.application.requestSubType then - return false, "BC.OnAppRegistered notification contains unexpected requestSubType parameter" - end - end - return true - end) :Do(function(_, d1) - hmiAppIds[m.getConfigAppParams(pAppId).appID] = d1.params.application.appID - EXPECT_HMICALL("BasicCommunication.UpdateAppList", { applications = { - { }, - { - appName = m.getConfigAppParams(pAppId).appName, - requestSubType = pRequestSubType - }}}) - :ValidIf(function(_, data) - if pAbsenceCheck then - if data.params.applications[2].requestSubType then - return false, "BC.UpdateAppList request contains unexpected requestSubType parameter" - end - end - return true - end) - end) + hmiAppIds[m.getConfigAppParams(pAppId).appID] = d1.params.application.appID + EXPECT_HMICALL("BasicCommunication.UpdateAppList", { applications = pApplications}) + end) mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() mobSession:ExpectNotification("OnHMIStatus", From 0a89602747f412a57a00197b50efbdabf7aca0c5 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 18 Apr 2018 14:53:12 +0300 Subject: [PATCH 360/681] Removed UpdateAppList check from scripts --- ...tered_with_value_list_in_requestSubType.lua} | 16 +++------------- ...ered_with_empty_array_in_requestSubType.lua} | 15 ++------------- ..._OnAppRegistered_without_requestSubType.lua} | 17 +++-------------- ...11_OnAppRegistered_by_fist_registration.lua} | 15 +++------------ .../commonDataExchange.lua | 3 +-- .../expanded_proprietary_data_exchange.txt | 9 +++++---- 6 files changed, 17 insertions(+), 58 deletions(-) rename test_scripts/API/Expanded_proprietary_data_exchange/{008_OnAppRegistered_UpdateAppList_with_value_list_in_requestSubType.lua => 008_OnAppRegistered_with_value_list_in_requestSubType.lua} (80%) rename test_scripts/API/Expanded_proprietary_data_exchange/{009_OnAppRegistered_UpdateAppList_with_empty_array_in_requestSubType.lua => 009_OnAppRegistered_with_empty_array_in_requestSubType.lua} (80%) rename test_scripts/API/Expanded_proprietary_data_exchange/{010_OnAppRegistered_UpdateAppList_without_requestSubType.lua => 010_OnAppRegistered_without_requestSubType.lua} (75%) rename test_scripts/API/Expanded_proprietary_data_exchange/{011_OnAppRegistered_UpdateAppList_by_fist_registration.lua => 011_OnAppRegistered_by_fist_registration.lua} (73%) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_UpdateAppList_with_value_list_in_requestSubType.lua b/test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_with_value_list_in_requestSubType.lua similarity index 80% rename from test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_UpdateAppList_with_value_list_in_requestSubType.lua rename to test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_with_value_list_in_requestSubType.lua index 213e25cce4..b17bd5ea55 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_UpdateAppList_with_value_list_in_requestSubType.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_with_value_list_in_requestSubType.lua @@ -10,7 +10,7 @@ -- In case: -- 1. PT is updated with list of values for requestSubType for application App2 and App2 starts regisration -- SDL does: --- 1. send list of requestSubType values from PT in OnAppRegistered and UpdateAppList during registration +-- 1. send list of requestSubType values from PT in OnAppRegistered during registration --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -22,16 +22,6 @@ runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local requestSubTypeArray = { "TYPE1", "TYPE2", "TYPE3" } -local applicationsParams = { - { - appName = common.getConfigAppParams(1).appName - }, - { - appName = common.getConfigAppParams(2).appName, - requestSubType = requestSubTypeArray - } -} - --[[ Local Functions ]] local function ptuFuncRPC(tbl) tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = tbl.policy_table.app_policies.default @@ -46,8 +36,8 @@ runner.Step("App registration", common.registerApp) runner.Step("Policy table update", common.policyTableUpdate, {ptuFuncRPC}) runner.Title("Test") -runner.Step("List of requestSubType in UpdateAppList and OnAppRegistered by app registration", common.registerAppWOPTU, - { 2, requestSubTypeArray, applicationsParams }) +runner.Step("List of requestSubType in OnAppRegistered by app registration", common.registerAppWOPTU, + { 2, requestSubTypeArray }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_UpdateAppList_with_empty_array_in_requestSubType.lua b/test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_with_empty_array_in_requestSubType.lua similarity index 80% rename from test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_UpdateAppList_with_empty_array_in_requestSubType.lua rename to test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_with_empty_array_in_requestSubType.lua index 9eae9496db..46cd76bb14 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_UpdateAppList_with_empty_array_in_requestSubType.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_with_empty_array_in_requestSubType.lua @@ -18,17 +18,6 @@ local json = require('modules/json') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false ---[[ Local Variables ]] -local applicationsParams = { - { - appName = common.getConfigAppParams(1).appName - }, - { - appName = common.getConfigAppParams(2).appName, - requestSubType = json.EMPTY_ARRAY - } -} - --[[ Local Functions ]] local function ptuFuncRPC(tbl) tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = tbl.policy_table.app_policies.default @@ -43,8 +32,8 @@ runner.Step("App registration", common.registerApp) runner.Step("Policy table update", common.policyTableUpdate, {ptuFuncRPC }) runner.Title("Test") -runner.Step("Empty array in requestSubType in UpdateAppList and OnAppRegistered by app registration", common.registerAppWOPTU, - { 2, json.EMPTY_ARRAY, applicationsParams }) +runner.Step("Empty array in requestSubType in OnAppRegistered by app registration", common.registerAppWOPTU, + { 2, json.EMPTY_ARRAY }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_UpdateAppList_without_requestSubType.lua b/test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_without_requestSubType.lua similarity index 75% rename from test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_UpdateAppList_without_requestSubType.lua rename to test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_without_requestSubType.lua index 9d04b68944..b2ddf85e0e 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_UpdateAppList_without_requestSubType.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_without_requestSubType.lua @@ -8,7 +8,7 @@ -- -- Description: -- In case: PT is updated without requestSubType for application App2 and App2 starts regisration --- SDL does: not send requestSubType in OnAppRegistered and UpdateAppList during registration +-- SDL does: not send requestSubType in OnAppRegistered during registration --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -18,17 +18,6 @@ local json = require('modules/json') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false ---[[ Local Variables ]] -local applicationsParams = { - { - appName = common.getConfigAppParams(1).appName - }, - { - appName = common.getConfigAppParams(2).appName, - requestSubType = json.EMPTY_ARRAY - } -} - --[[ Local Functions ]] local function ptuFuncRPC(tbl) tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = tbl.policy_table.app_policies.default @@ -43,8 +32,8 @@ runner.Step("App registration", common.registerApp) runner.Step("Policy table update", common.policyTableUpdate, {ptuFuncRPC}) runner.Title("Test") -runner.Step("Empty array in requestSubType in UpdateAppList and OnAppRegistered by app registration", common.registerAppWOPTU, - { 2, json.EMPTY_ARRAY, applicationsParams }) +runner.Step("Empty array in requestSubType in OnAppRegistered by app registration", common.registerAppWOPTU, + { 2, json.EMPTY_ARRAY }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_UpdateAppList_by_fist_registration.lua b/test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_by_fist_registration.lua similarity index 73% rename from test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_UpdateAppList_by_fist_registration.lua rename to test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_by_fist_registration.lua index f9a4e14f1c..6848cb1ef9 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_UpdateAppList_by_fist_registration.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_by_fist_registration.lua @@ -10,7 +10,7 @@ -- In case: -- 1. App registers first time, permissions are from preloaded_pt -- SDL does: --- 1. send empty array in requestSubType, requetsType in OnAppRegistered and UpdateAppList during registration +-- 1. send empty array in requestSubType, requetsType in OnAppRegistered during registration --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -20,23 +20,14 @@ local json = require('modules/json') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false ---[[ Local Variables ]] -local applicationsParams = { - { - appName = common.getConfigAppParams(1).appName, - requestSubType = json.EMPTY_ARRAY, - requestType = json.EMPTY_ARRAY - } -} - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") -runner.Step("Empty array in requestSubType in UpdateAppList and OnAppRegistered by app registration", - common.registerAppWOPTU, { 1, json.EMPTY_ARRAY, applicationsParams }) +runner.Step("Empty array in requestSubType in OnAppRegistered by app registration", + common.registerAppWOPTU, { 1, json.EMPTY_ARRAY }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua b/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua index 80d7d4c31b..376cc970f8 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua @@ -155,7 +155,7 @@ end --! pAppId - application number (1, 2, etc.) --! @return: none --]] -function m.registerAppWOPTU(pAppId, pRequestSubType, pApplications) +function m.registerAppWOPTU(pAppId, pRequestSubType) if not pAppId then pAppId = 1 end local mobSession = m.getMobileSession(pAppId) mobSession:StartService(7) @@ -169,7 +169,6 @@ function m.registerAppWOPTU(pAppId, pRequestSubType, pApplications) }) :Do(function(_, d1) hmiAppIds[m.getConfigAppParams(pAppId).appID] = d1.params.application.appID - EXPECT_HMICALL("BasicCommunication.UpdateAppList", { applications = pApplications}) end) mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() diff --git a/test_sets/expanded_proprietary_data_exchange.txt b/test_sets/expanded_proprietary_data_exchange.txt index 422510416e..0dcd89cc65 100644 --- a/test_sets/expanded_proprietary_data_exchange.txt +++ b/test_sets/expanded_proprietary_data_exchange.txt @@ -5,7 +5,8 @@ ./test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_pt.lua ./test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_pt.lua ./test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_pt.lua -./test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_UpdateAppList_with_value_list_in_requestSubType.lua -./test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_UpdateAppList_with_empty_array_in_requestSubType.lua -./test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_UpdateAppList_without_requestSubType.lua -./test_scripts/API/Expanded_proprietary_data_exchange/011_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua +./test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_with_value_list_in_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_with_empty_array_in_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_without_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_by_fist_registration.lua +./test_scripts/API/Expanded_proprietary_data_exchange/012_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua From f88dfe2613d0cc6f1dae179fecde5acdc5a9dec9 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 18 Apr 2018 16:52:19 +0300 Subject: [PATCH 361/681] Scripts for requestType --- ...equestSubType_with_empty_array_in_ptu.lua} | 0 ...stSubType_with_array_of_values_in_ptu.lua} | 0 ...Request_without_requestSubType_in_ptu.lua} | 0 ...mRequest_OEM_SPECIFIC_type_not_allowed.lua | 1 - ...st_requestType_with_empty_array_in_ptu.lua | 56 +++++++++++++++ ...st_requestType_with_list_of_values_ptu.lua | 69 ++++++++++++++++++ ...st_requestType_without_parameter_in_pt.lua | 72 +++++++++++++++++++ .../expanded_proprietary_data_exchange.txt | 9 ++- 8 files changed, 203 insertions(+), 4 deletions(-) rename test_scripts/API/Expanded_proprietary_data_exchange/{005_System_onSystemRequest_requestSubType_with_empty_array_in_pt.lua => 005_System_onSystemRequest_requestSubType_with_empty_array_in_ptu.lua} (100%) rename test_scripts/API/Expanded_proprietary_data_exchange/{006_System_onSystemRequest_requestSubType_with_array_of_values_in_pt.lua => 006_System_onSystemRequest_requestSubType_with_array_of_values_in_ptu.lua} (100%) rename test_scripts/API/Expanded_proprietary_data_exchange/{007_System_onSystemRequest_without_requestSubType_in_pt.lua => 007_System_onSystemRequest_without_requestSubType_in_ptu.lua} (100%) create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/013_System_onSystemRequest_requestType_with_empty_array_in_ptu.lua create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/014_System_onSystemRequest_requestType_with_list_of_values_ptu.lua create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/015_System_onSystemRequest_requestType_without_parameter_in_pt.lua diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_pt.lua b/test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_ptu.lua similarity index 100% rename from test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_pt.lua rename to test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_ptu.lua diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_pt.lua b/test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_ptu.lua similarity index 100% rename from test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_pt.lua rename to test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_ptu.lua diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_pt.lua b/test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_ptu.lua similarity index 100% rename from test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_pt.lua rename to test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_ptu.lua diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/012_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua b/test_scripts/API/Expanded_proprietary_data_exchange/012_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua index dd4e9e1f19..dc5107344b 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/012_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/012_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua @@ -23,7 +23,6 @@ runner.testSettings.isSelfIncluded = false local usedFile = "./files/action.png" local params = { requestType = "OEM_SPECIFIC", - requestSubType = "SomeSubType", fileName = "action.png" } --[[ Local Functions ]] diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/013_System_onSystemRequest_requestType_with_empty_array_in_ptu.lua b/test_scripts/API/Expanded_proprietary_data_exchange/013_System_onSystemRequest_requestType_with_empty_array_in_ptu.lua new file mode 100644 index 0000000000..d655ee93d8 --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/013_System_onSystemRequest_requestType_with_empty_array_in_ptu.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1. PTU is performed with empty array in requestType +-- 2. SDL receives SystemRequest and onSystemRequest with requestType after ptu +-- SDL does: +-- 1. not send OnAppPermissionChanged() to HMI during update +-- 2. successful process SystemRequest and resend onSystemRequest +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') +local json = require('modules/json') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local usedFile = "./files/action.png" +local params = { + requestType = "OEM_SPECIFIC", + fileName = "action.png" +} +--[[ Local Functions ]] +local function ptuFuncRPC(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].RequestType = json.EMPTY_ARRAY +end + +local function policyUpdate(pPtuFunc) + common.policyTableUpdate(pPtuFunc) + common.getHMIConnection():ExpectNotification("SDL.OnAppPermissionChanged") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerApp) + +runner.Title("Test") +runner.Step("Policy table update", policyUpdate, { ptuFuncRPC }) +runner.Step("SystemRequest with request type OEM_SPECIFIC", common.systemRequest, + {params, usedFile}) +runner.Step("onSystemRequest with request type OEM_SPECIFIC", common.onSystemRequest, + {params}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/014_System_onSystemRequest_requestType_with_list_of_values_ptu.lua b/test_scripts/API/Expanded_proprietary_data_exchange/014_System_onSystemRequest_requestType_with_list_of_values_ptu.lua new file mode 100644 index 0000000000..4092c67aaf --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/014_System_onSystemRequest_requestType_with_list_of_values_ptu.lua @@ -0,0 +1,69 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1. PTU is performed with list of values in requestType +-- 2. SDL receives SystemRequest and onSystemRequest with requestType with value from list in pt +-- 3. SDL receives SystemRequest and onSystemRequest with requestType with value not from list in pt +-- SDL does: +-- 1. send OnAppPermissionChanged with list of values in requestType parameter to HMI during update +-- 2. successful process SystemRequest RPC and resend onSystemRequest to mobile application +-- 3. respond disallowed to SystemRequest and not resend onSystemRequest +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local usedFile = "./files/action.png" +local params = { + requestType = "OEM_SPECIFIC", + fileName = "action.png" +} + +local paramsUnsuccess = { + requestType = "LAUNCH_APP", + fileName = "action.png" +} + +--[[ Local Functions ]] +local function ptuFuncRPC(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].RequestType = { "HTTP", "PROPRIETARY", "OEM_SPECIFIC" } +end + +local function policyUpdate() + common.policyTableUpdate(ptuFuncRPC) + common.getHMIConnection():ExpectNotification("SDL.OnAppPermissionChanged", { + appID = common.getHMIAppId(), + requestType = { "HTTP", "PROPRIETARY", "OEM_SPECIFIC" } + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerApp) + +runner.Title("Test") +runner.Step("Policy table update", policyUpdate) +runner.Step("SystemRequest with request type OEM_SPECIFIC", common.systemRequest, + {params, usedFile}) +runner.Step("SystemRequest with request type LAUNCH_APP not from the list", common.unsuccessSystemRequest, + {paramsUnsuccess, usedFile}) +runner.Step("onSystemRequest with request type OEM_SPECIFIC", common.onSystemRequest, + {params}) +runner.Step("onSystemRequest with request type LAUNCH_APP not from the list", common.unsuccessOnSystemRequest, + {paramsUnsuccess}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/015_System_onSystemRequest_requestType_without_parameter_in_pt.lua b/test_scripts/API/Expanded_proprietary_data_exchange/015_System_onSystemRequest_requestType_without_parameter_in_pt.lua new file mode 100644 index 0000000000..003af7be2a --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/015_System_onSystemRequest_requestType_without_parameter_in_pt.lua @@ -0,0 +1,72 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1. PTU is performed without requestType +-- 2. SDL receives SystemRequest and onSystemRequest with requestType value +-- SDL does: +-- 1. send OnAppPermissionChanged wihout requestType to HMI during update +-- 2. process SystemRequest request successful and resend onSystemRequest to mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local usedFile = "./files/action.png" +local params = { + requestType = "OEM_SPECIFIC", + fileName = "action.png" +} + +local paramsProprietary = { + requestType = "PROPRIETARY", + fileName = "action.png" +} +--[[ Local Functions ]] +local function ptuFuncRPC(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].RequestType = nil + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].RequestSubType = { "TYPE1" } +end + +local function policyUpdate() + common.policyTableUpdate(ptuFuncRPC) + common.getHMIConnection():ExpectNotification("SDL.OnAppPermissionChanged", { + appID = common.getHMIAppId(), + }) + :ValidIf(function(_, data) + if data.params.requestType then + return false, "SDL.OnAppPermissionChanged notification contains unexpected parameter requestType" + end + return true + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerApp) + +runner.Title("Test") +runner.Step("Policy table update", policyUpdate) +runner.Step("SystemRequest with request type OEM_SPECIFIC", common.systemRequest, + {params, usedFile}) +runner.Step("SystemRequest with request type PROPRIETARY", common.systemRequest, + {paramsProprietary, usedFile}) +runner.Step("onSystemRequest with request type OEM_SPECIFIC", common.onSystemRequest, + {params}) +runner.Step("onSystemRequest with request type PROPRIETARY", common.onSystemRequest, + {paramsProprietary}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_sets/expanded_proprietary_data_exchange.txt b/test_sets/expanded_proprietary_data_exchange.txt index 0dcd89cc65..856434e0f9 100644 --- a/test_sets/expanded_proprietary_data_exchange.txt +++ b/test_sets/expanded_proprietary_data_exchange.txt @@ -2,11 +2,14 @@ ./test_scripts/API/Expanded_proprietary_data_exchange/002_onSystemRequest_with_OEM_SPECIFIC_requestSubType.lua ./test_scripts/API/Expanded_proprietary_data_exchange/003_requestSubType_with_requestType_PROPRIETARY.lua ./test_scripts/API/Expanded_proprietary_data_exchange/004_requestSubType_with_requestType_HTTP.lua -./test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_pt.lua -./test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_pt.lua -./test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_pt.lua +./test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_ptu.lua +./test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_ptu.lua +./test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_ptu.lua ./test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_with_value_list_in_requestSubType.lua ./test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_with_empty_array_in_requestSubType.lua ./test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_without_requestSubType.lua ./test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_by_fist_registration.lua ./test_scripts/API/Expanded_proprietary_data_exchange/012_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua +./test_scripts/API/Expanded_proprietary_data_exchange/013_System_onSystemRequest_requestType_with_empty_array_in_ptu.lua +./test_scripts/API/Expanded_proprietary_data_exchange/014_System_onSystemRequest_requestType_with_list_of_values_ptu.lua +./test_scripts/API/Expanded_proprietary_data_exchange/015_System_onSystemRequest_requestType_without_parameter_in_pt.lua From 54dd3ae31d7ce9ebc23ad35b48632ccec5f940e2 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 18 Apr 2018 20:00:06 +0300 Subject: [PATCH 362/681] Fix issue with clone table --- ...quest_with_OEM_SPECIFIC_requestSubType.lua | 2 +- ...quest_with_OEM_SPECIFIC_requestSubType.lua | 5 ++-- ...stSubType_with_requestType_PROPRIETARY.lua | 4 +-- ...4_requestSubType_with_requestType_HTTP.lua | 12 ++++---- ...requestSubType_with_empty_array_in_ptu.lua | 4 +-- ...estSubType_with_array_of_values_in_ptu.lua | 2 +- ...mRequest_without_requestSubType_in_ptu.lua | 2 +- ...ered_with_value_list_in_requestSubType.lua | 2 +- ...red_with_empty_array_in_requestSubType.lua | 2 +- ...OnAppRegistered_without_requestSubType.lua | 10 ++++--- ...1_OnAppRegistered_by_fist_registration.lua | 2 +- ...mRequest_OEM_SPECIFIC_type_not_allowed.lua | 2 +- ...st_requestType_with_empty_array_in_ptu.lua | 2 +- ...st_requestType_with_list_of_values_ptu.lua | 2 +- ...st_requestType_without_parameter_in_pt.lua | 2 +- .../commonDataExchange.lua | 29 +++++++++++++++---- 16 files changed, 52 insertions(+), 32 deletions(-) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/001_SystemRequest_with_OEM_SPECIFIC_requestSubType.lua b/test_scripts/API/Expanded_proprietary_data_exchange/001_SystemRequest_with_OEM_SPECIFIC_requestSubType.lua index 2cdeaba6c8..2b53548231 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/001_SystemRequest_with_OEM_SPECIFIC_requestSubType.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/001_SystemRequest_with_OEM_SPECIFIC_requestSubType.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0083-Expandable-design-for-proprietary-data-exchange.md -- User story:TBD -- Use case:TBD -- diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/002_onSystemRequest_with_OEM_SPECIFIC_requestSubType.lua b/test_scripts/API/Expanded_proprietary_data_exchange/002_onSystemRequest_with_OEM_SPECIFIC_requestSubType.lua index 209926735a..5566698b95 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/002_onSystemRequest_with_OEM_SPECIFIC_requestSubType.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/002_onSystemRequest_with_OEM_SPECIFIC_requestSubType.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0083-Expandable-design-for-proprietary-data-exchange.md -- User story:TBD -- Use case:TBD -- @@ -7,7 +7,7 @@ -- TBD -- -- Description: --- In case: HMI sends onSystemRequest only with requestType = "OEM_SPECIFIC" or with +-- In case: HMI sends OnSystemRequest only with requestType = "OEM_SPECIFIC" or with -- requestType = "OEM_SPECIFIC" and requestSubType -- SDL does: resend notification with received parameters to mobile application --------------------------------------------------------------------------------------------------- @@ -27,7 +27,6 @@ local params = { local paramsWithoutSubType = { requestType = "OEM_SPECIFIC", - requestSubType = "SomeSubType", fileName = "action.png" } diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/003_requestSubType_with_requestType_PROPRIETARY.lua b/test_scripts/API/Expanded_proprietary_data_exchange/003_requestSubType_with_requestType_PROPRIETARY.lua index aa0d64cdf0..81517b02fa 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/003_requestSubType_with_requestType_PROPRIETARY.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/003_requestSubType_with_requestType_PROPRIETARY.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0083-Expandable-design-for-proprietary-data-exchange.md -- User story:TBD -- Use case:TBD -- @@ -8,7 +8,7 @@ -- -- Description: -- In case: SystemRequest and onSystemRequest with PROPRIETARY requestType contains requestSubType paramter during policy table update --- SDL does: ignore received requestSubType and process received messages as usual +-- SDL does: transfer message with requestSubType as usual --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/004_requestSubType_with_requestType_HTTP.lua b/test_scripts/API/Expanded_proprietary_data_exchange/004_requestSubType_with_requestType_HTTP.lua index 418ef8f03b..f150280c4d 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/004_requestSubType_with_requestType_HTTP.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/004_requestSubType_with_requestType_HTTP.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0083-Expandable-design-for-proprietary-data-exchange.md -- User story:TBD -- Use case:TBD -- @@ -7,8 +7,10 @@ -- TBD -- -- Description: --- In case: SDL reveives SystemRequest and on SystemRequest with requestType = HTTP and requestSubType --- SDL does: ignore requestSubType and process messages as usual +-- 1. In case: SDL receives SystemRequest and on SystemRequest with requestType = HTTP and requestSubType +-- SDL does: +-- 1. ignore requestSubType in SystemRequest and process messages as usual, +-- 2. transfer OnSystemRequest to mobile app as usual --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -41,8 +43,8 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerApp) runner.Title("Test") -runner.Step("SystemRequest with request type OEM_SPECIFIC", systemRequest, {params, usedFile}) -runner.Step("OnSystemRequest with request type OEM_SPECIFIC", common.onSystemRequest, {params}) +runner.Step("SystemRequest with request type HTTP", systemRequest, {params, usedFile}) +runner.Step("OnSystemRequest with request type HTTP", common.onSystemRequest, {params}) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_ptu.lua b/test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_ptu.lua index 910cb3e71e..24edb1c9df 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_ptu.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_ptu.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0083-Expandable-design-for-proprietary-data-exchange.md -- User story:TBD -- Use case:TBD -- @@ -11,7 +11,7 @@ -- 1. PTU is performed with empty array in requestSubType -- 2. SDL receives SystemRequest and onSystemRequest with requestSubType after ptu -- SDL does: --- 1. not send OnAppPermissionChanged() to HMI during update +-- 1. not send OnAppPermissionChanged() to HMI after update -- 2. successful process SystemRequest and resend onSystemRequest --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_ptu.lua b/test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_ptu.lua index 86ab41574f..9c909a9afc 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_ptu.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_ptu.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0083-Expandable-design-for-proprietary-data-exchange.md -- User story:TBD -- Use case:TBD -- diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_ptu.lua b/test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_ptu.lua index 85e3f1b513..f89d76ca6f 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_ptu.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_ptu.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0083-Expandable-design-for-proprietary-data-exchange.md -- User story:TBD -- Use case:TBD -- diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_with_value_list_in_requestSubType.lua b/test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_with_value_list_in_requestSubType.lua index b17bd5ea55..6bb15a7e97 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_with_value_list_in_requestSubType.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_with_value_list_in_requestSubType.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0083-Expandable-design-for-proprietary-data-exchange.md -- User story:TBD -- Use case:TBD -- diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_with_empty_array_in_requestSubType.lua b/test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_with_empty_array_in_requestSubType.lua index 46cd76bb14..d56e9f2485 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_with_empty_array_in_requestSubType.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_with_empty_array_in_requestSubType.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0083-Expandable-design-for-proprietary-data-exchange.md -- User story:TBD -- Use case:TBD -- diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_without_requestSubType.lua b/test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_without_requestSubType.lua index b2ddf85e0e..c93c4d90c2 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_without_requestSubType.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_without_requestSubType.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0083-Expandable-design-for-proprietary-data-exchange.md -- User story:TBD -- Use case:TBD -- @@ -8,20 +8,22 @@ -- -- Description: -- In case: PT is updated without requestSubType for application App2 and App2 starts regisration --- SDL does: not send requestSubType in OnAppRegistered during registration +-- SDL does: send empty array(value from default section) in requestSubType in OnAppRegistered during registration --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') local json = require('modules/json') +local utils = require("user_modules/utils") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] local function ptuFuncRPC(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = tbl.policy_table.app_policies.default - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID].RequestSubType = nil + local appId = config.application2.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId] = utils.cloneTable(tbl.policy_table.app_policies.default) + tbl.policy_table.app_policies[appId].RequestSubType = nil end --[[ Scenario ]] diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_by_fist_registration.lua b/test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_by_fist_registration.lua index 6848cb1ef9..564ddd5dfe 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_by_fist_registration.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_by_fist_registration.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0083-Expandable-design-for-proprietary-data-exchange.md -- User story:TBD -- Use case:TBD -- diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/012_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua b/test_scripts/API/Expanded_proprietary_data_exchange/012_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua index dc5107344b..7bd14948a2 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/012_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/012_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0083-Expandable-design-for-proprietary-data-exchange.md -- User story:TBD -- Use case:TBD -- diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/013_System_onSystemRequest_requestType_with_empty_array_in_ptu.lua b/test_scripts/API/Expanded_proprietary_data_exchange/013_System_onSystemRequest_requestType_with_empty_array_in_ptu.lua index d655ee93d8..a77a9a93d6 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/013_System_onSystemRequest_requestType_with_empty_array_in_ptu.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/013_System_onSystemRequest_requestType_with_empty_array_in_ptu.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0083-Expandable-design-for-proprietary-data-exchange.md -- User story:TBD -- Use case:TBD -- diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/014_System_onSystemRequest_requestType_with_list_of_values_ptu.lua b/test_scripts/API/Expanded_proprietary_data_exchange/014_System_onSystemRequest_requestType_with_list_of_values_ptu.lua index 4092c67aaf..f88f748250 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/014_System_onSystemRequest_requestType_with_list_of_values_ptu.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/014_System_onSystemRequest_requestType_with_list_of_values_ptu.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0083-Expandable-design-for-proprietary-data-exchange.md -- User story:TBD -- Use case:TBD -- diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/015_System_onSystemRequest_requestType_without_parameter_in_pt.lua b/test_scripts/API/Expanded_proprietary_data_exchange/015_System_onSystemRequest_requestType_without_parameter_in_pt.lua index 003af7be2a..5d9ed0a6ad 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/015_System_onSystemRequest_requestType_without_parameter_in_pt.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/015_System_onSystemRequest_requestType_without_parameter_in_pt.lua @@ -1,5 +1,5 @@ --------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0083-Expandable-design-for-proprietary-data-exchange.md -- User story:TBD -- Use case:TBD -- diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua b/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua index 376cc970f8..1d42bafe20 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua @@ -13,8 +13,13 @@ config.defaultProtocolVersion = 2 local m = actions local ptuTable = {} -local hmiAppIds = {} +--[[ @systemRequest: successful processing of SystemRequest +--! @parameters: +--! pParams - parameters for SystemRequest +--! pFile - file for SystemRequest +--! @return: none +--]] function m.systemRequest(pParams, pFile) local mobSession = m.getMobileSession() local cid = mobSession:SendRPC("SystemRequest", pParams, pFile) @@ -26,6 +31,12 @@ function m.systemRequest(pParams, pFile) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end +--[[ @unsuccessSystemRequest: processing SystemRequest in case notification is disallowed +--! @parameters: +--! pParams - parameters for SystemRequest +--! pFile - file for SystemRequest +--! @return: none +--]] function m.unsuccessSystemRequest(pParams, pFile) local mobSession = m.getMobileSession() local cid = mobSession:SendRPC("SystemRequest", pParams, pFile) @@ -34,12 +45,22 @@ function m.unsuccessSystemRequest(pParams, pFile) mobSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) end +--[[ @onSystemRequest: successful processing of OnSystemRequest +--! @parameters: +--! pParams - parameters for OnSystemRequest +--! @return: none +--]] function m.onSystemRequest(pParams) m.getHMIConnection():SendNotification("BasicCommunication.OnSystemRequest", pParams) if pParams.fileName then pParams.fileName = nil end m.getMobileSession():ExpectNotification("OnSystemRequest", pParams) end +--[[ @unsuccessOnSystemRequest: processing OnSystemRequest in case notification is disallowed +--! @parameters: +--! pParams - parameters for OnSystemRequest +--! @return: none +--]] function m.unsuccessOnSystemRequest(pParams) m.getHMIConnection():SendNotification("BasicCommunication.OnSystemRequest", pParams) m.getMobileSession():ExpectNotification("OnSystemRequest") @@ -130,8 +151,7 @@ function m.registerApp(pAppId) appName = m.getConfigAppParams(pAppId).appName } }) - :Do(function(_, d1) - hmiAppIds[m.getConfigAppParams(pAppId).appID] = d1.params.application.appID + :Do(function() m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) :Times(2) @@ -167,9 +187,6 @@ function m.registerAppWOPTU(pAppId, pRequestSubType) requestSubType = pRequestSubType } }) - :Do(function(_, d1) - hmiAppIds[m.getConfigAppParams(pAppId).appID] = d1.params.application.appID - end) mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() mobSession:ExpectNotification("OnHMIStatus", From b9be178736591f4e59431e8a14397ac068b7cb74 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 20 Apr 2018 13:07:30 +0300 Subject: [PATCH 363/681] Update test set name --- ...dable_design_for_proprietary_data_exchange.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 test_sets/expandable_design_for_proprietary_data_exchange.txt diff --git a/test_sets/expandable_design_for_proprietary_data_exchange.txt b/test_sets/expandable_design_for_proprietary_data_exchange.txt new file mode 100644 index 0000000000..856434e0f9 --- /dev/null +++ b/test_sets/expandable_design_for_proprietary_data_exchange.txt @@ -0,0 +1,15 @@ +./test_scripts/API/Expanded_proprietary_data_exchange/001_SystemRequest_with_OEM_SPECIFIC_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/002_onSystemRequest_with_OEM_SPECIFIC_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/003_requestSubType_with_requestType_PROPRIETARY.lua +./test_scripts/API/Expanded_proprietary_data_exchange/004_requestSubType_with_requestType_HTTP.lua +./test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_ptu.lua +./test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_ptu.lua +./test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_ptu.lua +./test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_with_value_list_in_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_with_empty_array_in_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_without_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_by_fist_registration.lua +./test_scripts/API/Expanded_proprietary_data_exchange/012_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua +./test_scripts/API/Expanded_proprietary_data_exchange/013_System_onSystemRequest_requestType_with_empty_array_in_ptu.lua +./test_scripts/API/Expanded_proprietary_data_exchange/014_System_onSystemRequest_requestType_with_list_of_values_ptu.lua +./test_scripts/API/Expanded_proprietary_data_exchange/015_System_onSystemRequest_requestType_without_parameter_in_pt.lua From 01c8cb35e0d40c1d566751206d924bc93746d912 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 26 Apr 2018 18:45:25 +0300 Subject: [PATCH 364/681] Add Title to ATF report --- user_modules/script_runner.lua | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/user_modules/script_runner.lua b/user_modules/script_runner.lua index e1b9edd26a..0eba2913ab 100644 --- a/user_modules/script_runner.lua +++ b/user_modules/script_runner.lua @@ -11,6 +11,7 @@ local runner = {} runner.testSettings = testSettings Test.isTest = true +Test.caseTitles = { } --[Utils] local function existsInList (pList, pValue) @@ -24,7 +25,7 @@ end --[ATF] local function buildTitle(titleText) - local maxLength = 101 + local maxLength = 96 local filler = "-" local resultTable = {} for line in titleText:gmatch("[^\n]+") do @@ -32,9 +33,7 @@ local function buildTitle(titleText) if lineLength >= maxLength then table.insert(resultTable, line) else - local tailLength = math.fmod(maxLength - lineLength, 2) - local emtyLineSideLength = math.floor((maxLength - lineLength) / 2) - table.insert(resultTable, filler:rep(emtyLineSideLength) .. line .. filler:rep(emtyLineSideLength + tailLength)) + table.insert(resultTable, "--- " .. line .. " " .. filler:rep(maxLength - line:len(line))) end end return table.concat(resultTable, "\n") @@ -69,15 +68,15 @@ local function checkStepImplFunction(testStepImplFunction) end local function addTestStep(testStepName, testStepImplFunction) - testStepName = buildStepName(testStepName) testStepImplFunction = checkStepImplFunction(testStepImplFunction) Test[testStepName] = testStepImplFunction end local function extendedAddTestStep(testStepName, testStepImplFunction, paramsTable) + testStepName = buildStepName(testStepName) local implFunctionsListWithParams = {} if isPrintTitle then - table.insert(implFunctionsListWithParams, {implFunc = commonFunctions.userPrint, params = {0, 32, title, "\n"}}) + Test.caseTitles[testStepName] = title isPrintTitle = false end if not paramsTable then From 5864fd93d053abd730ee44174cfc4179abfddd91 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 26 Apr 2018 19:48:39 +0300 Subject: [PATCH 365/681] Fix issue regarding uniqueness of test steps --- user_modules/script_runner.lua | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/user_modules/script_runner.lua b/user_modules/script_runner.lua index 0eba2913ab..0d29900b4d 100644 --- a/user_modules/script_runner.lua +++ b/user_modules/script_runner.lua @@ -4,8 +4,7 @@ local consts = require('user_modules/consts') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local isInitialStep = true -local isPrintTitle = false -local title +local idx = 1 local runner = {} runner.testSettings = testSettings @@ -29,12 +28,10 @@ local function buildTitle(titleText) local filler = "-" local resultTable = {} for line in titleText:gmatch("[^\n]+") do - local lineLength = #line - if lineLength >= maxLength then - table.insert(resultTable, line) - else - table.insert(resultTable, "--- " .. line .. " " .. filler:rep(maxLength - line:len(line))) + if line:len() >= maxLength then + line = line:sub(1, maxLength - 1) end + table.insert(resultTable, "--- " .. line .. " " .. filler:rep(maxLength - line:len(line))) end return table.concat(resultTable, "\n") end @@ -67,18 +64,9 @@ local function checkStepImplFunction(testStepImplFunction) end end -local function addTestStep(testStepName, testStepImplFunction) - testStepImplFunction = checkStepImplFunction(testStepImplFunction) - Test[testStepName] = testStepImplFunction -end - local function extendedAddTestStep(testStepName, testStepImplFunction, paramsTable) testStepName = buildStepName(testStepName) local implFunctionsListWithParams = {} - if isPrintTitle then - Test.caseTitles[testStepName] = title - isPrintTitle = false - end if not paramsTable then paramsTable = {} end @@ -91,7 +79,7 @@ local function extendedAddTestStep(testStepName, testStepImplFunction, paramsTab func.implFunc(unpack(func.params, 1, table.maxn(func.params))) end end - addTestStep(testStepName, newTestStepImplFunction) + Test[testStepName] = checkStepImplFunction(newTestStepImplFunction) end local function isTestApplicable(testApplicableSdlSettings) @@ -121,7 +109,6 @@ local function isTestApplicable(testApplicableSdlSettings) end local function skipTest(reason) - title = "" runner.Title("TEST SKIPPED") runner.Step( "Skip reason", @@ -152,13 +139,10 @@ end --[[ Title + Step approach]] function runner.Title(titleText) - if isPrintTitle == true then - title = title .. "\n" .. titleText - else - title = titleText - isPrintTitle = true + if Test.caseTitles[idx] == nil then + Test.caseTitles[idx] = {} end - title = buildTitle(title) + table.insert(Test.caseTitles[idx], buildTitle(titleText)) end function runner.Step(testStepName, testStepImplFunction, paramsTable) @@ -181,6 +165,7 @@ function runner.Step(testStepName, testStepImplFunction, paramsTable) else extendedAddTestStep(testStepName, testStepImplFunction, paramsTable) end + idx = idx + 1 end return runner From 492a17f17f76f11d68395d0303ebabeef88709ac Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 27 Apr 2018 14:33:46 +0300 Subject: [PATCH 366/681] Remove dependency on PTU in smoke test scripts --- ...tGlobalProperties_PositiveCase_SUCCESS.lua | 2 +- ...tGlobalProperties_PositiveCase_SUCCESS.lua | 2 +- .../003_AddCommand_PositiveCase_SUCCESS.lua | 2 +- ...004_DeleteCommand_PositiveCase_SUCCESS.lua | 2 +- .../005_AddSubMenu_PositiveCase_SUCCESS.lua | 2 +- ...006_DeleteSubMenu_PositiveCase_SUCCESS.lua | 2 +- .../API/007_Alert_PositiveCase_SUCCESS.lua | 2 +- ...eractionChoiceSet_PositiveCase_SUCCESS.lua | 2 +- ...eractionChoiceSet_PositiveCase_SUCCESS.lua | 2 +- .../010_DeleteFile_PositiveCase_SUCCESS.lua | 2 +- .../011_ListFiles_PositiveCase_SUCCESS.lua | 2 +- ...PerfomInteraction_PositiveCase_SUCCESS.lua | 2 +- ...ScrollableMessage_PositiveCase_SUCCESS.lua | 2 +- ...etMediaClockTimer_PositiveCase_SUCCESS.lua | 2 +- .../API/015_Show_PositiveCase_SUCCESS.lua | 2 +- ...6_ShowConstantTBT_PositiveCase_SUCCESS.lua | 15 +----- .../API/017_Slider_PositiveCase_SUCCESS.lua | 2 +- .../018_SendLocation_PositiveCase_SUCCESS.lua | 15 +----- .../019_SetAppIcon_PositiveCase_SUCCESS.lua | 2 +- ..._SetDisplayLayout_PositiveCase_SUCCESS.lua | 2 +- .../API/021_Speak_PositiveCase_SUCCESS.lua | 2 +- ...2_SubscribeButton_PositiveCase_SUCCESS.lua | 2 +- ...UnsubscribeButton_PositiveCase_SUCCESS.lua | 2 +- ...scribeVehicleData_PositiveCase_SUCCESS.lua | 15 +----- ...scribeVehicleData_PositiveCase_SUCCESS.lua | 18 +------ ...26_GetVehicleData_PositiveCase_SUCCESS.lua | 15 +----- ...27_UpdateTurnList_PositiveCase_SUCCESS.lua | 15 +----- ...028_AlertManeuver_PositiveCase_SUCCESS.lua | 15 +----- ...DriverDistraction_PositiveCase_SUCCESS.lua | 2 +- .../030_DialNumber_PositiveCase_SUCCESS.lua | 15 +----- ...formAudioPassThru_PositiveCase_SUCCESS.lua | 2 +- ..._EndAudioPassThru_PositiveCase_SUCCESS.lua | 2 +- .../API/033_ReadDID_PositiveCase_SUCCESS.lua | 15 +----- .../API/034_GetDTCs_PositiveCase_SUCCESS.lua | 14 +----- ...hangeRegistration_PositiveCase_SUCCESS.lua | 2 +- ...isterAppInterface_PositiveCase_SUCCESS.lua | 2 +- ...isterAppInterface_PositiveCase_SUCCESS.lua | 2 +- ...8_Alert_Non_Media_PositiveCase_SUCCESS.lua | 2 +- ...raction_Non_Media_PositiveCase_SUCCESS.lua | 2 +- ...ckTimer_Non_Media_PositiveCase_SUCCESS.lua | 2 +- ...1_Speak_Non_Media_PositiveCase_SUCCESS.lua | 2 +- ...eButton_Non_Media_PositiveCase_SUCCESS.lua | 2 +- ...eButton_Non_Media_PositiveCase_SUCCESS.lua | 2 +- ...aneuver_Non_Media_PositiveCase_SUCCESS.lua | 15 +----- ...assThru_Non_Media_PositiveCase_SUCCESS.lua | 2 +- test_scripts/Smoke/commonSmoke.lua | 50 +++++++++++++++++++ 46 files changed, 95 insertions(+), 190 deletions(-) diff --git a/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua index 91e13a915f..9fe7e0a346 100644 --- a/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/001_SetGlobalProperties_PositiveCase_SUCCESS.lua @@ -132,7 +132,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) diff --git a/test_scripts/Smoke/API/002_ResetGlobalProperties_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/002_ResetGlobalProperties_PositiveCase_SUCCESS.lua index 70caa5145b..8ab8a8fb27 100644 --- a/test_scripts/Smoke/API/002_ResetGlobalProperties_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/002_ResetGlobalProperties_PositiveCase_SUCCESS.lua @@ -114,7 +114,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/003_AddCommand_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/003_AddCommand_PositiveCase_SUCCESS.lua index a8447dbef3..d60952b4e4 100644 --- a/test_scripts/Smoke/API/003_AddCommand_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/003_AddCommand_PositiveCase_SUCCESS.lua @@ -113,7 +113,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) diff --git a/test_scripts/Smoke/API/004_DeleteCommand_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/004_DeleteCommand_PositiveCase_SUCCESS.lua index adef04d2ca..d209b54b0e 100644 --- a/test_scripts/Smoke/API/004_DeleteCommand_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/004_DeleteCommand_PositiveCase_SUCCESS.lua @@ -140,7 +140,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) runner.Step("AddCommand", addCommand, {addCommandAllParams}) diff --git a/test_scripts/Smoke/API/005_AddSubMenu_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/005_AddSubMenu_PositiveCase_SUCCESS.lua index e043e6afbe..36b97c3448 100644 --- a/test_scripts/Smoke/API/005_AddSubMenu_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/005_AddSubMenu_PositiveCase_SUCCESS.lua @@ -69,7 +69,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/006_DeleteSubMenu_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/006_DeleteSubMenu_PositiveCase_SUCCESS.lua index e9f7475c05..50ff4cebab 100644 --- a/test_scripts/Smoke/API/006_DeleteSubMenu_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/006_DeleteSubMenu_PositiveCase_SUCCESS.lua @@ -87,7 +87,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("AddSubMenu", addSubMenu, {addSubMenuAllParams}) diff --git a/test_scripts/Smoke/API/007_Alert_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/007_Alert_PositiveCase_SUCCESS.lua index 8cd94f296b..ba8afdd994 100644 --- a/test_scripts/Smoke/API/007_Alert_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/007_Alert_PositiveCase_SUCCESS.lua @@ -206,7 +206,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) diff --git a/test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua index a9c211df14..7fdf63822a 100644 --- a/test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua @@ -99,7 +99,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) diff --git a/test_scripts/Smoke/API/009_DeleteInteractionChoiceSet_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/009_DeleteInteractionChoiceSet_PositiveCase_SUCCESS.lua index 6619d60c59..0aeeee6005 100644 --- a/test_scripts/Smoke/API/009_DeleteInteractionChoiceSet_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/009_DeleteInteractionChoiceSet_PositiveCase_SUCCESS.lua @@ -126,7 +126,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) runner.Step("CreateInteractionChoiceSet", createInteractionChoiceSet, {createAllParams}) diff --git a/test_scripts/Smoke/API/010_DeleteFile_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/010_DeleteFile_PositiveCase_SUCCESS.lua index 2b68c689fa..ba2fa25926 100644 --- a/test_scripts/Smoke/API/010_DeleteFile_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/010_DeleteFile_PositiveCase_SUCCESS.lua @@ -72,7 +72,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) diff --git a/test_scripts/Smoke/API/011_ListFiles_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/011_ListFiles_PositiveCase_SUCCESS.lua index e018036722..31cc9e6400 100644 --- a/test_scripts/Smoke/API/011_ListFiles_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/011_ListFiles_PositiveCase_SUCCESS.lua @@ -83,7 +83,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) for i, fileName in ipairs(testFileNamesList) do runner.Step("Upload test file #" .. i, putFile, {fileName}) diff --git a/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua index 5dae576f79..751562663d 100644 --- a/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua @@ -340,7 +340,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) runner.Step("CreateInteractionChoiceSet with id 100", CreateInteractionChoiceSet, {100}) diff --git a/test_scripts/Smoke/API/013_ScrollableMessage_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/013_ScrollableMessage_PositiveCase_SUCCESS.lua index f10db381d5..affb12043a 100644 --- a/test_scripts/Smoke/API/013_ScrollableMessage_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/013_ScrollableMessage_PositiveCase_SUCCESS.lua @@ -112,7 +112,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) diff --git a/test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase_SUCCESS.lua index 7b73e25953..bab8fe3ebf 100644 --- a/test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase_SUCCESS.lua @@ -68,7 +68,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/015_Show_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/015_Show_PositiveCase_SUCCESS.lua index 7d4d4a1bab..cac2351c59 100644 --- a/test_scripts/Smoke/API/015_Show_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/015_Show_PositiveCase_SUCCESS.lua @@ -123,7 +123,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, { putFileParams }) diff --git a/test_scripts/Smoke/API/016_ShowConstantTBT_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/016_ShowConstantTBT_PositiveCase_SUCCESS.lua index 5c2e855227..21a7fd06bb 100644 --- a/test_scripts/Smoke/API/016_ShowConstantTBT_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/016_ShowConstantTBT_PositiveCase_SUCCESS.lua @@ -111,19 +111,6 @@ local allParams = { } --[[ Local Functions ]] -local function PTUpdateFuncRPC(tbl) - local ShowCTBT = { - rpcs = { - ShowConstantTBT = { - hmi_levels = { "NONE", "BACKGROUND", "FULL", "LIMITED" } - } - } - } - tbl.policy_table.functional_groupings.NewTestCaseGroup = ShowCTBT - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = - { "Base-4", "NewTestCaseGroup" } -end - local function showConstantTBT(params, self) local cid = self.mobileSession1:SendRPC("ShowConstantTBT", params.requestParams) params.responseUiParams.appID = commonSmoke.getHMIAppId() @@ -141,7 +128,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { nil, PTUpdateFuncRPC }) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) diff --git a/test_scripts/Smoke/API/017_Slider_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/017_Slider_PositiveCase_SUCCESS.lua index 4ffbaf9d78..73323feedb 100644 --- a/test_scripts/Smoke/API/017_Slider_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/017_Slider_PositiveCase_SUCCESS.lua @@ -64,7 +64,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/018_SendLocation_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/018_SendLocation_PositiveCase_SUCCESS.lua index effda4485e..1e5f4d905f 100644 --- a/test_scripts/Smoke/API/018_SendLocation_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/018_SendLocation_PositiveCase_SUCCESS.lua @@ -59,19 +59,6 @@ local requestParams = { } --[[ Local Functions ]] -local function ptuUpdateFuncRPC(tbl) - local SLgroup = { - rpcs = { - SendLocation = { - hmi_levels = { "NONE", "BACKGROUND", "FULL", "LIMITED" } - } - } - } - tbl.policy_table.functional_groupings.NewTestCaseGroup = SLgroup - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = - { "Base-4", "NewTestCaseGroup" } -end - local function sendLocation(params, self) local cid = self.mobileSession1:SendRPC("SendLocation", params) params.appID = commonSmoke.getHMIAppId() @@ -87,7 +74,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, ptuUpdateFuncRPC }) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, { putFileParams }) diff --git a/test_scripts/Smoke/API/019_SetAppIcon_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/019_SetAppIcon_PositiveCase_SUCCESS.lua index 1f13b19252..d5784d76f4 100644 --- a/test_scripts/Smoke/API/019_SetAppIcon_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/019_SetAppIcon_PositiveCase_SUCCESS.lua @@ -73,7 +73,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, { putFileParams }) diff --git a/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua index ddb94cea58..8d16ca3f59 100644 --- a/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua @@ -230,7 +230,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/021_Speak_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/021_Speak_PositiveCase_SUCCESS.lua index 5b07038ae7..2d60fadd12 100644 --- a/test_scripts/Smoke/API/021_Speak_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/021_Speak_PositiveCase_SUCCESS.lua @@ -74,7 +74,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/022_SubscribeButton_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/022_SubscribeButton_PositiveCase_SUCCESS.lua index ef27276aa0..01b1341ea8 100644 --- a/test_scripts/Smoke/API/022_SubscribeButton_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/022_SubscribeButton_PositiveCase_SUCCESS.lua @@ -61,7 +61,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase_SUCCESS.lua index db7bae55e7..91f8bfe97a 100644 --- a/test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase_SUCCESS.lua @@ -70,7 +70,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) for _, v in pairs(buttonName) do runner.Step("SubscribeButton " .. v .. " Positive Case", subscribeButtons, { v }) diff --git a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua index 25c1b23b7c..60198bac8e 100644 --- a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua @@ -68,19 +68,6 @@ local allParams = { } --[[ Local Functions ]] -local function PTUpdateFunc(tbl) - local SVDgroup = { - rpcs = { - SubscribeVehicleData = { - hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, - } - } - } - tbl.policy_table.functional_groupings.NewTestCaseGroup = SVDgroup - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = - { "Base-4", "NewTestCaseGroup" } -end - local function setVDRequest() local tmp = {} for k, _ in pairs(VDValues) do @@ -121,7 +108,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, PTUpdateFunc }) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua index 7acc4665ea..76044630ae 100644 --- a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua @@ -68,22 +68,6 @@ local allParams = { } --[[ Local Functions ]] -local function PTUpdateFunc(tbl) - local SVDgroup = { - rpcs = { - SubscribeVehicleData = { - hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, - }, - UnsubscribeVehicleData = { - hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, - } - } - } - tbl.policy_table.functional_groupings.NewTestCaseGroup = SVDgroup - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = - { "Base-4", "NewTestCaseGroup" } -end - local function setVDRequest() local tmp = {} for k, _ in pairs(VDValues) do @@ -134,7 +118,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, PTUpdateFunc }) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("SubscribeVehicleData", subscribeVD, { allParams }) diff --git a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua index 4349aaacaa..660799d725 100644 --- a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua @@ -164,19 +164,6 @@ local allParams = { } --[[ Local Functions ]] -local function PTUpdateFunc(tbl) - local SVDgroup = { - rpcs = { - GetVehicleData = { - hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, - } - } - } - tbl.policy_table.functional_groupings.NewTestCaseGroup = SVDgroup - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = - { "Base-4", "NewTestCaseGroup" } -end - local function getVD(pParams, self) local cid = self.mobileSession1:SendRPC("GetVehicleData", pParams.requestParams) EXPECT_HMICALL("VehicleInfo.GetVehicleData", pParams.requestParams) @@ -193,7 +180,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, PTUpdateFunc }) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/027_UpdateTurnList_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/027_UpdateTurnList_PositiveCase_SUCCESS.lua index 013d2fd75f..7a2e80c5da 100644 --- a/test_scripts/Smoke/API/027_UpdateTurnList_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/027_UpdateTurnList_PositiveCase_SUCCESS.lua @@ -83,19 +83,6 @@ local allParams = { } --[[ Local Functions ]] -local function ptuUpdateFunc(tbl) - local UpdateTurnListGroup = { - rpcs = { - UpdateTurnList = { - hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, - } - } - } - tbl.policy_table.functional_groupings.NewTestCaseGroup = UpdateTurnListGroup - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = - { "Base-4", "NewTestCaseGroup" } -end - local function updateTurnList(pParams, self) local cid = self.mobileSession1:SendRPC("UpdateTurnList", pParams.requestParams) EXPECT_HMICALL("Navigation.UpdateTurnList", pParams.responseUiParams) @@ -109,7 +96,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, ptuUpdateFunc }) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, { putFileParams }) diff --git a/test_scripts/Smoke/API/028_AlertManeuver_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/028_AlertManeuver_PositiveCase_SUCCESS.lua index b052e26c0f..a6bb821cb1 100644 --- a/test_scripts/Smoke/API/028_AlertManeuver_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/028_AlertManeuver_PositiveCase_SUCCESS.lua @@ -107,19 +107,6 @@ local allParams = { } --[[ Local Functions ]] -local function PTUpdateFunc(tbl) - local AlertMgroup = { - rpcs = { - AlertManeuver = { - hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, - } - } - } - tbl.policy_table.functional_groupings.NewTestCaseGroup = AlertMgroup - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = - { "Base-4", "NewTestCaseGroup" } -end - local function alertManeuver(pParams, self) local cid = self.mobileSession1:SendRPC("AlertManeuver", pParams.requestParams) EXPECT_HMICALL("Navigation.AlertManeuver", pParams.responseNaviParams) @@ -149,7 +136,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, PTUpdateFunc }) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, { putFileParams }) diff --git a/test_scripts/Smoke/API/029_OnDriverDistraction_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/029_OnDriverDistraction_PositiveCase_SUCCESS.lua index 5700197df3..e15b6a64de 100644 --- a/test_scripts/Smoke/API/029_OnDriverDistraction_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/029_OnDriverDistraction_PositiveCase_SUCCESS.lua @@ -43,7 +43,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/030_DialNumber_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/030_DialNumber_PositiveCase_SUCCESS.lua index 78770302d0..8512fd748e 100644 --- a/test_scripts/Smoke/API/030_DialNumber_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/030_DialNumber_PositiveCase_SUCCESS.lua @@ -37,19 +37,6 @@ local requestParams = { } --[[ Local Functions ]] -local function PTUpdateFuncRPC(tbl) - local DialNumberGroup = { - rpcs = { - DialNumber = { - hmi_levels = { "NONE", "BACKGROUND", "FULL", "LIMITED" } - } - } - } - tbl.policy_table.functional_groupings.NewTestCaseGroup = DialNumberGroup - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = - { "Base-4", "NewTestCaseGroup" } -end - local function dialNumber(pParams, self) local cid = self.mobileSession1:SendRPC("DialNumber", pParams) pParams.appID = commonSmoke.getHMIAppId() @@ -64,7 +51,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, PTUpdateFuncRPC }) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/031_PerformAudioPassThru_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/031_PerformAudioPassThru_PositiveCase_SUCCESS.lua index 3ce4a2ee06..3d04a95baa 100644 --- a/test_scripts/Smoke/API/031_PerformAudioPassThru_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/031_PerformAudioPassThru_PositiveCase_SUCCESS.lua @@ -137,7 +137,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/032_EndAudioPassThru_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/032_EndAudioPassThru_PositiveCase_SUCCESS.lua index 061bfc5b6e..6d3183cd80 100644 --- a/test_scripts/Smoke/API/032_EndAudioPassThru_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/032_EndAudioPassThru_PositiveCase_SUCCESS.lua @@ -119,7 +119,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/033_ReadDID_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/033_ReadDID_PositiveCase_SUCCESS.lua index 0adcb32c39..39465a0d7e 100644 --- a/test_scripts/Smoke/API/033_ReadDID_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/033_ReadDID_PositiveCase_SUCCESS.lua @@ -32,19 +32,6 @@ local runner = require('user_modules/script_runner') local commonSmoke = require('test_scripts/Smoke/commonSmoke') --[[ Local Functions ]] -local function PTUpdateFunc(tbl) - local ReadDIDgroup = { - rpcs = { - ReadDID = { - hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, - } - } - } - tbl.policy_table.functional_groupings.NewTestCaseGroup = ReadDIDgroup - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = - { "Base-4", "NewTestCaseGroup" } -end - local function setReadDIDRequest() local temp = { ecuName = 2000, @@ -88,7 +75,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, PTUpdateFunc}) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/034_GetDTCs_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/034_GetDTCs_PositiveCase_SUCCESS.lua index 66219634c2..beb81bd8d7 100644 --- a/test_scripts/Smoke/API/034_GetDTCs_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/034_GetDTCs_PositiveCase_SUCCESS.lua @@ -31,18 +31,6 @@ local runner = require('user_modules/script_runner') local commonSmoke = require('test_scripts/Smoke/commonSmoke') --[[ Local Functions ]] -local function PTUpdateFunc(tbl) - local GetDTCs = { - rpcs = { - GetDTCs = { - hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, - } - } - } - tbl.policy_table.functional_groupings.NewTestCaseGroup = GetDTCs - tbl.policy_table.app_policies[commonSmoke.getMobileAppId()].groups = { "Base-4", "NewTestCaseGroup" } -end - local function getDTCsSuccess(self) local requestParams = { ecuName = 2, @@ -73,7 +61,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, PTUpdateFunc }) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/035_ChangeRegistration_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/035_ChangeRegistration_PositiveCase_SUCCESS.lua index 14528bba6f..c7e3928b6f 100644 --- a/test_scripts/Smoke/API/035_ChangeRegistration_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/035_ChangeRegistration_PositiveCase_SUCCESS.lua @@ -85,7 +85,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/036_UnregisterAppInterface_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/036_UnregisterAppInterface_PositiveCase_SUCCESS.lua index d3110d397a..3d5dd8273b 100644 --- a/test_scripts/Smoke/API/036_UnregisterAppInterface_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/036_UnregisterAppInterface_PositiveCase_SUCCESS.lua @@ -40,7 +40,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua index 20ffcd8372..668f77cdea 100644 --- a/test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua @@ -105,7 +105,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("UnregisterAppInterface Positive Case", unregisterAppInterface) diff --git a/test_scripts/Smoke/API/038_Alert_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/038_Alert_Non_Media_PositiveCase_SUCCESS.lua index 99d8c6e005..b2de4b8e5b 100644 --- a/test_scripts/Smoke/API/038_Alert_Non_Media_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/038_Alert_Non_Media_PositiveCase_SUCCESS.lua @@ -212,7 +212,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) diff --git a/test_scripts/Smoke/API/039_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/039_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua index 6e7efdc2f2..8ea454da89 100644 --- a/test_scripts/Smoke/API/039_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/039_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua @@ -334,7 +334,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) runner.Step("CreateInteractionChoiceSet with id 100", CreateInteractionChoiceSet, {100}) diff --git a/test_scripts/Smoke/API/040_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/040_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua index 3556a5b973..8f704a54fa 100644 --- a/test_scripts/Smoke/API/040_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/040_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua @@ -68,7 +68,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/041_Speak_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/041_Speak_Non_Media_PositiveCase_SUCCESS.lua index adaf0c5fb2..6046cf152f 100644 --- a/test_scripts/Smoke/API/041_Speak_Non_Media_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/041_Speak_Non_Media_PositiveCase_SUCCESS.lua @@ -74,7 +74,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/042_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/042_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua index 2d11b6e04e..f39ff5c893 100644 --- a/test_scripts/Smoke/API/042_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/042_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua @@ -76,7 +76,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/API/043_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/043_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua index 819d394391..028c7c7c97 100644 --- a/test_scripts/Smoke/API/043_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/043_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua @@ -85,7 +85,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) for _, v in pairs(buttonName) do runner.Step("SubscribeButton " .. v .. " Positive Case", subscribeButtons, { v }) diff --git a/test_scripts/Smoke/API/044_AlertManeuver_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/044_AlertManeuver_Non_Media_PositiveCase_SUCCESS.lua index 2d9af5eec7..0b5f88155d 100644 --- a/test_scripts/Smoke/API/044_AlertManeuver_Non_Media_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/044_AlertManeuver_Non_Media_PositiveCase_SUCCESS.lua @@ -110,19 +110,6 @@ local allParams = { } --[[ Local Functions ]] -local function PTUpdateFunc(tbl) - local AlertMgroup = { - rpcs = { - AlertManeuver = { - hmi_levels = { "BACKGROUND", "FULL", "LIMITED" }, - } - } - } - tbl.policy_table.functional_groupings.NewTestCaseGroup = AlertMgroup - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = - { "Base-4", "NewTestCaseGroup" } -end - local function alertManeuver(pParams, self) local cid = self.mobileSession1:SendRPC("AlertManeuver", pParams.requestParams) EXPECT_HMICALL("Navigation.AlertManeuver", pParams.responseNaviParams) @@ -150,7 +137,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU, { 1, PTUpdateFunc }) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Step("Upload icon file", commonSmoke.putFile, { putFileParams }) diff --git a/test_scripts/Smoke/API/045_PerformAudioPassThru_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/045_PerformAudioPassThru_Non_Media_PositiveCase_SUCCESS.lua index a79131e7b6..c6085b7b51 100644 --- a/test_scripts/Smoke/API/045_PerformAudioPassThru_Non_Media_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/045_PerformAudioPassThru_Non_Media_PositiveCase_SUCCESS.lua @@ -138,7 +138,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI, PTU", commonSmoke.registerApplicationWithPTU) +runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") diff --git a/test_scripts/Smoke/commonSmoke.lua b/test_scripts/Smoke/commonSmoke.lua index e042fd169c..6d1e02b44e 100644 --- a/test_scripts/Smoke/commonSmoke.lua +++ b/test_scripts/Smoke/commonSmoke.lua @@ -16,10 +16,12 @@ local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') local events = require("events") +local utils = require('user_modules/utils') --[[ Local Variables ]] local ptu_table = {} local hmiAppIds = {} +local preloadedPT = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") local commonSmoke = {} @@ -126,6 +128,8 @@ function commonSmoke.preconditions() commonFunctions:SDLForceStop() commonSteps:DeletePolicyTable() commonSteps:DeleteLogsFiles() + commonPreconditions:BackupFile(preloadedPT) + commonSmoke.updatePreloadedPT() end function commonSmoke.getDeviceName() @@ -183,6 +187,9 @@ end function commonSmoke.getMobileSession(pAppId, self) self, pAppId = commonSmoke.getSelfAndParams(pAppId, self) if not pAppId then pAppId = 1 end + if not self["mobileSession" .. pAppId] then + self["mobileSession" .. pAppId] = mobile_session.MobileSession(self, self.mobileConnection) + end return self["mobileSession" .. pAppId] end @@ -363,6 +370,49 @@ end function commonSmoke.postconditions() StopSDL() + commonPreconditions:RestoreFile(preloadedPT) +end + +function commonSmoke.updatePreloadedPT() + local preloadedFile = commonPreconditions:GetPathToSDL() .. preloadedPT + local pt = utils.jsonFileToTable(preloadedFile) + pt.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + local additionalRPCs = { + "SendLocation", "SubscribeVehicleData", "UnsubscribeVehicleData", "GetVehicleData", "UpdateTurnList", + "AlertManeuver", "DialNumber", "ReadDID", "GetDTCs", "ShowConstantTBT" + } + pt.policy_table.functional_groupings.NewTestCaseGroup = { rpcs = { } } + for _, v in pairs(additionalRPCs) do + pt.policy_table.functional_groupings.NewTestCaseGroup.rpcs[v] = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED" } + } + end + pt.policy_table.app_policies["0000001"] = utils.cloneTable(pt.policy_table.app_policies.default) + pt.policy_table.app_policies["0000001"].groups = { "Base-4", "NewTestCaseGroup" } + pt.policy_table.app_policies["0000001"].keep_context = true + pt.policy_table.app_policies["0000001"].steal_focus = true + utils.tableToJsonFile(pt, preloadedFile) +end + +function commonSmoke.registerApp(pAppId, self) + self, pAppId = commonSmoke.getSelfAndParams(pAppId, self) + if not pAppId then pAppId = 1 end + local mobSession = commonSmoke.getMobileSession(pAppId, self) + mobSession:StartService(7) + :Do(function() + local corId = mobSession:SendRPC("RegisterAppInterface", config["application" .. pAppId].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) + :Do(function(_, data) + hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = data.params.application.appID + end) + mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + mobSession:ExpectNotification("OnPermissionsChange") + end) + end) end return commonSmoke From b6b29e28847d47f93e8c20ec44265d1b6af6a753 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 27 Apr 2018 17:47:28 +0300 Subject: [PATCH 367/681] Remove unused code in smoke coomon module --- test_scripts/Smoke/commonSmoke.lua | 131 ----------------------------- 1 file changed, 131 deletions(-) diff --git a/test_scripts/Smoke/commonSmoke.lua b/test_scripts/Smoke/commonSmoke.lua index 6d1e02b44e..fcfa798b48 100644 --- a/test_scripts/Smoke/commonSmoke.lua +++ b/test_scripts/Smoke/commonSmoke.lua @@ -1,7 +1,6 @@ --------------------------------------------------------------------------------------------------- -- Smoke API common module --------------------------------------------------------------------------------------------------- - --[[ General configuration parameters ]] config.mobileHost = "127.0.0.1" config.defaultProtocolVersion = 2 @@ -15,11 +14,9 @@ local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') -local events = require("events") local utils = require('user_modules/utils') --[[ Local Variables ]] -local ptu_table = {} local hmiAppIds = {} local preloadedPT = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") @@ -37,91 +34,6 @@ local function allowSDL(self) { allowed = true, source = "GUI", device = { id = commonSmoke.getDeviceMAC(), name = commonSmoke.getDeviceName() }}) end -local function jsonFileToTable(pFileName) - local f = io.open(pFileName, "r") - local content = f:read("*all") - f:close() - return json.decode(content) -end - -local function checkIfPTSIsSentAsBinary(bin_data) - if not (bin_data ~= nil and string.len(bin_data) > 0) then - commonFunctions:userPrint(consts.color.red, - "PTS was not sent to Mobile in payload of OnSystemRequest") - end -end - -local function getPTUFromPTS(tbl) - tbl.policy_table.consumer_friendly_messages.messages = nil - tbl.policy_table.device_data = nil - tbl.policy_table.module_meta = nil - tbl.policy_table.usage_and_error_counts = nil - tbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null - tbl.policy_table.module_config.preloaded_pt = nil - tbl.policy_table.module_config.preloaded_date = nil -end - -local function ptu(self, id, pUpdateFunction) - local function getAppsCount() - local count = 0 - for _ in pairs(hmiAppIds) do - count = count + 1 - end - return count - end - - local policy_file_name = "PolicyTableUpdate" - local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") - local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") - local ptu_file_name = os.tmpname() - local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(requestId) - :Do(function() - self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", - { requestType = "PROPRIETARY", fileName = pts_file_name }) - getPTUFromPTS(ptu_table) - local function updatePTU(tbl) - tbl.policy_table.app_policies[commonSmoke.getMobileAppId(id)] = commonSmoke.getSmokeAppPoliciesConfig() - end - updatePTU(ptu_table) - if pUpdateFunction then - pUpdateFunction(ptu_table) - end - local function tableToJsonFile(tbl, file_name) - local f = io.open(file_name, "w") - f:write(json.encode(tbl)) - f:close() - end - tableToJsonFile(ptu_table, ptu_file_name) - - local event = events.Event() - event.matches = function(self, e) return self == e end - EXPECT_EVENT(event, "PTU event") - :Timeout(11000) - - for id = 1, getAppsCount() do - local mobileSession = commonSmoke.getMobileSession(id, self) - mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) - :Do(function(_, data) - print("App ".. id .. " was used for PTU") - RAISE_EVENT(event, event, "PTU event") - checkIfPTSIsSentAsBinary(data.binaryData) - local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", - { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) - EXPECT_HMICALL("BasicCommunication.SystemRequest") - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) - self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", - { policyfile = policy_file_path .. "/" .. policy_file_name }) - end) - mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) - :Do(function() os.remove(ptu_file_name) end) - end) - :Times(AtMost(1)) - end - end) -end - --[[Module functions]] function commonSmoke.preconditions() @@ -193,16 +105,6 @@ function commonSmoke.getMobileSession(pAppId, self) return self["mobileSession" .. pAppId] end -function commonSmoke.getSmokeAppPoliciesConfig() - return { - keep_context = false, - steal_focus = false, - priority = "NONE", - default_hmi = "NONE", - groups = { "Base-4" } - } -end - function commonSmoke.splitString(inputStr, sep) if sep == nil then sep = "%s" @@ -294,39 +196,6 @@ function commonSmoke.start(pHMIParams, self) end) end -function commonSmoke.registerApplicationWithPTU(pAppId, pUpdateFunction, self) - self, pAppId, pUpdateFunction = commonSmoke.getSelfAndParams(pAppId, pUpdateFunction, self) - if not pAppId then pAppId = 1 end - self["mobileSession" .. pAppId] = mobile_session.MobileSession(self, self.mobileConnection) - self["mobileSession" .. pAppId]:StartService(7) - :Do(function() - local corId = self["mobileSession" .. pAppId]:SendRPC("RegisterAppInterface", - config["application" .. pAppId].registerAppInterfaceParams) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", - { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) - :Do(function(_, data) - hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = data.params.application.appID - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", - {status = "UPDATE_NEEDED"}, {status = "UPDATING"}, {status = "UP_TO_DATE" }) - :Times(3) - EXPECT_HMICALL("BasicCommunication.PolicyUpdate") - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) - ptu_table = jsonFileToTable(data.params.file) - ptu(self, pAppId, pUpdateFunction) - end) - end) - self["mobileSession" .. pAppId]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) - :Do(function() - self["mobileSession" .. pAppId]:ExpectNotification("OnHMIStatus", - {hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) - :Times(1) - self["mobileSession" .. pAppId]:ExpectNotification("OnPermissionsChange") - :Times(AtLeast(1)) -- todo: issue with SDL --> notification is sent twice - end) - end) -end - function commonSmoke.putFile(params, pAppId, self) if not pAppId then pAppId = 1 end local mobileSession = commonSmoke.getMobileSession(pAppId, self); From 89e2ede9f770c34e5e45aec58a72488101247c50 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Wed, 2 May 2018 15:26:46 -0400 Subject: [PATCH 368/681] Test Script for Template Color Schemes --- test_scripts/SDL4.6/TemplateColorSchemes.lua | 106 +++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 test_scripts/SDL4.6/TemplateColorSchemes.lua diff --git a/test_scripts/SDL4.6/TemplateColorSchemes.lua b/test_scripts/SDL4.6/TemplateColorSchemes.lua new file mode 100644 index 0000000000..1a0c497679 --- /dev/null +++ b/test_scripts/SDL4.6/TemplateColorSchemes.lua @@ -0,0 +1,106 @@ +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +local function getRequestParams() + return { + displayLayout = "ONSCREEN_PRESETS", + dayColorScheme = { + primaryColor = { + red = 0, + green = 255, + blue = 100 + } + } + } +end + +local function getRequestParams2() + return { + displayLayout = "ONSCREEN_PRESETS", + dayColorScheme = { + primaryColor = { + red = 0, + green = 0, + blue = 0 + } + } + } +end + +local function getRequestParams3() + return { + displayLayout = "MEDIA", + dayColorScheme = { + primaryColor = { + red = 0, + green = 255, + blue = 100 + } + } + } +end + +local function setDisplayWithColorsSuccess(self) + local responseParams = {} + local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams()) + EXPECT_HMICALL("UI.SetDisplayLayout", getRequestParams()) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", responseParams) + end) + self.mobileSession1:ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS" + }) +end + +local function setDisplayWithSameColorsSuccess(self) + local responseParams = {} + local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams()) + EXPECT_HMICALL("UI.SetDisplayLayout", getRequestParams()) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", responseParams) + end) + self.mobileSession1:ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS" + }) +end + +local function setDisplayWithColorsRejected(self) + local responseParams = {} + local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams2()) + self.mobileSession1:ExpectResponse(cid, { + success = false, + resultCode = "REJECTED" + }) +end + +local function setDisplayWithColorsAndNewLayoutSuccess(self) + local responseParams = {} + local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams3()) + EXPECT_HMICALL("UI.SetDisplayLayout", getRequestParams3()) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", responseParams) + end) + self.mobileSession1:ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS" + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI", commonSmoke.registerApp) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("SetDisplay Positive Case 1", setDisplayWithColorsSuccess) +runner.Step("SetDisplay Positive Case 2", setDisplayWithSameColorsSuccess) +runner.Step("SetDisplay Rejected Case", setDisplayWithColorsRejected) +runner.Step("SetDisplay Positive Case 3", setDisplayWithColorsAndNewLayoutSuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From 5d95ad0b2a1d302ed976bba26fd6f558380428e1 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Wed, 2 May 2018 15:30:04 -0400 Subject: [PATCH 369/681] Fix spacing --- test_scripts/SDL4.6/TemplateColorSchemes.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test_scripts/SDL4.6/TemplateColorSchemes.lua b/test_scripts/SDL4.6/TemplateColorSchemes.lua index 1a0c497679..c52e476718 100644 --- a/test_scripts/SDL4.6/TemplateColorSchemes.lua +++ b/test_scripts/SDL4.6/TemplateColorSchemes.lua @@ -3,7 +3,7 @@ local runner = require('user_modules/script_runner') local commonSmoke = require('test_scripts/Smoke/commonSmoke') local function getRequestParams() - return { + return { displayLayout = "ONSCREEN_PRESETS", dayColorScheme = { primaryColor = { @@ -16,7 +16,7 @@ local function getRequestParams() end local function getRequestParams2() - return { + return { displayLayout = "ONSCREEN_PRESETS", dayColorScheme = { primaryColor = { @@ -29,7 +29,7 @@ local function getRequestParams2() end local function getRequestParams3() - return { + return { displayLayout = "MEDIA", dayColorScheme = { primaryColor = { From cc96c4e82099e01a9254b4b25951f54757ee4cb2 Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Wed, 2 May 2018 17:26:48 -0400 Subject: [PATCH 370/681] Add `secondaryGraphic` to SetDisplayLayout smoke test --- .../Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua index 8d16ca3f59..1c881764bb 100644 --- a/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua @@ -87,6 +87,7 @@ local function getDisplayCapImageFieldsValues() "menuIcon", "cmdIcon", "graphic", + "secondaryGraphic", "showConstantTBTIcon", "showConstantTBTNextTurnIcon" } From aea53ba3e528f602226dd80285aa84fc9e643633 Mon Sep 17 00:00:00 2001 From: BSolonenko Date: Thu, 3 May 2018 10:51:49 +0300 Subject: [PATCH 371/681] Verified issue smartdevicelink/sdl_core#1031 Verified: SDL transfer OnKeyboardInput notification to not active App when there is no active PerformInteraction(KEYBOARD) smartdevicelink/sdl_core#1031 --- ..._no_active_PerformInteraction_KEYBOARD.lua | 159 ++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 test_scripts/Defects/4_6/1031_SDL_transfer_OnKeyboardInput_notification_to_not_active_App_when_there_is_no_active_PerformInteraction_KEYBOARD.lua diff --git a/test_scripts/Defects/4_6/1031_SDL_transfer_OnKeyboardInput_notification_to_not_active_App_when_there_is_no_active_PerformInteraction_KEYBOARD.lua b/test_scripts/Defects/4_6/1031_SDL_transfer_OnKeyboardInput_notification_to_not_active_App_when_there_is_no_active_PerformInteraction_KEYBOARD.lua new file mode 100644 index 0000000000..05e0f06f5c --- /dev/null +++ b/test_scripts/Defects/4_6/1031_SDL_transfer_OnKeyboardInput_notification_to_not_active_App_when_there_is_no_active_PerformInteraction_KEYBOARD.lua @@ -0,0 +1,159 @@ +-------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/1031 + +-- Pre-conditions: +-- 1. Core, HMI started. +-- 2. App is registered and deactivated on HMI (has LIMITED level) +-- 3. OnKeyboardInput notification is allowed to the App from LIMITED +-- 4. Choise set with id 1 is created. + +-- Steps to reproduce: +-- 1. Send PerformInteraction(ICON_ONLY) +-- 2. During processing request send OnKeyboardInput notification + +-- Expected: +-- In case there is no active PerformInteraction(KEYBOARD), SDL should resend +-- OnKeyboardInput only to App that is currently in FULL. +-------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/commonDefects') + +--[[ Local Variables ]] +local requestParams = { + initialText = "StartPerformInteraction", + interactionMode = "MANUAL_ONLY", + interactionChoiceSetIDList = { + 100 + }, + interactionLayout = "ICON_ONLY" +} + +--[[ Local Functions ]] +local function ptuForApp(tbl) + local AppGroup = { + rpcs = { + PerformInteraction = { + hmi_levels = { "NONE", "BACKGROUND", "FULL", "LIMITED" } + }, + OnKeyboardInput = { + hmi_levels = {"BACKGROUND", "FULL", "LIMITED"} + } + } + } + tbl.policy_table.functional_groupings.NewTestCaseGroup = AppGroup + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups = + { "Base-4", "NewTestCaseGroup" } + + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.DefaultStruct() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID].groups = + { "Base-4", "NewTestCaseGroup" } +end + +local function deactivateToLimited(self) + self.hmiConnection:SendNotification("BasicCommunication.OnAppDeactivated", {appID = common.getHMIAppId()}) + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE"}) +end + +local function setChoiseSet(choiceIDValue) + local temp = { + { + choiceID = choiceIDValue, + menuName ="Choice" .. tostring(choiceIDValue), + vrCommands = { + "VrChoice" .. tostring(choiceIDValue), + } + } + } + return temp +end + +local function CreateInteractionChoiceSet(choiceSetID, self) + local choiceID = choiceSetID + local cid = self.mobileSession1:SendRPC("CreateInteractionChoiceSet", { + interactionChoiceSetID = choiceSetID, + choiceSet = setChoiseSet(choiceID), + }) + EXPECT_HMICALL("VR.AddCommand", { + cmdID = choiceID, + type = "Choice", + vrCommands = { "VrChoice" .. tostring(choiceID) } + }) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + self.mobileSession1:ExpectResponse(cid, { resultCode = "SUCCESS", success = true }) +end + +local function SendOnSystemContext(self, ctx) + self.hmiConnection:SendNotification("UI.OnSystemContext", + { appID = common.getHMIAppId(), systemContext = ctx }) +end + +local function PI_PerformViaMANUAL_ONLY(onKeyboardInput, self) + local cid = self.mobileSession1:SendRPC("PerformInteraction", requestParams) + EXPECT_HMICALL("VR.PerformInteraction") + :Do(function(_,data) + self.hmiConnection:SendNotification("TTS.Started") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + EXPECT_HMICALL("UI.PerformInteraction") + :Do(function(_,data) + SendOnSystemContext(self,"HMI_OBSCURED") + onKeyboardInput(self) + local function uiResponse() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + { choiceID = requestParams.interactionChoiceSetIDList[1] }) + self.hmiConnection:SendNotification("TTS.Stopped") + SendOnSystemContext(self,"MAIN") + end + RUN_AFTER(uiResponse, 5000) + end) + self.mobileSession1:ExpectResponse(cid, + { success = true, resultCode = "SUCCESS", choiceID = requestParams.interactionChoiceSetIDList[1] }) +end + +local function OnKeyboardInput1app(self) + self.hmiConnection:SendNotification("UI.OnKeyboardInput",{data = "abc", event = "KEYPRESS"}) + self.mobileSession1:ExpectNotification("OnKeyboardInput") + :Times(0) +end + +local function OnKeyboardInput2app(self) + OnKeyboardInput1app(self); + self.mobileSession2:ExpectNotification("OnKeyboardInput") +end + +local function PI_PerformViaMANUAL_ONLY_1apps(self) + PI_PerformViaMANUAL_ONLY(OnKeyboardInput1app, self) +end + +local function PI_PerformViaMANUAL_ONLY_2apps(self) + PI_PerformViaMANUAL_ONLY(OnKeyboardInput2app, self) +end + +local function activateSecondApp(self) + common.activate_app(2, self) + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.rai_ptu, { ptuForApp }) +runner.Step("Activate App", common.activate_app) +runner.Step("Deactivate App to LIMITED", deactivateToLimited) +runner.Step("CreateInteractionChoiceSet with id 100", CreateInteractionChoiceSet, {100}) + +runner.Title("Test") +runner.Step("PerformInteraction in limited", PI_PerformViaMANUAL_ONLY_1apps) +runner.Step("RAI App2", common.rai_n, { 2 }) +runner.Step("Activate App2", activateSecondApp) +runner.Step("PerformInteraction in background", PI_PerformViaMANUAL_ONLY_2apps) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From a06cd08dab40b76c5471eb8508752cb4c67031d1 Mon Sep 17 00:00:00 2001 From: BSolonenko Date: Wed, 2 May 2018 15:57:37 +0300 Subject: [PATCH 372/681] Verified issue smartdevicelink/sdl_core#1035 Verified: SDL doesn't "REJECTED" code to mobile app when activating app from HMI with activate smartdevicelink/sdl_core#1035 --- ..._activating_app_from_HMI_with_activate.lua | 62 ++ test_scripts/Defects/commonDefects.lua | 542 ++++++++++++++++++ 2 files changed, 604 insertions(+) create mode 100644 test_scripts/Defects/4_6/1035_SDL_doesnt_send_REJECTED_code_to_mobile_app_when_activating_app_from_HMI_with_activate.lua create mode 100644 test_scripts/Defects/commonDefects.lua diff --git a/test_scripts/Defects/4_6/1035_SDL_doesnt_send_REJECTED_code_to_mobile_app_when_activating_app_from_HMI_with_activate.lua b/test_scripts/Defects/4_6/1035_SDL_doesnt_send_REJECTED_code_to_mobile_app_when_activating_app_from_HMI_with_activate.lua new file mode 100644 index 0000000000..cecebb5081 --- /dev/null +++ b/test_scripts/Defects/4_6/1035_SDL_doesnt_send_REJECTED_code_to_mobile_app_when_activating_app_from_HMI_with_activate.lua @@ -0,0 +1,62 @@ +-------------------------------------------------------------------------------- +-- Script verifies issue: +-- https://github.com/smartdevicelink/sdl_core/issues/1035 + +-- Pre-conditions: +-- 1. SDL is started +-- 2. HMI is started +-- 3. App is in "FULL" HMI Level. + +-- Steps to reproduce: +-- 1. Send "OnDeactivate notification send = true" from HMI +-- 2. send SDL.ActivateApp from HMI + +-- Expected: +-- SDL should send "REJECTED" code to HMI when HMI is active; +-- SDL should send "SUCCESS" code to HMI when HMI isn't active. +-------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/commonDefects') + +--[[ Local Variables ]] +local kRejected = 4 +local kSuccess = 0 + +--[[ Local Functions ]] +local function deactivateHmi(state, self) + self.hmiConnection:SendNotification("BasicCommunication.OnEventChanged", + {eventName="DEACTIVATE_HMI",isActive = state}) +end + +local function activateApp(expectedCode, self) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", + { appID = common.getHMIAppId(1) }) + EXPECT_HMIRESPONSE(requestId) + :ValidIf(function(_, data) + local actualCode = + (data.error ~= nil and data.error.code or data.result.code) + if(expectedCode == actualCode) then + return true + end + return false, "Expected value:" .. tostring(expectedCode) .. + "\nActual value: " .. tostring(actualCode) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.rai_ptu) +runner.Step("Activate App", activateApp, { kSuccess }) + +runner.Title("Test") +runner.Step("Deactivate HMI", deactivateHmi, { true }) +runner.Step("Rejected activation", activateApp, { kRejected }) +runner.Step("Activate HMI", deactivateHmi, { false }) +runner.Step("ActivateApp", activateApp, { kSuccess }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/commonDefects.lua b/test_scripts/Defects/commonDefects.lua new file mode 100644 index 0000000000..9b106fd952 --- /dev/null +++ b/test_scripts/Defects/commonDefects.lua @@ -0,0 +1,542 @@ +--------------------------------------------------------------------------------------------------- +-- RC common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +-- define MAC address mobile device +config.mobileHost = "127.0.0.1" +-- define 2nd version of SDL protocol by default +config.defaultProtocolVersion = 2 +-- switch off schema validation for output messages against APIs +config.ValidateSchema = false + +--[[ Required Shared libraries ]] +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +local sdl = require("SDL") +local mobile_session = require("mobile_session") +local events = require("events") +local json = require("modules/json") + +--[[ Local Variables ]] + +-- table with data for Policy Table Update +local ptu_table = {} +-- table with HMI application identifiers +local hmiAppIds = {} +-- table for module +local commonDefect = {} + +--[[ Module Constants ]] + +-- default timeout +commonDefect.timeout = 2000 +-- minimal timeout +commonDefect.minTimeout = 500 + +--[[ @getPTUFromPTS: create policy table update table (PTU) +--! @parameters: +--! tbl - table with policy table snapshot (PTS) +--! @return: table with PTU +--]] +local function getPTUFromPTS(tbl) + tbl.policy_table.consumer_friendly_messages.messages = nil + tbl.policy_table.device_data = nil + tbl.policy_table.module_meta = nil + tbl.policy_table.usage_and_error_counts = nil + tbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + tbl.policy_table.module_config.preloaded_pt = nil + tbl.policy_table.module_config.preloaded_date = nil +end + +--[[ @DefaultStruct: provide default values for application required in PTU +--! @parameters: none +--! @return: table with data +--]] +function commonDefect.DefaultStruct() + return { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + groups = { "Base-4"}, + } +end + +--[[ @updatePTU: update PTU with application data +--! @parameters: +--! tbl - table with data for policy table update +--! @return: none +--]] +local function updatePTU(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonDefect.DefaultStruct() +end + +--[[ @jsonFileToTable: convert .json file to table +--! @parameters: +--! file_name - file name +--! @return: table +--]] +local function jsonFileToTable(file_name) + local f = io.open(file_name, "r") + local content = f:read("*all") + f:close() + return json.decode(content) +end + +--[[ @tableToJsonFile: convert table to .json file +--! @parameters: +--! tbl - table +--! file_name - file name +--! @return: none +--]] +local function tableToJsonFile(tbl, file_name) + local f = io.open(file_name, "w") + f:write(json.encode(tbl)) + f:close() +end + +--[[ @ptu: perform policy table update +--! @parameters: +--! self - test object +--! ptu_update_func - additional function for update +--! @return: none +--]] +local function ptu(self, ptu_update_func) + local function getAppsCount() + local count = 0 + for _, _ in pairs(hmiAppIds) do + count = count + 1 + end + return count + end + + local policy_file_name = "PolicyTableUpdate" + local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + local ptu_file_name = os.tmpname() + local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) + EXPECT_HMIRESPONSE(requestId) + :Do(function() + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + { requestType = "PROPRIETARY", fileName = pts_file_name }) + getPTUFromPTS(ptu_table) + updatePTU(ptu_table) + if ptu_update_func then + ptu_update_func(ptu_table) + end + tableToJsonFile(ptu_table, ptu_file_name) + + local event = events.Event() + event.matches = function(e1, e2) return e1 == e2 end + EXPECT_EVENT(event, "PTU event") + :Timeout(11000) + + for id = 1, getAppsCount() do + local mobileSession = commonDefect.getMobileSession(self, id) + mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :Do(function(_, d2) + print("App ".. id .. " was used for PTU") + RAISE_EVENT(event, event, "PTU event") + local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", + { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, d3) + self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", + { policyfile = policy_file_path .. "/" .. policy_file_name }) + end) + mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + :Do(function() os.remove(ptu_file_name) end) + end) + :Times(AtMost(1)) + end + end) +end + +--[[ @getDeviceName: provides device name +--! @parameters: none +--! @return: device name +--]] +function commonDefect.getDeviceName() + return config.mobileHost .. ":" .. config.mobilePort +end + +--[[ @getDeviceMAC: provides device MAC address +--! @parameters: none +--! @return: device MAC address +--]] +function commonDefect.getDeviceMAC() + local cmd = "echo -n " .. commonDefect.getDeviceName() .. " | sha256sum | awk '{printf $1}'" + local handle = io.popen(cmd) + local result = handle:read("*a") + handle:close() + return result +end + +--[[ @allow_sdl: sequence that allows SDL functionality +--! @parameters: +--! self - test object +--! @return: none +--]] +function commonDefect.allow_sdl(self) + -- sending notification OnAllowSDLFunctionality from HMI to allow connected device + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { + allowed = true, + source = "GUI", + device = { + id = commonDefect.getDeviceMAC(), + name = commonDefect.getDeviceName() + } + }) +end + +--[[ @preconditions: precondition steps +--! @parameters: none +--! @return: none +--]] +function commonDefect.preconditions() + commonFunctions:SDLForceStop() + commonSteps:DeletePolicyTable() + commonSteps:DeleteLogsFiles() +end + +--[[ @start: starting sequence: starting of SDL, initialization of HMI, connect mobile +--! @parameters: +--! self - test object +--! @return: none +--]] +function commonDefect.start(self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady() + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + self:connectMobile() + :Do(function() + commonFunctions:userPrint(35, "Mobile connected") + commonDefect.allow_sdl(self) + end) + end) + end) + end) +end + +--[[ @startWithoutMobile: starting sequence: starting of SDL, initialization of HMI +--! @parameters: +--! self - test object +--! @return: none +--]] +function commonDefect.startWithoutMobile(pHMIParams, self) + self, pHMIParams = commonDefect.getSelfAndParams(pHMIParams, self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady(pHMIParams) + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + end) + end) + end) +end + +--[[ @postconditions: postcondition steps +--! @parameters: none +--! @return: none +--]] +function commonDefect.postconditions() + StopSDL() +end + +--[[ @printSDLConfig: print information about SDL build options +--! @parameters: none +--! @return: none +--]] +function commonDefect.printSDLConfig() + commonFunctions:printTable(sdl.buildOptions) +end + +--[[ @ignitionOff: IGNITION_OFF sequence +--! @parameters: +--! self - test object +--! @return: none +--]] +function commonDefect.ignitionOff(self) + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete") + :Do(function() + sdl:DeleteFile() + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) + self.mobileSession1:ExpectNotification("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + :Do(function() + sdl:StopSDL() + end) + end) +end + +--[[ @backupINIFile: backup SDL .ini file +--! @parameters: none +--! @return: none +--]] +function commonDefect.backupINIFile() + commonPreconditions:BackupFile("smartDeviceLink.ini") +end + +--[[ @restoreINIFile: restore SDL .ini file to an initial state +--! @parameters: none +--! @return: none +--]] +function commonDefect.restoreINIFile() + commonPreconditions:RestoreFile("smartDeviceLink.ini") +end + +--[[ @rai_ptu: register mobile application and perform PTU sequence for 1st application +--! @parameters: +--! ptu_update_func - additional function for update +--! self - test object +--! @return: none +--]] +function commonDefect.rai_ptu(ptu_update_func, self) + self, ptu_update_func = commonDefect.getSelfAndParams(ptu_update_func, self) + commonDefect.rai_ptu_n(1, ptu_update_func, self) +end + +--[[ @rai_ptu_n: register mobile application and perform PTU sequence for N application +--! @parameters: +--! id - application number (1, 2, etc.) +--! ptu_update_func - additional function for update +--! self - test object +--! @return: none +--]] +function commonDefect.rai_ptu_n(id, ptu_update_func, self) + self, id, ptu_update_func = commonDefect.getSelfAndParams(id, ptu_update_func, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC + ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :DoOnce(function(_, d2) + self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptu_table = jsonFileToTable(d2.params.file) + ptu(self, ptu_update_func) + end) + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + :Times(AtLeast(1)) + EXPECT_HMICALL("VehicleInfo.GetVehicleData", { odometer = true }) + end) + end) +end + +--[[ @rai_ptu_n_without_OnPermissionsChange: register mobile application and perform PTU sequence for N application +--! 'OnPermissionsChange' notification is excluded from expectations +--! @parameters: +--! id - application number (1, 2, etc.) +--! ptu_update_func - additional function for update +--! self - test object +--! @return: none +--]] +function commonDefect.rai_ptu_n_without_OnPermissionsChange(id, ptu_update_func, self) + self, id, ptu_update_func = commonDefect.getSelfAndParams(id, ptu_update_func, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC + ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :DoOnce(function(_, d2) + self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptu_table = jsonFileToTable(d2.params.file) + ptu(self, ptu_update_func) + end) + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) + EXPECT_HMICALL("VehicleInfo.GetVehicleData", { odometer = true }) + end) + end) +end + +--[[ @UnsuccessPTU: perform PTU sequence with failed result +--! @parameters: +--! ptu_update_func - additional function for update +--! self - test object +--! @return: none +--]] +function commonDefect.unsuccessfulPTU(ptu_update_func, self) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(2) + ptu(self, ptu_update_func) +end + +--[[ @rai_n: register N mobile application without PTU sequence +--! @parameters: +--! id - application number (1, 2, etc.) +--! self - test object +--! @return: none +--]] +function commonDefect.rai_n(id, self) + self, id = commonDefect.getSelfAndParams(id, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC + ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + end) + end) +end + +--[[ @delayedExp: delay test step for defined timeout +--! @parameters: +--! timeout - time of delay in milliseconds +--! @return: none +--]] +function commonDefect.delayedExp(timeout) + if not timeout then timeout = commonDefect.timeout end + commonTestCases:DelayedExp(timeout) +end + +--[[ @unregisterApp: unregister application +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! self - test object +--! @return: none +--]] +function commonDefect.unregisterApp(pAppId, self) + self, pAppId = commonDefect.getSelfAndParams(pAppId, self) + if not pAppId then pAppId = 1 end + local mobSession = commonDefect.getMobileSession(self, pAppId) + local hmiAppId = commonDefect.getHMIAppId(pAppId) + local cid = mobSession:SendRPC("UnregisterAppInterface",{}) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = hmiAppId, unexpectedDisconnect = false }) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +--[[ @activate_app: activate application +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! self - test object +--! @return: none +--]] +function commonDefect.activate_app(pAppId, self) + self, pAppId = commonDefect.getSelfAndParams(pAppId, self) + if not pAppId then pAppId = 1 end + local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + local mobSession = commonDefect.getMobileSession(self, pAppId) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + EXPECT_HMIRESPONSE(requestId) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + commonTestCases:DelayedExp(commonDefect.minTimeout) +end + +--[[ @putFile: perform PutFile sequence +--! @parameters: +--! pFileName - name of the file +--! self - test object +--! @return: none +--]] +function commonDefect.putFile(pFileName, self) + self, pFileName = commonDefect.getSelfAndParams(pFileName, self) + local cid = self.mobileSession1:SendRPC( + "PutFile", + {syncFileName = pFileName, fileType = "GRAPHIC_PNG", persistentFile = false, systemFile = false}, + "files/icon.png") + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +--[[ @getSelfAndParams: shifting parameters in order to move self at 1st position +--! @parameters: +--! ... - various parameters and self +--! @return: test object and other parameters +--]] +function commonDefect.getSelfAndParams(...) + local out = { } + local selfIdx = nil + for i,v in pairs({...}) do + if type(v) == "table" and v.isTest then + table.insert(out, v) + selfIdx = i + break + end + end + local idx = 2 + for i = 1, table.maxn({...}) do + if i ~= selfIdx then + out[idx] = ({...})[i] + idx = idx + 1 + end + end + return table.unpack(out, 1, table.maxn(out)) +end + +--[[ @getHMIAppId: get HMI application identifier +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: application identifier +--]] +function commonDefect.getHMIAppId(pAppId) + if not pAppId then pAppId = 1 end + return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] +end + +--[[ @getMobileSession: get mobile session +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! self - test object +--! @return: mobile session +--]] +function commonDefect.getMobileSession(self, pAppId) + if not pAppId then pAppId = 1 end + return self["mobileSession" .. pAppId] +end + +return commonDefect From 602ae9cb0ba195f9b1dac5d79f8621ad2ccef372 Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Fri, 4 May 2018 17:05:14 -0400 Subject: [PATCH 373/681] Genericize tests so that new params can be added --- .../GetVehicleData/001_Success_flow.lua | 11 +++++- ..._parameter_DISALLOWED_by_policies_flow.lua | 6 ++- .../OnVehicleData/001_Success_flow.lua | 17 ++++++-- ...onForUnsubsribedParameter_Ignored_flow.lua | 27 +++++++++---- ...meterDisallowedByPolicies_Ignored_flow.lua | 19 ++++++--- .../SubscribeVehicleData/001_Success_flow.lua | 15 +++++-- ..._parameter_DISALLOWED_by_policies_flow.lua | 20 +++++++--- ...already_subscribed_Result_IGNORED_flow.lua | 35 ++++++++++++----- .../001_Success_flow.lua | 23 ++++++++--- ...ameter_not_yet_subscribed_IGNORED_flow.lua | 20 +++++++--- ...ready_unsubscribed_Result_IGNORED_flow.lua | 39 ++++++++++++++----- ...wed_by_policies_Result_DISALLOWED_flow.lua | 20 +++++++--- 12 files changed, 186 insertions(+), 66 deletions(-) diff --git a/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua index 65ab5fd84d..986d993a57 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua @@ -27,15 +27,22 @@ local rpc = { } } +local vehicleDataValues { + engineOilLife = 50.30 +} + --[[ Local Functions ]] local function processRPCSuccess(self) local mobileSession = common.getMobileSession(self, 1) local cid = mobileSession:SendRPC(rpc.name, rpc.params) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { engineOilLife = 50.30 } ) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", vehicleDataValues ) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = 50.30 } ) + local responseParams = vehicleDataValues + responseParams.success = true + responseParams.resultCode = "SUCCESS" + mobileSession:ExpectResponse(cid, responseParams) end --[[ Scenario ]] diff --git a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index 9439671d11..12cab43be1 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -28,6 +28,10 @@ local rpc = { } } +local vehicleDataValues { + engineOilLife = 52.3 +} + --[[ Local Functions ]] local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["GetVehicleData"].parameters @@ -41,7 +45,7 @@ local function processRPCSuccess(self) local cid = mobileSession:SendRPC(rpc.name, rpc.params) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { engineOilLife = 52.3 }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", vehicleDataValues) end) mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end diff --git a/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua index 80d3094609..ad360ae051 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua @@ -34,17 +34,26 @@ local rpc2 = { } } +local vehicleDataResults = { + engineOilLife = { + dataType = "VEHICLEDATA_ENGINEOILLIFE", + resultCode = "SUCCESS" + } +} + --[[ Local Functions ]] local function processRPCSubscribeSuccess(self) local mobileSession = common.getMobileSession(self, 1) local cid = mobileSession:SendRPC(rpc1.name, rpc1.params) EXPECT_HMICALL("VehicleInfo." .. rpc1.name, rpc1.params) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", - {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", vehicleDataResults) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = - {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) + + local responseParams = vehicleDataResults + responseParams.success = true + responseParams.resultCode = "SUCCESS" + mobileSession:ExpectResponse(cid, responseParams) end local function checkNotificationSuccess(self) diff --git a/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua index ad456cf168..74f1bc33b6 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua @@ -43,6 +43,13 @@ local rpc3 = { } } +local vehicleDataResults = { + engineOilLife = { + dataType = "VEHICLEDATA_ENGINEOILLIFE", + resultCode = "SUCCESS" + } +} + --[[ Local Functions ]] local function processRPCSubscribeSuccess(self) local mobileSession = common.getMobileSession(self, 1) @@ -50,10 +57,12 @@ local function processRPCSubscribeSuccess(self) EXPECT_HMICALL("VehicleInfo." .. rpc1.name, rpc1.params) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", - {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) - end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) + vehicleDataResults}) + end) + local responseParams = vehicleDataResults + responseParams.success = true + responseParams.resultCode = "SUCCESS" + mobileSession:ExpectResponse(cid, responseParams) end local function processRPCUnsubscribeSuccess(self) @@ -62,10 +71,12 @@ local function processRPCUnsubscribeSuccess(self) EXPECT_HMICALL("VehicleInfo." .. rpc3.name, rpc3.params) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", - {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) - end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) + vehicleDataResults) + end) + local responseParams = vehicleDataResults + responseParams.success = true + responseParams.resultCode = "SUCCESS" + mobileSession:ExpectResponse(cid, responseParams) end local function checkNotificationSuccess(self) diff --git a/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua index c71a005c96..43e5fb785e 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua @@ -36,6 +36,13 @@ local rpc2 = { } } +local vehicleDataResults = { + engineOilLife = { + dataType = "VEHICLEDATA_ENGINEOILLIFE", + resultCode = "SUCCESS" + } +} + --[[ Local Functions ]] local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["OnVehicleData"].parameters @@ -49,11 +56,13 @@ local function processRPCSubscribeSuccess(self) local cid = mobileSession:SendRPC(rpc1.name, rpc1.params) EXPECT_HMICALL("VehicleInfo." .. rpc1.name, rpc1.params) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", - {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) - end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", engineOilLife = - {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + vehicleDataResults) + end) + local responseParams = vehicleDataResults + responseParams.success = true + responseParams.resultCode = "SUCCESS" + mobileSession:ExpectResponse(cid, responseParams) end local function checkNotificationIgnored(self) diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua index 7ecf79478b..068371830d 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua @@ -26,6 +26,13 @@ local rpc = { } } +local vehicleDataResults = { + engineOilLife = { + dataType = "VEHICLEDATA_ENGINEOILLIFE", + resultCode = "SUCCESS" + } +} + --[[ Local Functions ]] local function processRPCSuccess(self) local mobileSession = common.getMobileSession(self, 1) @@ -33,10 +40,12 @@ local function processRPCSuccess(self) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", - {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + vehicleDataResults) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) + local responseParams = vehicleDataResults + responseParams.success = true + responseParams.resultCode = "SUCCESS" + mobileSession:ExpectResponse(cid, responseParams) end --[[ Scenario ]] diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index 9fced65100..40d8e80542 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -21,10 +21,17 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ Local Variables ]] local rpc = { - name = "SubscribeVehicleData", - params = { + name = "SubscribeVehicleData", + params = { engineOilLife = true - } + } +} + +local vehicleDataResults = { + engineOilLife = { + dataType = "VEHICLEDATA_ENGINEOILLIFE", + resultCode = "DISALLOWED" + } } --[[ Local Functions ]] @@ -40,9 +47,10 @@ local function processRPCFailure(self) local cid = mobileSession:SendRPC(rpc.name, rpc.params) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params):Times(0) commonTestCases:DelayedExp(common.timeout) - mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED", - info = "'engineOilLife' parameter is disallowed by Policies", - engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DISALLOWED"} }) + local responseParams = vehicleDataResults + responseParams.success = false + responseParams.resultCode = "DISALLOWED" + mobileSession:ExpectResponse(cid, responseParams) end --[[ Scenario ]] diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua index d90bb4c3eb..dc6372c939 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua @@ -20,10 +20,24 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ Local Variables ]] local rpc = { - name = "SubscribeVehicleData", - params = { + name = "SubscribeVehicleData", + params = { engineOilLife = true - } + } +} + +local vehicleDataResults = { + engineOilLife = { + dataType = "VEHICLEDATA_ENGINEOILLIFE", + resultCode = "SUCCESS" + } +} + +local vehicleDataResults2 = { + engineOilLife = { + dataType = "VEHICLEDATA_ENGINEOILLIFE", + resultCode = "DATA_ALREADY_SUBSCRIBED" + } } --[[ Local Functions ]] @@ -33,10 +47,12 @@ local function processRPCSuccess(self) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", - {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + vehicleDataResults) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) + local responseParams = vehicleDataResults + responseParams.success = true + responseParams.resultCode = "SUCCESS" + mobileSession:ExpectResponse(cid, responseParams) end local function processRPCIgnored(self) @@ -44,9 +60,10 @@ local function processRPCIgnored(self) local cid = mobileSession:SendRPC(rpc.name, rpc.params) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params):Times(0) commonTestCases:DelayedExp(common.timeout) - mobileSession:ExpectResponse(cid, { success = false, resultCode = "IGNORED", - info = "Already subscribed on some provided VehicleData.", - engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DATA_ALREADY_SUBSCRIBED"} }) + local responseParams = vehicleDataResults2 + responseParams.success = false + responseParams.resultCode = "IGNORED" + mobileSession:ExpectResponse(cid, responseParams) end --[[ Scenario ]] diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua index 365c365369..1c7e5ba390 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua @@ -34,6 +34,13 @@ local rpc_unsubscribe = { } } +local vehicleDataResults = { + engineOilLife = { + dataType = "VEHICLEDATA_ENGINEOILLIFE", + resultCode = "SUCCESS" + } +} + --[[ Local Functions ]] local function processRPCSubscribeSuccess(self) local mobileSession = common.getMobileSession(self, 1) @@ -41,10 +48,12 @@ local function processRPCSubscribeSuccess(self) EXPECT_HMICALL("VehicleInfo." .. rpc_subscribe.name, rpc_subscribe.params) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", - {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + vehicleDataResults) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) + local responseParams = vehicleDataResults + responseParams.success = true + responseParams.resultCode = "SUCCESS" + mobileSession:ExpectResponse(cid, responseParams) end local function processRPCUnsubscribeSuccess(self) @@ -53,10 +62,12 @@ local function processRPCUnsubscribeSuccess(self) EXPECT_HMICALL("VehicleInfo." .. rpc_unsubscribe.name, rpc_unsubscribe.params) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", - {engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"}}) + vehicleDataResults) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) + local responseParams = vehicleDataResults + responseParams.success = true + responseParams.resultCode = "SUCCESS" + mobileSession:ExpectResponse(cid, responseParams) end --[[ Scenario ]] diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua index 1503a5a9c9..81c2e1f05a 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua @@ -22,10 +22,17 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ Local Variables ]] local rpc = { - name = "UnsubscribeVehicleData", - params = { + name = "UnsubscribeVehicleData", + params = { engineOilLife = true - } + } +} + +local vehicleDataResults = { + engineOilLife = { + dataType = "VEHICLEDATA_ENGINEOILLIFE", + resultCode = "DATA_NOT_SUBSCRIBED" + } } --[[ Local Functions ]] @@ -34,9 +41,10 @@ local function processRPCFailure(self) local cid = mobileSession:SendRPC(rpc.name, rpc.params) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params):Times(0) commonTestCases:DelayedExp(common.timeout) - mobileSession:ExpectResponse(cid, { success = false, resultCode = "IGNORED", - info = "Some provided VehicleData was not subscribed.", - engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DATA_NOT_SUBSCRIBED"} }) + local responseParams = vehicleDataResults + responseParams.success = false + responseParams.resultCode = "IGNORED" + mobileSession:ExpectResponse(cid, responseParams) end --[[ Scenario ]] diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua index a21444b40c..ceaa7d7edf 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua @@ -12,7 +12,7 @@ -- 1) Mobile application sends valid UnsubscribeVehicleData to SDL and this request is allowed by Policies -- 2) Mobile app is already unsubscribed from this parameter -- SDL must: --- Respond IGNORED, success:false {dataType = "VEHICLEDATA_ENGINEOILLIFE", +-- Respond IGNORED, success:false {dataType = "VEHICLEDATA_engin eOilLife", -- resultCode = "DATA_NOT_SUBSCRIBED"} to mobile application --------------------------------------------------------------------------------------------------- @@ -36,6 +36,20 @@ local rpc_unsubscribe = { } } +local vehicleDataResults = { + engineOilLife = { + dataType = "VEHICLEDATA_ENGINEOILLIFE", + resultCode = "SUCCESS" + } +} + +local vehicleDataResults2 = { + engineOilLife = { + dataType = "VEHICLEDATA_ENGINEOILLIFE", + resultCode = "DATA_NOT_SUBSCRIBED" + } +} + --[[ Local Functions ]] local function processRPCSubscribeSuccess(self) local mobileSession = common.getMobileSession(self, 1) @@ -43,10 +57,12 @@ local function processRPCSubscribeSuccess(self) EXPECT_HMICALL("VehicleInfo." .. rpc_subscribe.name, rpc_subscribe.params) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", - { engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS" } }) + vehicleDataResults) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS" } }) + local responseParams = vehicleDataResults + responseParams.success = true + responseParams.resultCode = "SUCCESS" + mobileSession:ExpectResponse(cid, responseParams) end local function processRPCUnsubscribeSuccess(self) @@ -55,10 +71,12 @@ local function processRPCUnsubscribeSuccess(self) EXPECT_HMICALL("VehicleInfo." .. rpc_unsubscribe.name, rpc_unsubscribe.params) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", - { engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS" } }) + vehicleDataResults) end) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS"} }) + local responseParams = vehicleDataResults + responseParams.success = true + responseParams.resultCode = "SUCCESS" + mobileSession:ExpectResponse(cid, responseParams) end local function processRPCUnsubscribeIgnored(self) @@ -66,9 +84,10 @@ local function processRPCUnsubscribeIgnored(self) local cid = mobileSession:SendRPC(rpc_unsubscribe.name, rpc_unsubscribe.params) EXPECT_HMICALL("VehicleInfo." .. rpc_unsubscribe.name, rpc_unsubscribe.params):Times(0) commonTestCases:DelayedExp(common.timeout) - mobileSession:ExpectResponse(cid, { success = false, resultCode = "IGNORED", - engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", - resultCode = "DATA_NOT_SUBSCRIBED"} }) + local responseParams = vehicleDataResults2 + responseParams.success = false + responseParams.resultCode = "IGNORED" + mobileSession:ExpectResponse(cid, responseParams) end --[[ Scenario ]] diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua index f18964f3ce..5a7cfdff7f 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua @@ -21,10 +21,17 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ Local Variables ]] local rpc = { - name = "UnsubscribeVehicleData", - params = { + name = "UnsubscribeVehicleData", + params = { engineOilLife = true - } + } +} + +local vehicleDataResults = { + engineOilLife = { + dataType = "VEHICLEDATA_ENGINEOILLIFE", + resultCode = "DISALLOWED" + } } --[[ Local Functions ]] @@ -40,9 +47,10 @@ local function processRPCFailure(self) local cid = mobileSession:SendRPC(rpc.name, rpc.params) EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params):Times(0) commonTestCases:DelayedExp(common.timeout) - mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED", - info = "'engineOilLife' parameter is disallowed by Policies", - engineOilLife = {dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DISALLOWED"} }) + local responseParams = vehicleDataResults + responseParams.success = false + responseParams.resultCode = "DISALLOWED" + mobileSession:ExpectResponse(cid, responseParams) end --[[ Scenario ]] From b89f6b07ec6fe00e4d5899b03cb1c0f5e89804a0 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Mon, 7 May 2018 14:59:08 +0300 Subject: [PATCH 374/681] Script for issue 959 --- .../4_6/959_resumption_limited_non_media.lua | 74 +++ test_scripts/Defects/commonDefects.lua | 554 ++++++++++++++++++ 2 files changed, 628 insertions(+) create mode 100644 test_scripts/Defects/4_6/959_resumption_limited_non_media.lua create mode 100644 test_scripts/Defects/commonDefects.lua diff --git a/test_scripts/Defects/4_6/959_resumption_limited_non_media.lua b/test_scripts/Defects/4_6/959_resumption_limited_non_media.lua new file mode 100644 index 0000000000..e4189c28a6 --- /dev/null +++ b/test_scripts/Defects/4_6/959_resumption_limited_non_media.lua @@ -0,0 +1,74 @@ +--------------------------------------------------------------------------------------------- +-- GitHub issue: https://github.com/smartdevicelink/sdl_core/issues/959 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonDefects = require('test_scripts/Defects/commonDefects') +local actions = require("user_modules/sequences/actions") +local test = require("user_modules/dummy_connecttest") +local mobile_session = require("mobile_session") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +config.application1.registerAppInterfaceParams.isMediaApplication = false +config.application1.registerAppInterfaceParams.appHMIType = {"COMMUNICATION"} + +--[[ Local Function ]] +local function onEventChange(pStatus) + actions.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", + { isActive = pStatus, eventName = "AUDIO_SOURCE" }) +end + +local function reconnect(pAppId) + if not pAppId then pAppId = 1 end + test.mobileSession[pAppId]:Stop() + actions.getHMIConnection():ExpectNotification("BasicCommunication.OnAppUnregistered", + {appID = actions.getHMIAppId(pAppId), unexpectedDisconnect = true}) + :Do(function() + test.mobileSession[pAppId] = mobile_session.MobileSession( + test, + test.mobileConnection, + config["application" .. pAppId].registerAppInterfaceParams) + test.mobileConnection:Connect() + end) +end + +local function registrationWithResumption() + local mobSession = actions.getMobileSession(1) + mobSession:StartService(7) + :Do(function() + local params = actions.getConfigAppParams(1) + params.hashID = commonDefects.hashId + local corId = mobSession:SendRPC("RegisterAppInterface", actions.getConfigAppParams(1)) + actions.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", + { application = { appName = actions.getConfigAppParams(1).appName } }) + mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + actions.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, + { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + end) +end + +local function fullLevel() + onEventChange(false) + actions.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonDefects.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", actions.start) +runner.Step("RAI, PTU", actions.registerApp) +runner.Step("Activate app", actions.activateApp) + +runner.Title("Test") +runner.Step("Reconnect", reconnect) +runner.Step("onEventChange AUDIO_SOURCE true", onEventChange, { true }) +runner.Step("App resumption in limited", registrationWithResumption) +runner.Step("App resumption in full after event is false", fullLevel) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonDefects.postconditions) diff --git a/test_scripts/Defects/commonDefects.lua b/test_scripts/Defects/commonDefects.lua new file mode 100644 index 0000000000..1757cdb285 --- /dev/null +++ b/test_scripts/Defects/commonDefects.lua @@ -0,0 +1,554 @@ +--------------------------------------------------------------------------------------------------- +-- RC common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +-- define MAC address mobile device +config.mobileHost = "127.0.0.1" +-- define 2nd version of SDL protocol by default +config.defaultProtocolVersion = 2 +-- switch off schema validation for output messages against APIs +config.ValidateSchema = false + +--[[ Required Shared libraries ]] +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +local sdl = require("SDL") +local mobile_session = require("mobile_session") +local events = require("events") +local json = require("modules/json") +local actions = require("user_modules/sequences/actions") +local test = require("user_modules/dummy_connecttest") + +--[[ Local Variables ]] + +-- table with data for Policy Table Update +local ptu_table = {} +-- table with HMI application identifiers +local hmiAppIds = {} +-- table for module +local commonDefect = {} + +--[[ Module Constants ]] + +-- default timeout +commonDefect.timeout = 2000 +-- minimal timeout +commonDefect.minTimeout = 500 + +--[[ @getPTUFromPTS: create policy table update table (PTU) +--! @parameters: +--! tbl - table with policy table snapshot (PTS) +--! @return: table with PTU +--]] +local function getPTUFromPTS(tbl) + tbl.policy_table.consumer_friendly_messages.messages = nil + tbl.policy_table.device_data = nil + tbl.policy_table.module_meta = nil + tbl.policy_table.usage_and_error_counts = nil + tbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + tbl.policy_table.module_config.preloaded_pt = nil + tbl.policy_table.module_config.preloaded_date = nil +end + +--[[ @DefaultStruct: provide default values for application required in PTU +--! @parameters: none +--! @return: table with data +--]] +function commonDefect.DefaultStruct() + return { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + groups = { "Base-4"}, + } +end + +--[[ @updatePTU: update PTU with application data +--! @parameters: +--! tbl - table with data for policy table update +--! @return: none +--]] +local function updatePTU(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonDefect.DefaultStruct() +end + +--[[ @jsonFileToTable: convert .json file to table +--! @parameters: +--! file_name - file name +--! @return: table +--]] +local function jsonFileToTable(file_name) + local f = io.open(file_name, "r") + local content = f:read("*all") + f:close() + return json.decode(content) +end + +--[[ @tableToJsonFile: convert table to .json file +--! @parameters: +--! tbl - table +--! file_name - file name +--! @return: none +--]] +local function tableToJsonFile(tbl, file_name) + local f = io.open(file_name, "w") + f:write(json.encode(tbl)) + f:close() +end + +--[[ @ptu: perform policy table update +--! @parameters: +--! self - test object +--! ptu_update_func - additional function for update +--! @return: none +--]] +local function ptu(self, ptu_update_func) + local function getAppsCount() + local count = 0 + for _, _ in pairs(hmiAppIds) do + count = count + 1 + end + return count + end + + local policy_file_name = "PolicyTableUpdate" + local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + local ptu_file_name = os.tmpname() + local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) + EXPECT_HMIRESPONSE(requestId) + :Do(function() + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + { requestType = "PROPRIETARY", fileName = pts_file_name }) + getPTUFromPTS(ptu_table) + updatePTU(ptu_table) + if ptu_update_func then + ptu_update_func(ptu_table) + end + tableToJsonFile(ptu_table, ptu_file_name) + + local event = events.Event() + event.matches = function(e1, e2) return e1 == e2 end + EXPECT_EVENT(event, "PTU event") + :Timeout(11000) + + for id = 1, getAppsCount() do + local mobileSession = commonDefect.getMobileSession(self, id) + mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :Do(function(_, d2) + print("App ".. id .. " was used for PTU") + RAISE_EVENT(event, event, "PTU event") + local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", + { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, d3) + self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", + { policyfile = policy_file_path .. "/" .. policy_file_name }) + end) + mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + :Do(function() os.remove(ptu_file_name) end) + end) + :Times(AtMost(1)) + end + end) +end + +--[[ @getDeviceName: provides device name +--! @parameters: none +--! @return: device name +--]] +function commonDefect.getDeviceName() + return config.mobileHost .. ":" .. config.mobilePort +end + +--[[ @getDeviceMAC: provides device MAC address +--! @parameters: none +--! @return: device MAC address +--]] +function commonDefect.getDeviceMAC() + local cmd = "echo -n " .. commonDefect.getDeviceName() .. " | sha256sum | awk '{printf $1}'" + local handle = io.popen(cmd) + local result = handle:read("*a") + handle:close() + return result +end + +--[[ @allow_sdl: sequence that allows SDL functionality +--! @parameters: +--! self - test object +--! @return: none +--]] +function commonDefect.allow_sdl(self) + -- sending notification OnAllowSDLFunctionality from HMI to allow connected device + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { + allowed = true, + source = "GUI", + device = { + id = commonDefect.getDeviceMAC(), + name = commonDefect.getDeviceName() + } + }) +end + +--[[ @preconditions: precondition steps +--! @parameters: none +--! @return: none +--]] +function commonDefect.preconditions() + commonFunctions:SDLForceStop() + commonSteps:DeletePolicyTable() + commonSteps:DeleteLogsFiles() +end + +--[[ @start: starting sequence: starting of SDL, initialization of HMI, connect mobile +--! @parameters: +--! self - test object +--! @return: none +--]] +function commonDefect.start(self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady() + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + self:connectMobile() + :Do(function() + commonFunctions:userPrint(35, "Mobile connected") + commonDefect.allow_sdl(self) + end) + end) + end) + end) +end + +--[[ @startWithoutMobile: starting sequence: starting of SDL, initialization of HMI +--! @parameters: +--! self - test object +--! @return: none +--]] +function commonDefect.startWithoutMobile(pHMIParams, self) + self, pHMIParams = commonDefect.getSelfAndParams(pHMIParams, self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady(pHMIParams) + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + end) + end) + end) +end + +--[[ @postconditions: postcondition steps +--! @parameters: none +--! @return: none +--]] +function commonDefect.postconditions() + StopSDL() +end + +--[[ @printSDLConfig: print information about SDL build options +--! @parameters: none +--! @return: none +--]] +function commonDefect.printSDLConfig() + commonFunctions:printTable(sdl.buildOptions) +end + +--[[ @ignitionOff: IGNITION_OFF sequence +--! @parameters: +--! self - test object +--! @return: none +--]] +function commonDefect.ignitionOff(self) + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete") + :Do(function() + sdl:DeleteFile() + self.hmiConnection:SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) + self.mobileSession1:ExpectNotification("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + :Do(function() + sdl:StopSDL() + end) + end) +end + +--[[ @backupINIFile: backup SDL .ini file +--! @parameters: none +--! @return: none +--]] +function commonDefect.backupINIFile() + commonPreconditions:BackupFile("smartDeviceLink.ini") +end + +--[[ @restoreINIFile: restore SDL .ini file to an initial state +--! @parameters: none +--! @return: none +--]] +function commonDefect.restoreINIFile() + commonPreconditions:RestoreFile("smartDeviceLink.ini") +end + +--[[ @rai_ptu: register mobile application and perform PTU sequence for 1st application +--! @parameters: +--! ptu_update_func - additional function for update +--! self - test object +--! @return: none +--]] +function commonDefect.rai_ptu(ptu_update_func, self) + self, ptu_update_func = commonDefect.getSelfAndParams(ptu_update_func, self) + commonDefect.rai_ptu_n(1, ptu_update_func, self) +end + +--[[ @rai_ptu_n: register mobile application and perform PTU sequence for N application +--! @parameters: +--! id - application number (1, 2, etc.) +--! ptu_update_func - additional function for update +--! self - test object +--! @return: none +--]] +function commonDefect.rai_ptu_n(id, ptu_update_func, self) + self, id, ptu_update_func = commonDefect.getSelfAndParams(id, ptu_update_func, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC + ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :DoOnce(function(_, d2) + self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptu_table = jsonFileToTable(d2.params.file) + ptu(self, ptu_update_func) + end) + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + :Times(AtLeast(1)) + EXPECT_HMICALL("VehicleInfo.GetVehicleData", { odometer = true }) + end) + end) +end + +--[[ @rai_ptu_n_without_OnPermissionsChange: register mobile application and perform PTU sequence for N application +--! 'OnPermissionsChange' notification is excluded from expectations +--! @parameters: +--! id - application number (1, 2, etc.) +--! ptu_update_func - additional function for update +--! self - test object +--! @return: none +--]] +function commonDefect.rai_ptu_n_without_OnPermissionsChange(id, ptu_update_func, self) + self, id, ptu_update_func = commonDefect.getSelfAndParams(id, ptu_update_func, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC + ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :DoOnce(function(_, d2) + self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptu_table = jsonFileToTable(d2.params.file) + ptu(self, ptu_update_func) + end) + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) + EXPECT_HMICALL("VehicleInfo.GetVehicleData", { odometer = true }) + end) + end) +end + +--[[ @UnsuccessPTU: perform PTU sequence with failed result +--! @parameters: +--! ptu_update_func - additional function for update +--! self - test object +--! @return: none +--]] +function commonDefect.unsuccessfulPTU(ptu_update_func, self) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + :Times(2) + ptu(self, ptu_update_func) +end + +--[[ @rai_n: register N mobile application without PTU sequence +--! @parameters: +--! id - application number (1, 2, etc.) +--! self - test object +--! @return: none +--]] +function commonDefect.rai_n(id, self) + self, id = commonDefect.getSelfAndParams(id, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC + ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + end) + end) +end + +--[[ @delayedExp: delay test step for defined timeout +--! @parameters: +--! timeout - time of delay in milliseconds +--! @return: none +--]] +function commonDefect.delayedExp(timeout) + if not timeout then timeout = commonDefect.timeout end + commonTestCases:DelayedExp(timeout) +end + +--[[ @unregisterApp: unregister application +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! self - test object +--! @return: none +--]] +function commonDefect.unregisterApp(pAppId, self) + self, pAppId = commonDefect.getSelfAndParams(pAppId, self) + if not pAppId then pAppId = 1 end + local mobSession = commonDefect.getMobileSession(self, pAppId) + local hmiAppId = commonDefect.getHMIAppId(pAppId) + local cid = mobSession:SendRPC("UnregisterAppInterface",{}) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = hmiAppId, unexpectedDisconnect = false }) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +--[[ @activate_app: activate application +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! self - test object +--! @return: none +--]] +function commonDefect.activate_app(pAppId, self) + self, pAppId = commonDefect.getSelfAndParams(pAppId, self) + if not pAppId then pAppId = 1 end + local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + local mobSession = commonDefect.getMobileSession(self, pAppId) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + EXPECT_HMIRESPONSE(requestId) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + commonTestCases:DelayedExp(commonDefect.minTimeout) +end + +--[[ @putFile: perform PutFile sequence +--! @parameters: +--! pFileName - name of the file +--! self - test object +--! @return: none +--]] +function commonDefect.putFile(pFileName, self) + self, pFileName = commonDefect.getSelfAndParams(pFileName, self) + local cid = self.mobileSession1:SendRPC( + "PutFile", + {syncFileName = pFileName, fileType = "GRAPHIC_PNG", persistentFile = false, systemFile = false}, + "files/icon.png") + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +--[[ @getSelfAndParams: shifting parameters in order to move self at 1st position +--! @parameters: +--! ... - various parameters and self +--! @return: test object and other parameters +--]] +function commonDefect.getSelfAndParams(...) + local out = { } + local selfIdx = nil + for i,v in pairs({...}) do + if type(v) == "table" and v.isTest then + table.insert(out, v) + selfIdx = i + break + end + end + local idx = 2 + for i = 1, table.maxn({...}) do + if i ~= selfIdx then + out[idx] = ({...})[i] + idx = idx + 1 + end + end + return table.unpack(out, 1, table.maxn(out)) +end + +--[[ @getHMIAppId: get HMI application identifier +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: application identifier +--]] +function commonDefect.getHMIAppId(pAppId) + if not pAppId then pAppId = 1 end + return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] +end + +--[[ @getMobileSession: get mobile session +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! self - test object +--! @return: mobile session +--]] +function commonDefect.getMobileSession(self, pAppId) + if not pAppId then pAppId = 1 end + return self["mobileSession" .. pAppId] +end + +function commonDefect.pinOnHashChange(pAppId) + if not pAppId then pAppId = 1 end + actions.getMobileSession(pAppId):ExpectNotification("OnHashChange") + :Pin() + :Times(AnyNumber()) + :Do(function(_, data) + commonDefect.hashId = data.payload.hashID + end) +end + +return commonDefect From 055cb97c6cddf622a4d4e1059cf96ebc83af5d42 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 8 May 2018 16:55:59 +0300 Subject: [PATCH 375/681] Remove check on SDL.OnStatusUpdate notification for compatibility with EXTERNAL_PROPRIETARY flow --- .../Expanded_proprietary_data_exchange/commonDataExchange.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua b/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua index 1d42bafe20..1bacea67b6 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua @@ -92,7 +92,6 @@ function m.policyTableUpdate(pPTUpdateFunc, pExpNotificationFunc, pRequestSubTyp if pExpNotificationFunc then pExpNotificationFunc() else - m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", { status = "UP_TO_DATE" }) m.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) end local ptsFileName = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" @@ -152,9 +151,6 @@ function m.registerApp(pAppId) } }) :Do(function() - m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) - :Times(2) m.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") :Do(function(_, d2) m.getHMIConnection():SendResponse(d2.id, d2.method, "SUCCESS", { }) From 3ba6635aa1ede7c901756c956e5fc430256b7745 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 9 May 2018 15:54:44 +0300 Subject: [PATCH 376/681] Initial version of scripts for Audio File Playback to TTSChunks feature --- .../TTSChunks/001_RegisterAppInterface.lua | 55 ++++++++++++ .../TTSChunks/002_SetGlobalProperties.lua | 59 +++++++++++++ .../TTSChunks/003_OnAppRegistered.lua | 46 ++++++++++ test_scripts/TTSChunks/004_Alert.lua | 49 +++++++++++ .../TTSChunks/005_ChangeRegistration.lua | 59 +++++++++++++ .../TTSChunks/006_PerformInteraction.lua | 88 +++++++++++++++++++ test_scripts/TTSChunks/007_Speak.lua | 49 +++++++++++ .../TTSChunks/008_PerformAudioPassThru.lua | 57 ++++++++++++ test_scripts/TTSChunks/009_AlertManeuver.lua | 58 ++++++++++++ test_scripts/TTSChunks/common.lua | 23 +++++ test_sets/audio_file_playback_tts_chunks.txt | 9 ++ 11 files changed, 552 insertions(+) create mode 100644 test_scripts/TTSChunks/001_RegisterAppInterface.lua create mode 100644 test_scripts/TTSChunks/002_SetGlobalProperties.lua create mode 100644 test_scripts/TTSChunks/003_OnAppRegistered.lua create mode 100644 test_scripts/TTSChunks/004_Alert.lua create mode 100644 test_scripts/TTSChunks/005_ChangeRegistration.lua create mode 100644 test_scripts/TTSChunks/006_PerformInteraction.lua create mode 100644 test_scripts/TTSChunks/007_Speak.lua create mode 100644 test_scripts/TTSChunks/008_PerformAudioPassThru.lua create mode 100644 test_scripts/TTSChunks/009_AlertManeuver.lua create mode 100644 test_scripts/TTSChunks/common.lua create mode 100644 test_sets/audio_file_playback_tts_chunks.txt diff --git a/test_scripts/TTSChunks/001_RegisterAppInterface.lua b/test_scripts/TTSChunks/001_RegisterAppInterface.lua new file mode 100644 index 0000000000..46b5b7090c --- /dev/null +++ b/test_scripts/TTSChunks/001_RegisterAppInterface.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0014-adding-audio-file-playback-to-ttschunk.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) HMI provides ‘FILE’ item in ‘speechCapabilities’ parameter of ‘TTS.GetCapabilities’ response +-- 2) New app registers +-- SDL does: +-- 1) Send ‘RegisterAppInterface’ response to mobile app with ‘FILE’ item in ‘speechCapabilities’ parameter +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/TTSChunks/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function registerApp() + common.getMobileSession():StartService(7) + :Do(function() + local corId = common.getMobileSession():SendRPC("RegisterAppInterface", common.getConfigAppParams()) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", + { application = { appName = common.getConfigAppParams().appName } }) + common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :ValidIf(function(_, data) + for _, v in pairs(data.payload.speechCapabilities) do + if v == common.type then return true end + end + return false, "'" .. common.type .. "'" + .. " item was not provided in 'speechCapabilities' of 'RegisterAppInterface' response" + end) + :Do(function() + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + common.getMobileSession():ExpectNotification("OnPermissionsChange") + end) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, init HMI, connect Mobile", common.start) + +runner.Title("Test") +runner.Step("Register App", registerApp) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/TTSChunks/002_SetGlobalProperties.lua b/test_scripts/TTSChunks/002_SetGlobalProperties.lua new file mode 100644 index 0000000000..ed3118fbcd --- /dev/null +++ b/test_scripts/TTSChunks/002_SetGlobalProperties.lua @@ -0,0 +1,59 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0014-adding-audio-file-playback-to-ttschunk.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) HMI provides ‘FILE’ item in ‘speechCapabilities’ parameter of ‘TTS.GetCapabilities’ response +-- 2) New app registers and send SetGlobalProperties with ‘FILE’ item in ‘helpPrompt’, ‘timeoutPrompt’ parameters +-- SDL does: +-- 1) Send TTS.SetGlobalProperties request to HMI with ‘FILE’ item in ‘helpPrompt’, ‘timeoutPrompt’ parameters +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/TTSChunks/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function sendSetGlobalProperties() + local params = { + helpPrompt = { + { type = common.type, text = "pathToFile1" } + }, + timeoutPrompt = { + { type = common.type, text = "pathToFile2" } + } + } + local corId = common.getMobileSession():SendRPC("SetGlobalProperties", params) + common.getHMIConnection():ExpectRequest("UI.SetGlobalProperties") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getHMIConnection():ExpectRequest("TTS.SetGlobalProperties", { + helpPrompt = params.helpPrompt, + timeoutPrompt = params.timeoutPrompt + }) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, init HMI, connect Mobile", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Send SetGlobalProperties", sendSetGlobalProperties) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/TTSChunks/003_OnAppRegistered.lua b/test_scripts/TTSChunks/003_OnAppRegistered.lua new file mode 100644 index 0000000000..ffc494568d --- /dev/null +++ b/test_scripts/TTSChunks/003_OnAppRegistered.lua @@ -0,0 +1,46 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0014-adding-audio-file-playback-to-ttschunk.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) HMI provides ‘FILE’ item in ‘speechCapabilities’ parameter of ‘TTS.GetCapabilities’ response +-- 2) New app registers with ‘FILE’ item in ‘ttsName’ parameter +-- SDL does: +-- 1) Send BC.OnAppRegistered notification to HMI with ‘FILE’ item in ‘ttsName’ parameter +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/TTSChunks/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function registerApp() + common.getMobileSession():StartService(7) + :Do(function() + local params = common.getConfigAppParams() + params.ttsName = { + { type = common.type, text = "pathToFile" } + } + local corId = common.getMobileSession():SendRPC("RegisterAppInterface", params) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", { ttsName = params.ttsName }) + common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, init HMI, connect Mobile", common.start) + +runner.Title("Test") +runner.Step("Register App", registerApp) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/TTSChunks/004_Alert.lua b/test_scripts/TTSChunks/004_Alert.lua new file mode 100644 index 0000000000..b2ab372f2c --- /dev/null +++ b/test_scripts/TTSChunks/004_Alert.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0014-adding-audio-file-playback-to-ttschunk.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) HMI provides ‘FILE’ item in ‘speechCapabilities’ parameter of ‘TTS.GetCapabilities’ response +-- 2) New app registers and send Alert with ‘FILE’ item in ‘ttsChunks’ parameter +-- SDL does: +-- 1) Send TTS.Speak request to HMI with ‘FILE’ item in ‘ttsChunks’ parameter +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/TTSChunks/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function sendAlert() + local params = { + ttsChunks = { + { type = common.type, text = "pathToFile" } + } + } + local corId = common.getMobileSession():SendRPC("Alert", params) + common.getHMIConnection():ExpectRequest("TTS.Speak", { ttsChunks = params.ttsChunks }) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, init HMI, connect Mobile", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Send Alert", sendAlert) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/TTSChunks/005_ChangeRegistration.lua b/test_scripts/TTSChunks/005_ChangeRegistration.lua new file mode 100644 index 0000000000..5a6eac49cc --- /dev/null +++ b/test_scripts/TTSChunks/005_ChangeRegistration.lua @@ -0,0 +1,59 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0014-adding-audio-file-playback-to-ttschunk.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) HMI provides ‘FILE’ item in ‘speechCapabilities’ parameter of ‘TTS.GetCapabilities’ response +-- 2) New app registers and send ChangeRegistration with ‘FILE’ item in ‘ttsName’ parameter +-- SDL does: +-- 1) Send TTS.ChangeRegistration request to HMI with ‘FILE’ item in ‘ttsName’ parameter +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/TTSChunks/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function sendChangeRegistration() + local params = { + language = "EN-US", + hmiDisplayLanguage = "EN-US", + ttsName = { + { type = common.type, text = "pathToFile" } + } + } + local corId = common.getMobileSession():SendRPC("ChangeRegistration", params) + common.getHMIConnection():ExpectRequest("UI.ChangeRegistration") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getHMIConnection():ExpectRequest("VR.ChangeRegistration") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getHMIConnection():ExpectRequest("TTS.ChangeRegistration", { ttsName = params.ttsName }) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, init HMI, connect Mobile", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Send ChangeRegistration", sendChangeRegistration) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/TTSChunks/006_PerformInteraction.lua b/test_scripts/TTSChunks/006_PerformInteraction.lua new file mode 100644 index 0000000000..697a251294 --- /dev/null +++ b/test_scripts/TTSChunks/006_PerformInteraction.lua @@ -0,0 +1,88 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0014-adding-audio-file-playback-to-ttschunk.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) HMI provides ‘FILE’ item in ‘speechCapabilities’ parameter of ‘TTS.GetCapabilities’ response +-- 2) New app registers and send PerformInteraction with ‘FILE’ item in ‘initialPrompt’, ‘helpPrompt’, +-- ‘timeoutPrompt’ parameters +-- SDL does: +-- 1) Send VR.PerformInteraction request to HMI with ‘FILE’ item in ‘initialPrompt’, ‘helpPrompt’, +-- ‘timeoutPrompt’ parameters +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/TTSChunks/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function createInteractionChoiceSet() + local params = { + interactionChoiceSetID = 100, + choiceSet = { + { + choiceID = 111, + menuName = "Choice111", + vrCommands = { "Choice111" } + } + } + } + local corId = common.getMobileSession():SendRPC("CreateInteractionChoiceSet", params) + common.getHMIConnection():ExpectRequest("VR.AddCommand") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) +end + +local function sendPerformInteraction() + local params = { + initialText = "StartPerformInteraction", + interactionMode = "VR_ONLY", + interactionChoiceSetIDList = { 100 }, + initialPrompt = { + { type = common.type, text = "pathToFile1" } + }, + helpPrompt = { + { type = common.type, text = "pathToFile2" } + }, + timeoutPrompt = { + { type = common.type, text = "pathToFile3" } + } + } + local corId = common.getMobileSession():SendRPC("PerformInteraction", params) + common.getHMIConnection():ExpectRequest("UI.PerformInteraction") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getHMIConnection():ExpectRequest("VR.PerformInteraction", { + initialPrompt = params.initialPrompt, + helpPrompt = params.helpPrompt, + timeoutPrompt = params.timeoutPrompt + }) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, init HMI, connect Mobile", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("Create InteractionChoiceSet", createInteractionChoiceSet) + +runner.Title("Test") +runner.Step("Send PerformInteraction", sendPerformInteraction) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/TTSChunks/007_Speak.lua b/test_scripts/TTSChunks/007_Speak.lua new file mode 100644 index 0000000000..4e039b2f91 --- /dev/null +++ b/test_scripts/TTSChunks/007_Speak.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0014-adding-audio-file-playback-to-ttschunk.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) HMI provides ‘FILE’ item in ‘speechCapabilities’ parameter of ‘TTS.GetCapabilities’ response +-- 2) New app registers and send Speak with ‘FILE’ item in ‘ttsChunks’ parameter +-- SDL does: +-- 1) Send TTS.Speak request to HMI with ‘FILE’ item in ‘ttsChunks’ parameter +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/TTSChunks/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function sendSpeak() + local params = { + ttsChunks = { + { type = common.type, text = "pathToFile" } + } + } + local corId = common.getMobileSession():SendRPC("Speak", params) + common.getHMIConnection():ExpectRequest("TTS.Speak", { ttsChunks = params.ttsChunks }) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, init HMI, connect Mobile", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Send Speak", sendSpeak) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/TTSChunks/008_PerformAudioPassThru.lua b/test_scripts/TTSChunks/008_PerformAudioPassThru.lua new file mode 100644 index 0000000000..e61b830146 --- /dev/null +++ b/test_scripts/TTSChunks/008_PerformAudioPassThru.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0014-adding-audio-file-playback-to-ttschunk.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) HMI provides ‘FILE’ item in ‘speechCapabilities’ parameter of ‘TTS.GetCapabilities’ response +-- 2) New app registers and send PerformAudioPassThru with ‘FILE’ item in ‘initialPrompt’ parameter +-- SDL does: +-- 1) Send TTS.Speak request to HMI with ‘FILE’ item in ‘ttsChunks’ parameter +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/TTSChunks/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function sendPerformAudioPassThru() + local params = { + samplingRate = "8KHZ", + maxDuration = 2000, + bitsPerSample = "8_BIT", + audioType = "PCM", + initialPrompt = { + { type = common.type, text = "pathToFile" } + } + } + local corId = common.getMobileSession():SendRPC("PerformAudioPassThru", params) + common.getHMIConnection():ExpectRequest("UI.PerformAudioPassThru") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getHMIConnection():ExpectRequest("TTS.Speak", { ttsChunks = params.initialPrompt }) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, init HMI, connect Mobile", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Send PerformAudioPassThru", sendPerformAudioPassThru) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/TTSChunks/009_AlertManeuver.lua b/test_scripts/TTSChunks/009_AlertManeuver.lua new file mode 100644 index 0000000000..ee96f22957 --- /dev/null +++ b/test_scripts/TTSChunks/009_AlertManeuver.lua @@ -0,0 +1,58 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0014-adding-audio-file-playback-to-ttschunk.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) HMI provides ‘FILE’ item in ‘speechCapabilities’ parameter of ‘TTS.GetCapabilities’ response +-- 2) New app registers and send AlertManeuver with ‘FILE’ item in ‘ttsChunks’ parameter +-- SDL does: +-- 1) Send TTS.Speak request to HMI with ‘FILE’ item in ‘ttsChunks’ parameter +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/TTSChunks/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function pTUpdateFunc(pTbl) + table.insert(pTbl.policy_table.app_policies[common.getConfigAppParams().appID].groups, "Navigation-1") +end + +local function sendAlertManeuver() + local params = { + ttsChunks = { + { type = common.type, text = "pathToFile" } + } + } + local corId = common.getMobileSession():SendRPC("AlertManeuver", params) + common.getHMIConnection():ExpectRequest("Navigation.AlertManeuver") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getHMIConnection():ExpectRequest("TTS.Speak", { ttsChunks = params.ttsChunks }) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, init HMI, connect Mobile", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PTU", common.policyTableUpdate, { pTUpdateFunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Send AlertManeuver", sendAlertManeuver) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/TTSChunks/common.lua b/test_scripts/TTSChunks/common.lua new file mode 100644 index 0000000000..f30f612053 --- /dev/null +++ b/test_scripts/TTSChunks/common.lua @@ -0,0 +1,23 @@ +--------------------------------------------------------------------------------------------------- +-- Common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 2 + +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") +local hmi_values = require('user_modules/hmi_values') + +--[[ Module ]] +local m = actions + +m.type = "FILE" + +local startOrigin = m.start +function m.start() + local params = hmi_values.getDefaultHMITable() + table.insert(params.TTS.GetCapabilities.params.speechCapabilities, m.type) + startOrigin(params) +end + +return m diff --git a/test_sets/audio_file_playback_tts_chunks.txt b/test_sets/audio_file_playback_tts_chunks.txt new file mode 100644 index 0000000000..be59961383 --- /dev/null +++ b/test_sets/audio_file_playback_tts_chunks.txt @@ -0,0 +1,9 @@ +./test_scripts/TTSChunks/001_RegisterAppInterface.lua +./test_scripts/TTSChunks/002_SetGlobalProperties.lua +./test_scripts/TTSChunks/003_OnAppRegistered.lua +./test_scripts/TTSChunks/004_Alert.lua +./test_scripts/TTSChunks/005_ChangeRegistration.lua +./test_scripts/TTSChunks/006_PerformInteraction.lua +./test_scripts/TTSChunks/007_Speak.lua +./test_scripts/TTSChunks/008_PerformAudioPassThru.lua +./test_scripts/TTSChunks/009_AlertManeuver.lua From dc4ce0957086f0fa6061edac6f527f74f1517a7c Mon Sep 17 00:00:00 2001 From: JackLivio Date: Wed, 9 May 2018 14:25:01 -0400 Subject: [PATCH 377/681] Split test cases into seperate files --- .DS_Store | Bin 0 -> 6148 bytes test_scripts/SDL4.6/TemplateColorSchemes.lua | 106 ------------------ ...etDisplayWithColorsAndNewLayoutSuccess.lua | 69 ++++++++++++ ...orSchemes_setDisplayWithColorsRejected.lua | 65 +++++++++++ ...chemes_setDisplayWithSameColorsSuccess.lua | 56 +++++++++ 5 files changed, 190 insertions(+), 106 deletions(-) create mode 100644 .DS_Store delete mode 100644 test_scripts/SDL4.6/TemplateColorSchemes.lua create mode 100644 test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua create mode 100644 test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithColorsRejected.lua create mode 100644 test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c856a9f05970cd44529e7b1450540f7033364ae1 GIT binary patch literal 6148 zcmeHKze~eF82zrMP=7%u5fsf*N1>yWLF(WvB2FqvTLnW(Z3nmP{sGPog5cs@7X=4L zCs%hT2XPeNcX!k~lhjQ_?%?hv_x*Z#m*#pzB-Z*-ov2Dg6?8^#0z*z?JNHa0>6v+; z;2cNo`evBKos6fOa0)mD{-Of>+x2Lf+H^=g^Y>ed-=|GmoHQCyzZVic-E5!BM;XS& zNmOX-9DIEf#!jy}uuLsfJEA5XTNU3{UTmvTb1-u$YZ|de)f}r?xAbw#!Bf=ZnizL6 zhSUX%4(==#V)5c^l&{IDw#8|S^O_8Q@-_L2jaSY)Zt-n?XG)@bmG70qF(+3JyBsf* z7mYD3ngEjo8irWIeW_xLPRy00#k@R9_y6_c z^S>SB?wkTnfq$id@EV(qH9V5uTQd*Gd##VYht7@tQiU=EgWiti1#iW(=(54)^93-_ Um@32!n)@RlWpIO2;8zv+1b1)q>i_@% literal 0 HcmV?d00001 diff --git a/test_scripts/SDL4.6/TemplateColorSchemes.lua b/test_scripts/SDL4.6/TemplateColorSchemes.lua deleted file mode 100644 index c52e476718..0000000000 --- a/test_scripts/SDL4.6/TemplateColorSchemes.lua +++ /dev/null @@ -1,106 +0,0 @@ ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local commonSmoke = require('test_scripts/Smoke/commonSmoke') - -local function getRequestParams() - return { - displayLayout = "ONSCREEN_PRESETS", - dayColorScheme = { - primaryColor = { - red = 0, - green = 255, - blue = 100 - } - } - } -end - -local function getRequestParams2() - return { - displayLayout = "ONSCREEN_PRESETS", - dayColorScheme = { - primaryColor = { - red = 0, - green = 0, - blue = 0 - } - } - } -end - -local function getRequestParams3() - return { - displayLayout = "MEDIA", - dayColorScheme = { - primaryColor = { - red = 0, - green = 255, - blue = 100 - } - } - } -end - -local function setDisplayWithColorsSuccess(self) - local responseParams = {} - local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams()) - EXPECT_HMICALL("UI.SetDisplayLayout", getRequestParams()) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", responseParams) - end) - self.mobileSession1:ExpectResponse(cid, { - success = true, - resultCode = "SUCCESS" - }) -end - -local function setDisplayWithSameColorsSuccess(self) - local responseParams = {} - local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams()) - EXPECT_HMICALL("UI.SetDisplayLayout", getRequestParams()) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", responseParams) - end) - self.mobileSession1:ExpectResponse(cid, { - success = true, - resultCode = "SUCCESS" - }) -end - -local function setDisplayWithColorsRejected(self) - local responseParams = {} - local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams2()) - self.mobileSession1:ExpectResponse(cid, { - success = false, - resultCode = "REJECTED" - }) -end - -local function setDisplayWithColorsAndNewLayoutSuccess(self) - local responseParams = {} - local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams3()) - EXPECT_HMICALL("UI.SetDisplayLayout", getRequestParams3()) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", responseParams) - end) - self.mobileSession1:ExpectResponse(cid, { - success = true, - resultCode = "SUCCESS" - }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonSmoke.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI", commonSmoke.registerApp) -runner.Step("Activate App", commonSmoke.activateApp) - -runner.Title("Test") -runner.Step("SetDisplay Positive Case 1", setDisplayWithColorsSuccess) -runner.Step("SetDisplay Positive Case 2", setDisplayWithSameColorsSuccess) -runner.Step("SetDisplay Rejected Case", setDisplayWithColorsRejected) -runner.Step("SetDisplay Positive Case 3", setDisplayWithColorsAndNewLayoutSuccess) - -runner.Title("Postconditions") -runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua b/test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua new file mode 100644 index 0000000000..68203f9a10 --- /dev/null +++ b/test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua @@ -0,0 +1,69 @@ +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +local function getRequestParams() + return { + displayLayout = "ONSCREEN_PRESETS", + dayColorScheme = { + primaryColor = { + red = 0, + green = 255, + blue = 100 + } + } + } +end + +local function getRequestParams2() + return { + displayLayout = "MEDIA", + dayColorScheme = { + primaryColor = { + red = 0, + green = 255, + blue = 100 + } + } + } +end + +local function setDisplayWithColorsSuccess(self) + local responseParams = {} + local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams()) + EXPECT_HMICALL("UI.SetDisplayLayout", getRequestParams()) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", responseParams) + end) + self.mobileSession1:ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS" + }) +end + +local function setDisplayWithColorsAndNewLayoutSuccess(self) + local responseParams = {} + local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams2()) + EXPECT_HMICALL("UI.SetDisplayLayout", getRequestParams2()) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", responseParams) + end) + self.mobileSession1:ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS" + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI", commonSmoke.registerApp) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("SetDisplay Positive Case 1", setDisplayWithColorsSuccess) +runner.Step("SetDisplay Positive Case 2", setDisplayWithColorsAndNewLayoutSuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithColorsRejected.lua b/test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithColorsRejected.lua new file mode 100644 index 0000000000..22f2ec0c61 --- /dev/null +++ b/test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithColorsRejected.lua @@ -0,0 +1,65 @@ +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +local function getRequestParams() + return { + displayLayout = "ONSCREEN_PRESETS", + dayColorScheme = { + primaryColor = { + red = 0, + green = 255, + blue = 100 + } + } + } +end + +local function getRequestParams2() + return { + displayLayout = "ONSCREEN_PRESETS", + dayColorScheme = { + primaryColor = { + red = 0, + green = 0, + blue = 0 + } + } + } +end + +local function setDisplayWithColorsSuccess(self) + local responseParams = {} + local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams()) + EXPECT_HMICALL("UI.SetDisplayLayout", getRequestParams()) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", responseParams) + end) + self.mobileSession1:ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS" + }) +end + +local function setDisplayWithColorsRejected(self) + local responseParams = {} + local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams2()) + self.mobileSession1:ExpectResponse(cid, { + success = false, + resultCode = "REJECTED" + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI", commonSmoke.registerApp) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("SetDisplay Positive Case 1", setDisplayWithColorsSuccess) +runner.Step("SetDisplay Rejected Case", setDisplayWithColorsRejected) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua b/test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua new file mode 100644 index 0000000000..7faa269a86 --- /dev/null +++ b/test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua @@ -0,0 +1,56 @@ +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +local function getRequestParams() + return { + displayLayout = "ONSCREEN_PRESETS", + dayColorScheme = { + primaryColor = { + red = 0, + green = 255, + blue = 100 + } + } + } +end + +local function setDisplayWithColorsSuccess(self) + local responseParams = {} + local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams()) + EXPECT_HMICALL("UI.SetDisplayLayout", getRequestParams()) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", responseParams) + end) + self.mobileSession1:ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS" + }) +end + +local function setDisplayWithSameColorsSuccess(self) + local responseParams = {} + local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams()) + EXPECT_HMICALL("UI.SetDisplayLayout", getRequestParams()) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", responseParams) + end) + self.mobileSession1:ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS" + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI", commonSmoke.registerApp) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("SetDisplay Positive Case 1", setDisplayWithColorsSuccess) +runner.Step("SetDisplay Positive Case 2", setDisplayWithSameColorsSuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From f61fe5cac02c7575a8b562cea65e5eb8940e7fae Mon Sep 17 00:00:00 2001 From: JackLivio Date: Wed, 9 May 2018 14:27:31 -0400 Subject: [PATCH 378/681] Rename Files with 00x prefix --- ...plateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua} | 0 ... => 002_TemplateColorSchemes_setDisplayWithColorsRejected.lua} | 0 ... 003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename test_scripts/SDL4.6/{TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua => 001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua} (100%) rename test_scripts/SDL4.6/{TemplateColorSchemes_setDisplayWithColorsRejected.lua => 002_TemplateColorSchemes_setDisplayWithColorsRejected.lua} (100%) rename test_scripts/SDL4.6/{TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua => 003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua} (100%) diff --git a/test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua b/test_scripts/SDL4.6/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua similarity index 100% rename from test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua rename to test_scripts/SDL4.6/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua diff --git a/test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithColorsRejected.lua b/test_scripts/SDL4.6/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua similarity index 100% rename from test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithColorsRejected.lua rename to test_scripts/SDL4.6/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua diff --git a/test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua b/test_scripts/SDL4.6/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua similarity index 100% rename from test_scripts/SDL4.6/TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua rename to test_scripts/SDL4.6/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua From 74630ce00a71ca2fed0d806cc6b28ef22fe31acb Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Tue, 8 May 2018 14:03:05 -0400 Subject: [PATCH 379/681] Add fuelRange to vehicle data tests --- .../GetVehicleData/001_Success_flow.lua | 13 +++++++++--- ..._parameter_DISALLOWED_by_policies_flow.lua | 17 ++++++++++++---- .../OnVehicleData/001_Success_flow.lua | 15 ++++++++++++-- ...onForUnsubsribedParameter_Ignored_flow.lua | 20 +++++++++++++++---- ...meterDisallowedByPolicies_Ignored_flow.lua | 19 +++++++++++++++--- .../SubscribeVehicleData/001_Success_flow.lua | 7 ++++++- ..._parameter_DISALLOWED_by_policies_flow.lua | 11 ++++++++-- ...already_subscribed_Result_IGNORED_flow.lua | 11 +++++++++- .../001_Success_flow.lua | 10 ++++++++-- ...ameter_not_yet_subscribed_IGNORED_flow.lua | 7 ++++++- ...ready_unsubscribed_Result_IGNORED_flow.lua | 14 +++++++++++-- ...wed_by_policies_Result_DISALLOWED_flow.lua | 11 ++++++++-- .../API/VehicleData/commonVehicleData.lua | 1 + ...scribeVehicleData_PositiveCase_SUCCESS.lua | 2 ++ ...scribeVehicleData_PositiveCase_SUCCESS.lua | 2 ++ ...26_GetVehicleData_PositiveCase_SUCCESS.lua | 7 +++++++ .../{EngineOilLife.txt => VehicleData.txt} | 6 +++--- 17 files changed, 143 insertions(+), 30 deletions(-) rename test_sets/{EngineOilLife.txt => VehicleData.txt} (71%) diff --git a/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua index 986d993a57..4a2cb93a59 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua @@ -23,12 +23,19 @@ local common = require('test_scripts/API/VehicleData/commonVehicleData') local rpc = { name = "GetVehicleData", params = { - engineOilLife = true + engineOilLife = true, + fuelRange = true } } -local vehicleDataValues { - engineOilLife = 50.30 +local vehicleDataValues = { + engineOilLife = 50.30, + fuelRange = { + { + type = "GASOLINE", + range = 400.00 + } + } } --[[ Local Functions ]] diff --git a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index 12cab43be1..07fcafeed1 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -24,20 +24,29 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local rpc = { name = "GetVehicleData", params = { - engineOilLife = true + engineOilLife = true, + fuelRange = true } } -local vehicleDataValues { - engineOilLife = 52.3 +local vehicleDataValues = { + engineOilLife = 52.3, + fuelRange = { + { + type = "GASOLINE", + range = 400.00 + } + } } --[[ Local Functions ]] local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["GetVehicleData"].parameters + local newParams = {} for index, value in pairs(params) do - if ("engineOilLife" == value) then table.remove(params, index) end + if not (("engineOilLife" == value) or ("fuelRange" == value)) then table.insert(newParams, value) end end + tbl.policy_table.functional_groupings["Emergency-1"].rpcs["GetVehicleData"].parameters = newParams end local function processRPCSuccess(self) diff --git a/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua index ad360ae051..c6a95167ef 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua @@ -23,14 +23,21 @@ local common = require('test_scripts/API/VehicleData/commonVehicleData') local rpc1 = { name = "SubscribeVehicleData", params = { - engineOilLife = true + engineOilLife = true, + fuelRange = true } } local rpc2 = { name = "OnVehicleData", params = { - engineOilLife = 50.3 + engineOilLife = 50.3, + fuelRange = { + { + type = "GASOLINE", + range = 400.00 + } + } } } @@ -38,6 +45,10 @@ local vehicleDataResults = { engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS" + }, + fuelRange = { + dataType = "VEHICLEDATA_FUELRANGE", + resultCode = "SUCCESS" } } diff --git a/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua index 74f1bc33b6..74b53bbb14 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua @@ -25,21 +25,29 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local rpc1 = { name = "SubscribeVehicleData", params = { - engineOilLife = true + engineOilLife = true, + fuelRange = true } } local rpc2 = { name = "OnVehicleData", params = { - engineOilLife = 50.3 + engineOilLife = 50.3, + fuelRange = { + { + type = "GASOLINE", + range = 400.00 + } + } } } local rpc3 = { name = "UnsubscribeVehicleData", params = { - engineOilLife = true + engineOilLife = true, + fuelRange = true } } @@ -47,6 +55,10 @@ local vehicleDataResults = { engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS" + }, + fuelRange = { + dataType = "VEHICLEDATA_FUELRANGE", + resultCode = "SUCCESS" } } @@ -57,7 +69,7 @@ local function processRPCSubscribeSuccess(self) EXPECT_HMICALL("VehicleInfo." .. rpc1.name, rpc1.params) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", - vehicleDataResults}) + vehicleDataResults) end) local responseParams = vehicleDataResults responseParams.success = true diff --git a/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua index 43e5fb785e..e2d20044cd 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua @@ -25,14 +25,21 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local rpc1 = { name = "SubscribeVehicleData", params = { - engineOilLife = true + engineOilLife = true, + fuelRange = true } } local rpc2 = { name = "OnVehicleData", params = { - engineOilLife = 50.3 + engineOilLife = 50.3, + fuelRange = { + { + type = "GASOLINE", + range = 400.00 + } + } } } @@ -40,15 +47,21 @@ local vehicleDataResults = { engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS" + }, + fuelRange = { + dataType = "VEHICLEDATA_FUELRANGE", + resultCode = "SUCCESS" } } --[[ Local Functions ]] local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["OnVehicleData"].parameters + local newParams = {} for index, value in pairs(params) do - if ("engineOilLife" == value) then table.remove(params, index) end + if not (("engineOilLife" == value) or ("fuelRange" == value)) then table.insert(newParams, value) end end + tbl.policy_table.functional_groupings["Emergency-1"].rpcs["OnVehicleData"].parameters = newParams end local function processRPCSubscribeSuccess(self) diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua index 068371830d..85c83d1cbb 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua @@ -22,7 +22,8 @@ local common = require('test_scripts/API/VehicleData/commonVehicleData') local rpc = { name = "SubscribeVehicleData", params = { - engineOilLife = true + engineOilLife = true, + fuelRange = true } } @@ -30,6 +31,10 @@ local vehicleDataResults = { engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS" + }, + fuelRange = { + dataType = "VEHICLEDATA_FUELRANGE", + resultCode = "SUCCESS" } } diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index 40d8e80542..8fa8a124bc 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -23,7 +23,8 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local rpc = { name = "SubscribeVehicleData", params = { - engineOilLife = true + engineOilLife = true, + fuelRange = true } } @@ -31,15 +32,21 @@ local vehicleDataResults = { engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DISALLOWED" + }, + fuelRange = { + dataType = "VEHICLEDATA_FUELRANGE", + resultCode = "DISALLOWED" } } --[[ Local Functions ]] local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["SubscribeVehicleData"].parameters + local newParams = {} for index, value in pairs(params) do - if ("engineOilLife" == value) then table.remove(params, index) end + if not (("engineOilLife" == value) or ("fuelRange" == value)) then table.insert(newParams, value) end end + tbl.policy_table.functional_groupings["Emergency-1"].rpcs["SubscribeVehicleData"].parameters = newParams end local function processRPCFailure(self) diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua index dc6372c939..eccb9ec574 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua @@ -22,7 +22,8 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local rpc = { name = "SubscribeVehicleData", params = { - engineOilLife = true + engineOilLife = true, + fuelRange = true } } @@ -30,6 +31,10 @@ local vehicleDataResults = { engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS" + }, + fuelRange = { + dataType = "VEHICLEDATA_FUELRANGE", + resultCode = "SUCCESS" } } @@ -37,6 +42,10 @@ local vehicleDataResults2 = { engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DATA_ALREADY_SUBSCRIBED" + }, + fuelRange = { + dataType = "VEHICLEDATA_FUELRANGE", + resultCode = "DATA_ALREADY_SUBSCRIBED" } } diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua index 1c7e5ba390..054deb1fd5 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua @@ -23,14 +23,16 @@ local common = require('test_scripts/API/VehicleData/commonVehicleData') local rpc_subscribe = { name = "SubscribeVehicleData", params = { - engineOilLife = true + engineOilLife = true, + fuelRange = true } } local rpc_unsubscribe = { name = "UnsubscribeVehicleData", params = { - engineOilLife = true + engineOilLife = true, + fuelRange = true } } @@ -38,6 +40,10 @@ local vehicleDataResults = { engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS" + }, + fuelRange = { + dataType = "VEHICLEDATA_FUELRANGE", + resultCode = "SUCCESS" } } diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua index 81c2e1f05a..47e1325538 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua @@ -24,7 +24,8 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local rpc = { name = "UnsubscribeVehicleData", params = { - engineOilLife = true + engineOilLife = true, + fuelRange = true } } @@ -32,6 +33,10 @@ local vehicleDataResults = { engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DATA_NOT_SUBSCRIBED" + }, + fuelRange = { + dataType = "VEHICLEDATA_FUELRANGE", + resultCode = "DATA_NOT_SUBSCRIBED" } } diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua index ceaa7d7edf..9d489b41c7 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua @@ -25,14 +25,16 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local rpc_subscribe = { name = "SubscribeVehicleData", params = { - engineOilLife = true + engineOilLife = true, + fuelRange = true } } local rpc_unsubscribe = { name = "UnsubscribeVehicleData", params = { - engineOilLife = true + engineOilLife = true, + fuelRange = true } } @@ -40,6 +42,10 @@ local vehicleDataResults = { engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "SUCCESS" + }, + fuelRange = { + dataType = "VEHICLEDATA_FUELRANGE", + resultCode = "SUCCESS" } } @@ -47,6 +53,10 @@ local vehicleDataResults2 = { engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DATA_NOT_SUBSCRIBED" + }, + fuelRange = { + dataType = "VEHICLEDATA_FUELRANGE", + resultCode = "DATA_NOT_SUBSCRIBED" } } diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua index 5a7cfdff7f..c8f09e1346 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua @@ -23,7 +23,8 @@ local commonTestCases = require('user_modules/shared_testcases/commonTestCases') local rpc = { name = "UnsubscribeVehicleData", params = { - engineOilLife = true + engineOilLife = true, + fuelRange = true } } @@ -31,15 +32,21 @@ local vehicleDataResults = { engineOilLife = { dataType = "VEHICLEDATA_ENGINEOILLIFE", resultCode = "DISALLOWED" + }, + fuelRange = { + dataType = "VEHICLEDATA_FUELRANGE", + resultCode = "DISALLOWED" } } --[[ Local Functions ]] local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["UnsubscribeVehicleData"].parameters + local newParams = {} for index, value in pairs(params) do - if ("engineOilLife" == value) then table.remove(params, index) end + if not (("engineOilLife" == value) or ("fuelRange" == value)) then table.insert(newParams, value) end end + tbl.policy_table.functional_groupings["Emergency-1"].rpcs["UnsubscribeVehicleData"].parameters = newParams end local function processRPCFailure(self) diff --git a/test_scripts/API/VehicleData/commonVehicleData.lua b/test_scripts/API/VehicleData/commonVehicleData.lua index 4833acbd75..0070dd8e9f 100644 --- a/test_scripts/API/VehicleData/commonVehicleData.lua +++ b/test_scripts/API/VehicleData/commonVehicleData.lua @@ -90,6 +90,7 @@ local function ptu(self, app_id, ptu_update_func) local function updatePTU(tbl) for rpc in pairs(tbl.policy_table.functional_groupings["Emergency-1"].rpcs) do addParamToRPC(tbl, "Emergency-1", rpc, "engineOilLife") + addParamToRPC(tbl, "Emergency-1", rpc, "fuelRange") end tbl.policy_table.app_policies[commonVehicleData.getMobileAppId(app_id)] = commonVehicleData.getGetVehicleDataConfig() end diff --git a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua index 25c1b23b7c..5f8f126da6 100644 --- a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua @@ -39,6 +39,7 @@ local VDValues = { rpm = "VEHICLEDATA_RPM", fuelLevel = "VEHICLEDATA_FUELLEVEL", fuelLevel_State = "VEHICLEDATA_FUELLEVEL_STATE", + fuelRange = "VEHICLEDATA_FUELRANGE" instantFuelConsumption = "VEHICLEDATA_FUELCONSUMPTION", externalTemperature = "VEHICLEDATA_EXTERNTEMP", prndl = "VEHICLEDATA_PRNDL", @@ -51,6 +52,7 @@ local VDValues = { wiperStatus = "VEHICLEDATA_WIPERSTATUS", headLampStatus = "VEHICLEDATA_HEADLAMPSTATUS", engineTorque = "VEHICLEDATA_ENGINETORQUE", + engineOilLife = "VEHICLEDATA_ENGINEOILLIFE", accPedalPosition = "VEHICLEDATA_ACCPEDAL", steeringWheelAngle = "VEHICLEDATA_STEERINGWHEEL", eCallInfo = "VEHICLEDATA_ECALLINFO", diff --git a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua index 7acc4665ea..dc3be47d9b 100644 --- a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua @@ -39,6 +39,7 @@ local VDValues = { rpm = "VEHICLEDATA_RPM", fuelLevel = "VEHICLEDATA_FUELLEVEL", fuelLevel_State = "VEHICLEDATA_FUELLEVEL_STATE", + fuelRange = "VEHICLEDATA_FUELRANGE" instantFuelConsumption = "VEHICLEDATA_FUELCONSUMPTION", externalTemperature = "VEHICLEDATA_EXTERNTEMP", prndl = "VEHICLEDATA_PRNDL", @@ -51,6 +52,7 @@ local VDValues = { wiperStatus = "VEHICLEDATA_WIPERSTATUS", headLampStatus = "VEHICLEDATA_HEADLAMPSTATUS", engineTorque = "VEHICLEDATA_ENGINETORQUE", + engineOilLife = "VEHICLEDATA_ENGINEOILLIFE", accPedalPosition = "VEHICLEDATA_ACCPEDAL", steeringWheelAngle = "VEHICLEDATA_STEERINGWHEEL", eCallInfo = "VEHICLEDATA_ECALLINFO", diff --git a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua index 4349aaacaa..be642152fa 100644 --- a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua @@ -58,6 +58,12 @@ local vehicleDataValues = { rpm = 1000, fuelLevel = 50.5, fuelLevel_State = "NORMAL", + fuelRange = { + { + type = "GASOLINE", + range = 400.5 + } + } instantFuelConsumption = 1000.5, externalTemperature = 55.5, vin = "123456", @@ -115,6 +121,7 @@ local vehicleDataValues = { ambientLightSensorStatus = "NIGHT" }, engineTorque = 555.5, + engineOilLife = 55.5, accPedalPosition = 55.5, steeringWheelAngle = 555.5, eCallInfo = { diff --git a/test_sets/EngineOilLife.txt b/test_sets/VehicleData.txt similarity index 71% rename from test_sets/EngineOilLife.txt rename to test_sets/VehicleData.txt index 2d6c710f89..47082138a0 100644 --- a/test_sets/EngineOilLife.txt +++ b/test_sets/VehicleData.txt @@ -2,10 +2,10 @@ ./test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua ./test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua ./test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua -./test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua +;./test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua ./test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua -./test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua -./test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua +;./test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +;./test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua ./test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua ./test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua ./test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua From 5b45f4a3967eef5cfbbb1fb72424fddf14790fda Mon Sep 17 00:00:00 2001 From: JackLivio Date: Wed, 9 May 2018 15:08:34 -0400 Subject: [PATCH 380/681] Add test descriptions --- ...s_setDisplayWithColorsAndNewLayoutSuccess.lua | 16 ++++++++++++++++ ...ColorSchemes_setDisplayWithColorsRejected.lua | 16 ++++++++++++++++ ...orSchemes_setDisplayWithSameColorsSuccess.lua | 16 ++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/test_scripts/SDL4.6/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua b/test_scripts/SDL4.6/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua index 68203f9a10..41df9b2a07 100644 --- a/test_scripts/SDL4.6/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua +++ b/test_scripts/SDL4.6/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua @@ -1,3 +1,19 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0147-template-color-scheme.md +-- +-- Description: +-- SDL Core should track the number of attempted SetDisplayLayout requests with the current template and REJECT +-- any beyond the first with the reason "Using SetDisplayLayout to change the color scheme may only be done once. +-- However, The color scheme can be changed if the layout is also changed. +-- +-- Preconditions: Send SetDisplayLayout with a layout and a color scheme. +-- +-- Steps: Send additional SetDisplayLayout with a different layout and a different color scheme. +-- +-- Expected result: +-- SDL Core returns SUCCESS +--------------------------------------------------------------------------------------------------- + --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonSmoke = require('test_scripts/Smoke/commonSmoke') diff --git a/test_scripts/SDL4.6/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua b/test_scripts/SDL4.6/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua index 22f2ec0c61..3862f9c427 100644 --- a/test_scripts/SDL4.6/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua +++ b/test_scripts/SDL4.6/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua @@ -1,3 +1,19 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0147-template-color-scheme.md +-- +-- Description: +-- SDL Core should track the number of attempted SetDisplayLayout requests with the current template and REJECT +-- any beyond the first with the reason "Using SetDisplayLayout to change the color scheme may only be done once. +-- +-- Preconditions: Send SetDisplayLayout with a layout and a color scheme. +-- +-- Steps: Send additional SetDisplayLayout with same layout but use a different color scheme +-- +-- Expected result: +-- SDL Core returns REJECTED +--------------------------------------------------------------------------------------------------- + + --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonSmoke = require('test_scripts/Smoke/commonSmoke') diff --git a/test_scripts/SDL4.6/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua b/test_scripts/SDL4.6/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua index 7faa269a86..b296364bd2 100644 --- a/test_scripts/SDL4.6/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua +++ b/test_scripts/SDL4.6/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua @@ -1,3 +1,19 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0147-template-color-scheme.md +-- +-- Description: +-- SDL Core should track the number of attempted SetDisplayLayout requests with the current template and REJECT +-- any beyond the first with the reason "Using SetDisplayLayout to change the color scheme may only be done once. +-- Sending A SetDisplayLayout with the same color should still return success. +-- +-- Preconditions: Send SetDisplayLayout with a layout and a color scheme. +-- +-- Steps: Send additional SetDisplayLayout with same layout and the same color scheme. +-- +-- Expected result: +-- SDL Core returns SUCCESS +--------------------------------------------------------------------------------------------------- + --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonSmoke = require('test_scripts/Smoke/commonSmoke') From 4714645f03d551e1936e8149c0bcf65ff8d21432 Mon Sep 17 00:00:00 2001 From: Jacob Keeler Date: Thu, 9 Mar 2017 16:45:38 -0500 Subject: [PATCH 381/681] Added "FILE" SpeechCapabilities type to all relevant tests --- test_scripts/API/ATF_Alert.lua | 6 +- test_scripts/API/ATF_AlertManeuver.lua | 4 +- test_scripts/API/ATF_ChangeRegistration.lua | 12 +- test_scripts/API/ATF_PerformAudioPassThru.lua | 8 +- test_scripts/API/ATF_PerformInteraction.lua | 4 +- test_scripts/API/ATF_RegisterAppInterface.lua | 44 +- test_scripts/API/ATF_SetGlobalProperties.lua | 699 ++++++++++++++++-- test_scripts/API/ATF_Speak.lua | 2 +- ...ATF_TTS_IsReady_NotRespond_RegisterApp.lua | 12 +- .../ATF_TTS_IsReady_NotRespond_Single_RPC.lua | 4 +- ...ATF_TTS_IsReady_NotRespond_Split_RPC_1.lua | 4 +- ...ATF_TTS_IsReady_NotRespond_Split_RPC_2.lua | 2 +- ...ATF_TTS_IsReady_NotRespond_Split_RPC_3.lua | 4 +- ...tRespond_Split_RPC_APPLINK_25139_RETRY.lua | 2 +- ...tRespond_Split_RPC_APPLINK_25139_SAVED.lua | 2 +- ...espond_Split_RPC_APPLINK_25139_SUCCESS.lua | 2 +- ...spond_Split_RPC_APPLINK_25139_WARNINGS.lua | 2 +- ...Split_RPC_APPLINK_25139_WRONG_LANGUAGE.lua | 2 +- .../ATF_TTS_IsReady_false_RegisterApp.lua | 4 +- .../ATF_TTS_IsReady_false_SingleRPC.lua | 4 +- .../ATF_TTS_IsReady_false_Split_RPC.lua | 4 +- .../ATF_Expanded_smoke_test_Genivi.lua | 121 ++- .../testCasesForArrayTTSChunksParameter.lua | 4 +- .../testCasesForTTSChunkParameter.lua | 6 +- 24 files changed, 842 insertions(+), 116 deletions(-) diff --git a/test_scripts/API/ATF_Alert.lua b/test_scripts/API/ATF_Alert.lua index 9ced22f1cd..97cfc0503e 100644 --- a/test_scripts/API/ATF_Alert.lua +++ b/test_scripts/API/ATF_Alert.lua @@ -5358,7 +5358,7 @@ end --Begin Test case PositiveRequestCheck.1.16 --Description: ttsChunks: available values of type - local ttsChunksType = {{text = "4025",type = "PRE_RECORDED"},{ text = "Sapi",type = "SAPI_PHONEMES"}, {text = "LHplus", type = "LHPLUS_PHONEMES"}, {text = "Silence", type = "SILENCE"}} + local ttsChunksType = {{text = "4025",type = "PRE_RECORDED"},{ text = "Sapi",type = "SAPI_PHONEMES"}, {text = "LHplus", type = "LHPLUS_PHONEMES"}, {text = "Silence", type = "SILENCE"}, {text = "File.m4a", type = "FILE"}} for i=1,#ttsChunksType do Test["Alert_ttsChunksType" .. tostring(ttsChunksType[i].type)] = function(self) --mobile side: Alert request @@ -10882,7 +10882,7 @@ end --Requirement id in JAMA: SDLAQ-CRS-1029 --Verification criteria: - --When "ttsChunks" are sent within the request but the type is different from "TEXT" (SAPI_PHONEMES, LHPLUS_PHONEMES, PRE_RECORDED or SILENCE), WARNINGS is returned as a result of request. Info parameter provides additional information about the case. General request result success=false in case of TTS is the only component which processes a request. + --When "ttsChunks" are sent within the request but the type is different from "TEXT" (SAPI_PHONEMES, LHPLUS_PHONEMES, PRE_RECORDED, SILENCE, or FILE), WARNINGS is returned as a result of request. Info parameter provides additional information about the case. General request result success=false in case of TTS is the only component which processes a request. function Test:Alert_WarningsSuccessFalse() @@ -10946,7 +10946,7 @@ end --Requirement id in JAMA: SDLAQ-CRS-1029 --Verification criteria: - --When "ttsChunks" are sent within the request but the type is different from "TEXT" (SAPI_PHONEMES, LHPLUS_PHONEMES, PRE_RECORDED or SILENCE), WARNINGS is returned as a result of request. Info parameter provides additional information about the case. General request result success=true in case of no errors from other components. + --When "ttsChunks" are sent within the request but the type is different from "TEXT" (SAPI_PHONEMES, LHPLUS_PHONEMES, PRE_RECORDED, SILENCE, or FILE), WARNINGS is returned as a result of request. Info parameter provides additional information about the case. General request result success=true in case of no errors from other components. function Test:Alert_WarningsSuccessTrue() diff --git a/test_scripts/API/ATF_AlertManeuver.lua b/test_scripts/API/ATF_AlertManeuver.lua index eaf7d60d83..4ab1ca3335 100644 --- a/test_scripts/API/ATF_AlertManeuver.lua +++ b/test_scripts/API/ATF_AlertManeuver.lua @@ -1350,7 +1350,7 @@ end --[[ - name="ttsChunks" minsize="1" maxsize="100" array="true" mandatory="false": - name="text" minlength="0" maxlength="500" type="String" - - name="type" : TEXT, SAPI_PHONEMES, LHPLUS_PHONEMES, PRE_RECORDED, SILENCE + - name="type" : TEXT, SAPI_PHONEMES, LHPLUS_PHONEMES, PRE_RECORDED, SILENCE, FILE - name="softButtons" minsize="0" maxsize="3" array="true" mandatory="false" : - name="type" : TEXT, IMAGE, BOTH; - name="text" minlength="0" maxlength="500" type="String" mandatory="false"; @@ -2723,7 +2723,7 @@ end --Begin Test case PositiveRequestCheck.1.6 --Description: ttsChunks: available values of type - local ttsChunksType = {{text = "4025",type = "PRE_RECORDED"},{ text = "Sapi",type = "SAPI_PHONEMES"}, {text = "LHplus", type = "LHPLUS_PHONEMES"}, {text = "Silence", type = "SILENCE"}} + local ttsChunksType = {{text = "4025",type = "PRE_RECORDED"},{ text = "Sapi",type = "SAPI_PHONEMES"}, {text = "LHplus", type = "LHPLUS_PHONEMES"}, {text = "Silence", type = "SILENCE"}, {text = "File.m4a", type = "FILE"}} for i=1,#ttsChunksType do Test["AlertManeuver_ttsChunksType" .. tostring(ttsChunksType[i].type)] = function(self) --mobile side: Alert request diff --git a/test_scripts/API/ATF_ChangeRegistration.lua b/test_scripts/API/ATF_ChangeRegistration.lua index 156903a8b0..fca5df458a 100644 --- a/test_scripts/API/ATF_ChangeRegistration.lua +++ b/test_scripts/API/ATF_ChangeRegistration.lua @@ -4832,7 +4832,7 @@ end --Requirement id in JAMA: SDLAQ-CRS-1047, SDLAQ-CRS-2678 --Verification criteria: - --The request result is success but the result code is WARNING when ttsName is recieved as a SAPI_PHONEMES or LHPLUS_PHONEMES or PRE_RECORDED or SILENCE. ttsName has not been sent to TTS component for futher processing, the other parts of the request are sent to HMI. The response's "Info" parameter provides the information that not supported TTSChunk type is used. + --The request result is success but the result code is WARNING when ttsName is recieved as a SAPI_PHONEMES or LHPLUS_PHONEMES or PRE_RECORDED or SILENCE or FILE. ttsName has not been sent to TTS component for futher processing, the other parts of the request are sent to HMI. The response's "Info" parameter provides the information that not supported TTSChunk type is used. --Begin Test case ResultCodeCheck.2.1 --Description: ttsName: type = PRE_RECORDED @@ -4879,6 +4879,16 @@ end self:changeRegistrationWarning(paramsSend) end --End Test case ResultCodeCheck.2.4 + + --Begin Test case ResultCodeCheck.2.5 + --Description: ttsName: type = FILE + function Test:ChangeRegistration_ttsNameTypeFILE() + local paramsSend = changeRegistrationAllParams() + paramsSend.ttsName[1].type = "FILE" + + self:changeRegistrationWarning(paramsSend) + end + --End Test case ResultCodeCheck.2.5 --End Test case ResultCodeCheck.2 ----------------------------------------------------------------------------------------- diff --git a/test_scripts/API/ATF_PerformAudioPassThru.lua b/test_scripts/API/ATF_PerformAudioPassThru.lua index 59b956b0a9..06ea0f7cad 100644 --- a/test_scripts/API/ATF_PerformAudioPassThru.lua +++ b/test_scripts/API/ATF_PerformAudioPassThru.lua @@ -1095,7 +1095,7 @@ end --Begin Test case PositiveRequestCheck.1.8 --Description: initialPrompt: type in bound - local initialPromptType = {"SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE"} + local initialPromptType = {"SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE"} for i=1, #initialPromptType do Test["PerformAudioPassThru_initialPromptType" .. initialPromptType[i]] = function(self) local params = createRequest() @@ -5339,7 +5339,7 @@ end -- Used when the user chooses to cancel the current Audio Pass Thru session and audio streaming -- GENERIC_ERROR comes as a result code on response when all other codes aren't applicable or the unknown issue occured. -- PerformAudioPassThru is finished being interrupted by the user who chooses to repeat the attempt from UI (e.g. by pressing the "Retry" button). The audio file written to the app's directory on SDL is cleaned up. The audio stream stops playing on mobile device. The resultCode of the request is returned as "RETRY". Success=true. - -- When "ttsChunks" are sent in the request but the type is different from "TEXT" (SAPI_PHONEMES, LHPLUS_PHONEMES, PRE_RECORDED or SILENCE), WARNINGS is returned as a result of request. Info parameter provides additional information about the case. General request result success=true in case of no errors from other components. + -- When "ttsChunks" are sent in the request but the type is different from "TEXT" (SAPI_PHONEMES, LHPLUS_PHONEMES, PRE_RECORDED, SILENCE, or FILE), WARNINGS is returned as a result of request. Info parameter provides additional information about the case. General request result success=true in case of no errors from other components. --Begin Test case ResultCodeCheck.1.1 --Description: Success resultCode from TTS, error resultCode from UI local resultCodes = {{code = "GENERIC_ERROR", success = false}, { code = "ABORTED", success = false}, { code = "REJECTED", success = false}, { code = "RETRY", success = true}, { code = "WARNINGS", success = true}} @@ -5615,9 +5615,9 @@ end --SDLAQ-CRS-1031 --Verification criteria: - -- When "ttsChunks" are sent in the request but the type is different from "TEXT" (SAPI_PHONEMES, LHPLUS_PHONEMES, PRE_RECORDED or SILENCE), WARNINGS is returned as a result of request. Info parameter provides additional information about the case. General request result success=true in case of no errors from other components. + -- When "ttsChunks" are sent in the request but the type is different from "TEXT" (SAPI_PHONEMES, LHPLUS_PHONEMES, PRE_RECORDED, SILENCE, or FILE), WARNINGS is returned as a result of request. Info parameter provides additional information about the case. General request result success=true in case of no errors from other components. --[[TODO: Update according to APPLINK-15261 - local ttsChunksType = {{text = "4025",type = "PRE_RECORDED"},{ text = "Sapi",type = "SAPI_PHONEMES"}, {text = "LHplus", type = "LHPLUS_PHONEMES"}, {text = "Silence", type = "SILENCE"}} + local ttsChunksType = {{text = "4025",type = "PRE_RECORDED"},{ text = "Sapi",type = "SAPI_PHONEMES"}, {text = "LHplus", type = "LHPLUS_PHONEMES"}, {text = "Silence", type = "SILENCE"}, {text = "File.m4a", type = "FILE"}} for i=1,#ttsChunksType do Test["PerformAudioPassThru_ttsChunksType" .. tostring(ttsChunksType[i].type)] = function(self) local params = createRequest() diff --git a/test_scripts/API/ATF_PerformInteraction.lua b/test_scripts/API/ATF_PerformInteraction.lua index 581fd3075d..1ed433d5a6 100644 --- a/test_scripts/API/ATF_PerformInteraction.lua +++ b/test_scripts/API/ATF_PerformInteraction.lua @@ -7176,7 +7176,7 @@ function Test:activationApp(appIDValue) --Verification criteria: - --1. When "ttsChunks" are sent within the request but the type is different from "TEXT" (SAPI_PHONEMES, LHPLUS_PHONEMES, PRE_RECORDED or SILENCE), WARNINGS is returned as a result in response. Info parameter provides additional information about the case. General result success=true in case of no errors from other components. + --1. When "ttsChunks" are sent within the request but the type is different from "TEXT" (SAPI_PHONEMES, LHPLUS_PHONEMES, PRE_RECORDED, SILENCE, or FILE), WARNINGS is returned as a result in response. Info parameter provides additional information about the case. General result success=true in case of no errors from other components. --2. Verifiable by the following sequence: --app->SDL: PerformInteraction (manual) @@ -7193,7 +7193,7 @@ function Test:activationApp(appIDValue) --SDL->app: PerformInteraction(WARNINGS,manualTextEntry) --Begin Test case ResultCodeCheck.6.1 - --Description: When "ttsChunks" are sent within the request but the type is different from "TEXT" (SAPI_PHONEMES, LHPLUS_PHONEMES, PRE_RECORDED or SILENCE), WARNINGS is returned as a result in response. Info parameter provides additional information about the case. General result success=true in case of no errors from other components. + --Description: When "ttsChunks" are sent within the request but the type is different from "TEXT" (SAPI_PHONEMES, LHPLUS_PHONEMES, PRE_RECORDED, SILENCE, or FILE), WARNINGS is returned as a result in response. Info parameter provides additional information about the case. General result success=true in case of no errors from other components. function Test:PI_VRWarningSuccessTrue() local paramsSend = performInteractionAllParams() paramsSend.interactionMode = "BOTH" diff --git a/test_scripts/API/ATF_RegisterAppInterface.lua b/test_scripts/API/ATF_RegisterAppInterface.lua index 2de5887f44..2365a3954a 100644 --- a/test_scripts/API/ATF_RegisterAppInterface.lua +++ b/test_scripts/API/ATF_RegisterAppInterface.lua @@ -12198,7 +12198,7 @@ end --Requirement id in JAMA: SDLAQ-CRS-1047, SDLAQ-CRS-1137 --Verification criteria: ---The request result is success but the result code is WARNING when ttsName is recieved as a SAPI_PHONEMES or LHPLUS_PHONEMES or PRE_RECORDED or SILENCE. ttsName has not been sent to TTS component for futher processing, the other parts of the request are sent to HMI. The response's "Info" parameter provides the information that not supported TTSChunk type is used. +--The request result is success but the result code is WARNING when ttsName is recieved as a SAPI_PHONEMES or LHPLUS_PHONEMES or PRE_RECORDED or SILENCE or FILE. ttsName has not been sent to TTS component for futher processing, the other parts of the request are sent to HMI. The response's "Info" parameter provides the information that not supported TTSChunk type is used. --Any TTSChunk sent from mobile app contains text to be spoken and a type of TTSChunk. SDL re-sends the valid RPC to HMI. --Begin Test case ResultCodeCheck.2.1 @@ -12369,6 +12369,48 @@ end --End Test case ResultCodeCheck.2.4 +--Begin Test case ResultCodeCheck.2.5 +--Description: ttsName: type = FILE + +-- Precondition: The application should be unregistered before next test. +function Test:UnregisterAppInterface_Success_ttsNameTypeFile() + UnregisterApplicationSessionOne(self) +end + +function Test:RegisterAppInterface_ttsNameTypeFile() + + --mobile side: RegisterAppInterface request + local CorIdRAI = self.mobileSession:SendRPC("RegisterAppInterface", + { + + syncMsgVersion = + { + majorVersion = 2, + minorVersion = 2, + }, + appName ="SyncProxyTester", + ttsName = + { + + { + text ="4005.wav", + type ="FILE", + }, + }, + isMediaApplication = AppMediaType, + languageDesired ="EN-US", + hmiDisplayLanguageDesired ="EN-US", + appID ="123456", + + }) + + --mobile side: RegisterAppInterface response + self.mobileSession:ExpectResponse(CorIdRAI, { success = true, resultCode = "WARNINGS"}) + +end + +--End Test case ResultCodeCheck.2.5 + --End Test case ResultCodeCheck.2 --Begin Test case ResultCodeCheck.3 diff --git a/test_scripts/API/ATF_SetGlobalProperties.lua b/test_scripts/API/ATF_SetGlobalProperties.lua index a6ff1ce208..5220f7dd9b 100644 --- a/test_scripts/API/ATF_SetGlobalProperties.lua +++ b/test_scripts/API/ATF_SetGlobalProperties.lua @@ -3703,6 +3703,146 @@ end --End test case PositiveResponseCheck.1.7 ----------------------------------------------------------------------------------------- + --Begin test case PositiveResponseCheck.1.120 + --Description: Check helpPrompt: type parameter is valid data (FILE) + + function Test:SetGlobalProperties_helpPrompt_type_FILE_SUCCESS() + + --mobile side: sending SetGlobalProperties request + local cid = self.mobileSession:SendRPC("SetGlobalProperties", + { + menuTitle = "Menu Title", + timeoutPrompt = + { + { + text = "Timeout prompt", + type = "TEXT" + } + }, + vrHelp = + { + { + position = 1, + image = + { + value = "action.png", + imageType = "DYNAMIC" + }, + text = "VR help item" + } + }, + menuIcon = + { + value = "action.png", + imageType = "DYNAMIC" + }, + helpPrompt = + { + { + text = "Help_prompt.m4a", + type = "FILE" + } + }, + vrHelpTitle = "VR help title", + keyboardProperties = + { + keyboardLayout = "QWERTY", + keypressMode = "SINGLE_KEYPRESS", + limitedCharacterList = + { + "a" + }, + language = "EN-US", + autoCompleteText = "Daemon, Freedom" + } + }) + + + --hmi side: expect TTS.SetGlobalProperties request + EXPECT_HMICALL("TTS.SetGlobalProperties", + { + timeoutPrompt = + { + { + text = "Timeout prompt", + type = "TEXT" + } + }, + helpPrompt = + { + { + text = "Help_prompt.m4a", + type = "FILE" + } + } + }) + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetGlobalProperties response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + + --hmi side: expect UI.SetGlobalProperties request + EXPECT_HMICALL("UI.SetGlobalProperties", + { + menuTitle = "Menu Title", + vrHelp = + { + { + position = 1, + --[=[ TODO: update after resolving APPLINK-16052 + + image = + { + imageType = "DYNAMIC", + value = strAppFolder .. "action.png" + },]=] + text = "VR help item" + } + }, + --Checked below + -- menuIcon = + -- { + -- imageType = "DYNAMIC", + -- value = strAppFolder .. "action.png" + -- }, + vrHelpTitle = "VR help title", + keyboardProperties = + { + keyboardLayout = "QWERTY", + keypressMode = "SINGLE_KEYPRESS", + --[=[ TODO: update after resolving APPLINK-16047 + + limitedCharacterList = + { + "a" + },]=] + language = "EN-US", + autoCompleteText = "Daemon, Freedom" + } + }) + :Timeout(iTimeout) + :ValidIf(function(_,data) + return Check_menuIconParams(data) + end) + :Do(function(_,data) + --hmi side: sending UI.SetGlobalProperties response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + --mobile side: expect SetGlobalProperties response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + --mobile side: expect OnHashChange notification + EXPECT_NOTIFICATION("OnHashChange") + end + + --End test case PositiveResponseCheck.1.120 + ----------------------------------------------------------------------------------------- + --Begin test case PositiveResponseCheck.1.8 --Description: Check helpPrompt: text parameter is lower bound @@ -6341,10 +6481,10 @@ end --End test case PositiveResponseCheck.1.20 ----------------------------------------------------------------------------------------- - --Begin test case PositiveResponseCheck.1.21 - --Description: Check timeoutPrompt: text parameter is lower bound + --Begin test case PositiveResponseCheck.1.121 + --Description: Check timeoutPrompt: type parameter is valid data (FILE) - function Test:SetGlobalProperties_timeoutPrompt_text_IsLowerBound_1_SUCCESS() + function Test:SetGlobalProperties_timeoutPrompt_type_FILE_SUCCESS() --mobile side: sending SetGlobalProperties request local cid = self.mobileSession:SendRPC("SetGlobalProperties", @@ -6353,8 +6493,8 @@ end timeoutPrompt = { { - text = "q", - type = "TEXT" + text = "Timeout_prompt.m4a", + type = "FILE" } }, vrHelp = @@ -6402,8 +6542,8 @@ end timeoutPrompt = { { - text = "q", - type = "TEXT" + text = "Timeout_prompt.m4a", + type = "FILE" } }, helpPrompt = @@ -6480,13 +6620,13 @@ end EXPECT_NOTIFICATION("OnHashChange") end - --End test case PositiveResponseCheck.1.21 + --End test case PositiveResponseCheck.1.121 ----------------------------------------------------------------------------------------- - --Begin test case PositiveResponseCheck.1.22 - --Description: Check timeoutPrompt: text parameter is upper bound + --Begin test case PositiveResponseCheck.1.21 + --Description: Check timeoutPrompt: text parameter is lower bound - function Test:SetGlobalProperties_timeoutPrompt_text_IsUpperBound_500_SUCCESS() + function Test:SetGlobalProperties_timeoutPrompt_text_IsLowerBound_1_SUCCESS() --mobile side: sending SetGlobalProperties request local cid = self.mobileSession:SendRPC("SetGlobalProperties", @@ -6495,7 +6635,7 @@ end timeoutPrompt = { { - text = "qA1_wB2_eA3_rB4_tA5_yB6_uA7_iB8_oA9_pB0_aA1_sB2_dA3_fB4_gA5_hB6_jA7_kB8_lA9_zB0_xA1_cB2_vA3_bB4_nA5_mB6_qA7_wB8_eA9_rB0_tA1_yB2_uA3_iB4_oA5_pB6_aA7_sB8_dA9_fB0_gA1_hB2_jA3_kB4_lA5_zB6_xA7_cB8_vA9_bB0_nA1_mB2_qA3_wB4_eA5_rB6_tA7_yB8_uA9_iB0_oA1_pB2_aA3_sB4_dA5_fB6_gA7_hB8_jA9_kB0_lA1_zB2_xA3_cB4_vA5_bB6_nA7_mB8_qA9_wB0_eA1_rB2_tA3_yB4_uA5_iB6_oA7_pB8_aA9_sB0_dA1_fB2_gA3_hB4_jA5_kB6_lA7_zB8_xA9_cB0_vA1_bB2_nA3_mB4_qA5_wB6_eA7_rB8_tA9_yB0_uA1_iB2_oA3_pB4_aA5_sB6_dA7_fB8_gA9_hB0_jA1_kB2_lA3_zB4_xA5_", + text = "q", type = "TEXT" } }, @@ -6544,7 +6684,7 @@ end timeoutPrompt = { { - text = "qA1_wB2_eA3_rB4_tA5_yB6_uA7_iB8_oA9_pB0_aA1_sB2_dA3_fB4_gA5_hB6_jA7_kB8_lA9_zB0_xA1_cB2_vA3_bB4_nA5_mB6_qA7_wB8_eA9_rB0_tA1_yB2_uA3_iB4_oA5_pB6_aA7_sB8_dA9_fB0_gA1_hB2_jA3_kB4_lA5_zB6_xA7_cB8_vA9_bB0_nA1_mB2_qA3_wB4_eA5_rB6_tA7_yB8_uA9_iB0_oA1_pB2_aA3_sB4_dA5_fB6_gA7_hB8_jA9_kB0_lA1_zB2_xA3_cB4_vA5_bB6_nA7_mB8_qA9_wB0_eA1_rB2_tA3_yB4_uA5_iB6_oA7_pB8_aA9_sB0_dA1_fB2_gA3_hB4_jA5_kB6_lA7_zB8_xA9_cB0_vA1_bB2_nA3_mB4_qA5_wB6_eA7_rB8_tA9_yB0_uA1_iB2_oA3_pB4_aA5_sB6_dA7_fB8_gA9_hB0_jA1_kB2_lA3_zB4_xA5_", + text = "q", type = "TEXT" } }, @@ -6622,13 +6762,13 @@ end EXPECT_NOTIFICATION("OnHashChange") end - --End test case PositiveResponseCheck.1.22 + --End test case PositiveResponseCheck.1.21 ----------------------------------------------------------------------------------------- - --Begin test case PositiveResponseCheck.1.23 - --Description: Check timeoutPrompt: text parameter contains space characters _SpaceCharacter_SpaceBefore + --Begin test case PositiveResponseCheck.1.22 + --Description: Check timeoutPrompt: text parameter is upper bound - function Test:SetGlobalProperties_timeoutPrompt_text__SpaceCharacter_SpaceBefore_SUCCESS() + function Test:SetGlobalProperties_timeoutPrompt_text_IsUpperBound_500_SUCCESS() --mobile side: sending SetGlobalProperties request local cid = self.mobileSession:SendRPC("SetGlobalProperties", @@ -6637,7 +6777,7 @@ end timeoutPrompt = { { - text = " SpaceBefore", + text = "qA1_wB2_eA3_rB4_tA5_yB6_uA7_iB8_oA9_pB0_aA1_sB2_dA3_fB4_gA5_hB6_jA7_kB8_lA9_zB0_xA1_cB2_vA3_bB4_nA5_mB6_qA7_wB8_eA9_rB0_tA1_yB2_uA3_iB4_oA5_pB6_aA7_sB8_dA9_fB0_gA1_hB2_jA3_kB4_lA5_zB6_xA7_cB8_vA9_bB0_nA1_mB2_qA3_wB4_eA5_rB6_tA7_yB8_uA9_iB0_oA1_pB2_aA3_sB4_dA5_fB6_gA7_hB8_jA9_kB0_lA1_zB2_xA3_cB4_vA5_bB6_nA7_mB8_qA9_wB0_eA1_rB2_tA3_yB4_uA5_iB6_oA7_pB8_aA9_sB0_dA1_fB2_gA3_hB4_jA5_kB6_lA7_zB8_xA9_cB0_vA1_bB2_nA3_mB4_qA5_wB6_eA7_rB8_tA9_yB0_uA1_iB2_oA3_pB4_aA5_sB6_dA7_fB8_gA9_hB0_jA1_kB2_lA3_zB4_xA5_", type = "TEXT" } }, @@ -6686,7 +6826,7 @@ end timeoutPrompt = { { - text = " SpaceBefore", + text = "qA1_wB2_eA3_rB4_tA5_yB6_uA7_iB8_oA9_pB0_aA1_sB2_dA3_fB4_gA5_hB6_jA7_kB8_lA9_zB0_xA1_cB2_vA3_bB4_nA5_mB6_qA7_wB8_eA9_rB0_tA1_yB2_uA3_iB4_oA5_pB6_aA7_sB8_dA9_fB0_gA1_hB2_jA3_kB4_lA5_zB6_xA7_cB8_vA9_bB0_nA1_mB2_qA3_wB4_eA5_rB6_tA7_yB8_uA9_iB0_oA1_pB2_aA3_sB4_dA5_fB6_gA7_hB8_jA9_kB0_lA1_zB2_xA3_cB4_vA5_bB6_nA7_mB8_qA9_wB0_eA1_rB2_tA3_yB4_uA5_iB6_oA7_pB8_aA9_sB0_dA1_fB2_gA3_hB4_jA5_kB6_lA7_zB8_xA9_cB0_vA1_bB2_nA3_mB4_qA5_wB6_eA7_rB8_tA9_yB0_uA1_iB2_oA3_pB4_aA5_sB6_dA7_fB8_gA9_hB0_jA1_kB2_lA3_zB4_xA5_", type = "TEXT" } }, @@ -6764,13 +6904,13 @@ end EXPECT_NOTIFICATION("OnHashChange") end - --End test case PositiveResponseCheck.1.23 + --End test case PositiveResponseCheck.1.22 ----------------------------------------------------------------------------------------- - --Begin test case PositiveResponseCheck.1.24 - --Description: Check timeoutPrompt: text parameter contains space characters SpaceAfter_SpaceCharacter_ + --Begin test case PositiveResponseCheck.1.23 + --Description: Check timeoutPrompt: text parameter contains space characters _SpaceCharacter_SpaceBefore - function Test:SetGlobalProperties_timeoutPrompt_text_SpaceAfter_SpaceCharacter__SUCCESS() + function Test:SetGlobalProperties_timeoutPrompt_text__SpaceCharacter_SpaceBefore_SUCCESS() --mobile side: sending SetGlobalProperties request local cid = self.mobileSession:SendRPC("SetGlobalProperties", @@ -6779,7 +6919,7 @@ end timeoutPrompt = { { - text = "SpaceAfter ", + text = " SpaceBefore", type = "TEXT" } }, @@ -6828,7 +6968,7 @@ end timeoutPrompt = { { - text = "SpaceAfter ", + text = " SpaceBefore", type = "TEXT" } }, @@ -6906,13 +7046,13 @@ end EXPECT_NOTIFICATION("OnHashChange") end - --End test case PositiveResponseCheck.1.24 + --End test case PositiveResponseCheck.1.23 ----------------------------------------------------------------------------------------- - --Begin test case PositiveResponseCheck.1.25 - --Description: Check timeoutPrompt: text parameter contains space characters Space_SpaceCharacter_In_SpaceCharacter_The_SpaceCharacter_Middle + --Begin test case PositiveResponseCheck.1.24 + --Description: Check timeoutPrompt: text parameter contains space characters SpaceAfter_SpaceCharacter_ - function Test:SetGlobalProperties_timeoutPrompt_text_Space_SpaceCharacter_In_SpaceCharacter_The_SpaceCharacter_Middle_SUCCESS() + function Test:SetGlobalProperties_timeoutPrompt_text_SpaceAfter_SpaceCharacter__SUCCESS() --mobile side: sending SetGlobalProperties request local cid = self.mobileSession:SendRPC("SetGlobalProperties", @@ -6921,7 +7061,7 @@ end timeoutPrompt = { { - text = "Space In The Middle", + text = "SpaceAfter ", type = "TEXT" } }, @@ -6970,7 +7110,7 @@ end timeoutPrompt = { { - text = "Space In The Middle", + text = "SpaceAfter ", type = "TEXT" } }, @@ -7048,13 +7188,13 @@ end EXPECT_NOTIFICATION("OnHashChange") end - --End test case PositiveResponseCheck.1.25 + --End test case PositiveResponseCheck.1.24 ----------------------------------------------------------------------------------------- - --Begin test case PositiveResponseCheck.1.26 - --Description: Check timeoutPrompt: text parameter contains space characters _SpaceCharacter_Space_SpaceCharacter_Every_SpaceCharacter_Where_SpaceCharacter_ + --Begin test case PositiveResponseCheck.1.25 + --Description: Check timeoutPrompt: text parameter contains space characters Space_SpaceCharacter_In_SpaceCharacter_The_SpaceCharacter_Middle - function Test:SetGlobalProperties_timeoutPrompt_text__SpaceCharacter_Space_SpaceCharacter_Every_SpaceCharacter_Where_SpaceCharacter__SUCCESS() + function Test:SetGlobalProperties_timeoutPrompt_text_Space_SpaceCharacter_In_SpaceCharacter_The_SpaceCharacter_Middle_SUCCESS() --mobile side: sending SetGlobalProperties request local cid = self.mobileSession:SendRPC("SetGlobalProperties", @@ -7063,7 +7203,7 @@ end timeoutPrompt = { { - text = " Space Every Where ", + text = "Space In The Middle", type = "TEXT" } }, @@ -7112,7 +7252,7 @@ end timeoutPrompt = { { - text = " Space Every Where ", + text = "Space In The Middle", type = "TEXT" } }, @@ -7150,7 +7290,7 @@ end text = "VR help item" } }, - --checked below + --Checked below -- menuIcon = -- { -- imageType = "DYNAMIC", @@ -7190,13 +7330,13 @@ end EXPECT_NOTIFICATION("OnHashChange") end - --End test case PositiveResponseCheck.1.26 + --End test case PositiveResponseCheck.1.25 ----------------------------------------------------------------------------------------- - --Begin test case PositiveResponseCheck.1.27 - --Description: Check vrHelpTitle parameter is lower bound + --Begin test case PositiveResponseCheck.1.26 + --Description: Check timeoutPrompt: text parameter contains space characters _SpaceCharacter_Space_SpaceCharacter_Every_SpaceCharacter_Where_SpaceCharacter_ - function Test:SetGlobalProperties_vrHelpTitle_IsLowerBound_1_SUCCESS() + function Test:SetGlobalProperties_timeoutPrompt_text__SpaceCharacter_Space_SpaceCharacter_Every_SpaceCharacter_Where_SpaceCharacter__SUCCESS() --mobile side: sending SetGlobalProperties request local cid = self.mobileSession:SendRPC("SetGlobalProperties", @@ -7205,7 +7345,7 @@ end timeoutPrompt = { { - text = "Timeout prompt", + text = " Space Every Where ", type = "TEXT" } }, @@ -7233,7 +7373,7 @@ end type = "TEXT" } }, - vrHelpTitle = "q", + vrHelpTitle = "VR help title", keyboardProperties = { keyboardLayout = "QWERTY", @@ -7254,7 +7394,7 @@ end timeoutPrompt = { { - text = "Timeout prompt", + text = " Space Every Where ", type = "TEXT" } }, @@ -7292,13 +7432,13 @@ end text = "VR help item" } }, - --Checked below + --checked below -- menuIcon = -- { -- imageType = "DYNAMIC", -- value = strAppFolder .. "action.png" -- }, - vrHelpTitle = "q", + vrHelpTitle = "VR help title", keyboardProperties = { keyboardLayout = "QWERTY", @@ -7332,13 +7472,13 @@ end EXPECT_NOTIFICATION("OnHashChange") end - --End test case PositiveResponseCheck.1.27 + --End test case PositiveResponseCheck.1.26 ----------------------------------------------------------------------------------------- - --Begin test case PositiveResponseCheck.1.28 - --Description: Check vrHelpTitle parameter is upper bound + --Begin test case PositiveResponseCheck.1.27 + --Description: Check vrHelpTitle parameter is lower bound - function Test:SetGlobalProperties_vrHelpTitle_IsUpperBound_500_SUCCESS() + function Test:SetGlobalProperties_vrHelpTitle_IsLowerBound_1_SUCCESS() --mobile side: sending SetGlobalProperties request local cid = self.mobileSession:SendRPC("SetGlobalProperties", @@ -7375,7 +7515,7 @@ end type = "TEXT" } }, - vrHelpTitle = "qA1_wB2_eA3_rB4_tA5_yB6_uA7_iB8_oA9_pB0_aA1_sB2_dA3_fB4_gA5_hB6_jA7_kB8_lA9_zB0_xA1_cB2_vA3_bB4_nA5_mB6_qA7_wB8_eA9_rB0_tA1_yB2_uA3_iB4_oA5_pB6_aA7_sB8_dA9_fB0_gA1_hB2_jA3_kB4_lA5_zB6_xA7_cB8_vA9_bB0_nA1_mB2_qA3_wB4_eA5_rB6_tA7_yB8_uA9_iB0_oA1_pB2_aA3_sB4_dA5_fB6_gA7_hB8_jA9_kB0_lA1_zB2_xA3_cB4_vA5_bB6_nA7_mB8_qA9_wB0_eA1_rB2_tA3_yB4_uA5_iB6_oA7_pB8_aA9_sB0_dA1_fB2_gA3_hB4_jA5_kB6_lA7_zB8_xA9_cB0_vA1_bB2_nA3_mB4_qA5_wB6_eA7_rB8_tA9_yB0_uA1_iB2_oA3_pB4_aA5_sB6_dA7_fB8_gA9_hB0_jA1_kB2_lA3_zB4_xA5_", + vrHelpTitle = "q", keyboardProperties = { keyboardLayout = "QWERTY", @@ -7440,7 +7580,7 @@ end -- imageType = "DYNAMIC", -- value = strAppFolder .. "action.png" -- }, - vrHelpTitle = "qA1_wB2_eA3_rB4_tA5_yB6_uA7_iB8_oA9_pB0_aA1_sB2_dA3_fB4_gA5_hB6_jA7_kB8_lA9_zB0_xA1_cB2_vA3_bB4_nA5_mB6_qA7_wB8_eA9_rB0_tA1_yB2_uA3_iB4_oA5_pB6_aA7_sB8_dA9_fB0_gA1_hB2_jA3_kB4_lA5_zB6_xA7_cB8_vA9_bB0_nA1_mB2_qA3_wB4_eA5_rB6_tA7_yB8_uA9_iB0_oA1_pB2_aA3_sB4_dA5_fB6_gA7_hB8_jA9_kB0_lA1_zB2_xA3_cB4_vA5_bB6_nA7_mB8_qA9_wB0_eA1_rB2_tA3_yB4_uA5_iB6_oA7_pB8_aA9_sB0_dA1_fB2_gA3_hB4_jA5_kB6_lA7_zB8_xA9_cB0_vA1_bB2_nA3_mB4_qA5_wB6_eA7_rB8_tA9_yB0_uA1_iB2_oA3_pB4_aA5_sB6_dA7_fB8_gA9_hB0_jA1_kB2_lA3_zB4_xA5_", + vrHelpTitle = "q", keyboardProperties = { keyboardLayout = "QWERTY", @@ -7474,13 +7614,13 @@ end EXPECT_NOTIFICATION("OnHashChange") end - --End test case PositiveResponseCheck.1.28 + --End test case PositiveResponseCheck.1.27 ----------------------------------------------------------------------------------------- - --Begin test case PositiveResponseCheck.1.29 - --Description: Check vrHelpTitle parameter contains space characters _SpaceCharacter_SpaceBefore + --Begin test case PositiveResponseCheck.1.28 + --Description: Check vrHelpTitle parameter is upper bound - function Test:SetGlobalProperties_vrHelpTitle__SpaceCharacter_SpaceBefore_SUCCESS() + function Test:SetGlobalProperties_vrHelpTitle_IsUpperBound_500_SUCCESS() --mobile side: sending SetGlobalProperties request local cid = self.mobileSession:SendRPC("SetGlobalProperties", @@ -7517,7 +7657,7 @@ end type = "TEXT" } }, - vrHelpTitle = " SpaceBefore", + vrHelpTitle = "qA1_wB2_eA3_rB4_tA5_yB6_uA7_iB8_oA9_pB0_aA1_sB2_dA3_fB4_gA5_hB6_jA7_kB8_lA9_zB0_xA1_cB2_vA3_bB4_nA5_mB6_qA7_wB8_eA9_rB0_tA1_yB2_uA3_iB4_oA5_pB6_aA7_sB8_dA9_fB0_gA1_hB2_jA3_kB4_lA5_zB6_xA7_cB8_vA9_bB0_nA1_mB2_qA3_wB4_eA5_rB6_tA7_yB8_uA9_iB0_oA1_pB2_aA3_sB4_dA5_fB6_gA7_hB8_jA9_kB0_lA1_zB2_xA3_cB4_vA5_bB6_nA7_mB8_qA9_wB0_eA1_rB2_tA3_yB4_uA5_iB6_oA7_pB8_aA9_sB0_dA1_fB2_gA3_hB4_jA5_kB6_lA7_zB8_xA9_cB0_vA1_bB2_nA3_mB4_qA5_wB6_eA7_rB8_tA9_yB0_uA1_iB2_oA3_pB4_aA5_sB6_dA7_fB8_gA9_hB0_jA1_kB2_lA3_zB4_xA5_", keyboardProperties = { keyboardLayout = "QWERTY", @@ -7582,7 +7722,7 @@ end -- imageType = "DYNAMIC", -- value = strAppFolder .. "action.png" -- }, - vrHelpTitle = " SpaceBefore", + vrHelpTitle = "qA1_wB2_eA3_rB4_tA5_yB6_uA7_iB8_oA9_pB0_aA1_sB2_dA3_fB4_gA5_hB6_jA7_kB8_lA9_zB0_xA1_cB2_vA3_bB4_nA5_mB6_qA7_wB8_eA9_rB0_tA1_yB2_uA3_iB4_oA5_pB6_aA7_sB8_dA9_fB0_gA1_hB2_jA3_kB4_lA5_zB6_xA7_cB8_vA9_bB0_nA1_mB2_qA3_wB4_eA5_rB6_tA7_yB8_uA9_iB0_oA1_pB2_aA3_sB4_dA5_fB6_gA7_hB8_jA9_kB0_lA1_zB2_xA3_cB4_vA5_bB6_nA7_mB8_qA9_wB0_eA1_rB2_tA3_yB4_uA5_iB6_oA7_pB8_aA9_sB0_dA1_fB2_gA3_hB4_jA5_kB6_lA7_zB8_xA9_cB0_vA1_bB2_nA3_mB4_qA5_wB6_eA7_rB8_tA9_yB0_uA1_iB2_oA3_pB4_aA5_sB6_dA7_fB8_gA9_hB0_jA1_kB2_lA3_zB4_xA5_", keyboardProperties = { keyboardLayout = "QWERTY", @@ -7616,13 +7756,13 @@ end EXPECT_NOTIFICATION("OnHashChange") end - --End test case PositiveResponseCheck.1.29 + --End test case PositiveResponseCheck.1.28 ----------------------------------------------------------------------------------------- - --Begin test case PositiveResponseCheck.1.30 - --Description: Check vrHelpTitle parameter contains space characters SpaceAfter_SpaceCharacter_ + --Begin test case PositiveResponseCheck.1.29 + --Description: Check vrHelpTitle parameter contains space characters _SpaceCharacter_SpaceBefore - function Test:SetGlobalProperties_vrHelpTitle_SpaceAfter_SpaceCharacter__SUCCESS() + function Test:SetGlobalProperties_vrHelpTitle__SpaceCharacter_SpaceBefore_SUCCESS() --mobile side: sending SetGlobalProperties request local cid = self.mobileSession:SendRPC("SetGlobalProperties", @@ -7659,7 +7799,7 @@ end type = "TEXT" } }, - vrHelpTitle = "SpaceAfter ", + vrHelpTitle = " SpaceBefore", keyboardProperties = { keyboardLayout = "QWERTY", @@ -7724,7 +7864,7 @@ end -- imageType = "DYNAMIC", -- value = strAppFolder .. "action.png" -- }, - vrHelpTitle = "SpaceAfter ", + vrHelpTitle = " SpaceBefore", keyboardProperties = { keyboardLayout = "QWERTY", @@ -7758,7 +7898,149 @@ end EXPECT_NOTIFICATION("OnHashChange") end - --End test case PositiveResponseCheck.1.30 + --End test case PositiveResponseCheck.1.29 + ----------------------------------------------------------------------------------------- + + --Begin test case PositiveResponseCheck.1.30 + --Description: Check vrHelpTitle parameter contains space characters SpaceAfter_SpaceCharacter_ + + function Test:SetGlobalProperties_vrHelpTitle_SpaceAfter_SpaceCharacter__SUCCESS() + + --mobile side: sending SetGlobalProperties request + local cid = self.mobileSession:SendRPC("SetGlobalProperties", + { + menuTitle = "Menu Title", + timeoutPrompt = + { + { + text = "Timeout prompt", + type = "TEXT" + } + }, + vrHelp = + { + { + position = 1, + image = + { + value = "action.png", + imageType = "DYNAMIC" + }, + text = "VR help item" + } + }, + menuIcon = + { + value = "action.png", + imageType = "DYNAMIC" + }, + helpPrompt = + { + { + text = "Help prompt", + type = "TEXT" + } + }, + vrHelpTitle = "SpaceAfter ", + keyboardProperties = + { + keyboardLayout = "QWERTY", + keypressMode = "SINGLE_KEYPRESS", + limitedCharacterList = + { + "a" + }, + language = "EN-US", + autoCompleteText = "Daemon, Freedom" + } + }) + + + --hmi side: expect TTS.SetGlobalProperties request + EXPECT_HMICALL("TTS.SetGlobalProperties", + { + timeoutPrompt = + { + { + text = "Timeout prompt", + type = "TEXT" + } + }, + helpPrompt = + { + { + text = "Help prompt", + type = "TEXT" + } + } + }) + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetGlobalProperties response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + + --hmi side: expect UI.SetGlobalProperties request + EXPECT_HMICALL("UI.SetGlobalProperties", + { + menuTitle = "Menu Title", + vrHelp = + { + { + position = 1, + --[=[ TODO: update after resolving APPLINK-16052 + + image = + { + imageType = "DYNAMIC", + value = strAppFolder .. "action.png" + },]=] + text = "VR help item" + } + }, + --Checked below + -- menuIcon = + -- { + -- imageType = "DYNAMIC", + -- value = strAppFolder .. "action.png" + -- }, + vrHelpTitle = "SpaceAfter ", + keyboardProperties = + { + keyboardLayout = "QWERTY", + keypressMode = "SINGLE_KEYPRESS", + --[=[ TODO: update after resolving APPLINK-16047 + + limitedCharacterList = + { + "a" + },]=] + language = "EN-US", + autoCompleteText = "Daemon, Freedom" + } + }) + :Timeout(iTimeout) + :ValidIf(function(_,data) + return Check_menuIconParams(data) + end) + :Do(function(_,data) + --hmi side: sending UI.SetGlobalProperties response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + + --mobile side: expect SetGlobalProperties response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + --mobile side: expect OnHashChange notification + EXPECT_NOTIFICATION("OnHashChange") + end + + --End test case PositiveResponseCheck.1.30 ----------------------------------------------------------------------------------------- --Begin test case PositiveResponseCheck.1.31 @@ -17558,6 +17840,149 @@ end --End test case PositiveResponseCheck.1.110 ----------------------------------------------------------------------------------------- +--Begin test case PositiveResponseCheck.1.122 + --Description: Check timeoutPrompt: type parameter (ttsChunks) is not supported data (FILE) + + function Test:SetGlobalProperties_timeoutPrompt_type_FILE_WARNINGS() + + --mobile side: sending SetGlobalProperties request + local cid = self.mobileSession:SendRPC("SetGlobalProperties", + { + menuTitle = "Menu Title", + timeoutPrompt = + { + { + text = "Timeout_prompt.m4a", + type = "FILE" + } + }, + vrHelp = + { + { + position = 1, + image = + { + value = "action.png", + imageType = "DYNAMIC" + }, + text = "VR help item" + } + }, + menuIcon = + { + value = "action.png", + imageType = "DYNAMIC" + }, + helpPrompt = + { + { + text = "Help prompt", + type = "TEXT" + } + }, + vrHelpTitle = "VR help title", + keyboardProperties = + { + keyboardLayout = "QWERTY", + keypressMode = "SINGLE_KEYPRESS", + limitedCharacterList = + { + "a" + }, + language = "EN-US", + autoCompleteText = "Daemon, Freedom" + } + }) + + + --hmi side: expect TTS.SetGlobalProperties request + EXPECT_HMICALL("TTS.SetGlobalProperties", + { + timeoutPrompt = + { + { + text = "Timeout_prompt.m4a", + type = "FILE" + } + }, + helpPrompt = + { + { + text = "Help prompt", + type = "TEXT" + } + } + }) + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending TTS.SetGlobalProperties response + self.hmiConnection:SendResponse(data.id, data.method, "WARNINGS", {}) + end) + + + + --hmi side: expect UI.SetGlobalProperties request + EXPECT_HMICALL("UI.SetGlobalProperties", + { + menuTitle = "Menu Title", + vrHelp = + { + { + position = 1, + --[=[ TODO: update after resolving APPLINK-16052 + + image = + { + imageType = "DYNAMIC", + value = strAppFolder .. "action.png" + },]=] + text = "VR help item" + } + }, + --Checked below + -- menuIcon = + -- { + -- imageType = "DYNAMIC", + -- value = strAppFolder .. "action.png" + -- }, + vrHelpTitle = "VR help title", + keyboardProperties = + { + keyboardLayout = "QWERTY", + keypressMode = "SINGLE_KEYPRESS", + --[=[ TODO: update after resolving APPLINK-16047 + + limitedCharacterList = + { + "a" + },]=] + language = "EN-US", + autoCompleteText = "Daemon, Freedom" + } + }) + :Timeout(iTimeout) + :ValidIf(function(_,data) + return Check_menuIconParams(data) + end) + :Do(function(_,data) + --hmi side: sending UI.SetGlobalProperties response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + + --mobile side: expect SetGlobalProperties response + EXPECT_RESPONSE(cid, { success = true, resultCode = "WARNINGS"}) + :Timeout(iTimeout) + + --mobile side: expect OnHashChange notification + EXPECT_NOTIFICATION("OnHashChange") + + end + + --End test case PositiveResponseCheck.1.122 + ----------------------------------------------------------------------------------------- + --Begin test case PositiveResponseCheck.1.111 --Description: Check helpPrompt: type parameter (ttsChunks) is not supported data (SAPI_PHONEMES) @@ -18123,6 +18548,148 @@ end --End test case PositiveResponseCheck.1.114 ----------------------------------------------------------------------------------------- + + --Begin test case PositiveResponseCheck.1.123 + --Description: Check helpPrompt: type parameter (ttsChunks) is not supported data (FILE) + + function Test:SetGlobalProperties_helpPrompt_type_FILE_WARNINGS() + + --mobile side: sending SetGlobalProperties request + local cid = self.mobileSession:SendRPC("SetGlobalProperties", + { + menuTitle = "Menu Title", + timeoutPrompt = + { + { + text = "Timeout prompt", + type = "TEXT" + } + }, + vrHelp = + { + { + position = 1, + image = + { + value = "action.png", + imageType = "DYNAMIC" + }, + text = "VR help item" + } + }, + menuIcon = + { + value = "action.png", + imageType = "DYNAMIC" + }, + helpPrompt = + { + { + text = "Help_prompt.m4a", + type = "FILE" + } + }, + vrHelpTitle = "VR help title", + keyboardProperties = + { + keyboardLayout = "QWERTY", + keypressMode = "SINGLE_KEYPRESS", + limitedCharacterList = + { + "a" + }, + language = "EN-US", + autoCompleteText = "Daemon, Freedom" + } + }) + + + --hmi side: expect TTS.SetGlobalProperties request + EXPECT_HMICALL("TTS.SetGlobalProperties", + { + timeoutPrompt = + { + { + text = "Timeout prompt", + type = "TEXT" + } + }, + helpPrompt = + { + { + text = "Help_prompt.m4a", + type = "FILE" + } + } + }) + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending TTS.SetGlobalProperties response + self.hmiConnection:SendResponse(data.id, data.method, "WARNINGS", {}) + end) + + + + --hmi side: expect UI.SetGlobalProperties request + EXPECT_HMICALL("UI.SetGlobalProperties", + { + menuTitle = "Menu Title", + vrHelp = + { + { + position = 1, + --[=[ TODO: update after resolving APPLINK-16052 + + image = + { + imageType = "DYNAMIC", + value = strAppFolder .. "action.png" + },]=] + text = "VR help item" + } + }, + --Checked below + -- menuIcon = + -- { + -- imageType = "DYNAMIC", + -- value = strAppFolder .. "action.png" + -- }, + vrHelpTitle = "VR help title", + keyboardProperties = + { + keyboardLayout = "QWERTY", + keypressMode = "SINGLE_KEYPRESS", + --[=[ TODO: update after resolving APPLINK-16047 + + limitedCharacterList = + { + "a" + },]=] + language = "EN-US", + autoCompleteText = "Daemon, Freedom" + } + }) + :Timeout(iTimeout) + :ValidIf(function(_,data) + return Check_menuIconParams(data) + end) + :Do(function(_,data) + --hmi side: sending UI.SetGlobalProperties response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + + --mobile side: expect SetGlobalProperties response + EXPECT_RESPONSE(cid, { success = true, resultCode = "WARNINGS"}) + :Timeout(iTimeout) + + --mobile side: expect OnHashChange notification + EXPECT_NOTIFICATION("OnHashChange") + end + + --End test case PositiveResponseCheck.1.123 + ----------------------------------------------------------------------------------------- --Begin test case PositiveResponseCheck.1.115 --Description: Check request the value of with menuIcon image = JPG diff --git a/test_scripts/API/ATF_Speak.lua b/test_scripts/API/ATF_Speak.lua index a4d2488839..45435e4028 100644 --- a/test_scripts/API/ATF_Speak.lua +++ b/test_scripts/API/ATF_Speak.lua @@ -174,7 +174,7 @@ end --7. IsOutUpperBound --8. Check children parameters: --text: minlength="0" maxlength="500" type="String" - --type: type="SpeechCapabilities": "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" + --type: type="SpeechCapabilities": "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" ----------------------------------------------------------------------------------------------- local Request = Test:createRequest() diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_RegisterApp.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_RegisterApp.lua index c4272b1a86..6a317c5606 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_RegisterApp.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_RegisterApp.lua @@ -411,7 +411,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) }, presetBankCapabilities = { onScreenPresetsAvailable = true } } - local speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE"} + local speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE"} ExpectRequest("Buttons.GetCapabilities", true, buttons_capabilities) ExpectRequest("VR.GetCapabilities", true, { vrCapabilities = { "TEXT" } }) --UPDATED @@ -420,7 +420,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) --UPDATED ExpectRequest("TTS.GetCapabilities", true, { - speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" }, + speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" }, prerecordedSpeechCapabilities = { "HELP_JINGLE", @@ -664,7 +664,7 @@ local function RegisterApplication_Check_TTS_Parameters_From_HMI_capabilities_js -- As TTS.GetCapabilities is received: GetCapabilities_language = "EN-US" -- - GetCapabilities_speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE"} + GetCapabilities_speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE"} GetCapabilities_prerecordedSpeechCapabilities = { "HELP_JINGLE", @@ -737,7 +737,7 @@ local function RegisterApplication_Check_TTS_Parameters_From_HMI_capabilities_js -- As TTS.GetCapabilities is received: GetCapabilities_language = "EN-US" -- - GetCapabilities_speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE"} + GetCapabilities_speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE"} GetCapabilities_prerecordedSpeechCapabilities = { "HELP_JINGLE", @@ -807,7 +807,7 @@ local function RegisterApplication_Check_TTS_Parameters_From_HMI_capabilities_js -- As TTS.GetCapabilities is received: GetCapabilities_language = "EN-US" -- - GetCapabilities_speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE"} + GetCapabilities_speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE"} GetCapabilities_prerecordedSpeechCapabilities = { "HELP_JINGLE", @@ -969,7 +969,7 @@ local function RegisterApplication_Check_TTS_Parameters_From_HMI_capabilities_js -- As TTS.GetCapabilities is received: GetCapabilities_language = "EN-US" -- - GetCapabilities_speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE"} + GetCapabilities_speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE"} GetCapabilities_prerecordedSpeechCapabilities = { "HELP_JINGLE", diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Single_RPC.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Single_RPC.lua index ef5ec147a4..c441695a42 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Single_RPC.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Single_RPC.lua @@ -400,14 +400,14 @@ function Test:initHMI_onReady_TTS_IsReady(case) }, presetBankCapabilities = { onScreenPresetsAvailable = true } } - local speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE"} + local speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE"} ExpectRequest("Buttons.GetCapabilities", true, buttons_capabilities) ExpectRequest("VR.GetCapabilities", true, { vrCapabilities = { "TEXT" } }) ExpectRequest("TTS.GetCapabilities", true, speech_capabilities) :Times(0) ExpectRequest("TTS.GetCapabilities", true, { - speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" }, + speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" }, prerecordedSpeechCapabilities = { "HELP_JINGLE", diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_1.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_1.lua index 116907e2df..e0a271eaab 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_1.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_1.lua @@ -428,14 +428,14 @@ function Test:initHMI_onReady_TTS_IsReady(case) }, presetBankCapabilities = { onScreenPresetsAvailable = true } } - local speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE"} + local speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE"} ExpectRequest("Buttons.GetCapabilities", true, buttons_capabilities) ExpectRequest("VR.GetCapabilities", true, { vrCapabilities = { "TEXT" } }) ExpectRequest("TTS.GetCapabilities", true, speech_capabilities) :Times(0) ExpectRequest("TTS.GetCapabilities", true, { - speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" }, + speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" }, prerecordedSpeechCapabilities = { "HELP_JINGLE", diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_2.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_2.lua index a5ef514904..c4372e0e92 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_2.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_2.lua @@ -434,7 +434,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) -- :Times(0) ExpectRequest("TTS.GetCapabilities", true, { - speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" }, + speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" }, prerecordedSpeechCapabilities = { "HELP_JINGLE", diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_3.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_3.lua index 95790f1770..413909e870 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_3.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_3.lua @@ -431,14 +431,14 @@ function Test:initHMI_onReady_TTS_IsReady(case) }, presetBankCapabilities = { onScreenPresetsAvailable = true } } - local speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE"} + local speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE"} ExpectRequest("Buttons.GetCapabilities", true, buttons_capabilities) ExpectRequest("VR.GetCapabilities", true, { vrCapabilities = { "TEXT" } }) ExpectRequest("TTS.GetCapabilities", true, speech_capabilities) :Times(0) ExpectRequest("TTS.GetCapabilities", true, { - speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" }, + speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" }, prerecordedSpeechCapabilities = { "HELP_JINGLE", diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_RETRY.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_RETRY.lua index cfa91dc66a..595f96dd60 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_RETRY.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_RETRY.lua @@ -417,7 +417,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) ExpectRequest("TTS.GetCapabilities", true, { - speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" }, + speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" }, prerecordedSpeechCapabilities = { "HELP_JINGLE", diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SAVED.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SAVED.lua index b31c4cf012..f9e590b800 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SAVED.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SAVED.lua @@ -418,7 +418,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) ExpectRequest("TTS.GetCapabilities", true, { - speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" }, + speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" }, prerecordedSpeechCapabilities = { "HELP_JINGLE", diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SUCCESS.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SUCCESS.lua index 7f1b2f9649..b1f022bdc3 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SUCCESS.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SUCCESS.lua @@ -419,7 +419,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) ExpectRequest("TTS.GetCapabilities", true, { - speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" }, + speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" }, prerecordedSpeechCapabilities = { "HELP_JINGLE", diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_WARNINGS.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_WARNINGS.lua index b69e60c8a7..8cfbe98e6a 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_WARNINGS.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_WARNINGS.lua @@ -416,7 +416,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) ExpectRequest("TTS.GetCapabilities", true, { - speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" }, + speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" }, prerecordedSpeechCapabilities = { "HELP_JINGLE", diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_WRONG_LANGUAGE.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_WRONG_LANGUAGE.lua index fc6605b3a5..2a8e3175f0 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_WRONG_LANGUAGE.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_WRONG_LANGUAGE.lua @@ -418,7 +418,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) ExpectRequest("TTS.GetCapabilities", true, { - speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" }, + speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" }, prerecordedSpeechCapabilities = { "HELP_JINGLE", diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_RegisterApp.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_RegisterApp.lua index f6241bff60..43bc24270a 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_RegisterApp.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_RegisterApp.lua @@ -403,11 +403,11 @@ function Test:initHMI_onReady_TTS_IsReady(case) }, presetBankCapabilities = { onScreenPresetsAvailable = true } } - local speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE"} + local speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE"} ExpectRequest("Buttons.GetCapabilities", true, buttons_capabilities) ExpectRequest("VR.GetCapabilities", true, { vrCapabilities = { "TEXT" } }) ExpectRequest("TTS.GetCapabilities", true, { - speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" }, + speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" }, prerecordedSpeechCapabilities = { "HELP_JINGLE", diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_SingleRPC.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_SingleRPC.lua index 552fe659ae..cd7a720701 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_SingleRPC.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_SingleRPC.lua @@ -402,14 +402,14 @@ function Test:initHMI_onReady_TTS_IsReady(case) }, presetBankCapabilities = { onScreenPresetsAvailable = true } } - local speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE"} + local speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE"} ExpectRequest("Buttons.GetCapabilities", true, buttons_capabilities) ExpectRequest("VR.GetCapabilities", true, { vrCapabilities = { "TEXT" } }) ExpectRequest("TTS.GetCapabilities", true, speech_capabilities) :Times(0) ExpectRequest("TTS.GetCapabilities", true, { - speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" }, + speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" }, prerecordedSpeechCapabilities = { "HELP_JINGLE", diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_Split_RPC.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_Split_RPC.lua index 79e04650eb..c6ee4e4332 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_Split_RPC.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_Split_RPC.lua @@ -402,14 +402,14 @@ function Test:initHMI_onReady_TTS_IsReady(case) }, presetBankCapabilities = { onScreenPresetsAvailable = true } } - local speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE"} + local speech_capabilities = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE"} ExpectRequest("Buttons.GetCapabilities", true, buttons_capabilities) ExpectRequest("VR.GetCapabilities", true, { vrCapabilities = { "TEXT" } }) ExpectRequest("TTS.GetCapabilities", true, speech_capabilities) :Times(0) ExpectRequest("TTS.GetCapabilities", true, { - speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" }, + speechCapabilities = { "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" }, prerecordedSpeechCapabilities = { "HELP_JINGLE", diff --git a/test_scripts/ATF_Expanded_smoke_test_Genivi.lua b/test_scripts/ATF_Expanded_smoke_test_Genivi.lua index 08a5ac5f62..b2a0b52d3e 100644 --- a/test_scripts/ATF_Expanded_smoke_test_Genivi.lua +++ b/test_scripts/ATF_Expanded_smoke_test_Genivi.lua @@ -46,7 +46,8 @@ local ttsChunksType = { { text = "4025", type = "PRE_RECORDED" }, { text = "Sapi", type = "SAPI_PHONEMES" }, { text = "LHplus", type = "LHPLUS_PHONEMES" }, - { text = "Silence", type = "SILENCE" } + { text = "Silence", type = "SILENCE" }, + { text = "File.m4a", type = "FILE" } } local positiveChoiceSets = { { choiceID = 1001, menuName ="Choice1001", image = { value = pathToAppFolder .. "icon.png", imageType ="DYNAMIC" } }, @@ -1400,8 +1401,8 @@ local blockId = 1 ----------------------------------------------------------------------------------------- - --Description: ttschunk in speechCapabilities is sent with values: SAPI_PHONEMES, LHPLUS_PHONEMES, PRE_RECORDED, SILENCE - local SpeechCapabilitiesArray = {"SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE"} + --Description: ttschunk in speechCapabilities is sent with values: SAPI_PHONEMES, LHPLUS_PHONEMES, PRE_RECORDED, SILENCE, FILE + local SpeechCapabilitiesArray = {"SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE"} for i=1,#SpeechCapabilitiesArray do @@ -4714,7 +4715,7 @@ local blockId = 1 -- request is sent with all parameters missing -- request is sent with soft buttons and image type DYNAMIC -- request is sent with soft buttons and image type STATIC - -- Request is sent with with different ttsChunks type both supported (TEXT) and not supported (PRE_RECORDED, SAPI_PHONEMES, LHPLUS_PHONEMES, SILENCE) + -- Request is sent with with different ttsChunks type both supported (TEXT) and not supported (PRE_RECORDED, SAPI_PHONEMES, LHPLUS_PHONEMES, SILENCE, FILE) -- List of parametres in the request -- 1. alertText1, type=String, maxlength=500, mandatory=false @@ -5374,7 +5375,7 @@ local blockId = 1 end --------------------------------------------------------------------------------------- - --Description: This test is intended to check providing request with ttsChunks with type "PRE_RECORDED", "SAPI_PHONEMES","LHPLUS_PHONEMES" and "SILENCE"}} + --Description: This test is intended to check providing request with ttsChunks with type "PRE_RECORDED", "SAPI_PHONEMES","LHPLUS_PHONEMES", "SILENCE", "FILE"}} for i=1, #ttsChunksType do Test["Alert_ttsChunksType_" .. tostring(ttsChunksType[i].type)] = function(self) @@ -5781,7 +5782,7 @@ local blockId = 1 -- Description: -- Request is sent with all parameters -- Request is sent with missing mandatory parameter - -- Request is sent with different ttsChunks types both supported (TEXT) and not supported (PRE_RECORDED, SAPI_PHONEMES, LHPLUS_PHONEMES, SILENCE) + -- Request is sent with different ttsChunks types both supported (TEXT) and not supported (PRE_RECORDED, SAPI_PHONEMES, LHPLUS_PHONEMES, SILENCE, FILE) -- List of parametres in the request -- 1. ttsChunks, type=TTSChunk, minsize=1, maxsize=100, array=true @@ -5853,7 +5854,7 @@ local blockId = 1 --------------------------------------------------------------------------------------- - --Description: This test is intended to check processing request with unsupported speechCapabilities ("SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE") + --Description: This test is intended to check processing request with unsupported speechCapabilities ("SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE") for i=1, #ttsChunksType do Test["Speak_ttsChunksType" .. tostring(ttsChunksType[i].type)] = function(self) --mobile side: Speak request @@ -7238,6 +7239,65 @@ local blockId = 1 end + +--------------------------------------------------------------------------------------------- + + -- Description: different speechCapabilities : FILE + function Test:Case_PerformAudioPassThruFILETest() + local CorIdPerformAudioPassThruFILEVD = self.mobileSession:SendRPC("PerformAudioPassThru", + { + initialPrompt = { + { + text = "Makeyourchoise.m4a", + type = "FILE", + }, + + }, + audioPassThruDisplayText1 = "DisplayText1", + audioPassThruDisplayText2 = "DisplayText2", + samplingRate = "8KHZ", + maxDuration = 2000, + bitsPerSample = "8_BIT", + audioType = "PCM", + muteAudio = true + }) + + --hmi side: expect for TTS.Speak + EXPECT_HMICALL("TTS.Speak", + { + ttsChunks = + { + { + text = "Makeyourchoise.m4a", + type = "FILE" + }, + } + }) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, "TTS.Speak", "UNSUPPORTED_RESOURCE", { }) + end) + + -- hmi expects UI.PerformAudioPassThru request + EXPECT_HMICALL("UI.PerformAudioPassThru", + { + appID = self.applications[applicationName], + audioPassThruDisplayTexts = { + {fieldName = "audioPassThruDisplayText1", fieldText = "DisplayText1"}, + {fieldName = "audioPassThruDisplayText2", fieldText = "DisplayText2"}, + + }, + maxDuration = 2000, + muteAudio = true + + }) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, "UI.PerformAudioPassThru", "SUCCESS", {}) + end) + + self.mobileSession:ExpectResponse(CorIdPerformAudioPassThruFILEVD, { success = true, resultCode = "WARNINGS"}) + + end + --End Test suit PerformAudioPassThru --------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------- @@ -9724,6 +9784,53 @@ local blockId = 1 end +--------------------------------------------------------------------------------------------- + + -- Description: Different speechCapabilities - FILE + function Test:Case_AlertManeuverFileTest() + local CorIdAlertManeuverFileVD = self.mobileSession:SendRPC("AlertManeuver", + {ttsChunks = { + { + text = "Alert.mp3", + type = "FILE", + }, + }, + }) + + + EXPECT_HMICALL("Navigation.AlertManeuver", + { + appID = self.applications[applicationName] + }) + + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, "Navigation.AlertManeuver","SUCCESS", {}) + + end) + + EXPECT_HMICALL("TTS.Speak", + { + speakType = "ALERT_MANEUVER", + ttsChunks = + { + + { + text = "Alert.mp3", + type = "FILE" + }, + }, + }) + :Do(function(_,data) + + self.hmiConnection:SendError(data.id, "TTS.Speak", "UNSUPPORTED_RESOURCE", "Error in speechCapabilities") + + end) + + + self.mobileSession:ExpectResponse(CorIdAlertManeuverFileVD, { success = true, resultCode = "WARNINGS", info = "Error in speechCapabilities"}) + + end + --End Test suit AlertManeuver --------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------- diff --git a/user_modules/shared_testcases/testCasesForArrayTTSChunksParameter.lua b/user_modules/shared_testcases/testCasesForArrayTTSChunksParameter.lua index 0ea540b8e4..a0a43cdfae 100644 --- a/user_modules/shared_testcases/testCasesForArrayTTSChunksParameter.lua +++ b/user_modules/shared_testcases/testCasesForArrayTTSChunksParameter.lua @@ -23,7 +23,7 @@ local TTSChunkParameter = require('user_modules/shared_testcases/testCasesForTTS --7. IsOutUpperBound --8. Check parameters in side TTSChunk: --text: minlength="0" maxlength="500" type="String" - --type: type="SpeechCapabilities": "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" + --type: type="SpeechCapabilities": "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" @@ -79,7 +79,7 @@ function testCasesForArrayTTSChunksParameter:verify_TTSChunks_Parameter(Request, --7. Verify TTSChunk --text: minlength="0" maxlength="500" type="String" - --type: type="SpeechCapabilities": "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" + --type: type="SpeechCapabilities": "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" --Set default parameters for request TestingRequest = commonFunctions:cloneTable(RequestParametersValues) diff --git a/user_modules/shared_testcases/testCasesForTTSChunkParameter.lua b/user_modules/shared_testcases/testCasesForTTSChunkParameter.lua index 6b22adb7e9..3856c9531c 100644 --- a/user_modules/shared_testcases/testCasesForTTSChunkParameter.lua +++ b/user_modules/shared_testcases/testCasesForTTSChunkParameter.lua @@ -21,7 +21,7 @@ local enumerationParameter = require('user_modules/shared_testcases/testCasesFor --2. IsEmpty --3. IsWrongDataType --4. text: minlength="0" maxlength="500" type="String" - --5. type: type="SpeechCapabilities": "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" + --5. type: type="SpeechCapabilities": "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" function testCasesForTTSChunkParameter:verify_TTSChunk_Parameter(Request, Parameter, Mandatory) @@ -54,8 +54,8 @@ function testCasesForTTSChunkParameter:verify_TTSChunk_Parameter(Request, Parame stringParameter:verify_String_Parameter(Request, parameter_text, Boundary, true) - --5. type: type="SpeechCapabilities": "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE" - local ExistentValues = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE"} + --5. type: type="SpeechCapabilities": "TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE" + local ExistentValues = {"TEXT", "SAPI_PHONEMES", "LHPLUS_PHONEMES", "PRE_RECORDED", "SILENCE", "FILE"} local parameter_type = commonFunctions:BuildChildParameter(Parameter, "type") enumerationParameter:verify_Enum_String_Parameter(Request, parameter_type, ExistentValues, true) From 082ab78efaf849d9d24d6fc3359048d9bcc6d687 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Mon, 14 May 2018 14:01:52 +0300 Subject: [PATCH 382/681] Update sequence according to defect steps --- .../Defects/4_6/959_resumption_limited_non_media.lua | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test_scripts/Defects/4_6/959_resumption_limited_non_media.lua b/test_scripts/Defects/4_6/959_resumption_limited_non_media.lua index e4189c28a6..f29cd0b1d4 100644 --- a/test_scripts/Defects/4_6/959_resumption_limited_non_media.lua +++ b/test_scripts/Defects/4_6/959_resumption_limited_non_media.lua @@ -51,10 +51,11 @@ local function registrationWithResumption() end) end -local function fullLevel() - onEventChange(false) +local function DeactivateApp() + actions.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", + { appID = actions.getHMIAppId(1)}) actions.getMobileSession():ExpectNotification("OnHMIStatus", - { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) end --[[ Scenario ]] @@ -63,12 +64,12 @@ runner.Step("Clean environment", commonDefects.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", actions.start) runner.Step("RAI, PTU", actions.registerApp) runner.Step("Activate app", actions.activateApp) +runner.Step("Deactivate app to LIMITED", DeactivateApp) runner.Title("Test") runner.Step("Reconnect", reconnect) runner.Step("onEventChange AUDIO_SOURCE true", onEventChange, { true }) runner.Step("App resumption in limited", registrationWithResumption) -runner.Step("App resumption in full after event is false", fullLevel) runner.Title("Postconditions") runner.Step("Stop SDL", commonDefects.postconditions) From 76657ab442f5eebb582438feda4e73677604b0e1 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 14 May 2018 17:56:57 +0300 Subject: [PATCH 383/681] Move test scripts --- .../TTSChunks/001_RegisterAppInterface.lua | 2 +- .../TTSChunks/002_SetGlobalProperties.lua | 2 +- .../TTSChunks/003_OnAppRegistered.lua | 2 +- test_scripts/{ => API}/TTSChunks/004_Alert.lua | 2 +- .../TTSChunks/005_ChangeRegistration.lua | 2 +- .../TTSChunks/006_PerformInteraction.lua | 2 +- test_scripts/{ => API}/TTSChunks/007_Speak.lua | 2 +- .../TTSChunks/008_PerformAudioPassThru.lua | 2 +- .../{ => API}/TTSChunks/009_AlertManeuver.lua | 2 +- test_scripts/{ => API}/TTSChunks/common.lua | 0 test_sets/audio_file_playback_tts_chunks.txt | 18 +++++++++--------- 11 files changed, 18 insertions(+), 18 deletions(-) rename test_scripts/{ => API}/TTSChunks/001_RegisterAppInterface.lua (97%) rename test_scripts/{ => API}/TTSChunks/002_SetGlobalProperties.lua (97%) rename test_scripts/{ => API}/TTSChunks/003_OnAppRegistered.lua (96%) rename test_scripts/{ => API}/TTSChunks/004_Alert.lua (96%) rename test_scripts/{ => API}/TTSChunks/005_ChangeRegistration.lua (97%) rename test_scripts/{ => API}/TTSChunks/006_PerformInteraction.lua (98%) rename test_scripts/{ => API}/TTSChunks/007_Speak.lua (96%) rename test_scripts/{ => API}/TTSChunks/008_PerformAudioPassThru.lua (97%) rename test_scripts/{ => API}/TTSChunks/009_AlertManeuver.lua (97%) rename test_scripts/{ => API}/TTSChunks/common.lua (100%) diff --git a/test_scripts/TTSChunks/001_RegisterAppInterface.lua b/test_scripts/API/TTSChunks/001_RegisterAppInterface.lua similarity index 97% rename from test_scripts/TTSChunks/001_RegisterAppInterface.lua rename to test_scripts/API/TTSChunks/001_RegisterAppInterface.lua index 46b5b7090c..2a53878770 100644 --- a/test_scripts/TTSChunks/001_RegisterAppInterface.lua +++ b/test_scripts/API/TTSChunks/001_RegisterAppInterface.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/TTSChunks/common') +local common = require('test_scripts/API/TTSChunks/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/TTSChunks/002_SetGlobalProperties.lua b/test_scripts/API/TTSChunks/002_SetGlobalProperties.lua similarity index 97% rename from test_scripts/TTSChunks/002_SetGlobalProperties.lua rename to test_scripts/API/TTSChunks/002_SetGlobalProperties.lua index ed3118fbcd..4494908537 100644 --- a/test_scripts/TTSChunks/002_SetGlobalProperties.lua +++ b/test_scripts/API/TTSChunks/002_SetGlobalProperties.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/TTSChunks/common') +local common = require('test_scripts/API/TTSChunks/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/TTSChunks/003_OnAppRegistered.lua b/test_scripts/API/TTSChunks/003_OnAppRegistered.lua similarity index 96% rename from test_scripts/TTSChunks/003_OnAppRegistered.lua rename to test_scripts/API/TTSChunks/003_OnAppRegistered.lua index ffc494568d..9dc63683ce 100644 --- a/test_scripts/TTSChunks/003_OnAppRegistered.lua +++ b/test_scripts/API/TTSChunks/003_OnAppRegistered.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/TTSChunks/common') +local common = require('test_scripts/API/TTSChunks/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/TTSChunks/004_Alert.lua b/test_scripts/API/TTSChunks/004_Alert.lua similarity index 96% rename from test_scripts/TTSChunks/004_Alert.lua rename to test_scripts/API/TTSChunks/004_Alert.lua index b2ab372f2c..5e455da8bc 100644 --- a/test_scripts/TTSChunks/004_Alert.lua +++ b/test_scripts/API/TTSChunks/004_Alert.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/TTSChunks/common') +local common = require('test_scripts/API/TTSChunks/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/TTSChunks/005_ChangeRegistration.lua b/test_scripts/API/TTSChunks/005_ChangeRegistration.lua similarity index 97% rename from test_scripts/TTSChunks/005_ChangeRegistration.lua rename to test_scripts/API/TTSChunks/005_ChangeRegistration.lua index 5a6eac49cc..0792d8174d 100644 --- a/test_scripts/TTSChunks/005_ChangeRegistration.lua +++ b/test_scripts/API/TTSChunks/005_ChangeRegistration.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/TTSChunks/common') +local common = require('test_scripts/API/TTSChunks/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/TTSChunks/006_PerformInteraction.lua b/test_scripts/API/TTSChunks/006_PerformInteraction.lua similarity index 98% rename from test_scripts/TTSChunks/006_PerformInteraction.lua rename to test_scripts/API/TTSChunks/006_PerformInteraction.lua index 697a251294..8dd6748356 100644 --- a/test_scripts/TTSChunks/006_PerformInteraction.lua +++ b/test_scripts/API/TTSChunks/006_PerformInteraction.lua @@ -17,7 +17,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/TTSChunks/common') +local common = require('test_scripts/API/TTSChunks/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/TTSChunks/007_Speak.lua b/test_scripts/API/TTSChunks/007_Speak.lua similarity index 96% rename from test_scripts/TTSChunks/007_Speak.lua rename to test_scripts/API/TTSChunks/007_Speak.lua index 4e039b2f91..e210c4f63d 100644 --- a/test_scripts/TTSChunks/007_Speak.lua +++ b/test_scripts/API/TTSChunks/007_Speak.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/TTSChunks/common') +local common = require('test_scripts/API/TTSChunks/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/TTSChunks/008_PerformAudioPassThru.lua b/test_scripts/API/TTSChunks/008_PerformAudioPassThru.lua similarity index 97% rename from test_scripts/TTSChunks/008_PerformAudioPassThru.lua rename to test_scripts/API/TTSChunks/008_PerformAudioPassThru.lua index e61b830146..9e03035ce5 100644 --- a/test_scripts/TTSChunks/008_PerformAudioPassThru.lua +++ b/test_scripts/API/TTSChunks/008_PerformAudioPassThru.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/TTSChunks/common') +local common = require('test_scripts/API/TTSChunks/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/TTSChunks/009_AlertManeuver.lua b/test_scripts/API/TTSChunks/009_AlertManeuver.lua similarity index 97% rename from test_scripts/TTSChunks/009_AlertManeuver.lua rename to test_scripts/API/TTSChunks/009_AlertManeuver.lua index ee96f22957..7584873ce7 100644 --- a/test_scripts/TTSChunks/009_AlertManeuver.lua +++ b/test_scripts/API/TTSChunks/009_AlertManeuver.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/TTSChunks/common') +local common = require('test_scripts/API/TTSChunks/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/TTSChunks/common.lua b/test_scripts/API/TTSChunks/common.lua similarity index 100% rename from test_scripts/TTSChunks/common.lua rename to test_scripts/API/TTSChunks/common.lua diff --git a/test_sets/audio_file_playback_tts_chunks.txt b/test_sets/audio_file_playback_tts_chunks.txt index be59961383..959c05f94c 100644 --- a/test_sets/audio_file_playback_tts_chunks.txt +++ b/test_sets/audio_file_playback_tts_chunks.txt @@ -1,9 +1,9 @@ -./test_scripts/TTSChunks/001_RegisterAppInterface.lua -./test_scripts/TTSChunks/002_SetGlobalProperties.lua -./test_scripts/TTSChunks/003_OnAppRegistered.lua -./test_scripts/TTSChunks/004_Alert.lua -./test_scripts/TTSChunks/005_ChangeRegistration.lua -./test_scripts/TTSChunks/006_PerformInteraction.lua -./test_scripts/TTSChunks/007_Speak.lua -./test_scripts/TTSChunks/008_PerformAudioPassThru.lua -./test_scripts/TTSChunks/009_AlertManeuver.lua +./test_scripts/API/TTSChunks/001_RegisterAppInterface.lua +./test_scripts/API/TTSChunks/002_SetGlobalProperties.lua +./test_scripts/API/TTSChunks/003_OnAppRegistered.lua +./test_scripts/API/TTSChunks/004_Alert.lua +./test_scripts/API/TTSChunks/005_ChangeRegistration.lua +./test_scripts/API/TTSChunks/006_PerformInteraction.lua +./test_scripts/API/TTSChunks/007_Speak.lua +./test_scripts/API/TTSChunks/008_PerformAudioPassThru.lua +./test_scripts/API/TTSChunks/009_AlertManeuver.lua From 07598bdd2ca4d909bea6ac313000ab05781cfdee Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Mon, 14 May 2018 15:50:05 -0400 Subject: [PATCH 384/681] Test handling of duplicate correlation IDs --- ...001_DuplicateCorrelationIDs_INVALID_ID.lua | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 test_scripts/SDL4.6/SDL-0162/001_DuplicateCorrelationIDs_INVALID_ID.lua diff --git a/test_scripts/SDL4.6/SDL-0162/001_DuplicateCorrelationIDs_INVALID_ID.lua b/test_scripts/SDL4.6/SDL-0162/001_DuplicateCorrelationIDs_INVALID_ID.lua new file mode 100644 index 0000000000..24ca4ecbbb --- /dev/null +++ b/test_scripts/SDL4.6/SDL-0162/001_DuplicateCorrelationIDs_INVALID_ID.lua @@ -0,0 +1,88 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0147-template-color-scheme.md +-- +-- Description: +-- SDL Core should track the number of attempted SetDisplayLayout requests with the current template and REJECT +-- any beyond the first with the reason "Using SetDisplayLayout to change the color scheme may only be done once. +-- However, The color scheme can be changed if the layout is also changed. +-- +-- Preconditions: Send SetDisplayLayout with a layout and a color scheme. +-- +-- Steps: Send additional SetDisplayLayout with a different layout and a different color scheme. +-- +-- Expected result: +-- SDL Core returns SUCCESS +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') +local functionId = require('function_id') +local json = require('json') + +local hmiRequestData = {} +local cid = 0 + +local requestParams = { + menuID = 100, + menuName = "Menu1" +} + +local requestParams2 = { + menuID = 101, + menuName = "Menu2" +} + +local hmiResponseParams = { + menuID = 100, + menuParams = { + menuName = "Menu1" + } +} + +local function addSubMenuWithoutResponse(self) + cid = self.mobileSession1:SendRPC("AddSubMenu", requestParams) + EXPECT_HMICALL("UI.AddSubMenu", hmiResponseParams) + :Do(function(_, data) + hmiRequestData = data + end) +end + +local function addSubMenuWithDuplicateCorrelationIDInvalidID(self) + local msg = { + serviceType = 7, + frameInfo = 0, + rpcType = 0, + rpcFunctionId = functionId["AddSubMenu"], + rpcCorrelationId = cid, + payload = json.encode(requestParams2) + } + self.mobileSession1:Send(msg) + self.mobileSession1:ExpectResponse(cid, { + success = false, + resultCode = "INVALID_ID" + }) +end + +local function addSubMenuRespondToOriginal(self) + self.hmiConnection:SendResponse(hmiRequestData.id, hmiRequestData.method, "SUCCESS", {}) + self.mobileSession1:ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS" + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI", commonSmoke.registerApp) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("Send AddSubMenu request with valid params", addSubMenuWithoutResponse) +runner.Step("Send AddSubMenu with Duplicate Correlation ID", addSubMenuWithDuplicateCorrelationIDInvalidID) +runner.Step("Send AddSubMenu response to original message", addSubMenuRespondToOriginal) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) \ No newline at end of file From 0b9eb4c29bd6983abaf0a893dd31b88b48ca058d Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 6 Apr 2018 11:11:57 +0300 Subject: [PATCH 385/681] Initial scripts for expand putFile --- test_scripts/API/Expand_PutFile/001.lua | 50 +++++++++++++++++++ test_scripts/API/Expand_PutFile/002.lua | 50 +++++++++++++++++++ test_scripts/API/Expand_PutFile/003.lua | 37 ++++++++++++++ .../API/Expand_PutFile/commonPutFile.lua | 39 +++++++++++++++ user_modules/sequences/actions.lua | 14 ++++++ 5 files changed, 190 insertions(+) create mode 100644 test_scripts/API/Expand_PutFile/001.lua create mode 100644 test_scripts/API/Expand_PutFile/002.lua create mode 100644 test_scripts/API/Expand_PutFile/003.lua create mode 100644 test_scripts/API/Expand_PutFile/commonPutFile.lua diff --git a/test_scripts/API/Expand_PutFile/001.lua b/test_scripts/API/Expand_PutFile/001.lua new file mode 100644 index 0000000000..9ee7261826 --- /dev/null +++ b/test_scripts/API/Expand_PutFile/001.lua @@ -0,0 +1,50 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1. Mobile application sends a PutFile "Single Frame" with a known counted checksum to the SDL. +-- 2. Mobile application sends a PutFile "Single Frame" with a incorrect counted checksum to the SDL. +-- SDL does: +-- 1. Receive PutFile "Single Frame" and verify the counted checksum from the Mobile app and respond with result code "SUCCESS". +-- 2. Receive PutFile "Single Frame" and verify the counted checksum from the Mobile app and respond with result code "CORRUPTED_DATA". +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expand_PutFile/commonPutFile') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local usedFile = "./files/binaryFile" + +local paramsCorrSum = common.putFileParams() +paramsCorrSum.crc = common.CheckSum(usedFile) + +local paramsIncorrSum = common.putFileParams() +paramsIncorrSum.crc = common.CheckSum(usedFile) - 100 + +local corrDataResult = { + success = false, + resultCode = "CORRUPTED_DATA", + info = "CRC Check on file failed. File upload has been cancelled, please retry." +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration with iconResumed = false", common.registerApp) + +runner.Title("Test") +runner.Step("Upload file with correct checksum", common.putFile, {paramsCorrSum, usedFile}) +runner.Step("Upload file with incorrect checksum", common.putFile, {paramsIncorrSum, usedFile, corrDataResult}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expand_PutFile/002.lua b/test_scripts/API/Expand_PutFile/002.lua new file mode 100644 index 0000000000..b7fe7a99b4 --- /dev/null +++ b/test_scripts/API/Expand_PutFile/002.lua @@ -0,0 +1,50 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1. Mobile application sends a PutFile "Multiple Frame" with a known counted checksum to the SDL. +-- 2. Mobile application sends a PutFile "Multiple Frame" with a incorrect counted checksum to the SDL. +-- SDL does: +-- 1. Receive PutFile "Multiple Frame" and verify the counted checksum from the Mobile app and respond with result code "SUCCESS". +-- 2. Receive PutFile "Multiple Frame" and verify the counted checksum from the Mobile app and respond with result code "CORRUPTED_DATA". +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expand_PutFile/commonPutFile') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local usedFile = "./files/icon.png" + +local paramsCorrSum = common.putFileParams() +paramsCorrSum.crc = common.CheckSum(usedFile) + +local paramsIncorrSum = common.putFileParams() +paramsIncorrSum.crc = common.CheckSum(usedFile) - 100 + +local corrDataResult = { + success = false, + resultCode = "CORRUPTED_DATA", + info = "CRC Check on file failed. File upload has been cancelled, please retry." +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration with iconResumed = false", common.registerApp) + +runner.Title("Test") +runner.Step("Upload file with correct checksum", common.putFile, {paramsCorrSum, usedFile}) +runner.Step("Upload file with incorrect checksum", common.putFile, {paramsIncorrSum, usedFile, corrDataResult}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expand_PutFile/003.lua b/test_scripts/API/Expand_PutFile/003.lua new file mode 100644 index 0000000000..f75bcab453 --- /dev/null +++ b/test_scripts/API/Expand_PutFile/003.lua @@ -0,0 +1,37 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- Mobile application sends a PutFile "Multiple Frame" without parameter “crc†to the SDL. +-- SDL does: +-- Receive PutFile without parameter “crcâ€, upload data and respond with resultCode: "SUCCESS" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expand_PutFile/commonPutFile') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local usedFile = "./files/icon.png" + +local params = common.putFileParams() + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration with iconResumed = false", common.registerApp) + +runner.Title("Test") +runner.Step("Upload file with correct checksum", common.putFile, {params, usedFile}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expand_PutFile/commonPutFile.lua b/test_scripts/API/Expand_PutFile/commonPutFile.lua new file mode 100644 index 0000000000..5e1ce7bb81 --- /dev/null +++ b/test_scripts/API/Expand_PutFile/commonPutFile.lua @@ -0,0 +1,39 @@ + +--------------------------------------------------------------------------------------------------- +-- Common module +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 2 + +local m = actions + +function m.putFileParams() + local temp = { + syncFileName = "icon.png", + fileType = "GRAPHIC_PNG", + } + return temp +end + +function m.CheckSum(pFile) + local getCRCinHex = 'crc32 ' .. pFile + local handle = io.popen(getCRCinHex) + local checkSumHex = handle:read("*a") + local CRChexToDec = 'echo $((0x' .. checkSumHex .. '))' + handle = io.popen(CRChexToDec) + local checkSumDec = handle:read("*a") + handle:close() + return checkSumDec +end + +function m.putFile(pParams, pFile, pResult) + if not pResult then pResult = { success = true, resultCode = "SUCCESS" } end + local mobSession = m.getMobileSession() + local cid = mobSession:SendRPC("PutFile", pParams, pFile) + mobSession:ExpectResponse(cid, pResult) +end + +return m diff --git a/user_modules/sequences/actions.lua b/user_modules/sequences/actions.lua index 23687cf56f..990d65c1cd 100644 --- a/user_modules/sequences/actions.lua +++ b/user_modules/sequences/actions.lua @@ -5,6 +5,7 @@ local mobileSession = require("mobile_session") local json = require("modules/json") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') local commonSteps = require("user_modules/shared_testcases/commonSteps") local events = require("events") local test = require("user_modules/dummy_connecttest") @@ -425,4 +426,17 @@ function m.getAppsCount() return #test.mobileSession end +--[[ @getPathToFileInStorage: full path to file in storage folder +--! @parameters: +--! @pFileName = file name +--! @pAppId = application number (1, 2, etc.) +--! @return: path +--]] +function m.getPathToFileInStorage(pFileName, pAppId) + if not pAppId then pAppId = 1 end + return commonPreconditions:GetPathToSDL() .. "storage/" + .. m.getConfigAppParams( pAppId ).appID .. "_" + .. utils.getDeviceMAC() .. "/" .. pFileName +end + return m From 4d50c9bce189466bd469660f494642a7ab842351 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 11 Apr 2018 08:52:40 +0300 Subject: [PATCH 386/681] Checksum value updated to integer --- test_scripts/API/Expand_PutFile/commonPutFile.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test_scripts/API/Expand_PutFile/commonPutFile.lua b/test_scripts/API/Expand_PutFile/commonPutFile.lua index 5e1ce7bb81..f2f943a047 100644 --- a/test_scripts/API/Expand_PutFile/commonPutFile.lua +++ b/test_scripts/API/Expand_PutFile/commonPutFile.lua @@ -8,6 +8,7 @@ local actions = require("user_modules/sequences/actions") --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 +--[[ Variables ]] local m = actions function m.putFileParams() @@ -22,10 +23,8 @@ function m.CheckSum(pFile) local getCRCinHex = 'crc32 ' .. pFile local handle = io.popen(getCRCinHex) local checkSumHex = handle:read("*a") - local CRChexToDec = 'echo $((0x' .. checkSumHex .. '))' - handle = io.popen(CRChexToDec) - local checkSumDec = handle:read("*a") handle:close() + local checkSumDec = tonumber(checkSumHex, 16) return checkSumDec end From 2b1acb79e0fbae31698694333e6b0d0cf402104e Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 12 Apr 2018 16:05:02 +0300 Subject: [PATCH 387/681] Script fot checking corrupted_data with PutFile chunks --- test_scripts/API/Expand_PutFile/004.lua | 138 ++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 test_scripts/API/Expand_PutFile/004.lua diff --git a/test_scripts/API/Expand_PutFile/004.lua b/test_scripts/API/Expand_PutFile/004.lua new file mode 100644 index 0000000000..8c9084a61c --- /dev/null +++ b/test_scripts/API/Expand_PutFile/004.lua @@ -0,0 +1,138 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1. Mobile application sends file via PutFile chunks +-- 2. SDL process some part of chunks wit success result code +-- 3. One chunk came with wrong crc value and SDL responds with result code "CORRUPTED_DATA" to mobile app +-- SDL does: +-- 1. After response "CORRUPTED_DATA" process all other chunks with resultCode "INVALID_DATA" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expand_PutFile/commonPutFile') +local json = require("modules/json") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local usedFile = "./files/icon.png" +local FramesCount = 10 +local frameSize +local offsetValue = 0 +local msgId = 1000 +local correlationId = 1000 +local binaryDataFrames + +local corrDataResult = { + success = false, + resultCode = "CORRUPTED_DATA", + info = "CRC Check on file failed. File upload has been cancelled, please retry." +} + +local invalidDataResult = { + success = false, + resultCode = "INVALID_DATA", +} + +local msg = { + version = config.defaultProtocolVersion, + encryption = false, + frameType = 0x01, + serviceType = 0x07, + frameInfo = 0x0, + rpcType = 0x0, + rpcFunctionId = 32, -- PutFile + } + +--[[ Local Functions ]] +local function PrepareFileForsendingViaChunks() + local f = assert(io.open(usedFile)) + local binaryData = f:read("*all") + io.close(f) + local binaryDataSize = #binaryData + frameSize = binaryDataSize/FramesCount + local frames = {} + local stringOffset = 0 + for i = 1, FramesCount do + frames[i] = string.sub(binaryData, stringOffset+1, stringOffset+frameSize) + stringOffset = i*frameSize + end + return frames +end + +binaryDataFrames = PrepareFileForsendingViaChunks() + +local function getFrameCheckSum(pData) + local file = "./files/tmp" + local f = io.open(file, "w") + f:write(pData) + f:close() + local crc = common.CheckSum(file) + os.remove(file) + return crc +end + +local function PutFile(pParams, pBinaryData, pResult) + msgId = msgId + 1 + correlationId = correlationId + 1 + + msg.sessionId = common.getMobileSession().sessionId + msg.messageId = msgId + msg.rpcCorrelationId = correlationId + msg.payload = json.encode(pParams) + msg.binaryData = pBinaryData + + if not pResult then pResult = { success = true, resultCode = "SUCCESS" } end + common.getMobileSession():Send(msg) + common.getMobileSession():ExpectResponse(correlationId, pResult) +end + +local function putFileSuccess() + local params = common.putFileParams() + for i=1,4 do + params.crc = getFrameCheckSum(binaryDataFrames[i]) + params.offset = offsetValue + PutFile(params, binaryDataFrames[i]) + offsetValue = offsetValue + frameSize + end +end + +local function putFileCorruptedDate() + local params = common.putFileParams() + params.crc = getFrameCheckSum(binaryDataFrames[5]) - 100 + params.offset = offsetValue + PutFile(params, binaryDataFrames[5], corrDataResult) + offsetValue = offsetValue + frameSize +end + +local function putFileInvalidData() + local params = common.putFileParams() + for i = 6, 10 do + params.crc = getFrameCheckSum(binaryDataFrames[i]) + params.offset = offsetValue + PutFile(params, binaryDataFrames[i], invalidDataResult) + offsetValue = offsetValue + frameSize + end +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration with iconResumed = false", common.registerApp) + +runner.Title("Test") +runner.Step("Success PutFile with crc", putFileSuccess) +runner.Step("Corrupted data PutFile with crc", putFileCorruptedDate) +runner.Step("invalid data PutFile with crc", putFileInvalidData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From 412942b69e07cede3a87d3ce85169243e995b727 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 12 Apr 2018 17:03:10 +0300 Subject: [PATCH 388/681] Updated script names, expanded list of scripts --- ...a => 001_PutFile_with_crc_singleFrame.lua} | 2 +- ...ua => 002_PutFile_with_crc_MultiFrame.lua} | 2 +- .../{003.lua => 003_PutFile_without_crc.lua} | 4 +- .../{004.lua => 004_PutFile_chunks.lua} | 104 +++++++++--------- ..._PutFile_with_negative_crc_singleFrame.lua | 43 ++++++++ ...6_PutFile_with_negative_crc_multiFrame.lua | 43 ++++++++ ...07_PutFile_with_crc_more_than_maxvalue.lua | 49 +++++++++ 7 files changed, 191 insertions(+), 56 deletions(-) rename test_scripts/API/Expand_PutFile/{001.lua => 001_PutFile_with_crc_singleFrame.lua} (96%) rename test_scripts/API/Expand_PutFile/{002.lua => 002_PutFile_with_crc_MultiFrame.lua} (96%) rename test_scripts/API/Expand_PutFile/{003.lua => 003_PutFile_without_crc.lua} (88%) rename test_scripts/API/Expand_PutFile/{004.lua => 004_PutFile_chunks.lua} (61%) create mode 100644 test_scripts/API/Expand_PutFile/005_PutFile_with_negative_crc_singleFrame.lua create mode 100644 test_scripts/API/Expand_PutFile/006_PutFile_with_negative_crc_multiFrame.lua create mode 100644 test_scripts/API/Expand_PutFile/007_PutFile_with_crc_more_than_maxvalue.lua diff --git a/test_scripts/API/Expand_PutFile/001.lua b/test_scripts/API/Expand_PutFile/001_PutFile_with_crc_singleFrame.lua similarity index 96% rename from test_scripts/API/Expand_PutFile/001.lua rename to test_scripts/API/Expand_PutFile/001_PutFile_with_crc_singleFrame.lua index 9ee7261826..7c89a72dab 100644 --- a/test_scripts/API/Expand_PutFile/001.lua +++ b/test_scripts/API/Expand_PutFile/001_PutFile_with_crc_singleFrame.lua @@ -40,7 +40,7 @@ local corrDataResult = { runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("App registration with iconResumed = false", common.registerApp) +runner.Step("App registration", common.registerApp) runner.Title("Test") runner.Step("Upload file with correct checksum", common.putFile, {paramsCorrSum, usedFile}) diff --git a/test_scripts/API/Expand_PutFile/002.lua b/test_scripts/API/Expand_PutFile/002_PutFile_with_crc_MultiFrame.lua similarity index 96% rename from test_scripts/API/Expand_PutFile/002.lua rename to test_scripts/API/Expand_PutFile/002_PutFile_with_crc_MultiFrame.lua index b7fe7a99b4..af218a3bf7 100644 --- a/test_scripts/API/Expand_PutFile/002.lua +++ b/test_scripts/API/Expand_PutFile/002_PutFile_with_crc_MultiFrame.lua @@ -40,7 +40,7 @@ local corrDataResult = { runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("App registration with iconResumed = false", common.registerApp) +runner.Step("App registration", common.registerApp) runner.Title("Test") runner.Step("Upload file with correct checksum", common.putFile, {paramsCorrSum, usedFile}) diff --git a/test_scripts/API/Expand_PutFile/003.lua b/test_scripts/API/Expand_PutFile/003_PutFile_without_crc.lua similarity index 88% rename from test_scripts/API/Expand_PutFile/003.lua rename to test_scripts/API/Expand_PutFile/003_PutFile_without_crc.lua index f75bcab453..03a208b44b 100644 --- a/test_scripts/API/Expand_PutFile/003.lua +++ b/test_scripts/API/Expand_PutFile/003_PutFile_without_crc.lua @@ -28,10 +28,10 @@ local params = common.putFileParams() runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("App registration with iconResumed = false", common.registerApp) +runner.Step("App registration", common.registerApp) runner.Title("Test") -runner.Step("Upload file with correct checksum", common.putFile, {params, usedFile}) +runner.Step("Upload file without checksum", common.putFile, {params, usedFile}) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expand_PutFile/004.lua b/test_scripts/API/Expand_PutFile/004_PutFile_chunks.lua similarity index 61% rename from test_scripts/API/Expand_PutFile/004.lua rename to test_scripts/API/Expand_PutFile/004_PutFile_chunks.lua index 8c9084a61c..bdd3d4dac5 100644 --- a/test_scripts/API/Expand_PutFile/004.lua +++ b/test_scripts/API/Expand_PutFile/004_PutFile_chunks.lua @@ -43,52 +43,52 @@ local invalidDataResult = { } local msg = { - version = config.defaultProtocolVersion, - encryption = false, - frameType = 0x01, - serviceType = 0x07, - frameInfo = 0x0, - rpcType = 0x0, - rpcFunctionId = 32, -- PutFile - } + version = config.defaultProtocolVersion, + encryption = false, + frameType = 0x01, + serviceType = 0x07, + frameInfo = 0x0, + rpcType = 0x0, + rpcFunctionId = 32, -- PutFile +} --[[ Local Functions ]] local function PrepareFileForsendingViaChunks() local f = assert(io.open(usedFile)) - local binaryData = f:read("*all") - io.close(f) - local binaryDataSize = #binaryData - frameSize = binaryDataSize/FramesCount - local frames = {} - local stringOffset = 0 - for i = 1, FramesCount do - frames[i] = string.sub(binaryData, stringOffset+1, stringOffset+frameSize) - stringOffset = i*frameSize - end - return frames + local binaryData = f:read("*all") + io.close(f) + local binaryDataSize = #binaryData + frameSize = binaryDataSize/FramesCount + local frames = {} + local stringOffset = 0 + for i = 1, FramesCount do + frames[i] = string.sub(binaryData, stringOffset+1, stringOffset+frameSize) + stringOffset = i*frameSize + end + return frames end binaryDataFrames = PrepareFileForsendingViaChunks() local function getFrameCheckSum(pData) - local file = "./files/tmp" - local f = io.open(file, "w") - f:write(pData) - f:close() - local crc = common.CheckSum(file) - os.remove(file) - return crc + local file = "./files/tmp" + local f = io.open(file, "w") + f:write(pData) + f:close() + local crc = common.CheckSum(file) + os.remove(file) + return crc end local function PutFile(pParams, pBinaryData, pResult) - msgId = msgId + 1 - correlationId = correlationId + 1 + msgId = msgId + 1 + correlationId = correlationId + 1 - msg.sessionId = common.getMobileSession().sessionId - msg.messageId = msgId - msg.rpcCorrelationId = correlationId - msg.payload = json.encode(pParams) - msg.binaryData = pBinaryData + msg.sessionId = common.getMobileSession().sessionId + msg.messageId = msgId + msg.rpcCorrelationId = correlationId + msg.payload = json.encode(pParams) + msg.binaryData = pBinaryData if not pResult then pResult = { success = true, resultCode = "SUCCESS" } end common.getMobileSession():Send(msg) @@ -96,31 +96,31 @@ local function PutFile(pParams, pBinaryData, pResult) end local function putFileSuccess() - local params = common.putFileParams() - for i=1,4 do - params.crc = getFrameCheckSum(binaryDataFrames[i]) - params.offset = offsetValue - PutFile(params, binaryDataFrames[i]) - offsetValue = offsetValue + frameSize - end + local params = common.putFileParams() + for i=1,4 do + params.crc = getFrameCheckSum(binaryDataFrames[i]) + params.offset = offsetValue + PutFile(params, binaryDataFrames[i]) + offsetValue = offsetValue + frameSize + end end local function putFileCorruptedDate() - local params = common.putFileParams() - params.crc = getFrameCheckSum(binaryDataFrames[5]) - 100 - params.offset = offsetValue - PutFile(params, binaryDataFrames[5], corrDataResult) - offsetValue = offsetValue + frameSize + local params = common.putFileParams() + params.crc = getFrameCheckSum(binaryDataFrames[5]) - 100 + params.offset = offsetValue + PutFile(params, binaryDataFrames[5], corrDataResult) + offsetValue = offsetValue + frameSize end local function putFileInvalidData() - local params = common.putFileParams() - for i = 6, 10 do - params.crc = getFrameCheckSum(binaryDataFrames[i]) - params.offset = offsetValue - PutFile(params, binaryDataFrames[i], invalidDataResult) - offsetValue = offsetValue + frameSize - end + local params = common.putFileParams() + for i = 6, 10 do + params.crc = getFrameCheckSum(binaryDataFrames[i]) + params.offset = offsetValue + PutFile(params, binaryDataFrames[i], invalidDataResult) + offsetValue = offsetValue + frameSize + end end --[[ Scenario ]] diff --git a/test_scripts/API/Expand_PutFile/005_PutFile_with_negative_crc_singleFrame.lua b/test_scripts/API/Expand_PutFile/005_PutFile_with_negative_crc_singleFrame.lua new file mode 100644 index 0000000000..504f21ac9e --- /dev/null +++ b/test_scripts/API/Expand_PutFile/005_PutFile_with_negative_crc_singleFrame.lua @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1. Mobile application sends a PutFile "Single Frame" with a negative (not valid) checksum to the SDL. +-- SDL does: +-- 1. SDL receive putfile “Single Frame†and counted checksum from the Mobile app and respond with result code "INVALID_DATA" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expand_PutFile/commonPutFile') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local usedFile = "./files/binaryFile" + +local paramsIncorrSum = common.putFileParams() +paramsIncorrSum.crc = - common.CheckSum(usedFile) + +local corrDataResult = { + success = false, + resultCode = "INVALID_DATA", +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration with iconResumed = false", common.registerApp) + +runner.Title("Test") +runner.Step("Upload file with negative checksum", common.putFile, {paramsIncorrSum, usedFile, corrDataResult}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expand_PutFile/006_PutFile_with_negative_crc_multiFrame.lua b/test_scripts/API/Expand_PutFile/006_PutFile_with_negative_crc_multiFrame.lua new file mode 100644 index 0000000000..0ed2b34365 --- /dev/null +++ b/test_scripts/API/Expand_PutFile/006_PutFile_with_negative_crc_multiFrame.lua @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1. Mobile application sends a PutFile "Multiple Frame" with a negative (not valid) checksum to the SDL. +-- SDL does: +-- 1. SDL receive putfile “Multiple Frame†and counted checksum from the Mobile app and respond with result code "INVALID_DATA" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expand_PutFile/commonPutFile') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local usedFile = "./files/icon.png" + +local paramsIncorrSum = common.putFileParams() +paramsIncorrSum.crc = - common.CheckSum(usedFile) + +local corrDataResult = { + success = false, + resultCode = "INVALID_DATA", +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration with iconResumed = false", common.registerApp) + +runner.Title("Test") +runner.Step("Upload file with negative checksum", common.putFile, {paramsIncorrSum, usedFile, corrDataResult}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expand_PutFile/007_PutFile_with_crc_more_than_maxvalue.lua b/test_scripts/API/Expand_PutFile/007_PutFile_with_crc_more_than_maxvalue.lua new file mode 100644 index 0000000000..85a153ceb0 --- /dev/null +++ b/test_scripts/API/Expand_PutFile/007_PutFile_with_crc_more_than_maxvalue.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1. The mobile application sends a putfile “Single Frame†with a more than maxvalue (not valid) checksum to the SDL. +-- 2. The mobile application sends a putfile “Multiple Frame†with a more than maxvalue (not valid) checksum to the SDL. +-- SDL does: +-- 1. SDL receives putfile “Single Frame†and counted checksum from the Mobile app and respond with result code "INVALID_DATA" +-- 2. SDL receives putfile “Multiple Frame†and counted checksum from the Mobile app and respond with result code "INVALID_DATA" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expand_PutFile/commonPutFile') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local usedFileSingleFrame = "./files/binaryFile" +local usedFileMultiFrame = "./files/png_1211kb.png" + +local paramsIncorrSum = common.putFileParams() +paramsIncorrSum.crc = 4294967296 + +local invalidDataResult = { + success = false, + resultCode = "INVALID_DATA" +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration with iconResumed = false", common.registerApp) + +runner.Title("Test") +runner.Step("Upload file as single frame with with crc more than maxvalue", common.putFile, + {paramsIncorrSum, usedFileSingleFrame, invalidDataResult}) +runner.Step("Upload file as multiple frame with with crc more than maxvalue", common.putFile, + {paramsIncorrSum, usedFileMultiFrame, invalidDataResult}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From 40aaa5074fefb7bceda0c06d7d96de4e089c9eaf Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Sun, 15 Apr 2018 15:15:03 +0300 Subject: [PATCH 389/681] Add script to check corrupted data behavior --- .../008_PutFile_corrupted_data.lua | 178 ++++++++++++++++++ test_sets/expand_put_file.txt | 8 + 2 files changed, 186 insertions(+) create mode 100644 test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua create mode 100644 test_sets/expand_put_file.txt diff --git a/test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua b/test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua new file mode 100644 index 0000000000..759bf4790a --- /dev/null +++ b/test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua @@ -0,0 +1,178 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0037-Expand-Mobile-putfile-RPC.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- Mobile application sends a PutFile with correct checksum +-- And some bytes of the data were corrupted +-- SDL does: +-- Receive PutFile, verify counted checksum and respond with result code "CORRUPTED_DATA" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expand_PutFile/commonPutFile') +local utils = require("user_modules/utils") +local json = require("modules/json") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + + +--[[ Local Variables ]] +local fileName = "./files/action.png" + +local function bytesToInt32(pVal, pOffset) + local res = bit32.lshift(string.byte(pVal, pOffset), 24) + + bit32.lshift(string.byte(pVal, pOffset + 1), 16) + + bit32.lshift(string.byte(pVal, pOffset + 2), 8) + + string.byte(pVal, pOffset + 3) + return res +end + +local function int32ToBytes(pVal) + local res = string.char( + bit32.rshift(bit32.band(pVal, 0xff000000), 24), + bit32.rshift(bit32.band(pVal, 0xff0000), 16), + bit32.rshift(bit32.band(pVal, 0xff00), 8), + bit32.band(pVal, 0xff) + ) + return res +end + +local function rpcPayload(pMsg) + pMsg.payload = pMsg.payload or "" + pMsg.binaryData = pMsg.binaryData or "" + local res = string.char( + bit32.lshift(pMsg.rpcType, 4) + bit32.band(bit32.rshift(pMsg.rpcFunctionId, 24), 0x0f), + bit32.rshift(bit32.band(pMsg.rpcFunctionId, 0xff0000), 16), + bit32.rshift(bit32.band(pMsg.rpcFunctionId, 0xff00), 8), + bit32.band(pMsg.rpcFunctionId, 0xff)) .. + int32ToBytes(pMsg.rpcCorrelationId) .. + int32ToBytes(#pMsg.payload) .. + pMsg.payload .. pMsg.binaryData + return res +end + +local function putFileByFrames(pParams) + local putFileParams = { + syncFileName = "action.png", + fileType = "GRAPHIC_PNG", + crc = common.CheckSum(fileName) + } + + local correlationId = common.getMobileSession().correlationId + 1 + + local msg = { + version = config.defaultProtocolVersion, + encryption = false, + frameType = 0x01, + serviceType = 0x07, + frameInfo = 0x0, + sessionId = common.getMobileSession().sessionId, + messageId = 1000, + rpcType = 0x0, + rpcFunctionId = 32, -- PutFile + rpcCorrelationId = correlationId, + payload = json.encode(putFileParams) + } + + local file = fileName + + local f = assert(io.open(file)) + msg.binaryData = f:read("*all") + io.close(f) + + msg.binaryData = rpcPayload(msg) + + local frames = {} + local binaryDataSize = #msg.binaryData + local max_size = 1400 + local frameMessage = { + version = msg.version, + encryption = msg.encryption, + serviceType = msg.serviceType, + sessionId = msg.sessionId, + messageId = msg.messageId + } + if binaryDataSize > max_size then + local countOfDataFrames = 0 + -- Create messages consecutive frames + while #msg.binaryData > 0 do + countOfDataFrames = countOfDataFrames + 1 + + local dataPart = string.sub(msg.binaryData, 1, max_size) + msg.binaryData = string.sub(msg.binaryData, max_size + 1) + + local frame_info = 0 -- last frame + if #msg.binaryData > 0 then + frame_info = ((countOfDataFrames - 1) % 255) + 1 + end + + local consecutiveFrameMessage = utils.cloneTable(frameMessage) + consecutiveFrameMessage.frameType = 0x03 + consecutiveFrameMessage.frameInfo = frame_info + consecutiveFrameMessage.binaryData = dataPart + table.insert(frames, consecutiveFrameMessage) + end + + -- Create message firstframe + local firstFrameMessage = utils.cloneTable(frameMessage) + firstFrameMessage.frameType = 0x02 + firstFrameMessage.frameInfo = 0 + firstFrameMessage.binaryData = int32ToBytes(binaryDataSize) .. int32ToBytes(countOfDataFrames) + firstFrameMessage.encryption = false + table.insert(frames, 1, firstFrameMessage) + else + table.insert(frames, msg) + end + + common.getMobileSession().mobile_session_impl.rpc_services:CheckCorrelationID(msg) + + local function replaceChar(pStr, pPos, pChar) + return string.sub(pStr, 1, pPos - 1) .. pChar .. string.sub(pStr, pPos + 1, pStr:len()) + end + + if pParams.isDataCorrupted == true then + frames[3].binaryData = replaceChar(frames[3].binaryData, 12, 'z') + end + + for _, frame in pairs(frames) do + common.getMobileSession():SendPacket(frame) + end + + common.getMobileSession():ExpectResponse(correlationId, { success = pParams.success, resultCode = pParams.resultCode }) + + common.getMobileSession():ExpectPacket({ + sessionId = common.getMobileSession().sessionId, + frameType = 0x01, + serviceType = 0x07 + }, + function(binaryData) + local rpcFunctionId = bit32.band(bytesToInt32(binaryData, 1), 0x0fffffff) + local rpcCorrelationId = bytesToInt32(binaryData, 5) + if rpcFunctionId ~= 32 or rpcCorrelationId ~= correlationId then return false end + return true + end) +end + + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration with iconResumed = false", common.registerApp) + +runner.Title("Test") +runner.Step("Upload file as multiple frames SUCCESS", putFileByFrames, { + { isDataCorrupted = false, success = true, resultCode = "SUCCESS" } +}) +runner.Step("Upload file as multiple frames CORRUPTED_DATA", putFileByFrames, { + { isDataCorrupted = true, success = false, resultCode = "CORRUPTED_DATA" } +}) +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_sets/expand_put_file.txt b/test_sets/expand_put_file.txt new file mode 100644 index 0000000000..71925772c8 --- /dev/null +++ b/test_sets/expand_put_file.txt @@ -0,0 +1,8 @@ +./test_scripts/API/Expand_PutFile/001_PutFile_with_crc_singleFrame.lua +./test_scripts/API/Expand_PutFile/002_PutFile_with_crc_MultiFrame.lua +./test_scripts/API/Expand_PutFile/003_PutFile_without_crc.lua +./test_scripts/API/Expand_PutFile/004_PutFile_chunks.lua +./test_scripts/API/Expand_PutFile/005_PutFile_with_negative_crc_singleFrame.lua +./test_scripts/API/Expand_PutFile/006_PutFile_with_negative_crc_multiFrame.lua +./test_scripts/API/Expand_PutFile/007_PutFile_with_crc_more_than_maxvalue.lua +./test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua From f18b34e83ab6a9355685f796ae36e5ac2ab10cb7 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 16 Apr 2018 14:58:09 +0300 Subject: [PATCH 390/681] Replace external crc32 utility by internal one --- .../API/Expand_PutFile/commonPutFile.lua | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/test_scripts/API/Expand_PutFile/commonPutFile.lua b/test_scripts/API/Expand_PutFile/commonPutFile.lua index f2f943a047..4b266487e9 100644 --- a/test_scripts/API/Expand_PutFile/commonPutFile.lua +++ b/test_scripts/API/Expand_PutFile/commonPutFile.lua @@ -4,6 +4,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local actions = require("user_modules/sequences/actions") +local utils = require("user_modules/utils") --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 @@ -19,13 +20,21 @@ function m.putFileParams() return temp end +local function bytesToInt(pStr) + local t = { string.byte(pStr, 1, -1) } + local n = 0 + for k = 1, #t do + n = n + t[k] * 2 ^ ((k - 1) * 8) + end + return n +end + function m.CheckSum(pFile) - local getCRCinHex = 'crc32 ' .. pFile - local handle = io.popen(getCRCinHex) - local checkSumHex = handle:read("*a") + local cmd = "cat " .. pFile .. " | gzip -1 | tail -c 8 | head -c 4" + local handle = io.popen(cmd) + local crc = handle:read("*a") handle:close() - local checkSumDec = tonumber(checkSumHex, 16) - return checkSumDec + return bytesToInt(crc) end function m.putFile(pParams, pFile, pResult) From 7d687dba006834ed21951893351648b54aacaf49 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 16 Apr 2018 15:01:09 +0300 Subject: [PATCH 391/681] Rename CheckSum function --- .../API/Expand_PutFile/001_PutFile_with_crc_singleFrame.lua | 4 ++-- .../API/Expand_PutFile/002_PutFile_with_crc_MultiFrame.lua | 4 ++-- test_scripts/API/Expand_PutFile/004_PutFile_chunks.lua | 2 +- .../005_PutFile_with_negative_crc_singleFrame.lua | 2 +- .../006_PutFile_with_negative_crc_multiFrame.lua | 2 +- .../API/Expand_PutFile/008_PutFile_corrupted_data.lua | 2 +- test_scripts/API/Expand_PutFile/commonPutFile.lua | 3 +-- 7 files changed, 9 insertions(+), 10 deletions(-) diff --git a/test_scripts/API/Expand_PutFile/001_PutFile_with_crc_singleFrame.lua b/test_scripts/API/Expand_PutFile/001_PutFile_with_crc_singleFrame.lua index 7c89a72dab..f8cdbcca2a 100644 --- a/test_scripts/API/Expand_PutFile/001_PutFile_with_crc_singleFrame.lua +++ b/test_scripts/API/Expand_PutFile/001_PutFile_with_crc_singleFrame.lua @@ -25,10 +25,10 @@ runner.testSettings.isSelfIncluded = false local usedFile = "./files/binaryFile" local paramsCorrSum = common.putFileParams() -paramsCorrSum.crc = common.CheckSum(usedFile) +paramsCorrSum.crc = common.getCheckSum(usedFile) local paramsIncorrSum = common.putFileParams() -paramsIncorrSum.crc = common.CheckSum(usedFile) - 100 +paramsIncorrSum.crc = common.getCheckSum(usedFile) - 100 local corrDataResult = { success = false, diff --git a/test_scripts/API/Expand_PutFile/002_PutFile_with_crc_MultiFrame.lua b/test_scripts/API/Expand_PutFile/002_PutFile_with_crc_MultiFrame.lua index af218a3bf7..bf3960728c 100644 --- a/test_scripts/API/Expand_PutFile/002_PutFile_with_crc_MultiFrame.lua +++ b/test_scripts/API/Expand_PutFile/002_PutFile_with_crc_MultiFrame.lua @@ -25,10 +25,10 @@ runner.testSettings.isSelfIncluded = false local usedFile = "./files/icon.png" local paramsCorrSum = common.putFileParams() -paramsCorrSum.crc = common.CheckSum(usedFile) +paramsCorrSum.crc = common.getCheckSum(usedFile) local paramsIncorrSum = common.putFileParams() -paramsIncorrSum.crc = common.CheckSum(usedFile) - 100 +paramsIncorrSum.crc = common.getCheckSum(usedFile) - 100 local corrDataResult = { success = false, diff --git a/test_scripts/API/Expand_PutFile/004_PutFile_chunks.lua b/test_scripts/API/Expand_PutFile/004_PutFile_chunks.lua index bdd3d4dac5..b1be842c46 100644 --- a/test_scripts/API/Expand_PutFile/004_PutFile_chunks.lua +++ b/test_scripts/API/Expand_PutFile/004_PutFile_chunks.lua @@ -75,7 +75,7 @@ local function getFrameCheckSum(pData) local f = io.open(file, "w") f:write(pData) f:close() - local crc = common.CheckSum(file) + local crc = common.getCheckSum(file) os.remove(file) return crc end diff --git a/test_scripts/API/Expand_PutFile/005_PutFile_with_negative_crc_singleFrame.lua b/test_scripts/API/Expand_PutFile/005_PutFile_with_negative_crc_singleFrame.lua index 504f21ac9e..f3b8a9cd65 100644 --- a/test_scripts/API/Expand_PutFile/005_PutFile_with_negative_crc_singleFrame.lua +++ b/test_scripts/API/Expand_PutFile/005_PutFile_with_negative_crc_singleFrame.lua @@ -23,7 +23,7 @@ runner.testSettings.isSelfIncluded = false local usedFile = "./files/binaryFile" local paramsIncorrSum = common.putFileParams() -paramsIncorrSum.crc = - common.CheckSum(usedFile) +paramsIncorrSum.crc = - common.getCheckSum(usedFile) local corrDataResult = { success = false, diff --git a/test_scripts/API/Expand_PutFile/006_PutFile_with_negative_crc_multiFrame.lua b/test_scripts/API/Expand_PutFile/006_PutFile_with_negative_crc_multiFrame.lua index 0ed2b34365..78a7fa316f 100644 --- a/test_scripts/API/Expand_PutFile/006_PutFile_with_negative_crc_multiFrame.lua +++ b/test_scripts/API/Expand_PutFile/006_PutFile_with_negative_crc_multiFrame.lua @@ -23,7 +23,7 @@ runner.testSettings.isSelfIncluded = false local usedFile = "./files/icon.png" local paramsIncorrSum = common.putFileParams() -paramsIncorrSum.crc = - common.CheckSum(usedFile) +paramsIncorrSum.crc = - common.getCheckSum(usedFile) local corrDataResult = { success = false, diff --git a/test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua b/test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua index 759bf4790a..d1598a7ff0 100644 --- a/test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua +++ b/test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua @@ -62,7 +62,7 @@ local function putFileByFrames(pParams) local putFileParams = { syncFileName = "action.png", fileType = "GRAPHIC_PNG", - crc = common.CheckSum(fileName) + crc = common.getCheckSum(fileName) } local correlationId = common.getMobileSession().correlationId + 1 diff --git a/test_scripts/API/Expand_PutFile/commonPutFile.lua b/test_scripts/API/Expand_PutFile/commonPutFile.lua index 4b266487e9..cea7329eca 100644 --- a/test_scripts/API/Expand_PutFile/commonPutFile.lua +++ b/test_scripts/API/Expand_PutFile/commonPutFile.lua @@ -4,7 +4,6 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local actions = require("user_modules/sequences/actions") -local utils = require("user_modules/utils") --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 @@ -29,7 +28,7 @@ local function bytesToInt(pStr) return n end -function m.CheckSum(pFile) +function m.getCheckSum(pFile) local cmd = "cat " .. pFile .. " | gzip -1 | tail -c 8 | head -c 4" local handle = io.popen(cmd) local crc = handle:read("*a") From 57ce325dcde5a5f36a481a67f868f863ec4c82af Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 16 Apr 2018 16:26:02 +0300 Subject: [PATCH 392/681] Minor corrections --- .../API/Expand_PutFile/004_PutFile_chunks.lua | 26 +++++++++---------- .../008_PutFile_corrupted_data.lua | 2 +- .../API/Expand_PutFile/commonPutFile.lua | 17 ++++++------ 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/test_scripts/API/Expand_PutFile/004_PutFile_chunks.lua b/test_scripts/API/Expand_PutFile/004_PutFile_chunks.lua index b1be842c46..b66f5d1cfd 100644 --- a/test_scripts/API/Expand_PutFile/004_PutFile_chunks.lua +++ b/test_scripts/API/Expand_PutFile/004_PutFile_chunks.lua @@ -9,7 +9,7 @@ -- Description: -- In case: -- 1. Mobile application sends file via PutFile chunks --- 2. SDL process some part of chunks wit success result code +-- 2. SDL process some part of chunks with success result code -- 3. One chunk came with wrong crc value and SDL responds with result code "CORRUPTED_DATA" to mobile app -- SDL does: -- 1. After response "CORRUPTED_DATA" process all other chunks with resultCode "INVALID_DATA" @@ -53,22 +53,22 @@ local msg = { } --[[ Local Functions ]] -local function PrepareFileForsendingViaChunks() +local function prepareFileForsendingViaChunks() local f = assert(io.open(usedFile)) local binaryData = f:read("*all") io.close(f) local binaryDataSize = #binaryData - frameSize = binaryDataSize/FramesCount + frameSize = binaryDataSize / FramesCount local frames = {} local stringOffset = 0 for i = 1, FramesCount do - frames[i] = string.sub(binaryData, stringOffset+1, stringOffset+frameSize) + frames[i] = string.sub(binaryData, stringOffset + 1, stringOffset + frameSize) stringOffset = i*frameSize end return frames end -binaryDataFrames = PrepareFileForsendingViaChunks() +binaryDataFrames = prepareFileForsendingViaChunks() local function getFrameCheckSum(pData) local file = "./files/tmp" @@ -80,7 +80,7 @@ local function getFrameCheckSum(pData) return crc end -local function PutFile(pParams, pBinaryData, pResult) +local function putFile(pParams, pBinaryData, pResult) msgId = msgId + 1 correlationId = correlationId + 1 @@ -97,19 +97,19 @@ end local function putFileSuccess() local params = common.putFileParams() - for i=1,4 do + for i = 1, 4 do params.crc = getFrameCheckSum(binaryDataFrames[i]) params.offset = offsetValue - PutFile(params, binaryDataFrames[i]) + putFile(params, binaryDataFrames[i]) offsetValue = offsetValue + frameSize end end -local function putFileCorruptedDate() +local function putFileCorruptedData() local params = common.putFileParams() params.crc = getFrameCheckSum(binaryDataFrames[5]) - 100 params.offset = offsetValue - PutFile(params, binaryDataFrames[5], corrDataResult) + putFile(params, binaryDataFrames[5], corrDataResult) offsetValue = offsetValue + frameSize end @@ -118,7 +118,7 @@ local function putFileInvalidData() for i = 6, 10 do params.crc = getFrameCheckSum(binaryDataFrames[i]) params.offset = offsetValue - PutFile(params, binaryDataFrames[i], invalidDataResult) + putFile(params, binaryDataFrames[i], invalidDataResult) offsetValue = offsetValue + frameSize end end @@ -131,8 +131,8 @@ runner.Step("App registration with iconResumed = false", common.registerApp) runner.Title("Test") runner.Step("Success PutFile with crc", putFileSuccess) -runner.Step("Corrupted data PutFile with crc", putFileCorruptedDate) -runner.Step("invalid data PutFile with crc", putFileInvalidData) +runner.Step("Corrupted data PutFile with crc", putFileCorruptedData) +runner.Step("Invalid data PutFile with crc", putFileInvalidData) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua b/test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua index d1598a7ff0..2e97ab1716 100644 --- a/test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua +++ b/test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua @@ -134,7 +134,7 @@ local function putFileByFrames(pParams) common.getMobileSession().mobile_session_impl.rpc_services:CheckCorrelationID(msg) local function replaceChar(pStr, pPos, pChar) - return string.sub(pStr, 1, pPos - 1) .. pChar .. string.sub(pStr, pPos + 1, pStr:len()) + return string.sub(pStr, 1, pPos - 1) .. pChar .. string.sub(pStr, pPos + 1, string.len(pStr)) end if pParams.isDataCorrupted == true then diff --git a/test_scripts/API/Expand_PutFile/commonPutFile.lua b/test_scripts/API/Expand_PutFile/commonPutFile.lua index cea7329eca..9c1c5c3a55 100644 --- a/test_scripts/API/Expand_PutFile/commonPutFile.lua +++ b/test_scripts/API/Expand_PutFile/commonPutFile.lua @@ -19,20 +19,19 @@ function m.putFileParams() return temp end -local function bytesToInt(pStr) - local t = { string.byte(pStr, 1, -1) } - local n = 0 - for k = 1, #t do - n = n + t[k] * 2 ^ ((k - 1) * 8) - end - return n -end - function m.getCheckSum(pFile) local cmd = "cat " .. pFile .. " | gzip -1 | tail -c 8 | head -c 4" local handle = io.popen(cmd) local crc = handle:read("*a") handle:close() + local function bytesToInt(pStr) + local t = { string.byte(pStr, 1, -1) } + local n = 0 + for k = 1, #t do + n = n + t[k] * 2 ^ ((k - 1) * 8) + end + return n + end return bytesToInt(crc) end From 0d846fa441d40a7bcf862022b14c6c9d2a942759 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 16 May 2018 15:16:59 +0300 Subject: [PATCH 393/681] Updated 008 script for using on develop ATF --- .../008_PutFile_corrupted_data.lua | 66 +++++++++++++------ 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua b/test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua index 2e97ab1716..affc75833c 100644 --- a/test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua +++ b/test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua @@ -22,16 +22,17 @@ local json = require("modules/json") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false - --[[ Local Variables ]] local fileName = "./files/action.png" -local function bytesToInt32(pVal, pOffset) - local res = bit32.lshift(string.byte(pVal, pOffset), 24) + - bit32.lshift(string.byte(pVal, pOffset + 1), 16) + - bit32.lshift(string.byte(pVal, pOffset + 2), 8) + - string.byte(pVal, pOffset + 3) - return res +local PROTOCOL_HEADER_SIZE = 12 + +local function getProtocolFrameSize(pVersion) + if pVersion == 2 then + return 1500 + else + return 131084 + end end local function int32ToBytes(pVal) @@ -44,6 +45,39 @@ local function int32ToBytes(pVal) return res end +local function createProtocolHeader(pMessage) + local res = string.char( + bit32.bor( + bit32.lshift(pMessage.version, 4), + (pMessage.encryption and 0x08 or 0), + bit32.band(pMessage.frameType, 0x07)), + pMessage.serviceType, + pMessage.frameInfo, + pMessage.sessionId) .. + (pMessage.binaryData and int32ToBytes(#pMessage.binaryData) or string.char(0, 0, 0, 0)) .. + int32ToBytes(pMessage.messageId) + return res +end + +local function GetBinaryFrame(pMessage) + local max_protocol_payload_size = getProtocolFrameSize(pMessage.version) + - PROTOCOL_HEADER_SIZE + if pMessage.binaryData then + if #pMessage.binaryData > max_protocol_payload_size then + error("Size of current frame is bigger than max frame size for protocol version " .. pMessage.version) + end + else + pMessage.binaryData = "" + end + return createProtocolHeader(pMessage) .. pMessage.binaryData +end + +local function SendFrame(pFrameMessage) + local frame = GetBinaryFrame(pFrameMessage) + local mobileConnection = common.getMobileSession().mobile_session_impl.connection + mobileConnection.connection:Send({frame}) +end + local function rpcPayload(pMsg) pMsg.payload = pMsg.payload or "" pMsg.binaryData = pMsg.binaryData or "" @@ -142,22 +176,12 @@ local function putFileByFrames(pParams) end for _, frame in pairs(frames) do - common.getMobileSession():SendPacket(frame) + SendFrame(frame) end - common.getMobileSession():ExpectResponse(correlationId, { success = pParams.success, resultCode = pParams.resultCode }) - - common.getMobileSession():ExpectPacket({ - sessionId = common.getMobileSession().sessionId, - frameType = 0x01, - serviceType = 0x07 - }, - function(binaryData) - local rpcFunctionId = bit32.band(bytesToInt32(binaryData, 1), 0x0fffffff) - local rpcCorrelationId = bytesToInt32(binaryData, 5) - if rpcFunctionId ~= 32 or rpcCorrelationId ~= correlationId then return false end - return true - end) + common.getMobileSession():ExpectResponse(correlationId, + { success = pParams.success, resultCode = pParams.resultCode }) + end From d1e08289dfcc24e8b8a5e530657dc6e90ed37d7c Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 18 May 2018 13:34:39 +0300 Subject: [PATCH 394/681] Pull request template --- .github/PULL_REQUEST_TEMPLATE.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..0745d1738b --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,24 @@ +ATF Test Scripts to check #[issue number in sdl_core repository] + +This PR is **[ready / not ready]** for review. + +### Summary +[Summary of PR changes] + +### ATF version +[ATF version to use] + +### Changelog + +##### Enhancements +* [Enhancement info] + +##### Bug Fixes +* [Bug Fix Info] + +### Dependencies: +- [ ] [Task 1] +- [ ] [Task 2] + +### CLA +- [ ] I have signed [the CLA](https://docs.google.com/forms/d/e/1FAIpQLSdsgJY33VByaX482zHzi-xUm49JNnmuJOyAM6uegPQ2LXYVfA/viewform) From cf36f0ab55db710b45404c05b867d032f5683699 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 16 Apr 2018 18:41:14 +0300 Subject: [PATCH 395/681] Initial version of the scripts for Mobile Projection 2 --- .../001_audioStreamingState_001-009.lua | 46 ++++ .../002_audioStreamingState_010-068.lua | 105 ++++++++ .../003_audioStreamingState_069-103.lua | 74 ++++++ .../004_audioStreamingState_104-110.lua | 65 +++++ .../006_videoStreamingState_001-006.lua | 43 ++++ .../007_videoStreamingState_007-030.lua | 70 ++++++ .../008_videoStreamingState_031-034.lua | 43 ++++ .../Phase2/009_hmiLevel_001-032.lua | 229 ++++++++++++++++++ .../MobileProjection/Phase2/common.lua | 112 +++++++++ test_sets/mobile_projection_2.txt | 8 + 10 files changed, 795 insertions(+) create mode 100644 test_scripts/MobileProjection/Phase2/001_audioStreamingState_001-009.lua create mode 100644 test_scripts/MobileProjection/Phase2/002_audioStreamingState_010-068.lua create mode 100644 test_scripts/MobileProjection/Phase2/003_audioStreamingState_069-103.lua create mode 100644 test_scripts/MobileProjection/Phase2/004_audioStreamingState_104-110.lua create mode 100644 test_scripts/MobileProjection/Phase2/006_videoStreamingState_001-006.lua create mode 100644 test_scripts/MobileProjection/Phase2/007_videoStreamingState_007-030.lua create mode 100644 test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-034.lua create mode 100644 test_scripts/MobileProjection/Phase2/009_hmiLevel_001-032.lua create mode 100644 test_scripts/MobileProjection/Phase2/common.lua create mode 100644 test_sets/mobile_projection_2.txt diff --git a/test_scripts/MobileProjection/Phase2/001_audioStreamingState_001-009.lua b/test_scripts/MobileProjection/Phase2/001_audioStreamingState_001-009.lua new file mode 100644 index 0000000000..c0e53bc892 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/001_audioStreamingState_001-009.lua @@ -0,0 +1,46 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [001] = { t = "PROJECTION", m = false, s = "NOT_AUDIBLE" }, + [002] = { t = "DEFAULT", m = false, s = "NOT_AUDIBLE" }, + [003] = { t = "NAVIGATION", m = false, s = "AUDIBLE" }, + [004] = { t = "COMMUNICATION", m = false, s = "AUDIBLE" }, + [005] = { t = "NAVIGATION", m = true, s = "AUDIBLE" }, + [006] = { t = "COMMUNICATION", m = true, s = "AUDIBLE" }, + [007] = { t = "PROJECTION", m = true, s = "AUDIBLE" }, + [008] = { t = "MEDIA", m = true, s = "AUDIBLE" }, + [009] = { t = "DEFAULT", m = true, s = "AUDIBLE" } +} + +--[[ Local Functions ]] +local function activateApp(pTC, pAudioSS) + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId() }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, "App1", pAudioSS, data.payload.audioStreamingState) + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp) + runner.Step("Activate App, audioState:" .. tc.s, activateApp, { n, tc.s }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/002_audioStreamingState_010-068.lua b/test_scripts/MobileProjection/Phase2/002_audioStreamingState_010-068.lua new file mode 100644 index 0000000000..52f32051b2 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/002_audioStreamingState_010-068.lua @@ -0,0 +1,105 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [010] = { [1] = { t = "NAVIGATION", m = false, s = "AUDIBLE" }, [2] = { t = "PROJECTION", m = false, s = "NOT_AUDIBLE" }}, + [011] = { [1] = { t = "NAVIGATION", m = false, s = "AUDIBLE" }, [2] = { t = "DEFAULT", m = false, s = "NOT_AUDIBLE" }}, + [012] = { [1] = { t = "NAVIGATION", m = true, s = "AUDIBLE" }, [2] = { t = "PROJECTION", m = false, s = "NOT_AUDIBLE" }}, + [013] = { [1] = { t = "NAVIGATION", m = true, s = "AUDIBLE" }, [2] = { t = "DEFAULT", m = false, s = "NOT_AUDIBLE" }}, + [014] = { [1] = { t = "COMMUNICATION", m = false, s = "AUDIBLE" }, [2] = { t = "PROJECTION", m = false, s = "NOT_AUDIBLE" }}, + [015] = { [1] = { t = "COMMUNICATION", m = false, s = "AUDIBLE" }, [2] = { t = "DEFAULT", m = false, s = "NOT_AUDIBLE" }}, + [016] = { [1] = { t = "COMMUNICATION", m = true, s = "AUDIBLE" }, [2] = { t = "PROJECTION", m = false, s = "NOT_AUDIBLE" }}, + [017] = { [1] = { t = "COMMUNICATION", m = true, s = "AUDIBLE" }, [2] = { t = "DEFAULT", m = false, s = "NOT_AUDIBLE" }}, + [018] = { [1] = { t = "PROJECTION", m = true, s = "AUDIBLE" }, [2] = { t = "PROJECTION", m = false, s = "NOT_AUDIBLE" }}, + [019] = { [1] = { t = "PROJECTION", m = true, s = "AUDIBLE" }, [2] = { t = "DEFAULT", m = false, s = "NOT_AUDIBLE" }}, + [020] = { [1] = { t = "MEDIA", m = true, s = "AUDIBLE" }, [2] = { t = "PROJECTION", m = false, s = "NOT_AUDIBLE" }}, + [021] = { [1] = { t = "MEDIA", m = true, s = "AUDIBLE" }, [2] = { t = "DEFAULT", m = false, s = "NOT_AUDIBLE" }}, + [022] = { [1] = { t = "DEFAULT", m = true, s = "AUDIBLE" }, [2] = { t = "PROJECTION", m = false, s = "NOT_AUDIBLE" }}, + [023] = { [1] = { t = "DEFAULT", m = true, s = "AUDIBLE" }, [2] = { t = "DEFAULT", m = false, s = "NOT_AUDIBLE" }}, + [024] = { [1] = { t = "NAVIGATION", m = false, s = "NOT_AUDIBLE" }, [2] = { t = "NAVIGATION", m = false, s = "AUDIBLE" } }, + [025] = { [1] = { t = "NAVIGATION", m = true, s = "NOT_AUDIBLE" }, [2] = { t = "NAVIGATION", m = false, s = "AUDIBLE" } }, + [026] = { [1] = { t = "NAVIGATION", m = false, s = "NOT_AUDIBLE" }, [2] = { t = "NAVIGATION", m = true, s = "AUDIBLE" } }, + [027] = { [1] = { t = "NAVIGATION", m = true, s = "NOT_AUDIBLE" }, [2] = { t = "NAVIGATION", m = true, s = "AUDIBLE" } }, + [028] = { [1] = { t = "COMMUNICATION", m = false, s = "NOT_AUDIBLE" }, [2] = { t = "COMMUNICATION", m = false, s = "AUDIBLE" } }, + [029] = { [1] = { t = "COMMUNICATION", m = true, s = "NOT_AUDIBLE" }, [2] = { t = "COMMUNICATION", m = false, s = "AUDIBLE" } }, + [030] = { [1] = { t = "COMMUNICATION", m = false, s = "NOT_AUDIBLE" }, [2] = { t = "COMMUNICATION", m = true, s = "AUDIBLE" } }, + [031] = { [1] = { t = "COMMUNICATION", m = true, s = "NOT_AUDIBLE" }, [2] = { t = "COMMUNICATION", m = true, s = "AUDIBLE" } }, + [032] = { [1] = { t = "NAVIGATION", m = false, s = "AUDIBLE" }, [2] = { t = "PROJECTION", m = true, s = "AUDIBLE" } }, + [033] = { [1] = { t = "NAVIGATION", m = false, s = "AUDIBLE" }, [2] = { t = "MEDIA", m = true, s = "AUDIBLE" } }, + [034] = { [1] = { t = "NAVIGATION", m = false, s = "AUDIBLE" }, [2] = { t = "DEFAULT", m = true, s = "AUDIBLE" } }, + [035] = { [1] = { t = "NAVIGATION", m = false, s = "AUDIBLE" }, [2] = { t = "COMMUNICATION", m = true, s = "AUDIBLE" } }, + [036] = { [1] = { t = "NAVIGATION", m = true, s = "AUDIBLE" }, [2] = { t = "PROJECTION", m = true, s = "AUDIBLE" } }, + [037] = { [1] = { t = "NAVIGATION", m = true, s = "AUDIBLE" }, [2] = { t = "MEDIA", m = true, s = "AUDIBLE" } }, + [038] = { [1] = { t = "NAVIGATION", m = true, s = "AUDIBLE" }, [2] = { t = "DEFAULT", m = true, s = "AUDIBLE" } }, + [039] = { [1] = { t = "NAVIGATION", m = true, s = "AUDIBLE" }, [2] = { t = "COMMUNICATION", m = true, s = "AUDIBLE" } }, + [040] = { [1] = { t = "COMMUNICATION", m = false, s = "AUDIBLE" }, [2] = { t = "PROJECTION", m = true, s = "AUDIBLE" } }, + [041] = { [1] = { t = "COMMUNICATION", m = false, s = "AUDIBLE" }, [2] = { t = "MEDIA", m = true, s = "AUDIBLE" } }, + [042] = { [1] = { t = "COMMUNICATION", m = false, s = "AUDIBLE" }, [2] = { t = "DEFAULT", m = true, s = "AUDIBLE" } }, + [043] = { [1] = { t = "COMMUNICATION", m = false, s = "AUDIBLE" }, [2] = { t = "NAVIGATION", m = true, s = "AUDIBLE" } }, + [044] = { [1] = { t = "COMMUNICATION", m = true, s = "AUDIBLE" }, [2] = { t = "PROJECTION", m = true, s = "AUDIBLE" } }, + [045] = { [1] = { t = "COMMUNICATION", m = true, s = "AUDIBLE" }, [2] = { t = "MEDIA", m = true, s = "AUDIBLE" } }, + [046] = { [1] = { t = "COMMUNICATION", m = true, s = "AUDIBLE" }, [2] = { t = "DEFAULT", m = true, s = "AUDIBLE" } }, + [047] = { [1] = { t = "COMMUNICATION", m = true, s = "AUDIBLE" }, [2] = { t = "NAVIGATION", m = true, s = "AUDIBLE" } }, + [048] = { [1] = { t = "PROJECTION", m = true, s = "AUDIBLE" }, [2] = { t = "NAVIGATION", m = false, s = "AUDIBLE" } }, + [049] = { [1] = { t = "PROJECTION", m = true, s = "AUDIBLE" }, [2] = { t = "COMMUNICATION", m = false, s = "AUDIBLE" } }, + [050] = { [1] = { t = "PROJECTION", m = true, s = "AUDIBLE" }, [2] = { t = "NAVIGATION", m = true, s = "AUDIBLE" } }, + [051] = { [1] = { t = "PROJECTION", m = true, s = "AUDIBLE" }, [2] = { t = "COMMUNICATION", m = true, s = "AUDIBLE" } }, + [052] = { [1] = { t = "MEDIA", m = true, s = "AUDIBLE" }, [2] = { t = "NAVIGATION", m = false, s = "AUDIBLE" } }, + [053] = { [1] = { t = "MEDIA", m = true, s = "AUDIBLE" }, [2] = { t = "COMMUNICATION", m = false, s = "AUDIBLE" } }, + [054] = { [1] = { t = "MEDIA", m = true, s = "AUDIBLE" }, [2] = { t = "NAVIGATION", m = true, s = "AUDIBLE" } }, + [055] = { [1] = { t = "MEDIA", m = true, s = "AUDIBLE" }, [2] = { t = "COMMUNICATION", m = true, s = "AUDIBLE" } }, + [056] = { [1] = { t = "DEFAULT", m = true, s = "AUDIBLE" }, [2] = { t = "NAVIGATION", m = false, s = "AUDIBLE" } }, + [057] = { [1] = { t = "DEFAULT", m = true, s = "AUDIBLE" }, [2] = { t = "COMMUNICATION", m = false, s = "AUDIBLE" } }, + [058] = { [1] = { t = "DEFAULT", m = true, s = "AUDIBLE" }, [2] = { t = "NAVIGATION", m = true, s = "AUDIBLE" } }, + [059] = { [1] = { t = "DEFAULT", m = true, s = "AUDIBLE" }, [2] = { t = "COMMUNICATION", m = true, s = "AUDIBLE" } }, + [060] = { [1] = { t = "PROJECTION", m = true, s = "NOT_AUDIBLE" }, [2] = { t = "PROJECTION", m = true, s = "AUDIBLE" } }, + [061] = { [1] = { t = "PROJECTION", m = true, s = "NOT_AUDIBLE" }, [2] = { t = "MEDIA", m = true, s = "AUDIBLE" } }, + [062] = { [1] = { t = "PROJECTION", m = true, s = "NOT_AUDIBLE" }, [2] = { t = "DEFAULT", m = true, s = "AUDIBLE" } }, + [063] = { [1] = { t = "MEDIA", m = true, s = "NOT_AUDIBLE" }, [2] = { t = "PROJECTION", m = true, s = "AUDIBLE" } }, + [064] = { [1] = { t = "MEDIA", m = true, s = "NOT_AUDIBLE" }, [2] = { t = "MEDIA", m = true, s = "AUDIBLE" } }, + [065] = { [1] = { t = "MEDIA", m = true, s = "NOT_AUDIBLE" }, [2] = { t = "DEFAULT", m = true, s = "AUDIBLE" } }, + [066] = { [1] = { t = "DEFAULT", m = true, s = "NOT_AUDIBLE" }, [2] = { t = "PROJECTION", m = true, s = "AUDIBLE" } }, + [067] = { [1] = { t = "DEFAULT", m = true, s = "NOT_AUDIBLE" }, [2] = { t = "MEDIA", m = true, s = "AUDIBLE" } }, + [068] = { [1] = { t = "DEFAULT", m = true, s = "NOT_AUDIBLE" }, [2] = { t = "DEFAULT", m = true, s = "AUDIBLE" } } +} + +--[[ Local Functions ]] +local function activateApp2(pTC, pAudioSSApp1, pAudioSSApp2) + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId(2) }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, "App1", pAudioSSApp1, data.payload.audioStreamingState) + end) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, "App2", pAudioSSApp2, data.payload.audioStreamingState) + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Activate App 2, audioStates: app1 " .. tc[1].s .. ", app2 " .. tc[2].s, activateApp2, + { n, tc[1].s, tc[2].s }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/003_audioStreamingState_069-103.lua b/test_scripts/MobileProjection/Phase2/003_audioStreamingState_069-103.lua new file mode 100644 index 0000000000..b77925d9bc --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/003_audioStreamingState_069-103.lua @@ -0,0 +1,74 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [069] = { t = "NAVIGATION", m = false, s = "NOT_AUDIBLE", e = "PHONE_CALL" }, + [070] = { t = "NAVIGATION", m = true, s = "NOT_AUDIBLE", e = "PHONE_CALL" }, + [071] = { t = "COMMUNICATION", m = false, s = "NOT_AUDIBLE", e = "PHONE_CALL" }, + [072] = { t = "COMMUNICATION", m = true, s = "NOT_AUDIBLE", e = "PHONE_CALL" }, + [073] = { t = "PROJECTION", m = true, s = "NOT_AUDIBLE", e = "PHONE_CALL" }, + [074] = { t = "MEDIA", m = true, s = "NOT_AUDIBLE", e = "PHONE_CALL" }, + [075] = { t = "DEFAULT", m = true, s = "NOT_AUDIBLE", e = "PHONE_CALL" }, + [076] = { t = "NAVIGATION", m = false, s = "NOT_AUDIBLE", e = "EMERGENCY_EVENT" }, + [077] = { t = "NAVIGATION", m = true, s = "NOT_AUDIBLE", e = "EMERGENCY_EVENT" }, + [078] = { t = "COMMUNICATION", m = false, s = "NOT_AUDIBLE", e = "EMERGENCY_EVENT" }, + [079] = { t = "COMMUNICATION", m = true, s = "NOT_AUDIBLE", e = "EMERGENCY_EVENT" }, + [080] = { t = "PROJECTION", m = true, s = "NOT_AUDIBLE", e = "EMERGENCY_EVENT" }, + [081] = { t = "MEDIA", m = true, s = "NOT_AUDIBLE", e = "EMERGENCY_EVENT" }, + [082] = { t = "DEFAULT", m = true, s = "NOT_AUDIBLE", e = "EMERGENCY_EVENT" }, + [083] = { t = "NAVIGATION", m = false, s = "NOT_AUDIBLE", e = "AUDIO_SOURCE" }, + [084] = { t = "NAVIGATION", m = true, s = "NOT_AUDIBLE", e = "AUDIO_SOURCE" }, + [085] = { t = "COMMUNICATION", m = false, s = "NOT_AUDIBLE", e = "AUDIO_SOURCE" }, + [086] = { t = "COMMUNICATION", m = true, s = "NOT_AUDIBLE", e = "AUDIO_SOURCE" }, + [087] = { t = "PROJECTION", m = true, s = "NOT_AUDIBLE", e = "AUDIO_SOURCE" }, + [088] = { t = "MEDIA", m = true, s = "NOT_AUDIBLE", e = "AUDIO_SOURCE" }, + [089] = { t = "DEFAULT", m = true, s = "NOT_AUDIBLE", e = "AUDIO_SOURCE" }, + [090] = { t = "NAVIGATION", m = false, s = "NOT_AUDIBLE", e = "EMBEDDED_NAVI" }, + [091] = { t = "NAVIGATION", m = true, s = "NOT_AUDIBLE", e = "EMBEDDED_NAVI" }, + [092] = { t = "COMMUNICATION", m = false, s = "NOT_AUDIBLE", e = "EMBEDDED_NAVI" }, + [093] = { t = "COMMUNICATION", m = true, s = "NOT_AUDIBLE", e = "EMBEDDED_NAVI" }, + [094] = { t = "PROJECTION", m = true, s = "NOT_AUDIBLE", e = "EMBEDDED_NAVI" }, + [095] = { t = "MEDIA", m = true, s = "NOT_AUDIBLE", e = "EMBEDDED_NAVI" }, + [096] = { t = "DEFAULT", m = true, s = "NOT_AUDIBLE", e = "EMBEDDED_NAVI" }, + [097] = { t = "NAVIGATION", m = false, s = "NOT_AUDIBLE", e = "DEACTIVATE_HMI" }, + [098] = { t = "NAVIGATION", m = true, s = "NOT_AUDIBLE", e = "DEACTIVATE_HMI" }, + [099] = { t = "COMMUNICATION", m = false, s = "NOT_AUDIBLE", e = "DEACTIVATE_HMI" }, + [100] = { t = "COMMUNICATION", m = true, s = "NOT_AUDIBLE", e = "DEACTIVATE_HMI" }, + [101] = { t = "PROJECTION", m = true, s = "NOT_AUDIBLE", e = "DEACTIVATE_HMI" }, + [102] = { t = "MEDIA", m = true, s = "NOT_AUDIBLE", e = "DEACTIVATE_HMI" }, + [103] = { t = "DEFAULT", m = true, s = "NOT_AUDIBLE", e = "DEACTIVATE_HMI" } +} + +--[[ Local Functions ]] +local function sendEvent(pTC, pEvent, pAudioSS) + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = pEvent, + isActive = true }) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, "App1", pAudioSS, data.payload.audioStreamingState) + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. ", event:" .. tc.e .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp) + runner.Step("Activate App", common.activateApp) + runner.Step("Send event from HMI: " .. tc.e, sendEvent, { n, tc.e, tc.s }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/004_audioStreamingState_104-110.lua b/test_scripts/MobileProjection/Phase2/004_audioStreamingState_104-110.lua new file mode 100644 index 0000000000..a76c10d132 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/004_audioStreamingState_104-110.lua @@ -0,0 +1,65 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [104] = { t = "NAVIGATION", m = false }, + [105] = { t = "NAVIGATION", m = true }, + [106] = { t = "COMMUNICATION", m = false }, + [107] = { t = "COMMUNICATION", m = true }, + [108] = { t = "PROJECTION", m = true }, + [109] = { t = "MEDIA", m = true }, + [110] = { t = "DEFAULT", m = true } +} + +--[[ Local Functions ]] +local function sendSpeak(pTC) + local request = { + ttsChunks = { + { text ="Text1", type ="TEXT" } + } + } + local cid = common.getMobileSession():SendRPC("Speak", request) + common.getHMIConnection():ExpectRequest("TTS.Speak") + :Do(function(_, data) + common.getHMIConnection():SendNotification("TTS.Started") + local function speakResponse() + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { }) + common.getHMIConnection():SendNotification("TTS.Stopped") + end + RUN_AFTER(speakResponse, 1000) + end) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + + common.getMobileSession():ExpectNotification("OnHMIStatus") + :ValidIf(function(e, data) + if e.occurences == 1 then + return common.checkAudioSS(pTC, "App1", "ATTENUATED", data.payload.audioStreamingState) + else + return common.checkAudioSS(pTC, "App1", "AUDIBLE", data.payload.audioStreamingState) + end + end) + :Times(2) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp) + runner.Step("Activate App", common.activateApp) + runner.Step("Send Speak, audioState:ATTENUATED", sendSpeak, { n }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/006_videoStreamingState_001-006.lua b/test_scripts/MobileProjection/Phase2/006_videoStreamingState_001-006.lua new file mode 100644 index 0000000000..65264f4d50 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/006_videoStreamingState_001-006.lua @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [001] = { t = "MEDIA", m = true, s = "NOT_STREAMABLE" }, + [002] = { t = "DEFAULT", m = false, s = "NOT_STREAMABLE" }, + [003] = { t = "NAVIGATION", m = true, s = "STREAMABLE" }, + [004] = { t = "NAVIGATION", m = false, s = "STREAMABLE" }, + [005] = { t = "PROJECTION", m = true, s = "STREAMABLE" }, + [006] = { t = "PROJECTION", m = false, s = "STREAMABLE" } +} + +--[[ Local Functions ]] +local function activateApp(pTC, pVideoSS) + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId() }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, "App1", pVideoSS, data.payload.videoStreamingState) + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp) + runner.Step("Activate App, videoState:" .. tc.s, activateApp, { n, tc.s }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/007_videoStreamingState_007-030.lua b/test_scripts/MobileProjection/Phase2/007_videoStreamingState_007-030.lua new file mode 100644 index 0000000000..85ea387569 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/007_videoStreamingState_007-030.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [007] = { [1] = { t = "NAVIGATION", m = true, s = "STREAMABLE" }, [2] = { t = "MEDIA", m = true, s = "NOT_STREAMABLE" }}, + [008] = { [1] = { t = "NAVIGATION", m = false, s = "STREAMABLE" }, [2] = { t = "MEDIA", m = true, s = "NOT_STREAMABLE" }}, + [009] = { [1] = { t = "PROJECTION", m = false, s = "STREAMABLE" }, [2] = { t = "MEDIA", m = true, s = "NOT_STREAMABLE" }}, + [010] = { [1] = { t = "PROJECTION", m = false, s = "STREAMABLE" }, [2] = { t = "MEDIA", m = true, s = "NOT_STREAMABLE" }}, + [011] = { [1] = { t = "NAVIGATION", m = true, s = "STREAMABLE" }, [2] = { t = "DEFAULT", m = false, s = "NOT_STREAMABLE" }}, + [012] = { [1] = { t = "NAVIGATION", m = false, s = "STREAMABLE" }, [2] = { t = "DEFAULT", m = false, s = "NOT_STREAMABLE" }}, + [013] = { [1] = { t = "PROJECTION", m = true, s = "STREAMABLE" }, [2] = { t = "DEFAULT", m = false, s = "NOT_STREAMABLE" }}, + [014] = { [1] = { t = "PROJECTION", m = false, s = "STREAMABLE" }, [2] = { t = "DEFAULT", m = false, s = "NOT_STREAMABLE" }}, + [015] = { [1] = { t = "NAVIGATION", m = true, s = "NOT_STREAMABLE" }, [2] = { t = "NAVIGATION", m = true, s = "STREAMABLE" }}, + [016] = { [1] = { t = "NAVIGATION", m = true, s = "NOT_STREAMABLE" }, [2] = { t = "NAVIGATION", m = false, s = "STREAMABLE" }}, + [017] = { [1] = { t = "NAVIGATION", m = false, s = "NOT_STREAMABLE" }, [2] = { t = "NAVIGATION", m = true, s = "STREAMABLE" }}, + [018] = { [1] = { t = "NAVIGATION", m = false, s = "NOT_STREAMABLE" }, [2] = { t = "NAVIGATION", m = false, s = "STREAMABLE" }}, + [019] = { [1] = { t = "PROJECTION", m = true, s = "NOT_STREAMABLE" }, [2] = { t = "NAVIGATION", m = true, s = "STREAMABLE" }}, + [020] = { [1] = { t = "PROJECTION", m = true, s = "NOT_STREAMABLE" }, [2] = { t = "NAVIGATION", m = false, s = "STREAMABLE" }}, + [021] = { [1] = { t = "PROJECTION", m = false, s = "NOT_STREAMABLE" }, [2] = { t = "NAVIGATION", m = true, s = "STREAMABLE" }}, + [022] = { [1] = { t = "PROJECTION", m = false, s = "NOT_STREAMABLE" }, [2] = { t = "NAVIGATION", m = false, s = "STREAMABLE" }}, + [023] = { [1] = { t = "PROJECTION", m = true, s = "NOT_STREAMABLE" }, [2] = { t = "PROJECTION", m = true, s = "STREAMABLE" }}, + [024] = { [1] = { t = "PROJECTION", m = true, s = "NOT_STREAMABLE" }, [2] = { t = "PROJECTION", m = false, s = "STREAMABLE" }}, + [025] = { [1] = { t = "PROJECTION", m = false, s = "NOT_STREAMABLE" }, [2] = { t = "PROJECTION", m = true, s = "STREAMABLE" }}, + [026] = { [1] = { t = "PROJECTION", m = false, s = "NOT_STREAMABLE" }, [2] = { t = "PROJECTION", m = false, s = "STREAMABLE" }}, + [027] = { [1] = { t = "NAVIGATION", m = true, s = "NOT_STREAMABLE" }, [2] = { t = "PROJECTION", m = true, s = "STREAMABLE" }}, + [028] = { [1] = { t = "NAVIGATION", m = true, s = "NOT_STREAMABLE" }, [2] = { t = "PROJECTION", m = false, s = "STREAMABLE" }}, + [029] = { [1] = { t = "NAVIGATION", m = false, s = "NOT_STREAMABLE" }, [2] = { t = "PROJECTION", m = true, s = "STREAMABLE" }}, + [030] = { [1] = { t = "NAVIGATION", m = false, s = "NOT_STREAMABLE" }, [2] = { t = "PROJECTION", m = false, s = "STREAMABLE" }} +} + +--[[ Local Functions ]] +local function activateApp2(pTC, pVideoSSApp1, pVideoSSApp2) + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId(2) }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, "App1", pVideoSSApp1, data.payload.videoStreamingState) + end) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, "App2", pVideoSSApp2, data.payload.videoStreamingState) + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Activate App 2, videoStates: app1 " .. tc[1].s .. ", app2 " .. tc[2].s, activateApp2, + { n, tc[1].s, tc[2].s }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-034.lua b/test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-034.lua new file mode 100644 index 0000000000..ec6783a5ed --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-034.lua @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [031] = { t = "NAVIGATION", m = true, s = "NOT_STREAMABLE", e = "DEACTIVATE_HMI" }, + [032] = { t = "NAVIGATION", m = false, s = "NOT_STREAMABLE", e = "DEACTIVATE_HMI" }, + [033] = { t = "PROJECTION", m = true, s = "NOT_STREAMABLE", e = "DEACTIVATE_HMI" }, + [034] = { t = "PROJECTION", m = false, s = "NOT_STREAMABLE", e = "DEACTIVATE_HMI" } +} + +--[[ Local Functions ]] +local function sendEvent(pTC, pEvent, pVideoSS) + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = pEvent, + isActive = true }) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, "App1", pVideoSS, data.payload.videoStreamingState) + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. ", event:" .. tc.e .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp) + runner.Step("Activate App", common.activateApp) + runner.Step("Send event from HMI: " .. tc.e, sendEvent, { n, tc.e, tc.s }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/009_hmiLevel_001-032.lua b/test_scripts/MobileProjection/Phase2/009_hmiLevel_001-032.lua new file mode 100644 index 0000000000..2bf4e7672b --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/009_hmiLevel_001-032.lua @@ -0,0 +1,229 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.checkAllValidations = true + +--[[ Event Functions ]] +local action = { + activateApp = { + name = "Activation", + func = function() + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { + appID = common.getHMIAppId() }) + common.getHMIConnection():ExpectResponse(requestId) + end + }, + deactivateApp = { + name = "De-activation", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId() }) + end + }, + deactivateHMI = { + name = "HMI De-activation", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "DEACTIVATE_HMI", + isActive = true }) + end + }, + activateHMI = { + name = "HMI Activation", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "DEACTIVATE_HMI", + isActive = false }) + end + }, + exitApp = { + name = "User Exit", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnExitApplication", { + appID = common.getHMIAppId(), + reason = "USER_EXIT" }) + end + } +} + +--[[ Local Variables ]] +local testCases = { + [001] = { t = "MEDIA", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "NOT_STREAMABLE" }, + [2] = { e = action.deactivateApp, l = "LIMITED", a = "AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [002] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateApp, l = "LIMITED", a = "NOT_AUDIBLE", v = "STREAMABLE" } + }}, + [003] = { t = "NAVIGATION", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateApp, l = "LIMITED", a = "AUDIBLE", v = "STREAMABLE" } + }}, + [004] = { t = "DEFAULT", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [2] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [005] = { t = "MEDIA", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "NOT_STREAMABLE" }, + [2] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [006] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [007] = { t = "NAVIGATION", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [008] = { t = "MEDIA", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "NOT_STREAMABLE" }, + [2] = { e = action.deactivateApp, l = "LIMITED", a = "AUDIBLE", v = "NOT_STREAMABLE" }, + [3] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [009] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateApp, l = "LIMITED", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [3] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [010] = { t = "NAVIGATION", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateApp, l = "LIMITED", a = "AUDIBLE", v = "STREAMABLE" }, + [3] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [011] = { t = "MEDIA", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "NOT_STREAMABLE" }, + [2] = { e = action.exitApp, l = "NONE", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [012] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.exitApp, l = "NONE", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [013] = { t = "NAVIGATION", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.exitApp, l = "NONE", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [014] = { t = "DEFAULT", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [2] = { e = action.exitApp, l = "NONE", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [015] = { t = "MEDIA", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [016] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" } + }}, + [017] = { t = "NAVIGATION", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "STREAMABLE" } + }}, + [018] = { t = "DEFAULT", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [019] = { t = "MEDIA", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "NOT_STREAMABLE" }, + [2] = { e = action.deactivateApp, l = "LIMITED", a = "AUDIBLE", v = "NOT_STREAMABLE" }, + [3] = { e = action.exitApp, l = "NONE", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [020] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateApp, l = "LIMITED", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [3] = { e = action.exitApp, l = "NONE", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [021] = { t = "NAVIGATION", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateApp, l = "LIMITED", a = "AUDIBLE", v = "STREAMABLE" }, + [3] = { e = action.exitApp, l = "NONE", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [022] = { t = "MEDIA", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "NOT_STREAMABLE" }, + [2] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [3] = { e = action.exitApp, l = "NONE", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [023] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [3] = { e = action.exitApp, l = "NONE", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [024] = { t = "NAVIGATION", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [3] = { e = action.exitApp, l = "NONE", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [025] = { t = "DEFAULT", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [2] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [3] = { e = action.exitApp, l = "NONE", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [026] = { t = "MEDIA", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "NOT_STREAMABLE" }, + [2] = { e = action.deactivateApp, l = "LIMITED", a = "AUDIBLE", v = "NOT_STREAMABLE" }, + [3] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [027] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateApp, l = "LIMITED", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [3] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" } + }}, + [028] = { t = "NAVIGATION", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateApp, l = "LIMITED", a = "AUDIBLE", v = "STREAMABLE" }, + [3] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "STREAMABLE" } + }}, + [029] = { t = "MEDIA", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "NOT_STREAMABLE" }, + [2] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [3] = { e = action.activateHMI, l = "FULL", a = "AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [030] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [3] = { e = action.activateHMI, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" } + }}, + [031] = { t = "NAVIGATION", m = true, s = { + [1] = { e = action.activateApp, l = "FULL", a = "AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [3] = { e = action.activateHMI, l = "FULL", a = "AUDIBLE", v = "STREAMABLE" } + }}, + [032] = { t = "DEFAULT", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [2] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [3] = { e = action.activateHMI, l = "FULL", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }} +} + +--[[ Local Functions ]] +local function doAction(pTC, pSS) + pSS.e.func() + common.getMobileSession():ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, pSS.e.name, pSS.a, data.payload.audioStreamingState) + end) + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, pSS.e.name, pSS.v, data.payload.videoStreamingState) + end) + :ValidIf(function(_, data) + return common.checkHMILevel(pTC, pSS.e.name, pSS.l, data.payload.hmiLevel) + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp) + for i = 1, #tc.s do + runner.Step("Action:" .. tc.s[i].e.name .. ",hmiLevel:" .. tc.s[i].l, doAction, { n, tc.s[i] }) + end + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/common.lua b/test_scripts/MobileProjection/Phase2/common.lua new file mode 100644 index 0000000000..150ed18d68 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/common.lua @@ -0,0 +1,112 @@ +--------------------------------------------------------------------------------------------------- +-- Common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 + +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") +local utils = require("user_modules/utils") +local test = require("user_modules/dummy_connecttest") + +--[[ Module ]] +local m = actions + +m.failedTCs = {} + +m.wait = utils.wait +m.registerApp = m.registerAppWOPTU + +function m.activateApp(pAppId) + if not pAppId then pAppId = 1 end + local requestId = test.hmiConnection:SendRequest("SDL.ActivateApp", { appID = m.getHMIAppId(pAppId) }) + test.hmiConnection:ExpectResponse(requestId) + m.getMobileSession(pAppId):ExpectNotification("OnHMIStatus", { hmiLevel = "FULL" }) + utils.wait() +end + +function m.setAppConfig(pAppId, pAppHMIType, pIsMedia) + m.getConfigAppParams(pAppId).appHMIType = { pAppHMIType } + m.getConfigAppParams(pAppId).isMediaApplication = pIsMedia +end + +function m.cleanSessions() + for i = 1, m.getAppsCount() do + test.mobileSession[i]:StopRPC() + :Do(function(_, d) + utils.cprint(35, "Mobile session " .. d.sessionId .. " deleted") + test.mobileSession[i] = nil + end) + end + utils.wait() +end + +function m.spairs(pTbl) + local keys = {} + for k in pairs(pTbl) do + keys[#keys+1] = k + end + local function getStringKey(pKey) + return tostring(string.format("%03d", pKey)) + end + table.sort(keys, function(a, b) return getStringKey(a) < getStringKey(b) end) + local i = 0 + return function() + i = i + 1 + if keys[i] then + return keys[i], pTbl[keys[i]] + end + end +end + +function m.checkAudioSS(pTC, pEvent, pExpAudioSS, pActAudioSS) + if pActAudioSS ~= pExpAudioSS then + if m.failedTCs[pTC] == nil then + m.failedTCs[pTC] = "" + else + m.failedTCs[pTC] = m.failedTCs[pTC] .. "\n\t" + end + local msg = pEvent .. ": audioStreamingState: expected " .. pExpAudioSS + .. ", actual value: " .. tostring(pActAudioSS) + m.failedTCs[pTC] = m.failedTCs[pTC] .. msg + return false, msg + end + return true +end + +function m.checkVideoSS(pTC, pEvent, pExpVideoSS, pActVideoSS) + if pActVideoSS ~= pExpVideoSS then + if m.failedTCs[pTC] == nil then + m.failedTCs[pTC] = "" + else + m.failedTCs[pTC] = m.failedTCs[pTC] .. "\n\t" + end + local msg = pEvent .. ": videoStreamingState: expected " .. pExpVideoSS + .. ", actual value: " .. tostring(pActVideoSS) + m.failedTCs[pTC] = m.failedTCs[pTC] .. msg + return false, msg + end + return true +end + +function m.checkHMILevel(pTC, pEvent, pExpHMILvl, pActHMILvl) + if pActHMILvl ~= pExpHMILvl then + if m.failedTCs[pTC] == nil then + m.failedTCs[pTC] = "" + else + m.failedTCs[pTC] = m.failedTCs[pTC] .. "\n\t" + end + local msg = pEvent .. ": hmiLevel: expected " .. pExpHMILvl .. ", actual value: " .. tostring(pActHMILvl) + m.failedTCs[pTC] = m.failedTCs[pTC] .. msg + return false, msg + end + return true +end + +function m.printFailedTCs() + for tc, msg in m.spairs(m.failedTCs) do + utils.cprint(35, string.format("%03d", tc), msg) + end +end + +return m diff --git a/test_sets/mobile_projection_2.txt b/test_sets/mobile_projection_2.txt new file mode 100644 index 0000000000..65c19289a7 --- /dev/null +++ b/test_sets/mobile_projection_2.txt @@ -0,0 +1,8 @@ +./test_scripts/MobileProjection/Phase2/001_audioStreamingState_001-009.lua +./test_scripts/MobileProjection/Phase2/002_audioStreamingState_010-068.lua +./test_scripts/MobileProjection/Phase2/003_audioStreamingState_069-103.lua +./test_scripts/MobileProjection/Phase2/004_audioStreamingState_104-110.lua +./test_scripts/MobileProjection/Phase2/006_videoStreamingState_001-006.lua +./test_scripts/MobileProjection/Phase2/007_videoStreamingState_007-030.lua +./test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-034.lua +./test_scripts/MobileProjection/Phase2/009_hmiLevel_001-032.lua From 57150bbf37dc667bb5f88589c13b95abbfacf642 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 18 May 2018 18:46:06 +0300 Subject: [PATCH 396/681] Add additional scripts --- .../005_audioStreamingState_111-118.lua | 103 ++++++ .../007_videoStreamingState_007-030.lua | 2 +- ...ua => 008_videoStreamingState_031-042.lua} | 10 +- ...0_single_app_audio_and_video_streaming.lua | 68 ++++ .../Phase2/011_single_app_video_streaming.lua | 62 ++++ .../Phase2/012_single_app_deactivation.lua | 66 ++++ .../Phase2/013_two_apps_interaction.lua | 116 +++++++ ...o_010-068_video_007-030_states_LIMITED.lua | 314 ++++++++++++++++++ ..._097-103_video_031-038_states_not_FULL.lua | 85 +++++ .../Phase2/016_BACKGROUND_not_changed.lua | 59 ++++ .../Phase2/017_two_apps_and_one_app_exits.lua | 61 ++++ .../018_two_apps_and_one_app_unregister.lua | 63 ++++ .../Phase2/019_SDL_stop_audio_video.lua | 101 ++++++ .../020_different_types_apps_interactions.lua | 244 ++++++++++++++ .../MobileProjection/Phase2/common.lua | 1 + test_sets/mobile_projection_2.txt | 14 +- 16 files changed, 1366 insertions(+), 3 deletions(-) create mode 100644 test_scripts/MobileProjection/Phase2/005_audioStreamingState_111-118.lua rename test_scripts/MobileProjection/Phase2/{008_videoStreamingState_031-034.lua => 008_videoStreamingState_031-042.lua} (73%) create mode 100644 test_scripts/MobileProjection/Phase2/010_single_app_audio_and_video_streaming.lua create mode 100644 test_scripts/MobileProjection/Phase2/011_single_app_video_streaming.lua create mode 100644 test_scripts/MobileProjection/Phase2/012_single_app_deactivation.lua create mode 100644 test_scripts/MobileProjection/Phase2/013_two_apps_interaction.lua create mode 100644 test_scripts/MobileProjection/Phase2/014_audio_010-068_video_007-030_states_LIMITED.lua create mode 100644 test_scripts/MobileProjection/Phase2/015_audio_083-089_097-103_video_031-038_states_not_FULL.lua create mode 100644 test_scripts/MobileProjection/Phase2/016_BACKGROUND_not_changed.lua create mode 100644 test_scripts/MobileProjection/Phase2/017_two_apps_and_one_app_exits.lua create mode 100644 test_scripts/MobileProjection/Phase2/018_two_apps_and_one_app_unregister.lua create mode 100644 test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua create mode 100644 test_scripts/MobileProjection/Phase2/020_different_types_apps_interactions.lua diff --git a/test_scripts/MobileProjection/Phase2/005_audioStreamingState_111-118.lua b/test_scripts/MobileProjection/Phase2/005_audioStreamingState_111-118.lua new file mode 100644 index 0000000000..61e801706f --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/005_audioStreamingState_111-118.lua @@ -0,0 +1,103 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') +local hmi_values = require('user_modules/hmi_values') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.defaultProtocolVersion = 3 + +--[[ Local Variables ]] +local testCases = { + [111] = { + [1] = { t = "NAVIGATION", m = false }, + [2] = { t = "MEDIA", m = true }, + a = 1, s = "ATTENUATED", mix = true + }, + [112] = { + [1] = { t = "NAVIGATION", m = false }, + [2] = { t = "MEDIA", m = true }, + a = 1, s = "NOT_AUDIBLE", mix = false + }, + [113] = { + [1] = { t = "MEDIA", m = true }, + [2] = { t = "NAVIGATION", m = false }, + a = 2, s = "ATTENUATED", mix = true + }, + [114] = { + [1] = { t = "MEDIA", m = true }, + [2] = { t = "NAVIGATION", m = false }, + a = 2, s = "NOT_AUDIBLE", mix = false + }, + [115] = { + [1] = { t = "NAVIGATION", m = false }, + [2] = { t = "COMMUNICATION", m = true }, + a = 1, s = "ATTENUATED", mix = true + }, + [116] = { + [1] = { t = "NAVIGATION", m = false }, + [2] = { t = "COMMUNICATION", m = true }, + a = 1, s = "NOT_AUDIBLE", mix = false + }, + [117] = { + [1] = { t = "COMMUNICATION", m = true }, + [2] = { t = "NAVIGATION", m = false }, + a = 2, s = "ATTENUATED", mix = true + }, + [118] = { + [1] = { t = "COMMUNICATION", m = true }, + [2] = { t = "NAVIGATION", m = false }, + a = 2, s = "NOT_AUDIBLE", mix = false + } +} + +--[[ Local Functions ]] +local function getHMIParams(pIsMixingSupported) + local hmiParams = hmi_values.getDefaultHMITable() + hmiParams.BasicCommunication.MixingAudioSupported.params.attenuatedSupported = pIsMixingSupported + return hmiParams +end + +local function appStartStreaming(pTC, pStreamingAppId, pAudioSSApp) + common.getMobileSession(pStreamingAppId):StartService(10) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartAudioStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession(pStreamingAppId):StartStreaming(10, "files/MP3_1140kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = true }) + end) + end) + local notStreamingAppId + if pStreamingAppId == 1 then notStreamingAppId = 2 else notStreamingAppId = 1 end + common.getMobileSession(pStreamingAppId):ExpectNotification("OnHMIStatus") + :Times(0) + common.getMobileSession(notStreamingAppId):ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + common.getMobileSession(pStreamingAppId):StopStreaming("files/MP3_1140kb.mp3") + return common.checkAudioSS(pTC, "App" .. notStreamingAppId, pAudioSSApp, data.payload.audioStreamingState) + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: isMixing:" .. tostring(tc.mix) .. ", " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session, isMixingSupported:" .. tostring(tc.mix), + common.start, { getHMIParams(tc.mix) }) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Activate App 2", common.activateApp, { 2 }) + runner.Step("App " .. tc.a .. " starts streaming", appStartStreaming, { n, tc.a, tc.s }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/007_videoStreamingState_007-030.lua b/test_scripts/MobileProjection/Phase2/007_videoStreamingState_007-030.lua index 85ea387569..a920413597 100644 --- a/test_scripts/MobileProjection/Phase2/007_videoStreamingState_007-030.lua +++ b/test_scripts/MobileProjection/Phase2/007_videoStreamingState_007-030.lua @@ -12,7 +12,7 @@ runner.testSettings.isSelfIncluded = false local testCases = { [007] = { [1] = { t = "NAVIGATION", m = true, s = "STREAMABLE" }, [2] = { t = "MEDIA", m = true, s = "NOT_STREAMABLE" }}, [008] = { [1] = { t = "NAVIGATION", m = false, s = "STREAMABLE" }, [2] = { t = "MEDIA", m = true, s = "NOT_STREAMABLE" }}, - [009] = { [1] = { t = "PROJECTION", m = false, s = "STREAMABLE" }, [2] = { t = "MEDIA", m = true, s = "NOT_STREAMABLE" }}, + [009] = { [1] = { t = "PROJECTION", m = true, s = "STREAMABLE" }, [2] = { t = "MEDIA", m = true, s = "NOT_STREAMABLE" }}, [010] = { [1] = { t = "PROJECTION", m = false, s = "STREAMABLE" }, [2] = { t = "MEDIA", m = true, s = "NOT_STREAMABLE" }}, [011] = { [1] = { t = "NAVIGATION", m = true, s = "STREAMABLE" }, [2] = { t = "DEFAULT", m = false, s = "NOT_STREAMABLE" }}, [012] = { [1] = { t = "NAVIGATION", m = false, s = "STREAMABLE" }, [2] = { t = "DEFAULT", m = false, s = "NOT_STREAMABLE" }}, diff --git a/test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-034.lua b/test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-042.lua similarity index 73% rename from test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-034.lua rename to test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-042.lua index ec6783a5ed..94efff4d07 100644 --- a/test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-034.lua +++ b/test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-042.lua @@ -13,7 +13,15 @@ local testCases = { [031] = { t = "NAVIGATION", m = true, s = "NOT_STREAMABLE", e = "DEACTIVATE_HMI" }, [032] = { t = "NAVIGATION", m = false, s = "NOT_STREAMABLE", e = "DEACTIVATE_HMI" }, [033] = { t = "PROJECTION", m = true, s = "NOT_STREAMABLE", e = "DEACTIVATE_HMI" }, - [034] = { t = "PROJECTION", m = false, s = "NOT_STREAMABLE", e = "DEACTIVATE_HMI" } + [034] = { t = "PROJECTION", m = false, s = "NOT_STREAMABLE", e = "DEACTIVATE_HMI" }, + [035] = { t = "NAVIGATION", m = true, s = "NOT_STREAMABLE", e = "AUDIO_SOURCE" }, + [036] = { t = "NAVIGATION", m = false, s = "NOT_STREAMABLE", e = "AUDIO_SOURCE" }, + [037] = { t = "PROJECTION", m = true, s = "NOT_STREAMABLE", e = "AUDIO_SOURCE" }, + [038] = { t = "PROJECTION", m = false, s = "NOT_STREAMABLE", e = "AUDIO_SOURCE" }, + [039] = { t = "NAVIGATION", m = true, s = "NOT_STREAMABLE", e = "EMBEDDED_NAVI" }, + [040] = { t = "NAVIGATION", m = false, s = "NOT_STREAMABLE", e = "EMBEDDED_NAVI" }, + [041] = { t = "PROJECTION", m = true, s = "NOT_STREAMABLE", e = "EMBEDDED_NAVI" }, + [042] = { t = "PROJECTION", m = false, s = "NOT_STREAMABLE", e = "EMBEDDED_NAVI" } } --[[ Local Functions ]] diff --git a/test_scripts/MobileProjection/Phase2/010_single_app_audio_and_video_streaming.lua b/test_scripts/MobileProjection/Phase2/010_single_app_audio_and_video_streaming.lua new file mode 100644 index 0000000000..2351f504fd --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/010_single_app_audio_and_video_streaming.lua @@ -0,0 +1,68 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.defaultProtocolVersion = 3 + +--[[ Local Variables ]] +local testCases = { + [001] = { t = "PROJECTION", m = true }, + [002] = { t = "NAVIGATION", m = true }, +} + +--[[ Local Functions ]] +local function appStartAudioStreaming() + common.getMobileSession():StartService(10) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartAudioStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(10,"files/MP3_1140kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = true }) + end) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function appStartVideoStreaming() + common.getMobileSession():StartService(11) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(11, "files/MP3_4555kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = true }) + end) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function appStopStreaming() + common.getMobileSession():StopStreaming("files/MP3_1140kb.mp3") + common.getMobileSession():StopStreaming("files/MP3_4555kb.mp3") + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp, { 1 }) + runner.Step("Activate App", common.activateApp, { 1 }) + runner.Step("App starts Audio streaming", appStartAudioStreaming) + runner.Step("App starts Video streaming", appStartVideoStreaming) + runner.Step("App stops streaming", appStopStreaming) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end diff --git a/test_scripts/MobileProjection/Phase2/011_single_app_video_streaming.lua b/test_scripts/MobileProjection/Phase2/011_single_app_video_streaming.lua new file mode 100644 index 0000000000..1b0fb9f85f --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/011_single_app_video_streaming.lua @@ -0,0 +1,62 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.defaultProtocolVersion = 3 + +--[[ Local Variables ]] +local testCases = { + [001] = { t = "PROJECTION", m = false } +} + +--[[ Local Functions ]] +local function activateApp() + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId() }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession():ExpectNotification("OnHMIStatus", { + hmiLevel = "FULL", + systemContext = "MAIN", + audioStreamingState = "NOT_AUDIBLE", + videoStreamingState = "STREAMABLE" + }) +end + +local function appStartVideoStreaming() + common.getMobileSession():StartService(11) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(11, "files/MP3_1140kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = true }) + end) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function appStopStreaming() + common.getMobileSession():StopStreaming("files/MP3_1140kb.mp3") + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp, { 1 }) + runner.Step("Activate App", activateApp) + runner.Step("App starts Video streaming", appStartVideoStreaming) + runner.Step("App stops streaming", appStopStreaming) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end diff --git a/test_scripts/MobileProjection/Phase2/012_single_app_deactivation.lua b/test_scripts/MobileProjection/Phase2/012_single_app_deactivation.lua new file mode 100644 index 0000000000..8bfab5037b --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/012_single_app_deactivation.lua @@ -0,0 +1,66 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.defaultProtocolVersion = 3 + +--[[ Local Variables ]] +local testCases = { + [001] = { t = "PROJECTION", m = true } +} + +--[[ Local Functions ]] +local function appStartAudioStreaming() + common.getMobileSession():StartService(10) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartAudioStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(10,"files/MP3_1140kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = true }) + end) + end) +end + +local function appStartVideoStreaming() + common.getMobileSession():StartService(11) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(11, "files/MP3_4555kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = true }) + end) + end) +end + +local function deactivateApp() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { appID = common.getHMIAppId() }) + common.getMobileSession():ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "AUDIBLE", + videoStreamingState = "STREAMABLE" + }) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp, { 1 }) + runner.Step("Activate App", common.activateApp, { 1 }) + runner.Step("App starts Audio streaming", appStartAudioStreaming) + runner.Step("App starts Video streaming", appStartVideoStreaming) + runner.Step("Deactivate App", deactivateApp) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end diff --git a/test_scripts/MobileProjection/Phase2/013_two_apps_interaction.lua b/test_scripts/MobileProjection/Phase2/013_two_apps_interaction.lua new file mode 100644 index 0000000000..87e05d3e6d --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/013_two_apps_interaction.lua @@ -0,0 +1,116 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.defaultProtocolVersion = 3 + +--[[ Local Variables ]] +local testCases = { + [001] = { + [1] = { t = "PROJECTION", m = true }, [2] = { t = "PROJECTION", m = false }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" } + }, + [002] = { + [1] = { t = "PROJECTION", m = true }, [2] = { t = "NAVIGATION", m = false }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" } + }, + [003] = { + [1] = { t = "PROJECTION", m = false }, [2] = { t = "PROJECTION", m = false }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "BACKGROUND", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" } + }, + [004] = { + [1] = { t = "PROJECTION", m = false }, [2] = { t = "PROJECTION", m = true }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "BACKGROUND", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" } + }, + [005] = { + [1] = { t = "PROJECTION", m = false }, [2] = { t = "NAVIGATION", m = false }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "BACKGROUND", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" } + }, + [006] = { + [1] = { t = "NAVIGATION", m = false }, [2] = { t = "PROJECTION", m = false }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" } + }, + [007] = { + [1] = { t = "NAVIGATION", m = false }, [2] = { t = "PROJECTION", m = true }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" } + }, + [008] = { + [1] = { t = "PROJECTION", m = true }, [2] = { t = "PROJECTION", m = true }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "BACKGROUND", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" } + }, + [009] = { + [1] = { t = "NAVIGATION", m = false }, [2] = { t = "NAVIGATION", m = false }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "BACKGROUND", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" } + } +} + +--[[ Local Functions ]] +local function deactivateApp(pApp1OHS) + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(1) + }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", { + hmiLevel = pApp1OHS.l, + systemContext = pApp1OHS.sc, + audioStreamingState = pApp1OHS.aSS, + videoStreamingState = pApp1OHS.vSS + }) +end + +local function activateApp(pApp1OHS, pApp2OHS) + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId(2) }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { + hmiLevel = pApp2OHS.l, + systemContext = pApp2OHS.sc, + audioStreamingState = pApp2OHS.aSS, + videoStreamingState = pApp2OHS.vSS + }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", { + hmiLevel = pApp1OHS.l, + systemContext = pApp1OHS.sc, + audioStreamingState = pApp1OHS.aSS, + videoStreamingState = pApp1OHS.vSS + }) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Deactivate App 1", deactivateApp, { tc.ohs1_1 }) + runner.Step("Activate App 2", activateApp, { tc.ohs1_2, tc.ohs2_1 }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end diff --git a/test_scripts/MobileProjection/Phase2/014_audio_010-068_video_007-030_states_LIMITED.lua b/test_scripts/MobileProjection/Phase2/014_audio_010-068_video_007-030_states_LIMITED.lua new file mode 100644 index 0000000000..560232c910 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/014_audio_010-068_video_007-030_states_LIMITED.lua @@ -0,0 +1,314 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [010] = { + [1] = { t = "NAVIGATION", m = false, aSS = { "AUDIBLE", "AUDIBLE" }, vSS = { "STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "PROJECTION", m = false, aSS = { nil, "NOT_AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [011] = { + [1] = { t = "NAVIGATION", m = false, aSS = { "AUDIBLE", nil }, vSS = { "STREAMABLE", nil } }, + [2] = { t = "DEFAULT", m = false, aSS = { nil, "NOT_AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [012] = { + [1] = { t = "NAVIGATION", m = true, aSS = { "AUDIBLE", "AUDIBLE" }, vSS = { "STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "PROJECTION", m = false, aSS = { nil, "NOT_AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [013] = { + [1] = { t = "NAVIGATION", m = true, aSS = { "AUDIBLE", nil }, vSS = { "STREAMABLE", nil } }, + [2] = { t = "DEFAULT", m = false, aSS = { nil, "NOT_AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [014] = { + [1] = { t = "COMMUNICATION", m = false, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "PROJECTION", m = false, aSS = { nil, "NOT_AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [015] = { + [1] = { t = "COMMUNICATION", m = false, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "DEFAULT", m = false, aSS = { nil, "NOT_AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [016] = { + [1] = { t = "COMMUNICATION", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "PROJECTION", m = false, aSS = { nil, "NOT_AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [017] = { + [1] = { t = "COMMUNICATION", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "DEFAULT", m = false, aSS = { nil, "NOT_AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [018] = { + [1] = { t = "PROJECTION", m = true, aSS = { "AUDIBLE", "AUDIBLE" }, vSS = { "STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "PROJECTION", m = false, aSS = { nil, "NOT_AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [019] = { + [1] = { t = "PROJECTION", m = true, aSS = { "AUDIBLE", nil }, vSS = { "STREAMABLE", nil } }, + [2] = { t = "DEFAULT", m = false, aSS = { nil, "NOT_AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [020] = { + [1] = { t = "MEDIA", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "PROJECTION", m = false, aSS = { nil, "NOT_AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [021] = { + [1] = { t = "MEDIA", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "DEFAULT", m = false, aSS = { nil, "NOT_AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [022] = { + [1] = { t = "DEFAULT", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "PROJECTION", m = false, aSS = { nil, "NOT_AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [023] = { + [1] = { t = "DEFAULT", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "DEFAULT", m = false, aSS = { nil, "NOT_AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [024] = { + [1] = { t = "NAVIGATION", m = false, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "NAVIGATION", m = false, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [025] = { + [1] = { t = "NAVIGATION", m = true, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "NAVIGATION", m = false, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [026] = { + [1] = { t = "NAVIGATION", m = false, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "NAVIGATION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [027] = { + [1] = { t = "NAVIGATION", m = true, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "NAVIGATION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [028] = { + [1] = { t = "COMMUNICATION", m = false, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "NOT_STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "COMMUNICATION", m = false, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [029] = { + [1] = { t = "COMMUNICATION", m = true, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "NOT_STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "COMMUNICATION", m = false, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [030] = { + [1] = { t = "COMMUNICATION", m = false, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "NOT_STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "COMMUNICATION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [031] = { + [1] = { t = "COMMUNICATION", m = true, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "NOT_STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "COMMUNICATION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [032] = { + [1] = { t = "NAVIGATION", m = false, aSS = { "AUDIBLE", "AUDIBLE" }, vSS = { "STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "PROJECTION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [033] = { + [1] = { t = "NAVIGATION", m = false, aSS = { "AUDIBLE", nil }, vSS = { "STREAMABLE", nil } }, + [2] = { t = "MEDIA", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [034] = { + [1] = { t = "NAVIGATION", m = false, aSS = { "AUDIBLE", nil }, vSS = { "STREAMABLE", nil } }, + [2] = { t = "DEFAULT", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [035] = { + [1] = { t = "NAVIGATION", m = false, aSS = { "AUDIBLE", nil }, vSS = { "STREAMABLE", nil } }, + [2] = { t = "COMMUNICATION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [036] = { + [1] = { t = "NAVIGATION", m = true, aSS = { "AUDIBLE", "AUDIBLE" }, vSS = { "STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "PROJECTION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [037] = { + [1] = { t = "NAVIGATION", m = true, aSS = { "AUDIBLE", nil }, vSS = { "STREAMABLE", nil } }, + [2] = { t = "MEDIA", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [038] = { + [1] = { t = "NAVIGATION", m = true, aSS = { "AUDIBLE", nil }, vSS = { "STREAMABLE", nil } }, + [2] = { t = "DEFAULT", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [039] = { + [1] = { t = "NAVIGATION", m = true, aSS = { "AUDIBLE", nil }, vSS = { "STREAMABLE", nil } }, + [2] = { t = "COMMUNICATION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [040] = { + [1] = { t = "COMMUNICATION", m = false, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "PROJECTION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [041] = { + [1] = { t = "COMMUNICATION", m = false, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "MEDIA", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [042] = { + [1] = { t = "COMMUNICATION", m = false, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "DEFAULT", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [043] = { + [1] = { t = "COMMUNICATION", m = false, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "NAVIGATION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [044] = { + [1] = { t = "COMMUNICATION", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "PROJECTION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [045] = { + [1] = { t = "COMMUNICATION", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "MEDIA", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [046] = { + [1] = { t = "COMMUNICATION", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "DEFAULT", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [047] = { + [1] = { t = "COMMUNICATION", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "NAVIGATION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [048] = { + [1] = { t = "PROJECTION", m = true, aSS = { "AUDIBLE", "AUDIBLE" }, vSS = { "STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "NAVIGATION", m = false, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [049] = { + [1] = { t = "PROJECTION", m = true, aSS = { "AUDIBLE", nil }, vSS = { "STREAMABLE", nil } }, + [2] = { t = "COMMUNICATION", m = false, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [050] = { + [1] = { t = "PROJECTION", m = true, aSS = { "AUDIBLE", "AUDIBLE" }, vSS = { "STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "NAVIGATION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [051] = { + [1] = { t = "PROJECTION", m = true, aSS = { "AUDIBLE", nil }, vSS = { "STREAMABLE", nil } }, + [2] = { t = "COMMUNICATION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [052] = { + [1] = { t = "MEDIA", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "NAVIGATION", m = false, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [053] = { + [1] = { t = "MEDIA", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "COMMUNICATION", m = false, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [054] = { + [1] = { t = "MEDIA", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "NAVIGATION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [055] = { + [1] = { t = "MEDIA", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "COMMUNICATION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [056] = { + [1] = { t = "DEFAULT", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "NAVIGATION", m = false, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [057] = { + [1] = { t = "DEFAULT", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "COMMUNICATION", m = false, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [058] = { + [1] = { t = "DEFAULT", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "NAVIGATION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [059] = { + [1] = { t = "DEFAULT", m = true, aSS = { "AUDIBLE", nil }, vSS = { "NOT_STREAMABLE", nil } }, + [2] = { t = "COMMUNICATION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [060] = { + [1] = { t = "PROJECTION", m = true, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "PROJECTION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [061] = { + [1] = { t = "PROJECTION", m = true, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "STREAMABLE", "STREAMABLE" } }, + [2] = { t = "MEDIA", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [062] = { + [1] = { t = "PROJECTION", m = true, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "STREAMABLE", "STREAMABLE" } }, + [2] = { t = "DEFAULT", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [063] = { + [1] = { t = "MEDIA", m = true, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "NOT_STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "PROJECTION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [064] = { + [1] = { t = "MEDIA", m = true, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "NOT_STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "MEDIA", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [065] = { + [1] = { t = "MEDIA", m = true, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "NOT_STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "DEFAULT", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [066] = { + [1] = { t = "DEFAULT", m = true, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "NOT_STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "PROJECTION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [067] = { + [1] = { t = "DEFAULT", m = true, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "NOT_STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "MEDIA", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, + [068] = { + [1] = { t = "DEFAULT", m = true, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "NOT_STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "DEFAULT", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "NOT_STREAMABLE" } } + }, +} + +--[[ Local Functions ]] +local function activateApp2(pTC, pAudioSSApp1, pVideoSSApp1, pAudioSSApp2, pVideoSSApp2) + local count = 1 + if pAudioSSApp1 == nil and pVideoSSApp1 == nil then count = 0 end + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId(2) }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, "App1", pAudioSSApp1, data.payload.audioStreamingState) + end) + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, "App1", pVideoSSApp1, data.payload.videoStreamingState) + end) + :Times(count) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, "App2", pAudioSSApp2, data.payload.audioStreamingState) + end) + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, "App2", pVideoSSApp2, data.payload.videoStreamingState) + end) +end + +local function deactivateApp1(pTC, pAudioSSApp1, pVideoSSApp1) + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { appID = common.getHMIAppId() }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, "App1", pAudioSSApp1, data.payload.audioStreamingState) + end) + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, "App1", pVideoSSApp1, data.payload.videoStreamingState) + end) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function getMsg(pTC, pAppId, pNotifId) + if pTC[pAppId].aSS[pNotifId] == nil and pTC[pAppId].vSS[pNotifId] == nil then + return "NO" + else + return pTC[pAppId].aSS[pNotifId] .. ":" .. pTC[pAppId].vSS[pNotifId] + end +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Deact. App 1:" .. "App1:" .. getMsg(tc, 1, 1) .. " App2:" .. getMsg(tc, 2, 1), + deactivateApp1, { n, tc[1].aSS[1], tc[1].vSS[1] }) + runner.Step("Act. App 2:" .. "App1:" .. getMsg(tc, 1, 2) .. " App2:" .. getMsg(tc, 2, 2), + activateApp2, { n, tc[1].aSS[2], tc[1].vSS[2], tc[2].aSS[2], tc[2].vSS[2] }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/015_audio_083-089_097-103_video_031-038_states_not_FULL.lua b/test_scripts/MobileProjection/Phase2/015_audio_083-089_097-103_video_031-038_states_not_FULL.lua new file mode 100644 index 0000000000..a4ffdb23b1 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/015_audio_083-089_097-103_video_031-038_states_not_FULL.lua @@ -0,0 +1,85 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local onHMIStatusData = {} +local testCases = { + [001] = { t = "NAVIGATION", m = true, e = "DEACTIVATE_HMI" }, + [002] = { t = "NAVIGATION", m = false, e = "DEACTIVATE_HMI" }, + [003] = { t = "PROJECTION", m = true, e = "DEACTIVATE_HMI" }, + [004] = { t = "PROJECTION", m = false, e = "DEACTIVATE_HMI" }, + [005] = { t = "COMMUNICATION", m = true, e = "DEACTIVATE_HMI" }, + [006] = { t = "COMMUNICATION", m = false, e = "DEACTIVATE_HMI" }, + [007] = { t = "MEDIA", m = true, e = "DEACTIVATE_HMI" }, + [008] = { t = "MEDIA", m = false, e = "DEACTIVATE_HMI" }, + [009] = { t = "DEFAULT", m = true, e = "DEACTIVATE_HMI" }, + [010] = { t = "DEFAULT", m = false, e = "DEACTIVATE_HMI" }, + [011] = { t = "NAVIGATION", m = true, e = "AUDIO_SOURCE" }, + [012] = { t = "NAVIGATION", m = false, e = "AUDIO_SOURCE" }, + [013] = { t = "PROJECTION", m = true, e = "AUDIO_SOURCE" }, + [014] = { t = "PROJECTION", m = false, e = "AUDIO_SOURCE" }, + [015] = { t = "COMMUNICATION", m = true, e = "AUDIO_SOURCE" }, + [016] = { t = "COMMUNICATION", m = false, e = "AUDIO_SOURCE" }, + [017] = { t = "MEDIA", m = true, e = "AUDIO_SOURCE" }, + [018] = { t = "MEDIA", m = false, e = "AUDIO_SOURCE" }, + [019] = { t = "DEFAULT", m = true, e = "AUDIO_SOURCE" }, + [020] = { t = "DEFAULT", m = false, e = "AUDIO_SOURCE" }, +} + +--[[ Local Functions ]] +local function sendEvent(pTC, pEvent, pIsActive) + local count = 1 + if onHMIStatusData.hmiL == "BACKGROUND" then count = 0 end + local status = common.cloneTable(onHMIStatusData) + if pIsActive == true then + status.hmiL = "BACKGROUND" + status.aSS = "NOT_AUDIBLE" + status.vSS = "NOT_STREAMABLE" + end + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = pEvent, + isActive = pIsActive }) + common.getMobileSession():ExpectNotification("OnHMIStatus", { hmiLevel = status.hmiL }) + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, "App1", status.aSS, data.payload.audioStreamingState) + end) + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, "App1", status.vSS, data.payload.videoStreamingState) + end) + :Times(count) + common.wait(500) +end + +local function deactivateApp() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { appID = common.getHMIAppId() }) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Do(function(_, data) + onHMIStatusData.hmiL = data.payload.hmiLevel + onHMIStatusData.aSS = data.payload.audioStreamingState + onHMIStatusData.vSS = data.payload.videoStreamingState + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. ", event:" .. tc.e .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp) + runner.Step("Activate App", common.activateApp) + runner.Step("Deactivate App", deactivateApp) + runner.Step("Send event from HMI isActive: true", sendEvent, { n, tc.e, true }) + runner.Step("Send event from HMI isActive: false", sendEvent, { n, tc.e, false }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/016_BACKGROUND_not_changed.lua b/test_scripts/MobileProjection/Phase2/016_BACKGROUND_not_changed.lua new file mode 100644 index 0000000000..d88c309cc6 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/016_BACKGROUND_not_changed.lua @@ -0,0 +1,59 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [001] = { [1] = { t = "MEDIA", m = false }, [2] = { t = "NAVIGATION", m = false }}, + [002] = { [1] = { t = "DEFAULT", m = false }, [2] = { t = "NAVIGATION", m = false }}, + [003] = { [1] = { t = "MEDIA", m = false }, [2] = { t = "NAVIGATION", m = true }}, + [004] = { [1] = { t = "DEFAULT", m = false }, [2] = { t = "NAVIGATION", m = true }}, + [005] = { [1] = { t = "MEDIA", m = false }, [2] = { t = "PROJECTION", m = false }}, + [006] = { [1] = { t = "DEFAULT", m = false }, [2] = { t = "PROJECTION", m = false }}, + [007] = { [1] = { t = "MEDIA", m = false }, [2] = { t = "PROJECTION", m = true }}, + [008] = { [1] = { t = "DEFAULT", m = false }, [2] = { t = "PROJECTION", m = true }}, +} + +--[[ Local Functions ]] +local function activateApp2() + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId(2) }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { hmiLevel = "FULL" }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function setApp1ToBACKGROUND() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { appID = common.getHMIAppId() }) + common.getMobileSession():ExpectNotification("OnHMIStatus", { + hmiLevel = "BACKGROUND", + systemContext = "MAIN", + audioStreamingState = "NOT_AUDIBLE", + videoStreamingState = "NOT_STREAMABLE" + }) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Set App 1 to BACKGROUND", setApp1ToBACKGROUND) + runner.Step("Activate App 2", activateApp2) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/017_two_apps_and_one_app_exits.lua b/test_scripts/MobileProjection/Phase2/017_two_apps_and_one_app_exits.lua new file mode 100644 index 0000000000..ad803d5815 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/017_two_apps_and_one_app_exits.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [001] = { [1] = { t = "NAVIGATION", m = false }, [2] = { t = "PROJECTION", m = true }}, + [002] = { [1] = { t = "NAVIGATION", m = false }, [2] = { t = "PROJECTION", m = false }}, + [003] = { [1] = { t = "NAVIGATION", m = true }, [2] = { t = "PROJECTION", m = true }}, + [004] = { [1] = { t = "NAVIGATION", m = true }, [2] = { t = "PROJECTION", m = false }}, + + [005] = { [1] = { t = "PROJECTION", m = false }, [2] = { t = "NAVIGATION", m = true }}, + [006] = { [1] = { t = "PROJECTION", m = false }, [2] = { t = "NAVIGATION", m = false }}, + [007] = { [1] = { t = "PROJECTION", m = true }, [2] = { t = "NAVIGATION", m = true }}, + [008] = { [1] = { t = "PROJECTION", m = true }, [2] = { t = "NAVIGATION", m = false }}, + + [009] = { [1] = { t = "NAVIGATION", m = false }, [2] = { t = "NAVIGATION", m = false }}, + [010] = { [1] = { t = "NAVIGATION", m = false }, [2] = { t = "NAVIGATION", m = true }}, + [011] = { [1] = { t = "NAVIGATION", m = true }, [2] = { t = "NAVIGATION", m = false }}, + [012] = { [1] = { t = "NAVIGATION", m = true }, [2] = { t = "NAVIGATION", m = true }}, + + [013] = { [1] = { t = "PROJECTION", m = false }, [2] = { t = "PROJECTION", m = false }}, + [014] = { [1] = { t = "PROJECTION", m = false }, [2] = { t = "PROJECTION", m = true }}, + [015] = { [1] = { t = "PROJECTION", m = true }, [2] = { t = "PROJECTION", m = false }}, + [016] = { [1] = { t = "PROJECTION", m = true }, [2] = { t = "PROJECTION", m = true }}, +} + +--[[ Local Functions ]] +local function exitApp2() + common.getHMIConnection():SendNotification("BasicCommunication.OnExitApplication", { + appID = common.getHMIAppId(2), + reason = "USER_EXIT" }) + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { hmiLevel = "NONE" }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Activate App 2", common.activateApp, { 2 }) + runner.Step("Exit App 2", exitApp2) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/018_two_apps_and_one_app_unregister.lua b/test_scripts/MobileProjection/Phase2/018_two_apps_and_one_app_unregister.lua new file mode 100644 index 0000000000..4c58ae32a9 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/018_two_apps_and_one_app_unregister.lua @@ -0,0 +1,63 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [001] = { [1] = { t = "NAVIGATION", m = false }, [2] = { t = "PROJECTION", m = true }}, + [002] = { [1] = { t = "NAVIGATION", m = false }, [2] = { t = "PROJECTION", m = false }}, + [003] = { [1] = { t = "NAVIGATION", m = true }, [2] = { t = "PROJECTION", m = true }}, + [004] = { [1] = { t = "NAVIGATION", m = true }, [2] = { t = "PROJECTION", m = false }}, + + [005] = { [1] = { t = "PROJECTION", m = false }, [2] = { t = "NAVIGATION", m = true }}, + [006] = { [1] = { t = "PROJECTION", m = false }, [2] = { t = "NAVIGATION", m = false }}, + [007] = { [1] = { t = "PROJECTION", m = true }, [2] = { t = "NAVIGATION", m = true }}, + [008] = { [1] = { t = "PROJECTION", m = true }, [2] = { t = "NAVIGATION", m = false }}, + + [009] = { [1] = { t = "NAVIGATION", m = false }, [2] = { t = "NAVIGATION", m = false }}, + [010] = { [1] = { t = "NAVIGATION", m = false }, [2] = { t = "NAVIGATION", m = true }}, + [011] = { [1] = { t = "NAVIGATION", m = true }, [2] = { t = "NAVIGATION", m = false }}, + [012] = { [1] = { t = "NAVIGATION", m = true }, [2] = { t = "NAVIGATION", m = true }}, + + [013] = { [1] = { t = "PROJECTION", m = false }, [2] = { t = "PROJECTION", m = false }}, + [014] = { [1] = { t = "PROJECTION", m = false }, [2] = { t = "PROJECTION", m = true }}, + [015] = { [1] = { t = "PROJECTION", m = true }, [2] = { t = "PROJECTION", m = false }}, + [016] = { [1] = { t = "PROJECTION", m = true }, [2] = { t = "PROJECTION", m = true }}, +} + +--[[ Local Functions ]] +local function unregisterApp2() + local cid = common.getMobileSession(2):SendRPC("UnregisterAppInterface", {}) + common.getMobileSession(2):ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppUnregistered", { + appID = common.getHMIAppId(2), + unexpectedDisconnect = false + }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Activate App 2", common.activateApp, { 2 }) + runner.Step("Unregister App 2", unregisterApp2) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua b/test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua new file mode 100644 index 0000000000..0795e213bc --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua @@ -0,0 +1,101 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') +local events = require("events") +local constants = require("protocol_handler/ford_protocol_constants") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.defaultProtocolVersion = 3 + +--[[ Local Variables ]] +local testCases = { + [001] = { t = "PROJECTION", m = true }, + [002] = { t = "NAVIGATION", m = true }, +} + +--[[ Local Functions ]] +local function appStartAudioStreaming() + common.getMobileSession():StartService(10) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartAudioStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(10,"files/MP3_1140kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = true }) + end) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function appStartVideoStreaming() + common.getMobileSession():StartService(11) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(11, "files/MP3_4555kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = true }) + end) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function appStopStreaming() + common.getMobileSession():StopStreaming("files/MP3_1140kb.mp3") + common.getMobileSession():StopStreaming("files/MP3_4555kb.mp3") + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function expectEndService(pServiceId) + local event = events.Event() + event.matches = function(_, data) + return data.frameType == constants.FRAME_TYPE.CONTROL_FRAME + and data.serviceType == pServiceId + and data.sessionId == common.getMobileSession().mobile_session_impl.control_services.session.sessionId.get() + and data.frameInfo == constants.FRAME_INFO.END_SERVICE + end + return common.getMobileSession():ExpectEvent(event, "EndService") +end + +local function changeAudioSource() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true }) + common.getMobileSession():ExpectNotification("OnHMIStatus", { + hmiLevel = "BACKGROUND", + systemContext = "MAIN", + audioStreamingState = "NOT_AUDIBLE", + videoStreamingState = "NOT_STREAMABLE" + }) + common.wait(2000) + common.getHMIConnection():SendNotification("Navigation.OnAudioDataStreaming", { available = false }) + common.getHMIConnection():SendNotification("Navigation.OnVideoDataStreaming", { available = false }) + common.getHMIConnection():SendNotification("Navigation.StopAudioStream", { appID = common.getHMIAppId() }) + common.getHMIConnection():SendNotification("Navigation.StopStream", { appID = common.getHMIAppId() }) + expectEndService(10) + expectEndService(11) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp, { 1 }) + runner.Step("Activate App", common.activateApp, { 1 }) + runner.Step("App starts Audio streaming", appStartAudioStreaming) + runner.Step("App starts Video streaming", appStartVideoStreaming) + runner.Step("Change Audio Source", changeAudioSource) + runner.Step("Stop A/V streaming", appStopStreaming) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end diff --git a/test_scripts/MobileProjection/Phase2/020_different_types_apps_interactions.lua b/test_scripts/MobileProjection/Phase2/020_different_types_apps_interactions.lua new file mode 100644 index 0000000000..29b8fffe3b --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/020_different_types_apps_interactions.lua @@ -0,0 +1,244 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.defaultProtocolVersion = 3 + +--[[ Local Variables ]] +local actions = { + activateApp = { + name = "Activation", + func = function(pAppId) + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { + appID = common.getHMIAppId(pAppId) }) + common.getHMIConnection():ExpectResponse(requestId) + end + }, + deactivateApp = { + name = "De-activation", + func = function(pAppId) + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(pAppId) }) + end + }, + phoneCallStart = { + name = "Phone call start", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "PHONE_CALL", + isActive = true }) + end + }, + phoneCallEnd = { + name = "Phone call end", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "PHONE_CALL", + isActive = false }) + end + }, + embeddedNaviActivate = { + name = "Embedded navigation activation", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "EMBEDDED_NAVI", + isActive = true }) + end + }, + embeddedNaviDeactivate = { + name = "Embedded navigation deactivation", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "EMBEDDED_NAVI", + isActive = false }) + end + }, + deactivateHMI = { + name = "HMI De-activation", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "DEACTIVATE_HMI", + isActive = true }) + end + }, + activateHMI = { + name = "HMI Activation", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "DEACTIVATE_HMI", + isActive = false }) + end + }, + exitApp = { + name = "User Exit", + func = function(pAppId) + common.getHMIConnection():SendNotification("BasicCommunication.OnExitApplication", { + appID = common.getHMIAppId(), + reason = "USER_EXIT" }) + end + } +} + +local testCases = { + [001] = { -- testcase + apps = { + [1] = { t = "MEDIA", m = true }, + [2] = { t = "PROJECTION", m = false }, + [3] = { t = "DEFAULT", m = false }, + [4] = { t = "NAVIGATION", m = true } + }, + steps = { + [1] = { + action = { event = actions.activateApp, appId = 1 }, + checks = { + ohs = { + [1] = { hLvl = "FULL", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" }, + [2] = { }, -- hLvl = "NONE", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [3] = { }, -- hLvl = "NONE", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [4] = { } -- hLvl = "NONE", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + } + } + }, + [2] = { + action = { event = actions.activateApp, appId = 2 }, + checks = { + ohs = { + [1] = { hLvl = "LIMITED", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" }, + [2] = { hLvl = "FULL", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" }, + [3] = { }, -- hLvl = "NONE", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [4] = { } -- hLvl = "NONE", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + } + } + }, + [3] = { + action = { event = actions.activateApp, appId = 3 }, + checks = { + ohs = { + [1] = { }, -- hLvl = "LIMITED", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" + [2] = { hLvl = "LIMITED", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" }, + [3] = { hLvl = "FULL", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + [4] = { } -- hLvl = "NONE", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + } + } + }, + [4] = { + action = { event = actions.activateApp, appId = 4 }, + checks = { + ohs = { + [1] = { }, -- hLvl = "LIMITED", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" + [2] = { hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + [3] = { hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + [4] = { hLvl = "FULL", aSS = "AUDIBLE", vSS = "STREAMABLE" } + } + } + }, + [5] = { + action = { event = actions.phoneCallStart, appId = "none" }, + checks = { + ohs = { + [1] = { hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + [2] = { }, -- hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [3] = { }, -- hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [4] = { hLvl = "LIMITED", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" } + } + } + }, + [6] = { + action = { event = actions.phoneCallEnd, appId = "none" }, + checks = { + ohs = { + [1] = { hLvl = "LIMITED", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" }, + [2] = { }, -- hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [3] = { }, -- hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [4] = { hLvl = "FULL", aSS = "AUDIBLE", vSS = "STREAMABLE" } + } + } + }, + [7] = { + action = { event = actions.activateApp, appId = 2 }, + checks = { + ohs = { + [1] = { }, -- hLvl = "LIMITED", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" + [2] = { hLvl = "FULL", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" }, + [3] = { }, -- hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [4] = { hLvl = "LIMITED", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" } + } + } + }, + [8] = { + action = { event = actions.embeddedNaviActivate, appId = "none" }, + checks = { + ohs = { + [1] = { hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, -- + [2] = { hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + [3] = { }, -- hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [4] = { hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" } + } + } + }, + [9] = { + action = { event = actions.embeddedNaviDeactivate, appId = "none" }, + checks = { + ohs = { + [1] = { hLvl = "LIMITED", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" }, -- + [2] = { hLvl = "FULL", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" }, + [3] = { }, -- hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [4] = { hLvl = "LIMITED", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" } + } + } + } + } + }, +} + + +local function performChecks(pTestCaseNum, pStep, pAppId, pExpectVal) + local exp = common.getMobileSession(pAppId):ExpectNotification("OnHMIStatus") + if pExpectVal.hLvl then + exp:ValidIf(function(_, data) + return common.checkAudioSS(pTestCaseNum, pStep.action.event.name, pExpectVal.aSS, data.payload.audioStreamingState) + end) + exp:ValidIf(function(_, data) + return common.checkVideoSS(pTestCaseNum, pStep.action.event.name, pExpectVal.vSS, data.payload.videoStreamingState) + end) + exp:ValidIf(function(_, data) + return common.checkHMILevel(pTestCaseNum, pStep.action.event.name, pExpectVal.hLvl, data.payload.hmiLevel) + end) + else + exp:Times(0) + end +end + +local function doAction(pTestCaseNum, pStep) + pStep.action.event.func(pStep.action.appId) + for appId, ohsChecks in ipairs(pStep.checks.ohs) do + performChecks(pTestCaseNum, pStep, appId, ohsChecks) + end +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc.apps[1].t, tc.apps[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc.apps[2].t, tc.apps[2].m }) + runner.Step("Set App 3 Config", common.setAppConfig, { 3, tc.apps[3].t, tc.apps[3].m }) + runner.Step("Set App 4 Config", common.setAppConfig, { 4, tc.apps[4].t, tc.apps[4].m }) + + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Register App 3", common.registerApp, { 3 }) + runner.Step("Register App 4", common.registerApp, { 4 }) + + for i = 1, #tc.steps do + runner.Step("Action:" .. tc.steps[i].action.event.name .. " app " .. tc.steps[i].action.appId, doAction, { n, tc.steps[i] }) + end + + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end diff --git a/test_scripts/MobileProjection/Phase2/common.lua b/test_scripts/MobileProjection/Phase2/common.lua index 150ed18d68..e5d6632e5d 100644 --- a/test_scripts/MobileProjection/Phase2/common.lua +++ b/test_scripts/MobileProjection/Phase2/common.lua @@ -15,6 +15,7 @@ local m = actions m.failedTCs = {} m.wait = utils.wait +m.cloneTable = utils.cloneTable m.registerApp = m.registerAppWOPTU function m.activateApp(pAppId) diff --git a/test_sets/mobile_projection_2.txt b/test_sets/mobile_projection_2.txt index 65c19289a7..d43012b28b 100644 --- a/test_sets/mobile_projection_2.txt +++ b/test_sets/mobile_projection_2.txt @@ -2,7 +2,19 @@ ./test_scripts/MobileProjection/Phase2/002_audioStreamingState_010-068.lua ./test_scripts/MobileProjection/Phase2/003_audioStreamingState_069-103.lua ./test_scripts/MobileProjection/Phase2/004_audioStreamingState_104-110.lua +./test_scripts/MobileProjection/Phase2/005_audioStreamingState_111-118.lua ./test_scripts/MobileProjection/Phase2/006_videoStreamingState_001-006.lua ./test_scripts/MobileProjection/Phase2/007_videoStreamingState_007-030.lua -./test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-034.lua +./test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-042.lua ./test_scripts/MobileProjection/Phase2/009_hmiLevel_001-032.lua +./test_scripts/MobileProjection/Phase2/010_single_app_audio_and_video_streaming.lua +./test_scripts/MobileProjection/Phase2/011_single_app_video_streaming.lua +./test_scripts/MobileProjection/Phase2/012_single_app_deactivation.lua +./test_scripts/MobileProjection/Phase2/013_two_apps_interaction.lua +./test_scripts/MobileProjection/Phase2/014_audio_010-068_video_007-030_states_LIMITED.lua +./test_scripts/MobileProjection/Phase2/015_audio_083-089_097-103_video_031-038_states_not_FULL.lua +./test_scripts/MobileProjection/Phase2/016_BACKGROUND_not_changed.lua +./test_scripts/MobileProjection/Phase2/017_two_apps_and_one_app_exits.lua +./test_scripts/MobileProjection/Phase2/018_two_apps_and_one_app_unregister.lua +./test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua +./test_scripts/MobileProjection/Phase2/020_different_types_apps_interactions.lua From 306449b31c2ffba698f5e90fb7e80e35bfe88188 Mon Sep 17 00:00:00 2001 From: HSavynetska Date: Tue, 24 Apr 2018 15:48:08 +0300 Subject: [PATCH 397/681] Test_scripts for rpc:AddSubMenu, menuIcon --- .../SubMenuIcon/001_menuIcon_is_SUCCESS.lua | 67 ++++++++++++++ .../SubMenuIcon/002_menuIcon_invalid_type.lua | 52 +++++++++++ ...03_menuIcon_selected_not_existing_file.lua | 50 +++++++++++ .../SubMenuIcon/004_menuIcon_is_absent.lua | 52 +++++++++++ .../API/SubMenuIcon/commonSubMenuIcon.lua | 90 +++++++++++++++++++ test_sets/submenu_icon.txt | 4 + 6 files changed, 315 insertions(+) create mode 100644 test_scripts/API/SubMenuIcon/001_menuIcon_is_SUCCESS.lua create mode 100644 test_scripts/API/SubMenuIcon/002_menuIcon_invalid_type.lua create mode 100644 test_scripts/API/SubMenuIcon/003_menuIcon_selected_not_existing_file.lua create mode 100644 test_scripts/API/SubMenuIcon/004_menuIcon_is_absent.lua create mode 100644 test_scripts/API/SubMenuIcon/commonSubMenuIcon.lua create mode 100644 test_sets/submenu_icon.txt diff --git a/test_scripts/API/SubMenuIcon/001_menuIcon_is_SUCCESS.lua b/test_scripts/API/SubMenuIcon/001_menuIcon_is_SUCCESS.lua new file mode 100644 index 0000000000..712d40c615 --- /dev/null +++ b/test_scripts/API/SubMenuIcon/001_menuIcon_is_SUCCESS.lua @@ -0,0 +1,67 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0085-submenu-icon.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Mobile application sends AddSubMenu request to SDL with valid "menuIcon" parameter. +-- SDL does: +-- 1) Forward UI.AddSubMenu request params to HMI. +-- 2) Respond with (resultCode: SUCCESS, success:true) to mobile application. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/SubMenuIcon/commonSubMenuIcon') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + menuID = 1000, + position = 500, + menuName ="SubMenupositive", + menuIcon = { + imageType = "DYNAMIC", + value = "icon.png" + } +} + +local requestUiParams = { + menuID = requestParams.menuID, + menuParams = { + menuName = requestParams.menuName, + position = requestParams.position + }, + menuIcon = common.cloneTable(requestParams.menuIcon) +} +requestUiParams.menuIcon.value = common.getPathToFileInStorage("icon.png") + +local function sendAddSubMenu() + local corId = common.getMobileSession():SendRPC("AddSubMenu", requestParams) + common.getHMIConnection():ExpectRequest("UI.AddSubMenu", requestUiParams) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "SUCCESS"}) + common.getMobileSession():ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Activate Application", common.activateApp) +runner.Step("Upload icon file", common.putFile) + +runner.Title("Test") +runner.Step("MenuIcon with result code_SUCCESS ", sendAddSubMenu) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SubMenuIcon/002_menuIcon_invalid_type.lua b/test_scripts/API/SubMenuIcon/002_menuIcon_invalid_type.lua new file mode 100644 index 0000000000..d5917c7a8d --- /dev/null +++ b/test_scripts/API/SubMenuIcon/002_menuIcon_invalid_type.lua @@ -0,0 +1,52 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0085-submenu-icon.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Mobile application sends AddSubMenu request to SDL with invalid "menuIcon" parameter. +-- SDL does: +-- 1) Respond with (resultCode: INVALID_DATA, success:false) to mobile application. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/SubMenuIcon/commonSubMenuIcon') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] + +local function sendsAddSubMenu_Invalid_Type() + local params = { + menuID = 1000, + position = 500, + menuName ="SubMenupositive", + menuIcon = { + imageType = "DYNAMIC", + value = 123 + } + } + local corId = common.getMobileSession():SendRPC("AddSubMenu", params) + common.getHMIConnection():ExpectRequest("UI.AddSubMenu", params.requestUiParams) + :Times(0) + common.getMobileSession():ExpectResponse(corId, { success = false, resultCode = "INVALID_DATA"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Activate Application", common.activateApp) +runner.Step("Upload icon file", common.putFile) + +runner.Title("Test") +runner.Step("MenuIcon sets an invalid parameter type", sendsAddSubMenu_Invalid_Type) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SubMenuIcon/003_menuIcon_selected_not_existing_file.lua b/test_scripts/API/SubMenuIcon/003_menuIcon_selected_not_existing_file.lua new file mode 100644 index 0000000000..6312b46286 --- /dev/null +++ b/test_scripts/API/SubMenuIcon/003_menuIcon_selected_not_existing_file.lua @@ -0,0 +1,50 @@ + --------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0085-submenu-icon.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Mobile application sends AddSubMenu request to SDL with "menuIcon"= icon.png +-- ("Icon.png" is missing on the system, it was not added via PutFile) +-- SDL does: +-- 1) Respond with (resultCode: INVALID_DATA, success:false) to mobile application. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/SubMenuIcon/commonSubMenuIcon') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local function menuIconNotExistingFile() + local params = { + menuID = 1000, + position = 500, + menuName ="SubMenupositive", + menuIcon = { + imageType = "DYNAMIC", + value = "icon.png" + } + } + local corId = common.getMobileSession():SendRPC("AddSubMenu", params) + common.getHMIConnection():ExpectRequest("UI.AddSubMenu", params.requestUiParams) + :Times(0) + common.getMobileSession():ExpectResponse(corId, { success = false, resultCode = "INVALID_DATA"}) +end +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Activate Application", common.activateApp) + +runner.Title("Test") +runner.Step("MenuIcon with result code_INVALID_DATA", menuIconNotExistingFile) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SubMenuIcon/004_menuIcon_is_absent.lua b/test_scripts/API/SubMenuIcon/004_menuIcon_is_absent.lua new file mode 100644 index 0000000000..68cb16e75d --- /dev/null +++ b/test_scripts/API/SubMenuIcon/004_menuIcon_is_absent.lua @@ -0,0 +1,52 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0085-submenu-icon.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Mobile application sends AddSubMenu request to SDL without menuIcon parameter. +-- SDL does: +-- 1) Forward UI.AddSubMenu request params to HMI. +-- 2) Respond with (resultCode: SUCCESS, success:true) to mobile application. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/SubMenuIcon/commonSubMenuIcon') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] + +local function addSubMenu() + local params = { + menuID = 1000, + position = 500, + menuName ="SubMenupositive" + } + local corId = common.getMobileSession():SendRPC("AddSubMenu", params) + common.getHMIConnection():ExpectRequest("UI.AddSubMenu", params.requestUiParams) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "SUCCESS"}) + common.getMobileSession():ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Activate Application", common.activateApp) + +runner.Title("Test") +runner.Step("AddSubMenu request without menuIcon", addSubMenu) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/SubMenuIcon/commonSubMenuIcon.lua b/test_scripts/API/SubMenuIcon/commonSubMenuIcon.lua new file mode 100644 index 0000000000..9986b956e0 --- /dev/null +++ b/test_scripts/API/SubMenuIcon/commonSubMenuIcon.lua @@ -0,0 +1,90 @@ +--------------------------------------------------------------------------------------------------- +-- Common module +--------------------------------------------------------------------------------------------------- +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 2 + +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local utils = require("user_modules/utils") + +--[[ Module ]] +local m = actions + +m.cloneTable = utils.cloneTable + +--[[ @getPathToFileInStorage: Get path of app icon from storage +--! @parameters: +--! pFileName - Name of file +--! pAppId - application number (1, 2, etc.) +--! @return: app icon path +--]] +function m.getPathToFileInStorage(pFileName, pAppId) + if not pAppId then pAppId = 1 end + return commonPreconditions:GetPathToSDL() .. "storage/" + .. m.getConfigAppParams(pAppId).appID .. "_" + .. utils.getDeviceMAC() .. "/" .. pFileName +end + +--[[ @getPutFileAllParams: get all parameter for PutFile +--! @parameters: none +--! @return: parameters for PutFile +--]] +local function getPutFileAllParams() + return { + syncFileName = "icon.png", + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false, + offset = 0, + length = 11600 + } +end + +--[[ @putFile: Successful processing PutFile RPC +--! @parameters: +--! pParamsSend - parameters for PutFile RPC +--! pFile - file will be used to send to SDL +--! pAppId - Application number (1, 2, etc.) +--! @return: none +--]] +function m.putFile(pParamsSend, pFile, pAppId) + if pParamsSend then + pParamsSend = pParamsSend + else + pParamsSend = getPutFileAllParams() + end + if not pAppId then pAppId = 1 end + local mobSession = m.getMobileSession(pAppId) + local cid + if pFile ~= nil then + cid = mobSession:SendRPC("PutFile", pParamsSend, pFile) + else + cid = mobSession:SendRPC("PutFile", pParamsSend, "files/icon_png.png") + end + + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ @AddSubMenu: Successful processing AddSubMenu RPC +--! @parameters: +--! pParams - Parameters for AddSubMenu RPC +--! @return: none +--]] +function m.addSubMenu(pParams) + local mobSession = m.getMobileSession() + local cid = mobSession:SendRPC("AddSubMenu", pParams.requestParams) + + pParams.responseUiParams.appID = m.getHMIAppId() + EXPECT_HMICALL("UI.AddSubMenu", pParams.responseUiParams) + :Do(function(_,data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + mobSession:ExpectNotification("OnHashChange") +end + +return m diff --git a/test_sets/submenu_icon.txt b/test_sets/submenu_icon.txt new file mode 100644 index 0000000000..5be783cef2 --- /dev/null +++ b/test_sets/submenu_icon.txt @@ -0,0 +1,4 @@ +./test_scripts/API/SubMenuIcon/001_menuIcon_is_SUCCESS.lua +./test_scripts/API/SubMenuIcon/002_menuIcon_invalid_type.lua +./test_scripts/API/SubMenuIcon/003_menuIcon_selected_not_existing_file.lua +./test_scripts/API/SubMenuIcon/004_menuIcon_is_absent.lua From d63d41f83e9adac35ea84d401bca64fd469e3aab Mon Sep 17 00:00:00 2001 From: JackLivio Date: Mon, 21 May 2018 16:17:21 -0400 Subject: [PATCH 398/681] Move tests to subfolder --- ...mplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua | 0 .../002_TemplateColorSchemes_setDisplayWithColorsRejected.lua | 0 .../003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename test_scripts/SDL4.6/{ => TemplateColorShemes}/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua (100%) rename test_scripts/SDL4.6/{ => TemplateColorShemes}/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua (100%) rename test_scripts/SDL4.6/{ => TemplateColorShemes}/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua (100%) diff --git a/test_scripts/SDL4.6/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua b/test_scripts/SDL4.6/TemplateColorShemes/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua similarity index 100% rename from test_scripts/SDL4.6/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua rename to test_scripts/SDL4.6/TemplateColorShemes/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua diff --git a/test_scripts/SDL4.6/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua b/test_scripts/SDL4.6/TemplateColorShemes/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua similarity index 100% rename from test_scripts/SDL4.6/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua rename to test_scripts/SDL4.6/TemplateColorShemes/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua diff --git a/test_scripts/SDL4.6/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua b/test_scripts/SDL4.6/TemplateColorShemes/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua similarity index 100% rename from test_scripts/SDL4.6/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua rename to test_scripts/SDL4.6/TemplateColorShemes/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua From 5c9417302bc8a68d70c580924403591b177fc961 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Mon, 21 May 2018 16:18:00 -0400 Subject: [PATCH 399/681] Spelling --- ...mplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua | 0 .../002_TemplateColorSchemes_setDisplayWithColorsRejected.lua | 0 .../003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename test_scripts/SDL4.6/{TemplateColorShemes => TemplateColorSchemes}/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua (100%) rename test_scripts/SDL4.6/{TemplateColorShemes => TemplateColorSchemes}/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua (100%) rename test_scripts/SDL4.6/{TemplateColorShemes => TemplateColorSchemes}/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua (100%) diff --git a/test_scripts/SDL4.6/TemplateColorShemes/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua b/test_scripts/SDL4.6/TemplateColorSchemes/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua similarity index 100% rename from test_scripts/SDL4.6/TemplateColorShemes/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua rename to test_scripts/SDL4.6/TemplateColorSchemes/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua diff --git a/test_scripts/SDL4.6/TemplateColorShemes/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua b/test_scripts/SDL4.6/TemplateColorSchemes/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua similarity index 100% rename from test_scripts/SDL4.6/TemplateColorShemes/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua rename to test_scripts/SDL4.6/TemplateColorSchemes/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua diff --git a/test_scripts/SDL4.6/TemplateColorShemes/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua b/test_scripts/SDL4.6/TemplateColorSchemes/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua similarity index 100% rename from test_scripts/SDL4.6/TemplateColorShemes/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua rename to test_scripts/SDL4.6/TemplateColorSchemes/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua From bc0e25d2973898294e9da89f4146b5e96f223b5f Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 22 May 2018 09:39:01 +0300 Subject: [PATCH 400/681] Fixed resumption error print --- user_modules/shared_testcases/commonStepsResumption.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_modules/shared_testcases/commonStepsResumption.lua b/user_modules/shared_testcases/commonStepsResumption.lua index 2ceb439571..01a2760dfa 100644 --- a/user_modules/shared_testcases/commonStepsResumption.lua +++ b/user_modules/shared_testcases/commonStepsResumption.lua @@ -90,7 +90,7 @@ function commonStepsResumption:RegisterApp(app, additional_expectations , resume return true end end - return false, "The value of " .. pA .. " (".. tostring(pA) .. ") is not as expected (" .. tostring(pE) .. ")" + return false, "The value of (".. tostring(pA) .. ") is not as expected (" .. tostring(pE) .. ")" end) Test.mobileSession:ExpectResponse(correlation_id, { success = true}) local exp = additional_expectations(Test, app) From cfc7d0a7a1f8681b3639709e4ed70a0fb7fabc4b Mon Sep 17 00:00:00 2001 From: BSolonenko Date: Fri, 4 May 2018 16:18:10 +0300 Subject: [PATCH 401/681] Verified issue smartdevicelink/sdl_core#842 Verified: App does not activate when policies are disabled smartdevicelink/sdl_core#842 --- ...ot_activate_when_policies_are_disabled.lua | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 test_scripts/Defects/4_6/842_App_does_not_activate_when_policies_are_disabled.lua diff --git a/test_scripts/Defects/4_6/842_App_does_not_activate_when_policies_are_disabled.lua b/test_scripts/Defects/4_6/842_App_does_not_activate_when_policies_are_disabled.lua new file mode 100644 index 0000000000..48c9ace355 --- /dev/null +++ b/test_scripts/Defects/4_6/842_App_does_not_activate_when_policies_are_disabled.lua @@ -0,0 +1,81 @@ +-------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/842 + +-- Pre-conditions: +-- 1. SDL is started (EnablePolicy = false) +-- 2. HMI is started + +-- Steps to reproduce: +-- 1. Activate App + +-- Expected: +-- The application was activated. +-------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/commonDefects') +local mobile_session = require("mobile_session") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") + +--[[ Local Variables ]] +local kSuccess = 0 +local hmiAppIds = {} + +--[[ Local Functions ]] +local function rai(self) + self, id = common.getSelfAndParams(1, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC + ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) + end) + end) +end + +local function disablingPolicy() + enablePolicyBackup = commonFunctions:read_parameter_from_smart_device_link_ini("EnablePolicy") + if not commonFunctions:write_parameter_to_smart_device_link_ini("EnablePolicy", "false") then + test:FailTestCase("Value is not set.") + end +end + +local function activateApp(expectedCode, self) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", + { appID = hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] }) + EXPECT_HMIRESPONSE(requestId) + :ValidIf(function(_, data) + local actualCode = + (data.error ~= nil and data.error.code or data.result.code) + if(expectedCode == actualCode) then + return true + end + return false, "Expected value:" .. tostring(expectedCode) .. + "\nActual value: " .. tostring(actualCode) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Disabling Policy", disablingPolicy) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", rai) + +runner.Title("Test") +runner.Step("ActivateApp", activateApp, { kSuccess }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From 8d91a70bcd056d145dbbaca591a7fdc9da2d2481 Mon Sep 17 00:00:00 2001 From: HSavynetska Date: Mon, 21 May 2018 11:13:10 +0300 Subject: [PATCH 402/681] Script for reproducing issue 965 --- ...ason_=_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 test_scripts/Defects/4_6/965_API_App_is_not_unregistered_by_reason_=_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua diff --git a/test_scripts/Defects/4_6/965_API_App_is_not_unregistered_by_reason_=_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua b/test_scripts/Defects/4_6/965_API_App_is_not_unregistered_by_reason_=_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua new file mode 100644 index 0000000000..f5e9c3bf66 --- /dev/null +++ b/test_scripts/Defects/4_6/965_API_App_is_not_unregistered_by_reason_=_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua @@ -0,0 +1,60 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/965 +-- +-- Precondition: +-- 1) SDL Core and HMI are started. App is registered, HMI level = FULL +-- 2) App is registered +-- Description: +-- Steps to reproduce: +-- 1) Send 10 ListFiles request from app +-- Expected: +-- 1) App is unregistered by REQUEST_WHILE_IN_NONE_HMI_LEVEL reason +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/commonDefects') +local commonFunctions = require('user_modules/shared_testcases/commonFunctions') + +-- [[Local variables]] +local count_of_requests = 1 + +--[[ Local Functions ]] +local function updateINIFile() + common.backupINIFile() + commonFunctions:write_parameter_to_smart_device_link_ini("AppHMILevelNoneTimeScaleMaxRequests", count_of_requests) + commonFunctions:write_parameter_to_smart_device_link_ini("AppHMILevelNoneRequestsTimeScale", 30000) +end + +local function listFilesRequests(self) + for i = 1, 10 do + self.mobileSession1:SendRPC("ListFiles", {}) + end + self.mobileSession1:ExpectResponse("ListFiles") + :Do(function(_, data) + if + data.payload.resultCode == "SUCCESS" then + return true + elseif + data.payload.resultCode == "APPLICATION_NOT_REGISTERED" then + return true + else return false, "Received unexpected resultCode " .. data.payload.resultCode + end + end) + :Times(AtMost(10)) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {appID = common.getHMIAppId(pAppId), unexpectedDisconnect = false}) + self.mobileSession1:ExpectNotification("OnAppInterfaceUnregistered", {{reason = reason }}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Update .ini file", updateINIFile) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", common.rai_n) + +runner.Title("Test") +runner.Step("App is unregistered by REQUEST_WHILE_IN_NONE_HMI_LEVEL reason", listFilesRequests) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) +runner.Step("Restore INI file", common.restoreINIFile) From 430bc45c56bd00010bb505e29c2ee091c8fdde0d Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 23 May 2018 11:48:27 +0300 Subject: [PATCH 403/681] Update script --- ...ot_activate_when_policies_are_disabled.lua | 77 +++++++------------ 1 file changed, 28 insertions(+), 49 deletions(-) diff --git a/test_scripts/Defects/4_6/842_App_does_not_activate_when_policies_are_disabled.lua b/test_scripts/Defects/4_6/842_App_does_not_activate_when_policies_are_disabled.lua index 48c9ace355..4f579e7f09 100644 --- a/test_scripts/Defects/4_6/842_App_does_not_activate_when_policies_are_disabled.lua +++ b/test_scripts/Defects/4_6/842_App_does_not_activate_when_policies_are_disabled.lua @@ -1,9 +1,9 @@ -------------------------------------------------------------------------------- --- User story: https://github.com/smartdevicelink/sdl_core/issues/842 +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/842 -- Pre-conditions: -- 1. SDL is started (EnablePolicy = false) --- 2. HMI is started +-- 2. HMI is started -- Steps to reproduce: -- 1. Activate App @@ -14,68 +14,47 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Defects/commonDefects') -local mobile_session = require("mobile_session") -local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local common = require("user_modules/sequences/actions") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local kSuccess = 0 -local hmiAppIds = {} +local hmiAppId --[[ Local Functions ]] -local function rai(self) - self, id = common.getSelfAndParams(1, self) - if not id then id = 1 end - self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) - self["mobileSession" .. id]:StartService(7) - :Do(function() - local corId = self["mobileSession" .. id]:SendRPC - ("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", - { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) - :Do(function(_, d1) - hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID - end) - self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) - :Do(function() - self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", - { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - :Times(AtLeast(1)) - end) - end) -end - -local function disablingPolicy() - enablePolicyBackup = commonFunctions:read_parameter_from_smart_device_link_ini("EnablePolicy") - if not commonFunctions:write_parameter_to_smart_device_link_ini("EnablePolicy", "false") then - test:FailTestCase("Value is not set.") - end +local function disablePolicy() + common.setSDLIniParameter("EnablePolicy", "false") end -local function activateApp(expectedCode, self) - local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", - { appID = hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] }) - EXPECT_HMIRESPONSE(requestId) - :ValidIf(function(_, data) - local actualCode = - (data.error ~= nil and data.error.code or data.result.code) - if(expectedCode == actualCode) then - return true - end - return false, "Expected value:" .. tostring(expectedCode) .. - "\nActual value: " .. tostring(actualCode) +local function registerApp() + common.getMobileSession():StartService(7) + :Do(function() + local corId = common.getMobileSession():SendRPC("RegisterAppInterface", common.getConfigAppParams()) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered") + :Do(function(_, d1) + hmiAppId = d1.params.application.appID + end) + common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) end) end +local function activateApp() + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = hmiAppId }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession():ExpectNotification("OnHMIStatus", { + hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) +end + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Disabling Policy", disablingPolicy) +runner.Step("Disabling Policy", disablePolicy) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI", rai) +runner.Step("Register App", registerApp) runner.Title("Test") -runner.Step("ActivateApp", activateApp, { kSuccess }) +runner.Step("Activate App", activateApp) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) From 9fa099775067cfdcb1b1e3efecee4e9608ccb6d5 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 24 May 2018 16:51:22 +0300 Subject: [PATCH 404/681] Add removal of storage folder in preconditions --- test_scripts/API/SubMenuIcon/commonSubMenuIcon.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test_scripts/API/SubMenuIcon/commonSubMenuIcon.lua b/test_scripts/API/SubMenuIcon/commonSubMenuIcon.lua index 9986b956e0..076e9dc91e 100644 --- a/test_scripts/API/SubMenuIcon/commonSubMenuIcon.lua +++ b/test_scripts/API/SubMenuIcon/commonSubMenuIcon.lua @@ -87,4 +87,12 @@ function m.addSubMenu(pParams) mobSession:ExpectNotification("OnHashChange") end +local preconditionsOrig = m.preconditions + +function m.preconditions() + preconditionsOrig() + local storage = commonPreconditions:GetPathToSDL() .. "storage" + os.execute("rm -rf " .. storage) +end + return m From 107529f264e14ad8fb6fc982d41db0bea10ffacb Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 24 May 2018 18:32:13 +0300 Subject: [PATCH 405/681] Add removal of storage folder in preconditions --- test_scripts/API/SetAppIcon/commonIconResumed.lua | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test_scripts/API/SetAppIcon/commonIconResumed.lua b/test_scripts/API/SetAppIcon/commonIconResumed.lua index cda2c45a0c..82f505a5c5 100644 --- a/test_scripts/API/SetAppIcon/commonIconResumed.lua +++ b/test_scripts/API/SetAppIcon/commonIconResumed.lua @@ -185,4 +185,16 @@ function m.openConnection() test.mobileSession[1]:StartRPC() end +local preconditionsOrig = m.preconditions + +--[[ @preconditions: Expand initial precondition with removing storage folder +--! @parameters: none +--! return: none +--]] +function m.preconditions() + preconditionsOrig() + local storage = commonPreconditions:GetPathToSDL() .. "storage" + os.execute("rm -rf " .. storage) +end + return m From 201761a3df0f1f07cae0229bfec7f016021685e8 Mon Sep 17 00:00:00 2001 From: "Ira Lytvynenko (GitHub)" Date: Mon, 21 May 2018 14:08:11 +0300 Subject: [PATCH 406/681] Verifies that SDL does not put RC apps to NONE state when user disables RC in HMI --- .../008_Allowed_false.lua | 35 +++++++++---------- .../024_Allowed_false_no_PTU.lua | 15 ++++---- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua index f272226a97..c1f0faa4fc 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 -- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md --- Item: Use Case 1: Main Flow +-- Item: Use Case 1: Main Flow (updates https://github.com/smartdevicelink/sdl_core/issues/2173) -- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode @@ -12,9 +12,8 @@ -- -- SDL must: -- 1) store RC state allowed:false internally --- 2) assign HMILevel none to all registered applications with appHMIType REMOTE_CONTROL and send OnHMIStatus (NONE) to such apps --- 3) keep all applications with appHMIType REMOTE_CONTROL registered --- 4) unsubscribe all REMOTE_CONTROL applications from OnInteriorVehicleData notifications for all HMI modules internally +-- 2) keep all applications with appHMIType REMOTE_CONTROL registered and in current HMI levels +-- 3) unsubscribe all REMOTE_CONTROL applications from OnInteriorVehicleData notifications for all HMI modules internally --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -29,29 +28,29 @@ local rcRpcs = {"GetInteriorVehicleData", "SetInteriorVehicleData", "ButtonPress --[[ Local Functions ]] local function ptu_update_func(tbl) - local notRcAppConfig = { - keep_context = false, - steal_focus = false, + local notRcAppConfig = { + keep_context = false, + steal_focus = false, priority = "NONE", default_hmi = "NONE", groups = { "Base-4" }, groups_primaryRC = { "Base-4"}, AppHMIType = { "NAVIGATION" } - } + } tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() tbl.policy_table.app_policies[config.application3.registerAppInterfaceParams.appID] = notRcAppConfig end local function disableRcFromHmi(self) - local mobileSession1 = commonRC.getMobileSession(self, 1) - local mobileSession2 = commonRC.getMobileSession(self, 2) + local mobileSession1 = commonRC.getMobileSession(self, 1) + local mobileSession2 = commonRC.getMobileSession(self, 2) local mobileSession3 = commonRC.getMobileSession(self, 3) - commonRC.defineRAMode(false, nil, self) + commonRC.defineRAMode(false, nil, self) - mobileSession1:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE"}):Times(AtLeast(1)) -- issue with SDL --> notification is sent twice - mobileSession2:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE"}):Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + mobileSession1:ExpectNotification("OnHMIStatus"):Times(0) + mobileSession2:ExpectNotification("OnHMIStatus"):Times(0) mobileSession3:ExpectNotification("OnHMIStatus"):Times(0) -- NAVIGATION app commonTestCases:DelayedExp(commonRC.timeout) @@ -77,11 +76,11 @@ for _, mod in pairs(modules) do -- Apps are not subscribed from RC modules runner.Step("Check App1 is not subscribed on " .. mod, commonRC.isUnsubscribed, { mod, 1 }) runner.Step("Check App2 is not subscribed on " .. mod, commonRC.isUnsubscribed, { mod, 2 }) - -- -- All RC RPCs denied - need clarification - -- for _, rpc in pairs(rcRpcs) do - -- runner.Step("Check module " .. mod .." App1 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 1, rpc, "DISALLOWED" }) - -- runner.Step("Check module " .. mod .." App2 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 2, rpc, "DISALLOWED" }) - -- end + -- All RC RPCs rejected + for _, rpc in pairs(rcRpcs) do + runner.Step("Check module " .. mod .." App1 " .. rpc .. " rejected", commonRC.rpcDenied, { mod, 1, rpc, "USER_DISALLOWED" }) + runner.Step("Check module " .. mod .." App2 " .. rpc .. " rejected", commonRC.rpcDenied, { mod, 2, rpc, "USER_DISALLOWED" }) + end end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua index f3e8812b5c..f9c77cf3fc 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 -- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md --- Item: Use Case 1: Main Flow +-- Item: Use Case 1: Main Flow (updates https://github.com/smartdevicelink/sdl_core/issues/2173) -- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode @@ -13,8 +13,7 @@ -- SDL must: -- 1) store RC state allowed:false internally -- 2) assign HMILevel none to all registered applications with appHMIType REMOTE_CONTROL --- and send OnHMIStatus (NONE) to such apps --- 3) keep all applications with appHMIType REMOTE_CONTROL registered +-- 3) keep all applications with appHMIType REMOTE_CONTROL registered and in current HMI levels --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -63,12 +62,12 @@ local function activate_app(pAppId, self) end local function disableRCFromHMI(self) - commonRC.defineRAMode(false, nil, self) + commonRC.defineRAMode(false, nil, self) - self.mobileSession1:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE" }) - :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice - self.mobileSession2:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE" }) - :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + self.mobileSession1:ExpectNotification("OnHMIStatus") + :Times(0) + self.mobileSession2:ExpectNotification("OnHMIStatus") + :Times(0) self.mobileSession3:ExpectNotification("OnHMIStatus") :Times(0) From 9bf8567254b5957177f38d539835aa727fe03995 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Thu, 24 May 2018 14:45:52 -0400 Subject: [PATCH 407/681] Add displayName to GetCapabilities responses --- files/OnAppregistered/connecttest.lua | 1 + files/connecttest_Navigation_Unsupported.lua | 1 + files/hmi_capabilities_SearchButton.json | 1 + files/hmi_capabilities_Without_PRESET9.json | 1 + test_scripts/API/ATF_BasicCommunication_OnReady.lua | 1 + test_scripts/API/ATF_OnScreenPresetsAvailable.lua | 2 ++ test_scripts/API/ATF_SetDisplayLayout.lua | 2 ++ test_scripts/API/ATF_VehicleInfo_IsReady.lua | 1 + ...TF_Navigation_IsReady_available_false_OnExitApplication.lua | 1 + ...Navigation_IsReady_available_false_UNSUPPORTED_RESOURCE.lua | 1 + ..._Navigation_IsReady_no_response_single_RPC_Result_Codes.lua | 1 + ...F_Navigation_IsReady_no_response_single_RPC_no_response.lua | 1 + .../NotUsed/ATF_Navigation_IsReady_no_response_split_RPC.lua | 1 + .../NotUsed/ATF_TTS_IsReady_NotRespond_RegisterApp.lua | 1 + .../NotUsed/ATF_TTS_IsReady_NotRespond_Single_RPC.lua | 1 + .../NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_1.lua | 1 + .../NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_3.lua | 1 + ...TF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_RETRY.lua | 1 + ...TF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SAVED.lua | 1 + ..._TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SUCCESS.lua | 1 + ...TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_WARNINGS.lua | 1 + ...Ready_NotRespond_Split_RPC_APPLINK_25139_WRONG_LANGUAGE.lua | 1 + .../TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_RegisterApp.lua | 1 + .../TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_SingleRPC.lua | 1 + .../TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_Split_RPC.lua | 1 + .../VR_IsReady/NotUsed/ATF_VR_IsReady_available_false_RAI.lua | 2 ++ .../NotUsed/ATF_VR_IsReady_available_false_singleRPC.lua | 1 + .../ATF_VR_IsReady_available_false_splitRPC_errorCode.lua | 1 + .../ATF_VR_IsReady_available_false_splitRPC_success.lua | 1 + .../IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_RAI.lua | 1 + .../VR_IsReady/NotUsed/ATF_VR_IsReady_missed_singleRPC.lua | 1 + .../NotUsed/ATF_VR_IsReady_missed_splitRPC_VR_NotRespond.lua | 1 + ...splitRPC_VR_responds_UNSUPPORTED_RESOURCE_other_SUCCESS.lua | 1 + ...d_splitRPC_VR_responds_UNSUPPORTED_RESOURCE_other_error.lua | 1 + test_scripts/ATF_Expanded_smoke_test_Genivi.lua | 2 ++ test_scripts/Capabilities/ATF_Buttons_GetCapabilities.lua | 3 +++ .../Capabilities/ATF_Buttons_GetCapabilities_ButtonName.lua | 1 + .../279_ATF_Store_vin_from_GetVehicleData_in_PT.lua | 1 + .../Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua | 1 + .../API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua | 2 +- .../API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua | 2 +- .../Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua | 2 +- test_scripts/smoke_api.lua | 1 + .../ATF_Interface_IsReady_available_false_RAI_Template.lua | 1 + user_modules/IsReady_Template/Interfaces_RPC.lua | 1 + user_modules/IsReady_Template/isReady.lua | 2 ++ user_modules/IsReady_Template/testCasesForNavi_IsReady.lua | 1 + user_modules/IsReady_Template/testCasesForTTS_IsReady.lua | 1 + user_modules/IsReady_Template/testCasesForUI_IsReady.lua | 1 + user_modules/IsReady_Template/testCasesForVR_IsReady.lua | 1 + user_modules/connecttest_TTS_Isready.lua | 1 + user_modules/connecttest_VR_Isready.lua | 1 + user_modules/connecttest_initHMI.lua | 1 + user_modules/connecttest_resumption.lua | 1 + user_modules/hmi_values.lua | 1 + user_modules/shared_testcases/connecttest_TTS_Isready.lua | 1 + 56 files changed, 63 insertions(+), 3 deletions(-) diff --git a/files/OnAppregistered/connecttest.lua b/files/OnAppregistered/connecttest.lua index 43a8128f77..65913094c5 100644 --- a/files/OnAppregistered/connecttest.lua +++ b/files/OnAppregistered/connecttest.lua @@ -360,6 +360,7 @@ function module:InitHMI_onReady() displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/files/connecttest_Navigation_Unsupported.lua b/files/connecttest_Navigation_Unsupported.lua index 5ad40d8e6f..c53bd7b5ba 100644 --- a/files/connecttest_Navigation_Unsupported.lua +++ b/files/connecttest_Navigation_Unsupported.lua @@ -507,6 +507,7 @@ function module:runSDL() displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/files/hmi_capabilities_SearchButton.json b/files/hmi_capabilities_SearchButton.json index 1ae0822155..aa327865b7 100644 --- a/files/hmi_capabilities_SearchButton.json +++ b/files/hmi_capabilities_SearchButton.json @@ -9,6 +9,7 @@ "displayCapabilities": { "displayType":"GEN2_8_DMA", + "displayName":"GENERIC_DISPLAY", "textFields": [{ "name": "mainField1", "characterSet": "TYPE2SET", diff --git a/files/hmi_capabilities_Without_PRESET9.json b/files/hmi_capabilities_Without_PRESET9.json index 2309e84a15..5b4df0b338 100644 --- a/files/hmi_capabilities_Without_PRESET9.json +++ b/files/hmi_capabilities_Without_PRESET9.json @@ -9,6 +9,7 @@ "displayCapabilities": { "displayType":"GEN2_8_DMA", + "displayName":"GENERIC_DISPLAY", "textFields": [{ "name": "mainField1", "characterSet": "TYPE2SET", diff --git a/test_scripts/API/ATF_BasicCommunication_OnReady.lua b/test_scripts/API/ATF_BasicCommunication_OnReady.lua index c6bf3d4560..0bffb23695 100644 --- a/test_scripts/API/ATF_BasicCommunication_OnReady.lua +++ b/test_scripts/API/ATF_BasicCommunication_OnReady.lua @@ -186,6 +186,7 @@ function Test:initHMI_BasicCommunication_OnReady_Invalid(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/ATF_OnScreenPresetsAvailable.lua b/test_scripts/API/ATF_OnScreenPresetsAvailable.lua index 9ec996d2f5..f628bed9b7 100644 --- a/test_scripts/API/ATF_OnScreenPresetsAvailable.lua +++ b/test_scripts/API/ATF_OnScreenPresetsAvailable.lua @@ -277,6 +277,7 @@ function Test:initHMI_onReady(bOnScreenPresetsAvailable) ExpectRequest("UI.GetCapabilities", true, { displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), text_field("mainField2"), @@ -895,6 +896,7 @@ end displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/ATF_SetDisplayLayout.lua b/test_scripts/API/ATF_SetDisplayLayout.lua index 96e67024de..92a64bce9d 100644 --- a/test_scripts/API/ATF_SetDisplayLayout.lua +++ b/test_scripts/API/ATF_SetDisplayLayout.lua @@ -670,6 +670,7 @@ function displayCap_Value() local displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", graphicSupported = true, imageCapabilities = { @@ -942,6 +943,7 @@ function displayCap_ValueForMobile() local displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", graphicSupported = true, --[[ ToDo: uncomment when APPLINK-8959 is fixed diff --git a/test_scripts/API/ATF_VehicleInfo_IsReady.lua b/test_scripts/API/ATF_VehicleInfo_IsReady.lua index 7df09f1747..defa13b9b8 100644 --- a/test_scripts/API/ATF_VehicleInfo_IsReady.lua +++ b/test_scripts/API/ATF_VehicleInfo_IsReady.lua @@ -228,6 +228,7 @@ function Test:initHMI_onReady_VehicleinfoIsReady(method1, resultCode, params1, c displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_available_false_OnExitApplication.lua b/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_available_false_OnExitApplication.lua index b6bba7b2d5..4ffedd0716 100644 --- a/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_available_false_OnExitApplication.lua +++ b/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_available_false_OnExitApplication.lua @@ -535,6 +535,7 @@ function Test:initHMI_onReady_Navi_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_available_false_UNSUPPORTED_RESOURCE.lua b/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_available_false_UNSUPPORTED_RESOURCE.lua index 6959712eda..d200440099 100644 --- a/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_available_false_UNSUPPORTED_RESOURCE.lua +++ b/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_available_false_UNSUPPORTED_RESOURCE.lua @@ -535,6 +535,7 @@ function Test:initHMI_onReady_Navi_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_no_response_single_RPC_Result_Codes.lua b/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_no_response_single_RPC_Result_Codes.lua index 8326ea2b1d..536c4c6fb0 100644 --- a/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_no_response_single_RPC_Result_Codes.lua +++ b/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_no_response_single_RPC_Result_Codes.lua @@ -535,6 +535,7 @@ function Test:initHMI_onReady_Navi_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_no_response_single_RPC_no_response.lua b/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_no_response_single_RPC_no_response.lua index 183c55f57e..421fb6a019 100644 --- a/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_no_response_single_RPC_no_response.lua +++ b/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_no_response_single_RPC_no_response.lua @@ -535,6 +535,7 @@ function Test:initHMI_onReady_Navi_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_no_response_split_RPC.lua b/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_no_response_split_RPC.lua index da20a93006..62b943b25a 100644 --- a/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_no_response_split_RPC.lua +++ b/test_scripts/API/IsReady/Navigation_IsReady/NotUsed/ATF_Navigation_IsReady_no_response_split_RPC.lua @@ -535,6 +535,7 @@ function Test:initHMI_onReady_Navi_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_RegisterApp.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_RegisterApp.lua index c4272b1a86..8868f70ea0 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_RegisterApp.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_RegisterApp.lua @@ -468,6 +468,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Single_RPC.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Single_RPC.lua index ef5ec147a4..cafd8b1e94 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Single_RPC.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Single_RPC.lua @@ -452,6 +452,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_1.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_1.lua index 116907e2df..6b3971e72b 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_1.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_1.lua @@ -480,6 +480,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_3.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_3.lua index 95790f1770..5edbe00771 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_3.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_3.lua @@ -483,6 +483,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_RETRY.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_RETRY.lua index cfa91dc66a..6f429af760 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_RETRY.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_RETRY.lua @@ -463,6 +463,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SAVED.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SAVED.lua index b31c4cf012..b70b262752 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SAVED.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SAVED.lua @@ -464,6 +464,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SUCCESS.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SUCCESS.lua index 7f1b2f9649..3e32ea25b2 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SUCCESS.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_SUCCESS.lua @@ -465,6 +465,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_WARNINGS.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_WARNINGS.lua index b69e60c8a7..1d7d41a9fe 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_WARNINGS.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_WARNINGS.lua @@ -460,6 +460,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_WRONG_LANGUAGE.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_WRONG_LANGUAGE.lua index fc6605b3a5..7104d26a29 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_WRONG_LANGUAGE.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_NotRespond_Split_RPC_APPLINK_25139_WRONG_LANGUAGE.lua @@ -462,6 +462,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_RegisterApp.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_RegisterApp.lua index f6241bff60..076142fae7 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_RegisterApp.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_RegisterApp.lua @@ -452,6 +452,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_SingleRPC.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_SingleRPC.lua index 552fe659ae..7a1b671c21 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_SingleRPC.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_SingleRPC.lua @@ -454,6 +454,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_Split_RPC.lua b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_Split_RPC.lua index 79e04650eb..54e78297f7 100644 --- a/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_Split_RPC.lua +++ b/test_scripts/API/IsReady/TTS_IsReady/NotUsed/ATF_TTS_IsReady_false_Split_RPC.lua @@ -454,6 +454,7 @@ function Test:initHMI_onReady_TTS_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_available_false_RAI.lua b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_available_false_RAI.lua index 122b7f6a89..f9d57e3029 100644 --- a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_available_false_RAI.lua +++ b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_available_false_RAI.lua @@ -462,6 +462,7 @@ function Test:initHMI_onReady_VR_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), @@ -831,6 +832,7 @@ local function Case1_BothVR_TTS_IsReady_available_false() displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_available_false_singleRPC.lua b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_available_false_singleRPC.lua index 98e81344a2..2f4002d9bf 100644 --- a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_available_false_singleRPC.lua +++ b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_available_false_singleRPC.lua @@ -433,6 +433,7 @@ function Test:initHMI_onReady_VR_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_available_false_splitRPC_errorCode.lua b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_available_false_splitRPC_errorCode.lua index 9ee3cc8212..9d8178ec73 100644 --- a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_available_false_splitRPC_errorCode.lua +++ b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_available_false_splitRPC_errorCode.lua @@ -432,6 +432,7 @@ function Test:initHMI_onReady_VR_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_available_false_splitRPC_success.lua b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_available_false_splitRPC_success.lua index ad68252359..f1ac3a3848 100644 --- a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_available_false_splitRPC_success.lua +++ b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_available_false_splitRPC_success.lua @@ -432,6 +432,7 @@ function Test:initHMI_onReady_VR_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_RAI.lua b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_RAI.lua index 4fcebb47c9..9f62b5a42a 100644 --- a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_RAI.lua +++ b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_RAI.lua @@ -467,6 +467,7 @@ function Test:initHMI_onReady_VR_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_singleRPC.lua b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_singleRPC.lua index a33ccbd6ee..40408fa007 100644 --- a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_singleRPC.lua +++ b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_singleRPC.lua @@ -432,6 +432,7 @@ function Test:initHMI_onReady_VR_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_splitRPC_VR_NotRespond.lua b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_splitRPC_VR_NotRespond.lua index 15504e55a8..5c4e7e0b21 100644 --- a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_splitRPC_VR_NotRespond.lua +++ b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_splitRPC_VR_NotRespond.lua @@ -433,6 +433,7 @@ function Test:initHMI_onReady_VR_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_splitRPC_VR_responds_UNSUPPORTED_RESOURCE_other_SUCCESS.lua b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_splitRPC_VR_responds_UNSUPPORTED_RESOURCE_other_SUCCESS.lua index e845b0a73d..da278078c2 100644 --- a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_splitRPC_VR_responds_UNSUPPORTED_RESOURCE_other_SUCCESS.lua +++ b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_splitRPC_VR_responds_UNSUPPORTED_RESOURCE_other_SUCCESS.lua @@ -439,6 +439,7 @@ function Test:initHMI_onReady_VR_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_splitRPC_VR_responds_UNSUPPORTED_RESOURCE_other_error.lua b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_splitRPC_VR_responds_UNSUPPORTED_RESOURCE_other_error.lua index ae4164b700..b5a16c26f4 100644 --- a/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_splitRPC_VR_responds_UNSUPPORTED_RESOURCE_other_error.lua +++ b/test_scripts/API/IsReady/VR_IsReady/NotUsed/ATF_VR_IsReady_missed_splitRPC_VR_responds_UNSUPPORTED_RESOURCE_other_error.lua @@ -439,6 +439,7 @@ function Test:initHMI_onReady_VR_IsReady(case) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/ATF_Expanded_smoke_test_Genivi.lua b/test_scripts/ATF_Expanded_smoke_test_Genivi.lua index 08a5ac5f62..fabbdd491f 100644 --- a/test_scripts/ATF_Expanded_smoke_test_Genivi.lua +++ b/test_scripts/ATF_Expanded_smoke_test_Genivi.lua @@ -10655,6 +10655,7 @@ local blockId = 1 { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { { @@ -10746,6 +10747,7 @@ local blockId = 1 displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { { diff --git a/test_scripts/Capabilities/ATF_Buttons_GetCapabilities.lua b/test_scripts/Capabilities/ATF_Buttons_GetCapabilities.lua index 4dfa053995..488db4a45d 100644 --- a/test_scripts/Capabilities/ATF_Buttons_GetCapabilities.lua +++ b/test_scripts/Capabilities/ATF_Buttons_GetCapabilities.lua @@ -373,6 +373,7 @@ local function HMI_Send_Button_GetCapabilities_Response(Input_capabilities) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), @@ -657,6 +658,7 @@ local function HMI_Send_Button_GetCapabilities_Response_Timeout(Input_Timeoutcap displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), @@ -942,6 +944,7 @@ local function HMI_Send_Button_GetCapabilities_Response_Invalid() displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/Capabilities/ATF_Buttons_GetCapabilities_ButtonName.lua b/test_scripts/Capabilities/ATF_Buttons_GetCapabilities_ButtonName.lua index b7c209b62c..0ab506bd5f 100644 --- a/test_scripts/Capabilities/ATF_Buttons_GetCapabilities_ButtonName.lua +++ b/test_scripts/Capabilities/ATF_Buttons_GetCapabilities_ButtonName.lua @@ -229,6 +229,7 @@ local function HMI_Send_Button_GetCapabilities_Response(Input_capabilities) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/Policies/Validation_of_PolicyTables/279_ATF_Store_vin_from_GetVehicleData_in_PT.lua b/test_scripts/Policies/Validation_of_PolicyTables/279_ATF_Store_vin_from_GetVehicleData_in_PT.lua index 425a7889ae..748817ac0c 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/279_ATF_Store_vin_from_GetVehicleData_in_PT.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/279_ATF_Store_vin_from_GetVehicleData_in_PT.lua @@ -207,6 +207,7 @@ function Test:Step1_SDL_requests_vin_on_InitHMI_OnReady() displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua index 8d16ca3f59..cbd4cbb041 100644 --- a/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/020_SetDisplayLayout_PositiveCase_SUCCESS.lua @@ -162,6 +162,7 @@ local function getDisplayCapValues() -- some capabilities are excluded due to SDL issue return { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", graphicSupported = true, -- imageCapabilities = { -- "DYNAMIC", diff --git a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua index ab6ee8b20c..a31911a983 100644 --- a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua @@ -39,7 +39,7 @@ local VDValues = { rpm = "VEHICLEDATA_RPM", fuelLevel = "VEHICLEDATA_FUELLEVEL", fuelLevel_State = "VEHICLEDATA_FUELLEVEL_STATE", - fuelRange = "VEHICLEDATA_FUELRANGE" + fuelRange = "VEHICLEDATA_FUELRANGE", instantFuelConsumption = "VEHICLEDATA_FUELCONSUMPTION", externalTemperature = "VEHICLEDATA_EXTERNTEMP", prndl = "VEHICLEDATA_PRNDL", diff --git a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua index ac43225490..96924ec0d3 100644 --- a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua @@ -39,7 +39,7 @@ local VDValues = { rpm = "VEHICLEDATA_RPM", fuelLevel = "VEHICLEDATA_FUELLEVEL", fuelLevel_State = "VEHICLEDATA_FUELLEVEL_STATE", - fuelRange = "VEHICLEDATA_FUELRANGE" + fuelRange = "VEHICLEDATA_FUELRANGE", instantFuelConsumption = "VEHICLEDATA_FUELCONSUMPTION", externalTemperature = "VEHICLEDATA_EXTERNTEMP", prndl = "VEHICLEDATA_PRNDL", diff --git a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua index 74a9dc78db..085fd32155 100644 --- a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua @@ -63,7 +63,7 @@ local vehicleDataValues = { type = "GASOLINE", range = 400.5 } - } + }, instantFuelConsumption = 1000.5, externalTemperature = 55.5, vin = "123456", diff --git a/test_scripts/smoke_api.lua b/test_scripts/smoke_api.lua index a03e98210b..ff2ebf6b79 100644 --- a/test_scripts/smoke_api.lua +++ b/test_scripts/smoke_api.lua @@ -2818,6 +2818,7 @@ local function displayCap_Value() local displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", graphicSupported = true, imageCapabilities = { diff --git a/user_modules/IsReady_Template/ATF_Interface_IsReady_available_false_RAI_Template.lua b/user_modules/IsReady_Template/ATF_Interface_IsReady_available_false_RAI_Template.lua index 4d75af878b..7daf804795 100644 --- a/user_modules/IsReady_Template/ATF_Interface_IsReady_available_false_RAI_Template.lua +++ b/user_modules/IsReady_Template/ATF_Interface_IsReady_available_false_RAI_Template.lua @@ -234,6 +234,7 @@ function StopStartSDL_HMI_MOBILE_VR_TTS(self) displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/user_modules/IsReady_Template/Interfaces_RPC.lua b/user_modules/IsReady_Template/Interfaces_RPC.lua index 7f7410ce6e..64808ad986 100644 --- a/user_modules/IsReady_Template/Interfaces_RPC.lua +++ b/user_modules/IsReady_Template/Interfaces_RPC.lua @@ -61,6 +61,7 @@ interfaces.RAI = { hmiDisplayLanguage = "EN-US", displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { { name = "mainField1", characterSet = "TYPE2SET", width = 500, rows = 1}, diff --git a/user_modules/IsReady_Template/isReady.lua b/user_modules/IsReady_Template/isReady.lua index 81a3e3af1b..c375f961e5 100644 --- a/user_modules/IsReady_Template/isReady.lua +++ b/user_modules/IsReady_Template/isReady.lua @@ -762,6 +762,7 @@ end displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), @@ -1124,6 +1125,7 @@ end displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/user_modules/IsReady_Template/testCasesForNavi_IsReady.lua b/user_modules/IsReady_Template/testCasesForNavi_IsReady.lua index 1d2f7c10e3..c32626a597 100644 --- a/user_modules/IsReady_Template/testCasesForNavi_IsReady.lua +++ b/user_modules/IsReady_Template/testCasesForNavi_IsReady.lua @@ -152,6 +152,7 @@ function testCasesForNavi_IsReady.InitHMI_onReady_without_Navi_IsReady(self, exp displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/user_modules/IsReady_Template/testCasesForTTS_IsReady.lua b/user_modules/IsReady_Template/testCasesForTTS_IsReady.lua index 409b0635b3..6a409f58cd 100644 --- a/user_modules/IsReady_Template/testCasesForTTS_IsReady.lua +++ b/user_modules/IsReady_Template/testCasesForTTS_IsReady.lua @@ -157,6 +157,7 @@ function testCasesForTTS_IsReady.InitHMI_onReady_without_TTS_IsReady(self, exp_o displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/user_modules/IsReady_Template/testCasesForUI_IsReady.lua b/user_modules/IsReady_Template/testCasesForUI_IsReady.lua index a03ac4e7c9..6464ca53a0 100644 --- a/user_modules/IsReady_Template/testCasesForUI_IsReady.lua +++ b/user_modules/IsReady_Template/testCasesForUI_IsReady.lua @@ -157,6 +157,7 @@ function testCasesForUI_IsReady.InitHMI_onReady_without_UI_IsReady(self, exp_occ displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/user_modules/IsReady_Template/testCasesForVR_IsReady.lua b/user_modules/IsReady_Template/testCasesForVR_IsReady.lua index 64a819644b..0352b27d82 100644 --- a/user_modules/IsReady_Template/testCasesForVR_IsReady.lua +++ b/user_modules/IsReady_Template/testCasesForVR_IsReady.lua @@ -156,6 +156,7 @@ function testCasesForVR_IsReady.InitHMI_onReady_without_VR_IsReady(self, exp_occ displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/user_modules/connecttest_TTS_Isready.lua b/user_modules/connecttest_TTS_Isready.lua index bcf0ba3c06..1042f17cb5 100644 --- a/user_modules/connecttest_TTS_Isready.lua +++ b/user_modules/connecttest_TTS_Isready.lua @@ -533,6 +533,7 @@ function module:initHMI_onReady() displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/user_modules/connecttest_VR_Isready.lua b/user_modules/connecttest_VR_Isready.lua index fc9445dde2..f89d7a28c7 100644 --- a/user_modules/connecttest_VR_Isready.lua +++ b/user_modules/connecttest_VR_Isready.lua @@ -532,6 +532,7 @@ function module:initHMI_onReady() displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/user_modules/connecttest_initHMI.lua b/user_modules/connecttest_initHMI.lua index 877a96f207..df5319efaf 100644 --- a/user_modules/connecttest_initHMI.lua +++ b/user_modules/connecttest_initHMI.lua @@ -513,6 +513,7 @@ function module:initHMI_onReady() displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/user_modules/connecttest_resumption.lua b/user_modules/connecttest_resumption.lua index cff55d9d12..990685ffc1 100644 --- a/user_modules/connecttest_resumption.lua +++ b/user_modules/connecttest_resumption.lua @@ -516,6 +516,7 @@ function module:initHMI_onReady() displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index e4d9fc261a..9c375a8bd1 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -195,6 +195,7 @@ function module.getDefaultHMITable() params = { displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = (function() local fields = { "mainField1", "mainField2", "mainField3", "mainField4", "statusBar", "mediaClock", "mediaTrack", diff --git a/user_modules/shared_testcases/connecttest_TTS_Isready.lua b/user_modules/shared_testcases/connecttest_TTS_Isready.lua index bcf0ba3c06..1042f17cb5 100644 --- a/user_modules/shared_testcases/connecttest_TTS_Isready.lua +++ b/user_modules/shared_testcases/connecttest_TTS_Isready.lua @@ -533,6 +533,7 @@ function module:initHMI_onReady() displayCapabilities = { displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", textFields = { text_field("mainField1"), From 2ee5ad5d854782affdc1b3c3d79a78d1ad17dc70 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Thu, 24 May 2018 15:30:56 -0400 Subject: [PATCH 408/681] add test script for displayName --- ..._SetDisplayLayout_DisplayNameParameter.lua | 191 ++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 test_scripts/SDL4.6/DisplayName/001_SetDisplayLayout_DisplayNameParameter.lua diff --git a/test_scripts/SDL4.6/DisplayName/001_SetDisplayLayout_DisplayNameParameter.lua b/test_scripts/SDL4.6/DisplayName/001_SetDisplayLayout_DisplayNameParameter.lua new file mode 100644 index 0000000000..5285d60d07 --- /dev/null +++ b/test_scripts/SDL4.6/DisplayName/001_SetDisplayLayout_DisplayNameParameter.lua @@ -0,0 +1,191 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0063-display-name-parameter.md +-- +-- Description: +-- Add displayName to the displayCapabiilities response. Mobile will expect this field to be populated +-- +-- Steps: Send SetDisplayLayout request. +-- +-- Expected result: +-- SDL Core returns SUCCESS with displayCapabilities: displayName: "GENERIC_DISPLAY" +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +local function getRequestParams() + return { + displayLayout = "ONSCREEN_PRESETS" + } +end + +local function getDisplayCapTextFieldsValues() + -- some text fields are excluded due to SDL issue + local names = { + "alertText1", + "alertText2", + "alertText3", + "audioPassThruDisplayText1", + "audioPassThruDisplayText2", + "ETA", + "initialInteractionText", + -- "phoneNumber", + "mainField1", + "mainField2", + "mainField3", + "mainField4", + "mediaClock", + "mediaTrack", + "menuName", + "menuTitle", + -- "addressLines", + -- "locationName", + "navigationText1", + "navigationText2", + -- "locationDescription", + "scrollableMessageBody", + "secondaryText", + "sliderFooter", + "sliderHeader", + "statusBar", + "tertiaryText", + "totalDistance", + -- "notificationText", + -- "navigationText", + -- "timeToDestination", + -- "turnText" + } + local values = { } + for _, v in pairs(names) do + local item = { + characterSet = "TYPE2SET", + name = v, + rows = 1, + width = 500 + } + table.insert(values, item) + end + return values +end + +local function getDisplayCapImageFieldsValues() + local names = { + "softButtonImage", + "choiceImage", + "choiceSecondaryImage", + "vrHelpItem", + "turnIcon", + "menuIcon", + "cmdIcon", + "graphic", + "showConstantTBTIcon", + "showConstantTBTNextTurnIcon" + } + local values = { } + for _, v in pairs(names) do + local item = { + imageResolution = { + resolutionHeight = 64, + resolutionWidth = 64 + }, + imageTypeSupported = { + "GRAPHIC_BMP", + "GRAPHIC_JPEG", + "GRAPHIC_PNG" + }, + name = v + } + table.insert(values, item) + end + return values +end + +local function setDisplayWithDisplayNameSuccess(self) + local responseParams = { + displayCapabilities = { + displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", + graphicSupported = true, + imageFields = getDisplayCapImageFieldsValues(), + mediaClockFormats = { + "CLOCK1", + "CLOCK2", + "CLOCK3", + "CLOCKTEXT1", + "CLOCKTEXT2", + "CLOCKTEXT3", + "CLOCKTEXT4" + }, + numCustomPresetsAvailable = 10, + screenParams = { + resolution = { + resolutionHeight = 480, + resolutionWidth = 800 + }, + touchEventAvailable = { + doublePressAvailable = false, + multiTouchAvailable = true, + pressAvailable = true + } + }, + templatesAvailable = { + "ONSCREEN_PRESETS" + }, + textFields = getDisplayCapTextFieldsValues() + } + } + local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams()) + EXPECT_HMICALL("UI.SetDisplayLayout", getRequestParams()) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", responseParams) + end) + self.mobileSession1:ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS", + displayCapabilities = { + displayType = "GEN2_8_DMA", + displayName = "GENERIC_DISPLAY", + graphicSupported = true, + imageFields = getDisplayCapImageFieldsValues(), + mediaClockFormats = { + "CLOCK1", + "CLOCK2", + "CLOCK3", + "CLOCKTEXT1", + "CLOCKTEXT2", + "CLOCKTEXT3", + "CLOCKTEXT4" + }, + numCustomPresetsAvailable = 10, + screenParams = { + resolution = { + resolutionHeight = 480, + resolutionWidth = 800 + }, + touchEventAvailable = { + doublePressAvailable = false, + multiTouchAvailable = true, + pressAvailable = true + } + }, + templatesAvailable = { + "ONSCREEN_PRESETS" + }, + textFields = getDisplayCapTextFieldsValues() + } + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI", commonSmoke.registerApp) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +runner.Step("Set displayLayout with display name Positive Case 1", setDisplayWithDisplayNameSuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From 18997d85dce255825925652137809c38cbb0d060 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 25 May 2018 13:20:58 +0300 Subject: [PATCH 409/681] Fix link to script in RC test set --- test_sets/rc_CLIMATE_RADIO.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_sets/rc_CLIMATE_RADIO.txt b/test_sets/rc_CLIMATE_RADIO.txt index a40098b191..d960cea13e 100644 --- a/test_sets/rc_CLIMATE_RADIO.txt +++ b/test_sets/rc_CLIMATE_RADIO.txt @@ -89,7 +89,7 @@ ./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua ./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua ./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua -./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/001_Success_flow.lua ./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua ./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua ./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua From 3356f3f2d07a97aebba2fc612fb9d58da2998fa6 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 24 May 2018 16:43:40 +0300 Subject: [PATCH 410/681] Add new scripts on 2 apps and deactivation --- .../Phase2/021_two_apps_and_deactivation.lua | 77 +++++++++++++++ ..._proj_media_and_deactivation_streaming.lua | 94 +++++++++++++++++++ ...s_navi_comm_and_deactivation_streaming.lua | 90 ++++++++++++++++++ .../MobileProjection/Phase2/common.lua | 12 +++ test_sets/mobile_projection_2.txt | 4 + 5 files changed, 277 insertions(+) create mode 100644 test_scripts/MobileProjection/Phase2/021_two_apps_and_deactivation.lua create mode 100644 test_scripts/MobileProjection/Phase2/022_two_apps_proj_media_and_deactivation_streaming.lua create mode 100644 test_scripts/MobileProjection/Phase2/023_two_apps_navi_comm_and_deactivation_streaming.lua diff --git a/test_scripts/MobileProjection/Phase2/021_two_apps_and_deactivation.lua b/test_scripts/MobileProjection/Phase2/021_two_apps_and_deactivation.lua new file mode 100644 index 0000000000..b8e99cc9cf --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/021_two_apps_and_deactivation.lua @@ -0,0 +1,77 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [001] = { [1] = { t = "PROJECTION", m = true }, [2] = { t = "MEDIA", m = true }}, +} + +--[[ Local Functions ]] +local function deactivateApp1() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(1) }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "AUDIBLE", + videoStreamingState = "STREAMABLE" + }) + :Times(1) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function deactivateApp2() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(2) }) + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "AUDIBLE", + videoStreamingState = "NOT_STREAMABLE" + }) + :Times(1) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function onHMIStatus2Apps() + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { + hmiLevel = "FULL", + systemContext = "MAIN", + audioStreamingState = "AUDIBLE", + videoStreamingState = "NOT_STREAMABLE" + }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "NOT_AUDIBLE", + videoStreamingState = "STREAMABLE" + }) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Deactivate App 1", deactivateApp1) + runner.Step("Activate App 2", common.activateAppCustomOnHMIStatusExpectation, { 2, onHMIStatus2Apps }) + runner.Step("Deactivate App 2", deactivateApp2) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end diff --git a/test_scripts/MobileProjection/Phase2/022_two_apps_proj_media_and_deactivation_streaming.lua b/test_scripts/MobileProjection/Phase2/022_two_apps_proj_media_and_deactivation_streaming.lua new file mode 100644 index 0000000000..61972858e5 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/022_two_apps_proj_media_and_deactivation_streaming.lua @@ -0,0 +1,94 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [001] = { [1] = { t = "PROJECTION", m = true }, [2] = { t = "MEDIA", m = true }}, +} + +--[[ Local Functions ]] +local function deactivateApp1() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(1) }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "AUDIBLE", + videoStreamingState = "STREAMABLE" + }) + :Times(1) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function deactivateApp2() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(2) }) + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "AUDIBLE", + videoStreamingState = "NOT_STREAMABLE" + }) + :Times(1) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function appStartVideoStreaming() + common.getMobileSession():StartService(11) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(11, "files/MP3_4555kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = true }) + end) + end) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function onHMIStatus2Apps() + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { + hmiLevel = "FULL", + systemContext = "MAIN", + audioStreamingState = "AUDIBLE", + videoStreamingState = "NOT_STREAMABLE" + }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "NOT_AUDIBLE", + videoStreamingState = "STREAMABLE" + }) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("App 1 starts Video streaming", appStartVideoStreaming) + runner.Step("Deactivate App 1", deactivateApp1) + runner.Step("Activate App 2", common.activateAppCustomOnHMIStatusExpectation, { 2, onHMIStatus2Apps }) + runner.Step("Deactivate App 2", deactivateApp2) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end diff --git a/test_scripts/MobileProjection/Phase2/023_two_apps_navi_comm_and_deactivation_streaming.lua b/test_scripts/MobileProjection/Phase2/023_two_apps_navi_comm_and_deactivation_streaming.lua new file mode 100644 index 0000000000..2f9da6498f --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/023_two_apps_navi_comm_and_deactivation_streaming.lua @@ -0,0 +1,90 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [001] = { [1] = { t = "NAVIGATION", m = true }, [2] = { t = "COMMUNICATION", m = false }}, +} + +--[[ Local Functions ]] +local function deactivateApp1() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(1) }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "AUDIBLE", + videoStreamingState = "STREAMABLE" + }) + :Times(1) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function deactivateApp2() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(2) }) + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "ATTENUATED", + videoStreamingState = "NOT_STREAMABLE" + }) + :Times(1) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function appStartVideoStreaming() + common.getMobileSession():StartService(11) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(11, "files/MP3_4555kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = true }) + end) + end) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function onHMIStatus2Apps() + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { + hmiLevel = "FULL", + systemContext = "MAIN", + audioStreamingState = "ATTENUATED", + videoStreamingState = "NOT_STREAMABLE" + }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("App 1 starts Video streaming", appStartVideoStreaming) + runner.Step("Deactivate App 1", deactivateApp1) + runner.Step("Activate App 2", common.activateAppCustomOnHMIStatusExpectation, { 2, onHMIStatus2Apps }) + runner.Step("Deactivate App 2", deactivateApp2) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end diff --git a/test_scripts/MobileProjection/Phase2/common.lua b/test_scripts/MobileProjection/Phase2/common.lua index e5d6632e5d..d5bd4b8f4b 100644 --- a/test_scripts/MobileProjection/Phase2/common.lua +++ b/test_scripts/MobileProjection/Phase2/common.lua @@ -26,6 +26,18 @@ function m.activateApp(pAppId) utils.wait() end +function m.activateAppCustomOnHMIStatusExpectation(pAppId, pOnHMIStatusFunc) + if not pAppId then pAppId = 1 end + local requestId = test.hmiConnection:SendRequest("SDL.ActivateApp", { appID = m.getHMIAppId(pAppId) }) + test.hmiConnection:ExpectResponse(requestId) + if not pOnHMIStatusFunc then + m.getMobileSession(pAppId):ExpectNotification("OnHMIStatus", { hmiLevel = "FULL" }) + else + pOnHMIStatusFunc() + end + utils.wait() +end + function m.setAppConfig(pAppId, pAppHMIType, pIsMedia) m.getConfigAppParams(pAppId).appHMIType = { pAppHMIType } m.getConfigAppParams(pAppId).isMediaApplication = pIsMedia diff --git a/test_sets/mobile_projection_2.txt b/test_sets/mobile_projection_2.txt index d43012b28b..d6daf0d1fb 100644 --- a/test_sets/mobile_projection_2.txt +++ b/test_sets/mobile_projection_2.txt @@ -18,3 +18,7 @@ ./test_scripts/MobileProjection/Phase2/018_two_apps_and_one_app_unregister.lua ./test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua ./test_scripts/MobileProjection/Phase2/020_different_types_apps_interactions.lua +./test_scripts/MobileProjection/Phase2/021_two_apps_and_deactivation.lua +./test_scripts/MobileProjection/Phase2/022_two_apps_proj_media_and_deactivation_streaming.lua +./test_scripts/MobileProjection/Phase2/023_two_apps_navi_comm_and_deactivation_streaming.lua + From edf102cb06cbe5f926a76ee70c65335a8fb0dc91 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 29 May 2018 14:06:14 -0400 Subject: [PATCH 411/681] Add new tire pressure parameters --- .../GetVehicleData/001_Success_flow.lua | 17 +++++++++++++- ..._parameter_DISALLOWED_by_policies_flow.lua | 17 ++++++++++++-- .../OnVehicleData/001_Success_flow.lua | 19 +++++++++++++++- ...onForUnsubsribedParameter_Ignored_flow.lua | 22 +++++++++++++++++-- ...meterDisallowedByPolicies_Ignored_flow.lua | 21 ++++++++++++++++-- .../SubscribeVehicleData/001_Success_flow.lua | 7 +++++- ..._parameter_DISALLOWED_by_policies_flow.lua | 9 ++++++-- ...already_subscribed_Result_IGNORED_flow.lua | 11 +++++++++- .../001_Success_flow.lua | 10 +++++++-- ...ameter_not_yet_subscribed_IGNORED_flow.lua | 7 +++++- ...ready_unsubscribed_Result_IGNORED_flow.lua | 14 ++++++++++-- ...wed_by_policies_Result_DISALLOWED_flow.lua | 9 ++++++-- .../API/VehicleData/commonVehicleData.lua | 1 + 13 files changed, 145 insertions(+), 19 deletions(-) diff --git a/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua index 4a2cb93a59..b18a9f1445 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua @@ -24,7 +24,8 @@ local rpc = { name = "GetVehicleData", params = { engineOilLife = true, - fuelRange = true + fuelRange = true, + tirePressure = true } } @@ -35,9 +36,23 @@ local vehicleDataValues = { type = "GASOLINE", range = 400.00 } + }, + tirePressure = { + leftFront = { + status = "NORMAL", + tpms = "SYSTEM_ACTIVE", + pressure = 35.00 + }, + rightFront = { + status = "NORMAL", + tpms = "SYSTEM_ACTIVE", + pressure = 35.00 + } } } + + --[[ Local Functions ]] local function processRPCSuccess(self) local mobileSession = common.getMobileSession(self, 1) diff --git a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index 07fcafeed1..694b41001b 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -25,7 +25,8 @@ local rpc = { name = "GetVehicleData", params = { engineOilLife = true, - fuelRange = true + fuelRange = true, + tirePressure = true } } @@ -36,6 +37,18 @@ local vehicleDataValues = { type = "GASOLINE", range = 400.00 } + }, + tirePressure = { + leftFront = { + status = "NORMAL", + tpms = "SYSTEM_ACTIVE", + pressure = 35.00 + }, + rightFront = { + status = "NORMAL", + tpms = "SYSTEM_ACTIVE", + pressure = 35.00 + } } } @@ -44,7 +57,7 @@ local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["GetVehicleData"].parameters local newParams = {} for index, value in pairs(params) do - if not (("engineOilLife" == value) or ("fuelRange" == value)) then table.insert(newParams, value) end + if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value)) then table.insert(newParams, value) end end tbl.policy_table.functional_groupings["Emergency-1"].rpcs["GetVehicleData"].parameters = newParams end diff --git a/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua index c6a95167ef..fa577bd8d2 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua @@ -24,7 +24,8 @@ local rpc1 = { name = "SubscribeVehicleData", params = { engineOilLife = true, - fuelRange = true + fuelRange = true, + tirePressure = true } } @@ -37,6 +38,18 @@ local rpc2 = { type = "GASOLINE", range = 400.00 } + }, + tirePressure = { + leftFront = { + status = "NORMAL", + tpms = "SYSTEM_ACTIVE", + pressure = 35.00 + }, + rightFront = { + status = "NORMAL", + tpms = "SYSTEM_ACTIVE", + pressure = 35.00 + } } } } @@ -49,6 +62,10 @@ local vehicleDataResults = { fuelRange = { dataType = "VEHICLEDATA_FUELRANGE", resultCode = "SUCCESS" + }, + tirePressure = { + dataType = "VEHICLEDATA_TIREPRESSURE", + resultCode = "SUCCESS" } } diff --git a/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua index 74b53bbb14..198e447a03 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua @@ -26,7 +26,8 @@ local rpc1 = { name = "SubscribeVehicleData", params = { engineOilLife = true, - fuelRange = true + fuelRange = true, + tirePressure = true } } @@ -39,6 +40,18 @@ local rpc2 = { type = "GASOLINE", range = 400.00 } + }, + tirePressure = { + leftFront = { + status = "NORMAL", + tpms = "SYSTEM_ACTIVE", + pressure = 35.00 + }, + rightFront = { + status = "NORMAL", + tpms = "SYSTEM_ACTIVE", + pressure = 35.00 + } } } } @@ -47,7 +60,8 @@ local rpc3 = { name = "UnsubscribeVehicleData", params = { engineOilLife = true, - fuelRange = true + fuelRange = true, + tirePressure = true } } @@ -59,6 +73,10 @@ local vehicleDataResults = { fuelRange = { dataType = "VEHICLEDATA_FUELRANGE", resultCode = "SUCCESS" + }, + tirePressure = { + dataType = "VEHICLEDATA_TIREPRESSURE", + resultCode = "SUCCESS" } } diff --git a/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua index e2d20044cd..5017412636 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua @@ -26,7 +26,8 @@ local rpc1 = { name = "SubscribeVehicleData", params = { engineOilLife = true, - fuelRange = true + fuelRange = true, + tirePressure = true } } @@ -39,6 +40,18 @@ local rpc2 = { type = "GASOLINE", range = 400.00 } + }, + tirePressure = { + leftFront = { + status = "NORMAL", + tpms = "SYSTEM_ACTIVE", + pressure = 35.00 + }, + rightFront = { + status = "NORMAL", + tpms = "SYSTEM_ACTIVE", + pressure = 35.00 + } } } } @@ -51,6 +64,10 @@ local vehicleDataResults = { fuelRange = { dataType = "VEHICLEDATA_FUELRANGE", resultCode = "SUCCESS" + }, + tirePressure = { + dataType = "VEHICLEDATA_TIREPRESSURE", + resultCode = "SUCCESS" } } @@ -59,7 +76,7 @@ local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["OnVehicleData"].parameters local newParams = {} for index, value in pairs(params) do - if not (("engineOilLife" == value) or ("fuelRange" == value)) then table.insert(newParams, value) end + if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value)) then table.insert(newParams, value) end end tbl.policy_table.functional_groupings["Emergency-1"].rpcs["OnVehicleData"].parameters = newParams end diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua index 85c83d1cbb..519fc629b6 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua @@ -23,7 +23,8 @@ local rpc = { name = "SubscribeVehicleData", params = { engineOilLife = true, - fuelRange = true + fuelRange = true, + tirePressure = true } } @@ -35,6 +36,10 @@ local vehicleDataResults = { fuelRange = { dataType = "VEHICLEDATA_FUELRANGE", resultCode = "SUCCESS" + }, + tirePressure = { + dataType = "VEHICLEDATA_TIREPRESSURE", + resultCode = "SUCCESS" } } diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index 8fa8a124bc..d111e36b24 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -24,7 +24,8 @@ local rpc = { name = "SubscribeVehicleData", params = { engineOilLife = true, - fuelRange = true + fuelRange = true, + tirePressure = true } } @@ -36,6 +37,10 @@ local vehicleDataResults = { fuelRange = { dataType = "VEHICLEDATA_FUELRANGE", resultCode = "DISALLOWED" + }, + tirePressure = { + dataType = "VEHICLEDATA_TIREPRESSURE", + resultCode = "DISALLOWED" } } @@ -44,7 +49,7 @@ local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["SubscribeVehicleData"].parameters local newParams = {} for index, value in pairs(params) do - if not (("engineOilLife" == value) or ("fuelRange" == value)) then table.insert(newParams, value) end + if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value)) then table.insert(newParams, value) end end tbl.policy_table.functional_groupings["Emergency-1"].rpcs["SubscribeVehicleData"].parameters = newParams end diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua index eccb9ec574..8a0991c33b 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua @@ -23,7 +23,8 @@ local rpc = { name = "SubscribeVehicleData", params = { engineOilLife = true, - fuelRange = true + fuelRange = true, + tirePressure = true } } @@ -35,6 +36,10 @@ local vehicleDataResults = { fuelRange = { dataType = "VEHICLEDATA_FUELRANGE", resultCode = "SUCCESS" + }, + tirePressure = { + dataType = "VEHICLEDATA_TIREPRESSURE", + resultCode = "SUCCESS" } } @@ -46,6 +51,10 @@ local vehicleDataResults2 = { fuelRange = { dataType = "VEHICLEDATA_FUELRANGE", resultCode = "DATA_ALREADY_SUBSCRIBED" + }, + tirePressure = { + dataType = "VEHICLEDATA_TIREPRESSURE", + resultCode = "DATA_ALREADY_SUBSCRIBED" } } diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua index 054deb1fd5..184745f351 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua @@ -24,7 +24,8 @@ local rpc_subscribe = { name = "SubscribeVehicleData", params = { engineOilLife = true, - fuelRange = true + fuelRange = true, + tirePressure = true } } @@ -32,7 +33,8 @@ local rpc_unsubscribe = { name = "UnsubscribeVehicleData", params = { engineOilLife = true, - fuelRange = true + fuelRange = true, + tirePressure = true } } @@ -44,6 +46,10 @@ local vehicleDataResults = { fuelRange = { dataType = "VEHICLEDATA_FUELRANGE", resultCode = "SUCCESS" + }, + tirePressure = { + dataType = "VEHICLEDATA_TIREPRESSURE", + resultCode = "SUCCESS" } } diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua index 47e1325538..368c604206 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua @@ -25,7 +25,8 @@ local rpc = { name = "UnsubscribeVehicleData", params = { engineOilLife = true, - fuelRange = true + fuelRange = true, + tirePressure = true } } @@ -37,6 +38,10 @@ local vehicleDataResults = { fuelRange = { dataType = "VEHICLEDATA_FUELRANGE", resultCode = "DATA_NOT_SUBSCRIBED" + }, + tirePressure = { + dataType = "VEHICLEDATA_TIREPRESSURE", + resultCode = "DATA_NOT_SUBSCRIBED" } } diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua index 9d489b41c7..4b550f319b 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua @@ -26,7 +26,8 @@ local rpc_subscribe = { name = "SubscribeVehicleData", params = { engineOilLife = true, - fuelRange = true + fuelRange = true, + tirePressure = true } } @@ -34,7 +35,8 @@ local rpc_unsubscribe = { name = "UnsubscribeVehicleData", params = { engineOilLife = true, - fuelRange = true + fuelRange = true, + tirePressure = true } } @@ -46,6 +48,10 @@ local vehicleDataResults = { fuelRange = { dataType = "VEHICLEDATA_FUELRANGE", resultCode = "SUCCESS" + }, + tirePressure = { + dataType = "VEHICLEDATA_TIREPRESSURE", + resultCode = "SUCCESS" } } @@ -57,6 +63,10 @@ local vehicleDataResults2 = { fuelRange = { dataType = "VEHICLEDATA_FUELRANGE", resultCode = "DATA_NOT_SUBSCRIBED" + }, + tirePressure = { + dataType = "VEHICLEDATA_TIREPRESSURE", + resultCode = "DATA_NOT_SUBSCRIBED" } } diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua index c8f09e1346..3144254c7c 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua @@ -24,7 +24,8 @@ local rpc = { name = "UnsubscribeVehicleData", params = { engineOilLife = true, - fuelRange = true + fuelRange = true, + tirePressure = true } } @@ -36,6 +37,10 @@ local vehicleDataResults = { fuelRange = { dataType = "VEHICLEDATA_FUELRANGE", resultCode = "DISALLOWED" + }, + tirePressure = { + dataType = "VEHICLEDATA_TIREPRESSURE", + resultCode = "DISALLOWED" } } @@ -44,7 +49,7 @@ local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["UnsubscribeVehicleData"].parameters local newParams = {} for index, value in pairs(params) do - if not (("engineOilLife" == value) or ("fuelRange" == value)) then table.insert(newParams, value) end + if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value)) then table.insert(newParams, value) end end tbl.policy_table.functional_groupings["Emergency-1"].rpcs["UnsubscribeVehicleData"].parameters = newParams end diff --git a/test_scripts/API/VehicleData/commonVehicleData.lua b/test_scripts/API/VehicleData/commonVehicleData.lua index 0070dd8e9f..7b82d0d301 100644 --- a/test_scripts/API/VehicleData/commonVehicleData.lua +++ b/test_scripts/API/VehicleData/commonVehicleData.lua @@ -91,6 +91,7 @@ local function ptu(self, app_id, ptu_update_func) for rpc in pairs(tbl.policy_table.functional_groupings["Emergency-1"].rpcs) do addParamToRPC(tbl, "Emergency-1", rpc, "engineOilLife") addParamToRPC(tbl, "Emergency-1", rpc, "fuelRange") + addParamToRPC(tbl, "Emergency-1", rpc, "tirePressure") end tbl.policy_table.app_policies[commonVehicleData.getMobileAppId(app_id)] = commonVehicleData.getGetVehicleDataConfig() end From 6b88572e0d549f183051b4de27dd533b58058b16 Mon Sep 17 00:00:00 2001 From: HSavynetska Date: Wed, 30 May 2018 13:24:13 +0300 Subject: [PATCH 412/681] Updated by comments --- ...by_reason_=_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/test_scripts/Defects/4_6/965_API_App_is_not_unregistered_by_reason_=_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua b/test_scripts/Defects/4_6/965_API_App_is_not_unregistered_by_reason_=_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua index f5e9c3bf66..8c89ad69b4 100644 --- a/test_scripts/Defects/4_6/965_API_App_is_not_unregistered_by_reason_=_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua +++ b/test_scripts/Defects/4_6/965_API_App_is_not_unregistered_by_reason_=_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua @@ -27,22 +27,20 @@ end local function listFilesRequests(self) for i = 1, 10 do - self.mobileSession1:SendRPC("ListFiles", {}) + self.mobileSession1:SendRPC("ListFiles", {}) end self.mobileSession1:ExpectResponse("ListFiles") :Do(function(_, data) - if - data.payload.resultCode == "SUCCESS" then + if data.payload.resultCode == "SUCCESS" then return true - elseif - data.payload.resultCode == "APPLICATION_NOT_REGISTERED" then + elseif data.payload.resultCode == "APPLICATION_NOT_REGISTERED" then return true else return false, "Received unexpected resultCode " .. data.payload.resultCode end end) - :Times(AtMost(10)) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {appID = common.getHMIAppId(pAppId), unexpectedDisconnect = false}) - self.mobileSession1:ExpectNotification("OnAppInterfaceUnregistered", {{reason = reason }}) + :Times(Between(1,10)) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {appID = common.getHMIAppId(), unexpectedDisconnect = false}) + self.mobileSession1:ExpectNotification("OnAppInterfaceUnregistered", { reason = "REQUEST_WHILE_IN_NONE_HMI_LEVEL" }) end --[[ Scenario ]] From fe67fef656d169b991a24cb506fcb4de8ce13964 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 31 May 2018 12:57:21 +0300 Subject: [PATCH 413/681] Removed redundant new line in test set --- test_sets/mobile_projection_2.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/test_sets/mobile_projection_2.txt b/test_sets/mobile_projection_2.txt index d6daf0d1fb..fce382a1d1 100644 --- a/test_sets/mobile_projection_2.txt +++ b/test_sets/mobile_projection_2.txt @@ -21,4 +21,3 @@ ./test_scripts/MobileProjection/Phase2/021_two_apps_and_deactivation.lua ./test_scripts/MobileProjection/Phase2/022_two_apps_proj_media_and_deactivation_streaming.lua ./test_scripts/MobileProjection/Phase2/023_two_apps_navi_comm_and_deactivation_streaming.lua - From d09a9fd91386225af9229644fa691f9c3e7bfaf2 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Thu, 31 May 2018 10:34:50 -0400 Subject: [PATCH 414/681] Remove extra new lines --- .../API/VehicleData/GetVehicleData/001_Success_flow.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua index b18a9f1445..ee90d4c76f 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua @@ -51,8 +51,6 @@ local vehicleDataValues = { } } - - --[[ Local Functions ]] local function processRPCSuccess(self) local mobileSession = common.getMobileSession(self, 1) From cbb10737739f024a3160fe94e4641b148cf9b717 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 1 Jun 2018 09:55:32 +0300 Subject: [PATCH 415/681] Add additional script for GST --- .../025_GetSystemTime_is_sent_later.lua | 57 +++++++++++++++++++ test_sets/get_system_time.txt | 1 + 2 files changed, 58 insertions(+) create mode 100644 test_scripts/Security/GetSystemTime/025_GetSystemTime_is_sent_later.lua diff --git a/test_scripts/Security/GetSystemTime/025_GetSystemTime_is_sent_later.lua b/test_scripts/Security/GetSystemTime/025_GetSystemTime_is_sent_later.lua new file mode 100644 index 0000000000..e0c952deb0 --- /dev/null +++ b/test_scripts/Security/GetSystemTime/025_GetSystemTime_is_sent_later.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) HMI does not send BC.OnSystemTimeReady notification to SDL during initialization +-- 2) Mobile and sdl certificates are valid +-- 3) Mobile app starts secure service +-- 4) SDL respond with NACK +-- 5) HMI sends BC.OnSystemTimeReady notification +-- 6) Mobile app starts secure service again +-- SDL must: +-- 1) Send GetSystemTime request to HMI (and HMI replies with valid system time) +-- 2) Start secure service: Handshake is finished with frameInfo = START_SERVICE_ACK, encryption = true +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Security/GetSystemTime/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local serviceId = 7 + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt +end + +local function sendOnSystemTimeReady() + common.getHMIConnection():SendNotification("BasicCommunication.OnSystemTimeReady") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI without BC.OnSystemTimeReady, connect Mobile, start Session", common.start, { false }) + +runner.Title("Test") + +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate with certificate", common.policyTableUpdate, { ptUpdate }) +runner.Step("Handshake without BC.GetSystemTime request from SDL", common.startServiceSecured, { + { frameInfo = common.frameInfo.START_SERVICE_NACK, encryption = false }, serviceId, 0 }) +runner.Step("Send BC.OnSystemTimeReady from HMI", sendOnSystemTimeReady) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, { + { frameInfo = common.frameInfo.START_SERVICE_ACK, encryption = true }, serviceId, 1 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_sets/get_system_time.txt b/test_sets/get_system_time.txt index 1d30b388b0..e5306550b2 100644 --- a/test_sets/get_system_time.txt +++ b/test_sets/get_system_time.txt @@ -22,3 +22,4 @@ ./test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua ./test_scripts/Security/GetSystemTime/023_GetSystemTime_without_response_from_HMI.lua ./test_scripts/Security/GetSystemTime/024_GetSystemTime_with_response_from_HMI_in_9_sec.lua +./test_scripts/Security/GetSystemTime/025_GetSystemTime_is_sent_later.lua From 920be50ff8698645ae2aa7c5cb6b385dd87b4e47 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 1 Jun 2018 11:39:02 +0300 Subject: [PATCH 416/681] Remove duplicated test set --- test_sets/expanded_proprietary_data_exchange.txt | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 test_sets/expanded_proprietary_data_exchange.txt diff --git a/test_sets/expanded_proprietary_data_exchange.txt b/test_sets/expanded_proprietary_data_exchange.txt deleted file mode 100644 index 856434e0f9..0000000000 --- a/test_sets/expanded_proprietary_data_exchange.txt +++ /dev/null @@ -1,15 +0,0 @@ -./test_scripts/API/Expanded_proprietary_data_exchange/001_SystemRequest_with_OEM_SPECIFIC_requestSubType.lua -./test_scripts/API/Expanded_proprietary_data_exchange/002_onSystemRequest_with_OEM_SPECIFIC_requestSubType.lua -./test_scripts/API/Expanded_proprietary_data_exchange/003_requestSubType_with_requestType_PROPRIETARY.lua -./test_scripts/API/Expanded_proprietary_data_exchange/004_requestSubType_with_requestType_HTTP.lua -./test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_ptu.lua -./test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_ptu.lua -./test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_ptu.lua -./test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_with_value_list_in_requestSubType.lua -./test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_with_empty_array_in_requestSubType.lua -./test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_without_requestSubType.lua -./test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_by_fist_registration.lua -./test_scripts/API/Expanded_proprietary_data_exchange/012_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua -./test_scripts/API/Expanded_proprietary_data_exchange/013_System_onSystemRequest_requestType_with_empty_array_in_ptu.lua -./test_scripts/API/Expanded_proprietary_data_exchange/014_System_onSystemRequest_requestType_with_list_of_values_ptu.lua -./test_scripts/API/Expanded_proprietary_data_exchange/015_System_onSystemRequest_requestType_without_parameter_in_pt.lua From e4e1d24fe28d65758b0657681cbe5472ab09fa37 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 6 Jun 2018 12:14:29 +0300 Subject: [PATCH 417/681] Add additional test scripts to check absence of parameters in PreloadedPT --- ...ut_parameter_in_preloadedPT_DISALLOWED.lua | 82 ++++++++++++++++++ ...ut_parameter_in_preloadedPT_DISALLOWED.lua | 83 +++++++++++++++++++ ...e_design_for_proprietary_data_exchange.txt | 2 + 3 files changed, 167 insertions(+) create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/016_System_onSystemRequest_requestType_without_parameter_in_preloadedPT_DISALLOWED.lua create mode 100644 test_scripts/API/Expanded_proprietary_data_exchange/017_System_onSystemRequest_requestSubType_without_parameter_in_preloadedPT_DISALLOWED.lua diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/016_System_onSystemRequest_requestType_without_parameter_in_preloadedPT_DISALLOWED.lua b/test_scripts/API/Expanded_proprietary_data_exchange/016_System_onSystemRequest_requestType_without_parameter_in_preloadedPT_DISALLOWED.lua new file mode 100644 index 0000000000..81f8669dd8 --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/016_System_onSystemRequest_requestType_without_parameter_in_preloadedPT_DISALLOWED.lua @@ -0,0 +1,82 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0083-Expandable-design-for-proprietary-data-exchange.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1. requestType is absent in PreloadedPT +-- 2. SDL receives the following messages with 'requestType' value: +-- 'SystemRequest' request from mobile app +-- 'OnSystemRequest' notification from HMI +-- SDL does: +-- 1. Respond with DISALLOWED to app +-- 2. Not transfer 'OnSystemRequest' notification to app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local utils = require('user_modules/utils') +local json = require("modules/json") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local file = "./files/action.png" +local params = { + requestType = "OEM_SPECIFIC", + fileName = "action.png" +} +local preloadedPT = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + +--[[ Local Functions ]] +local function backupPreloadedPT() + commonPreconditions:BackupFile(preloadedPT) +end + +local function updatePreloadedPT() + local preloadedFile = commonPreconditions:GetPathToSDL() .. preloadedPT + local pt = utils.jsonFileToTable(preloadedFile) + pt.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + pt.policy_table.app_policies["default"].RequestType = nil + utils.tableToJsonFile(pt, preloadedFile) +end + +local function restorePreloadedPT() + commonPreconditions:RestoreFile(preloadedPT) +end + +local function systemRequest() + local cid = common.getMobileSession():SendRPC("SystemRequest", params, file) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Times(0) + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function onSystemRequest() + common.getHMIConnection():SendNotification("BasicCommunication.OnSystemRequest", params) + common.getMobileSession():ExpectNotification("OnSystemRequest") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Back-up PreloadedPT", backupPreloadedPT) +runner.Step("Update PreloadedPT", updatePreloadedPT) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerApp) + +runner.Title("Test") +runner.Step("SystemRequest with requestType OEM_SPECIFIC_DISALLOWED", systemRequest) +runner.Step("OnSystemRequest with requestType OEM_SPECIFIC_no_transfer_to_app", onSystemRequest) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) +runner.Step("Restore PreloadedPT", restorePreloadedPT) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/017_System_onSystemRequest_requestSubType_without_parameter_in_preloadedPT_DISALLOWED.lua b/test_scripts/API/Expanded_proprietary_data_exchange/017_System_onSystemRequest_requestSubType_without_parameter_in_preloadedPT_DISALLOWED.lua new file mode 100644 index 0000000000..0ea5fee422 --- /dev/null +++ b/test_scripts/API/Expanded_proprietary_data_exchange/017_System_onSystemRequest_requestSubType_without_parameter_in_preloadedPT_DISALLOWED.lua @@ -0,0 +1,83 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0083-Expandable-design-for-proprietary-data-exchange.md +-- User story:TBD +-- Use case:TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1. requestSubType is absent in PreloadedPT +-- 2. SDL receives the following messages with 'requestSubType' value: +-- 'SystemRequest' request from mobile app +-- 'OnSystemRequest' notification from HMI +-- SDL does: +-- 1. Respond with DISALLOWED to app +-- 2. Not transfer 'OnSystemRequest' notification to app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local utils = require('user_modules/utils') +local json = require("modules/json") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local file = "./files/action.png" +local params = { + requestType = "OEM_SPECIFIC", + requestSubType = "someValue", + fileName = "action.png" +} +local preloadedPT = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + +--[[ Local Functions ]] +local function backupPreloadedPT() + commonPreconditions:BackupFile(preloadedPT) +end + +local function updatePreloadedPT() + local preloadedFile = commonPreconditions:GetPathToSDL() .. preloadedPT + local pt = utils.jsonFileToTable(preloadedFile) + pt.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + pt.policy_table.app_policies["default"].RequestSubType = nil + utils.tableToJsonFile(pt, preloadedFile) +end + +local function restorePreloadedPT() + commonPreconditions:RestoreFile(preloadedPT) +end + +local function systemRequest() + local cid = common.getMobileSession():SendRPC("SystemRequest", params, file) + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Times(0) + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function onSystemRequest() + common.getHMIConnection():SendNotification("BasicCommunication.OnSystemRequest", params) + common.getMobileSession():ExpectNotification("OnSystemRequest") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Back-up PreloadedPT", backupPreloadedPT) +runner.Step("Update PreloadedPT", updatePreloadedPT) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerApp) + +runner.Title("Test") +runner.Step("SystemRequest with requestSubType_DISALLOWED", systemRequest) +runner.Step("OnSystemRequest with requestSubType_no_transfer_to_app", onSystemRequest) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) +runner.Step("Restore PreloadedPT", restorePreloadedPT) diff --git a/test_sets/expandable_design_for_proprietary_data_exchange.txt b/test_sets/expandable_design_for_proprietary_data_exchange.txt index 856434e0f9..0d8cbb7eba 100644 --- a/test_sets/expandable_design_for_proprietary_data_exchange.txt +++ b/test_sets/expandable_design_for_proprietary_data_exchange.txt @@ -13,3 +13,5 @@ ./test_scripts/API/Expanded_proprietary_data_exchange/013_System_onSystemRequest_requestType_with_empty_array_in_ptu.lua ./test_scripts/API/Expanded_proprietary_data_exchange/014_System_onSystemRequest_requestType_with_list_of_values_ptu.lua ./test_scripts/API/Expanded_proprietary_data_exchange/015_System_onSystemRequest_requestType_without_parameter_in_pt.lua +./test_scripts/API/Expanded_proprietary_data_exchange/016_System_onSystemRequest_requestType_without_parameter_in_preloadedPT_DISALLOWED.lua +./test_scripts/API/Expanded_proprietary_data_exchange/017_System_onSystemRequest_requestSubType_without_parameter_in_preloadedPT_DISALLOWED.lua From e9be6220556b654220078af142d4be7df8440071 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 7 Jun 2018 12:53:36 +0300 Subject: [PATCH 418/681] Add description to test scripts --- .../001_audioStreamingState_001-009.lua | 9 +++++++- .../002_audioStreamingState_010-068.lua | 12 +++++++++- .../003_audioStreamingState_069-103.lua | 10 +++++++- .../004_audioStreamingState_104-110.lua | 9 +++++++- .../005_audioStreamingState_111-118.lua | 14 ++++++++++- .../006_videoStreamingState_001-006.lua | 9 +++++++- .../007_videoStreamingState_007-030.lua | 12 +++++++++- .../008_videoStreamingState_031-042.lua | 10 +++++++- .../Phase2/009_hmiLevel_001-032.lua | 11 ++++++++- ...0_single_app_audio_and_video_streaming.lua | 10 +++++++- .../Phase2/011_single_app_video_streaming.lua | 10 +++++++- .../Phase2/012_single_app_deactivation.lua | 11 ++++++++- .../Phase2/013_two_apps_interaction.lua | 15 +++++++++++- ...o_010-068_video_007-030_states_LIMITED.lua | 13 ++++++++++- ..._097-103_video_031-038_states_not_FULL.lua | 14 ++++++++++- .../Phase2/016_BACKGROUND_not_changed.lua | 14 ++++++++++- .../Phase2/017_two_apps_and_one_app_exits.lua | 12 +++++++++- .../018_two_apps_and_one_app_unregister.lua | 11 ++++++++- .../Phase2/019_SDL_stop_audio_video.lua | 16 ++++++++++++- .../020_different_types_apps_interactions.lua | 23 ++++++++++++++++++- .../Phase2/021_two_apps_and_deactivation.lua | 16 ++++++++++++- ..._proj_media_and_deactivation_streaming.lua | 16 ++++++++++++- ...s_navi_comm_and_deactivation_streaming.lua | 16 ++++++++++++- 23 files changed, 270 insertions(+), 23 deletions(-) diff --git a/test_scripts/MobileProjection/Phase2/001_audioStreamingState_001-009.lua b/test_scripts/MobileProjection/Phase2/001_audioStreamingState_001-009.lua index c0e53bc892..a6ac7f4477 100644 --- a/test_scripts/MobileProjection/Phase2/001_audioStreamingState_001-009.lua +++ b/test_scripts/MobileProjection/Phase2/001_audioStreamingState_001-009.lua @@ -1,5 +1,12 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) Mobile app is activated +-- SDL must: +-- 1) Send OnHMIStatus notification with appropriate value of 'audioStreamingState' parameter +-- Particular value depends on app's 'appHMIType' and 'isMediaApplication' flag, and described in 'testCases' table below --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/002_audioStreamingState_010-068.lua b/test_scripts/MobileProjection/Phase2/002_audioStreamingState_010-068.lua index 52f32051b2..1792bbf569 100644 --- a/test_scripts/MobileProjection/Phase2/002_audioStreamingState_010-068.lua +++ b/test_scripts/MobileProjection/Phase2/002_audioStreamingState_010-068.lua @@ -1,5 +1,15 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps: +-- app1: is audio source ('audioStreamingState' = AUDIBLE) +-- app2: is not audio source ('audioStreamingState' = NOT_AUDIBLE) +-- 2) Mobile app2 is activated +-- SDL must: +-- 1) Send OnHMIStatus notification for both apps with appropriate value of 'audioStreamingState' parameter +-- Particular value depends on app's 'appHMIType' and 'isMediaApplication' flag, and described in 'testCases' table below --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/003_audioStreamingState_069-103.lua b/test_scripts/MobileProjection/Phase2/003_audioStreamingState_069-103.lua index b77925d9bc..91cbc997c2 100644 --- a/test_scripts/MobileProjection/Phase2/003_audioStreamingState_069-103.lua +++ b/test_scripts/MobileProjection/Phase2/003_audioStreamingState_069-103.lua @@ -1,5 +1,13 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) Mobile app is audio source ('audioStreamingState' = AUDIBLE) +-- 2) One of the event below is received from HMI within 'BC.OnEventChanged' notification: +-- PHONE_CALL, EMERGENCY_EVENT, AUDIO_SOURCE, EMBEDDED_NAVI, DEACTIVATE_HMI +-- SDL must: +-- 1) Send OnHMIStatus notification with 'audioStreamingState' = NOT_AUDIBLE --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/004_audioStreamingState_104-110.lua b/test_scripts/MobileProjection/Phase2/004_audioStreamingState_104-110.lua index a76c10d132..61ec6862f7 100644 --- a/test_scripts/MobileProjection/Phase2/004_audioStreamingState_104-110.lua +++ b/test_scripts/MobileProjection/Phase2/004_audioStreamingState_104-110.lua @@ -1,5 +1,12 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) Mobile app is audio source ('audioStreamingState' = AUDIBLE) +-- 2) And TTS is started +-- SDL must: +-- 1) Send OnHMIStatus notification with 'audioStreamingState' = ATTENUATED --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/005_audioStreamingState_111-118.lua b/test_scripts/MobileProjection/Phase2/005_audioStreamingState_111-118.lua index 61e801706f..507ca57a0b 100644 --- a/test_scripts/MobileProjection/Phase2/005_audioStreamingState_111-118.lua +++ b/test_scripts/MobileProjection/Phase2/005_audioStreamingState_111-118.lua @@ -1,5 +1,17 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps: +-- app1: NAVIGATION, is audio source ('audioStreamingState' = AUDIBLE) +-- app2: MEDIA, is audio source ('audioStreamingState' = AUDIBLE) +-- 2) And NAVI app starts streaming +-- SDL must: +-- 1) Not change the value of 'audioStreamingState' parameter for NAVI app +-- 2) Change 'audioStreamingState' parameter for MEDIA app to: +-- ATTENUATED - in case if MixingAudioSupported = true +-- NOT_AUDIBLE - in case if MixingAudioSupported = false --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/006_videoStreamingState_001-006.lua b/test_scripts/MobileProjection/Phase2/006_videoStreamingState_001-006.lua index 65264f4d50..3d9fbf6e87 100644 --- a/test_scripts/MobileProjection/Phase2/006_videoStreamingState_001-006.lua +++ b/test_scripts/MobileProjection/Phase2/006_videoStreamingState_001-006.lua @@ -1,5 +1,12 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) Mobile app is activated +-- SDL must: +-- 1) Send OnHMIStatus notification with appropriate value of 'videoStreamingState' parameter +-- Particular value depends on app's 'appHMIType' and described in 'testCases' table below --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/007_videoStreamingState_007-030.lua b/test_scripts/MobileProjection/Phase2/007_videoStreamingState_007-030.lua index a920413597..d0ce1e4fec 100644 --- a/test_scripts/MobileProjection/Phase2/007_videoStreamingState_007-030.lua +++ b/test_scripts/MobileProjection/Phase2/007_videoStreamingState_007-030.lua @@ -1,5 +1,15 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps: +-- app1: is video source ('videoStreamingState' = STREAMABLE) +-- app2: is not video source ('audioStreamingState' = NOT_STREAMABLE) +-- 2) Mobile app2 is activated +-- SDL must: +-- 1) Send OnHMIStatus notification for both apps with appropriate value of 'videoStreamingState' parameter +-- Particular value depends on app's 'appHMIType' and described in 'testCases' table below --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-042.lua b/test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-042.lua index 94efff4d07..175097f732 100644 --- a/test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-042.lua +++ b/test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-042.lua @@ -1,5 +1,13 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) Mobile app is video source ('videoStreamingState' = STREAMABLE) +-- 2) One of the event below is received from HMI within 'BC.OnEventChanged' notification: +-- DEACTIVATE_HMI, AUDIO_SOURCE, EMBEDDED_NAVI +-- SDL must: +-- 1) Send OnHMIStatus notification with 'videoStreamingState' = NOT_STREAMABLE --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/009_hmiLevel_001-032.lua b/test_scripts/MobileProjection/Phase2/009_hmiLevel_001-032.lua index 2bf4e7672b..d4bb0e3af2 100644 --- a/test_scripts/MobileProjection/Phase2/009_hmiLevel_001-032.lua +++ b/test_scripts/MobileProjection/Phase2/009_hmiLevel_001-032.lua @@ -1,5 +1,14 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) Mobile app is in some state +-- 2) Mobile app is moving to another state by one of the events: +-- App activation, App deactivation, Deactivation of HMI, User exit +-- SDL must: +-- 1) Send (or not send) OnHMIStatus notification with appropriate value of 'hmiLevel' parameter +-- Particular behavior and value depends on initial state and event, and described in 'testCases' table below --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/010_single_app_audio_and_video_streaming.lua b/test_scripts/MobileProjection/Phase2/010_single_app_audio_and_video_streaming.lua index 2351f504fd..ef77b2408c 100644 --- a/test_scripts/MobileProjection/Phase2/010_single_app_audio_and_video_streaming.lua +++ b/test_scripts/MobileProjection/Phase2/010_single_app_audio_and_video_streaming.lua @@ -1,5 +1,13 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There is a mobile app which is audio/video source +-- 2) And this app starts Audio/Video streaming +-- 3) And this app stops Audio/Video streaming +-- SDL must: +-- 1) Not send 'OnHMIStatus' when Audio/Video streaming is started or stopped --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/011_single_app_video_streaming.lua b/test_scripts/MobileProjection/Phase2/011_single_app_video_streaming.lua index 1b0fb9f85f..54307c3c80 100644 --- a/test_scripts/MobileProjection/Phase2/011_single_app_video_streaming.lua +++ b/test_scripts/MobileProjection/Phase2/011_single_app_video_streaming.lua @@ -1,5 +1,13 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There is a mobile app which is video source +-- 2) And this app starts Video streaming +-- 3) And this app stops Video streaming +-- SDL must: +-- 1) Not send 'OnHMIStatus' when Video streaming is started or stopped --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/012_single_app_deactivation.lua b/test_scripts/MobileProjection/Phase2/012_single_app_deactivation.lua index 8bfab5037b..d6f8b98711 100644 --- a/test_scripts/MobileProjection/Phase2/012_single_app_deactivation.lua +++ b/test_scripts/MobileProjection/Phase2/012_single_app_deactivation.lua @@ -1,5 +1,14 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There is a mobile app which is video source +-- 2) And this app starts Audio/Video streaming +-- 3) And this app is deactivated +-- SDL must: +-- 1) Not change the value of 'audioStreamingState' and 'videoStreamingState' parameters in 'OnHMIStatus' +-- 2) Change the value of 'hmiLevel' to LIMITED --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/013_two_apps_interaction.lua b/test_scripts/MobileProjection/Phase2/013_two_apps_interaction.lua index 87e05d3e6d..583b2b5b06 100644 --- a/test_scripts/MobileProjection/Phase2/013_two_apps_interaction.lua +++ b/test_scripts/MobileProjection/Phase2/013_two_apps_interaction.lua @@ -1,5 +1,18 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) Mobile app1 is registered and activated +-- 2) Mobile app2 is registered +-- 3) Mobile app1 is deactivated +-- 4) Mobile app2 is activated +-- SDL must: +-- 1) Send 'OnHMIStatus' notification to app1 with appropriate values for 'audioStreamingState' +-- and 'videoStreamingState' parameters when app1 is deactivated +-- 2) Send 'OnHMIStatus' notification to app1 and app2 with appropriate values for 'audioStreamingState' +-- and 'videoStreamingState' parameters when app2 is activated +-- Particular values depends on app's 'appHMIType' and described in 'testCases' table below --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/014_audio_010-068_video_007-030_states_LIMITED.lua b/test_scripts/MobileProjection/Phase2/014_audio_010-068_video_007-030_states_LIMITED.lua index 560232c910..ce60ee0e35 100644 --- a/test_scripts/MobileProjection/Phase2/014_audio_010-068_video_007-030_states_LIMITED.lua +++ b/test_scripts/MobileProjection/Phase2/014_audio_010-068_video_007-030_states_LIMITED.lua @@ -1,5 +1,16 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps: +-- app1: is video source ('videoStreamingState' = STREAMABLE) +-- app2: is not video source ('audioStreamingState' = NOT_STREAMABLE) +-- 2) Mobile app1 is deactivated +-- 3) Mobile app2 is activated +-- SDL must: +-- 1) Send OnHMIStatus notification for both apps with appropriate value of 'videoStreamingState' parameter +-- Particular value depends on app's 'appHMIType' and described in 'testCases' table below --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/015_audio_083-089_097-103_video_031-038_states_not_FULL.lua b/test_scripts/MobileProjection/Phase2/015_audio_083-089_097-103_video_031-038_states_not_FULL.lua index a4ffdb23b1..59dcd01b8c 100644 --- a/test_scripts/MobileProjection/Phase2/015_audio_083-089_097-103_video_031-038_states_not_FULL.lua +++ b/test_scripts/MobileProjection/Phase2/015_audio_083-089_097-103_video_031-038_states_not_FULL.lua @@ -1,5 +1,17 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) Mobile app is audio/video source +-- 2) Mobile app is deactivated +-- 3) One of the event below is received from HMI within 'BC.OnEventChanged' (isActive = true) notification: +-- DEACTIVATE_HMI, AUDIO_SOURCE +-- 4) The same event notification (isActive = false) is received +-- SDL must: +-- 1) Send OnHMIStatus notification with 'audioStreamingState' = NOT_AUDIBLE and 'videoStreamingState' = NOT_STREAMABLE +-- 2) Restore original state of mobile app +-- Particular value depends on app's 'appHMIType' and described in 'testCases' table below --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/016_BACKGROUND_not_changed.lua b/test_scripts/MobileProjection/Phase2/016_BACKGROUND_not_changed.lua index d88c309cc6..4112d45737 100644 --- a/test_scripts/MobileProjection/Phase2/016_BACKGROUND_not_changed.lua +++ b/test_scripts/MobileProjection/Phase2/016_BACKGROUND_not_changed.lua @@ -1,5 +1,17 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps registered: +-- app1: is not audio/video source +-- app2: is NAVIGATION +-- 2) Mobile app1 is activated +-- 3) Mobile app1 is deactivated (moved to BACKGROUND) +-- 4) Mobile app2 is activated +-- SDL must: +-- 1) Not send 'OnHMIStatus' notification to app1 +-- 2) Send 'OnHMIStatus' notification to app2 with 'hmiLevel' = FULL --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/017_two_apps_and_one_app_exits.lua b/test_scripts/MobileProjection/Phase2/017_two_apps_and_one_app_exits.lua index ad803d5815..b826c6c882 100644 --- a/test_scripts/MobileProjection/Phase2/017_two_apps_and_one_app_exits.lua +++ b/test_scripts/MobileProjection/Phase2/017_two_apps_and_one_app_exits.lua @@ -1,5 +1,15 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps registered: PROJECTION and NAVIGATION +-- 2) Mobile app1 is activated +-- 3) Mobile app2 is activated +-- 4) HMI sends 'BC.OnExitApplication' (USER_EXIT) for app2 +-- SDL must: +-- 1) Not send 'OnHMIStatus' notification to app1 +-- 2) Send 'OnHMIStatus' notification to app2 with 'hmiLevel' = NONE --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/018_two_apps_and_one_app_unregister.lua b/test_scripts/MobileProjection/Phase2/018_two_apps_and_one_app_unregister.lua index 4c58ae32a9..ac1013fe87 100644 --- a/test_scripts/MobileProjection/Phase2/018_two_apps_and_one_app_unregister.lua +++ b/test_scripts/MobileProjection/Phase2/018_two_apps_and_one_app_unregister.lua @@ -1,5 +1,14 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps registered: PROJECTION and NAVIGATION +-- 2) Mobile app1 is activated +-- 3) Mobile app2 is activated +-- 4) Mobile App2 is unregistered +-- SDL must: +-- 1) Not send 'OnHMIStatus' notification to app1 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua b/test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua index 0795e213bc..67b8c2ce32 100644 --- a/test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua +++ b/test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua @@ -1,5 +1,19 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There is a mobile app which is audio/video source +-- 2) And this app starts Audio/Video streaming +-- 3) And HMI sends 'BC.OnEventChanged' (AUDIO_SOURCE) +-- 4) And app still continue streaming +-- SDL must: +-- 1) Send to HMI: +-- Navigation.OnAudioDataStreaming(available = false) +-- Navigation.OnVideoDataStreaming(available = false) +-- Navigation.StopAudioStream +-- Navigation.StopStream +-- 2) Send End Audio/Video service control messages to app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/020_different_types_apps_interactions.lua b/test_scripts/MobileProjection/Phase2/020_different_types_apps_interactions.lua index 29b8fffe3b..de6daf3164 100644 --- a/test_scripts/MobileProjection/Phase2/020_different_types_apps_interactions.lua +++ b/test_scripts/MobileProjection/Phase2/020_different_types_apps_interactions.lua @@ -1,5 +1,26 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 4 mobile apps: +-- MEDIA (isMediaApplication = true) +-- PROJECTION (isMediaApplication = false) +-- DEFAULT (isMediaApplication = false) +-- NAVIGATION (isMediaApplication = true) +-- 2) And there is the following sequence of actions: +-- Activation of app1 +-- Activation of app2 +-- Activation of app3 +-- Activation of app4 +-- HMI sends PHONE_CALL event (active/inactive) +-- Activation of app2 +-- HMI sends EMBEDDED_NAVI event (active/inactive) +-- SDL must: +-- 1) Send (or not send) 'OnHMIStatus' notification to all apps with appropriate value for +-- 'hmiLevel', 'audioStreamingState' and 'videoStreamingState' parameters +-- Particular values depends on app's 'appHMIType', 'isMediaApplication' flag, current app's state +-- and described in 'testCases' table below --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/021_two_apps_and_deactivation.lua b/test_scripts/MobileProjection/Phase2/021_two_apps_and_deactivation.lua index b8e99cc9cf..71a8fe7f0e 100644 --- a/test_scripts/MobileProjection/Phase2/021_two_apps_and_deactivation.lua +++ b/test_scripts/MobileProjection/Phase2/021_two_apps_and_deactivation.lua @@ -1,5 +1,19 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps: +-- app1: PROJECTION, isMediaApplication = true +-- app2: MEDIA, isMediaApplication = true +-- 2) And app1 activated and then deactivated +-- 3) And app2 activated and then deactivated +-- SDL must: (in case of deactivation of app1) +-- 1) Send 'OnHMIStatus' notification to app1: 'audioStreamingState' = AUDIBLE and 'videoStreamingState' = STREAMABLE +-- 2) Not send 'OnHMIStatus' notification to app2 +-- SDL must: (in case of deactivation of app2) +-- 1) Not send 'OnHMIStatus' notification to app1 +-- 2) Send 'OnHMIStatus' notification to app2: 'audioStreamingState' = AUDIBLE and 'videoStreamingState' = NOT_STREAMABLE --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/022_two_apps_proj_media_and_deactivation_streaming.lua b/test_scripts/MobileProjection/Phase2/022_two_apps_proj_media_and_deactivation_streaming.lua index 61972858e5..8f67e004ef 100644 --- a/test_scripts/MobileProjection/Phase2/022_two_apps_proj_media_and_deactivation_streaming.lua +++ b/test_scripts/MobileProjection/Phase2/022_two_apps_proj_media_and_deactivation_streaming.lua @@ -1,5 +1,19 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps: +-- app1: PROJECTION, isMediaApplication = true +-- app2: MEDIA, isMediaApplication = true +-- 2) And app1 activated, starts Video streaming and then deactivated +-- 3) And app2 activated and then deactivated +-- SDL must: (in case of deactivation of app1) +-- 1) Send 'OnHMIStatus' notification to app1: 'audioStreamingState' = AUDIBLE and 'videoStreamingState' = STREAMABLE +-- 2) Not send 'OnHMIStatus' notification to app2 +-- SDL must: (in case of deactivation of app2) +-- 1) Not send 'OnHMIStatus' notification to app1 +-- 2) Send 'OnHMIStatus' notification to app2: 'audioStreamingState' = AUDIBLE and 'videoStreamingState' = NOT_STREAMABLE --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') diff --git a/test_scripts/MobileProjection/Phase2/023_two_apps_navi_comm_and_deactivation_streaming.lua b/test_scripts/MobileProjection/Phase2/023_two_apps_navi_comm_and_deactivation_streaming.lua index 2f9da6498f..4f70ce5872 100644 --- a/test_scripts/MobileProjection/Phase2/023_two_apps_navi_comm_and_deactivation_streaming.lua +++ b/test_scripts/MobileProjection/Phase2/023_two_apps_navi_comm_and_deactivation_streaming.lua @@ -1,5 +1,19 @@ --------------------------------------------------------------------------------------------------- --- Issue: +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps: +-- app1: NAVIGATION, isMediaApplication = true +-- app2: COMMUNICATION, isMediaApplication = false +-- 2) And app1 activated, starts Video streaming and then deactivated +-- 3) And app2 activated and then deactivated +-- SDL must: (in case of deactivation of app1) +-- 1) Send 'OnHMIStatus' notification to app1: 'audioStreamingState' = AUDIBLE and 'videoStreamingState' = STREAMABLE +-- 2) Not send 'OnHMIStatus' notification to app2 +-- SDL must: (in case of deactivation of app2) +-- 1) Not send 'OnHMIStatus' notification to app1 +-- 2) Send 'OnHMIStatus' notification to app2: 'audioStreamingState' = ATTENUATED and 'videoStreamingState' = NOT_STREAMABLE --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/MobileProjection/Phase2/common') From 98407ca6e3a2485a0477787831529b45d1133f49 Mon Sep 17 00:00:00 2001 From: Jacob Keeler Date: Fri, 8 Jun 2018 07:38:12 -0700 Subject: [PATCH 419/681] Move tests and update for Core branch changes --- test_scripts/API/TTSChunks/common.lua | 23 ----- .../SDL4_0_Common_cases.lua | 0 .../{SDL4.0 => SDL4_0}/SDL4_0_Icons.lua | 0 .../SDL4_0_JSON_Validation.lua | 0 .../SDL4_0_OnSystemRequest_LAUNCH_APP.lua | 0 .../SDL4_0_OnSystemRequest_QUERY_APPS.lua | 0 .../SDL4_0_UpdateAppList.lua | 0 .../SDL_4.0_Language_parameter.lua | 0 .../TTSChunks/001_RegisterAppInterface.lua | 2 +- .../TTSChunks/002_SetGlobalProperties.lua | 69 +++++++++---- .../TTSChunks/003_OnAppRegistered.lua | 11 ++- .../{API => SDL4_6}/TTSChunks/004_Alert.lua | 43 ++++++-- .../TTSChunks/005_ChangeRegistration.lua | 47 ++++++--- .../TTSChunks/006_PerformInteraction.lua | 99 ++++++++++++++----- .../{API => SDL4_6}/TTSChunks/007_Speak.lua | 43 ++++++-- .../TTSChunks/008_PerformAudioPassThru.lua | 51 +++++++--- .../TTSChunks/009_AlertManeuver.lua | 43 ++++++-- test_scripts/SDL4_6/TTSChunks/common.lua | 68 +++++++++++++ test_sets/audio_file_playback_tts_chunks.txt | 18 ++-- 19 files changed, 391 insertions(+), 126 deletions(-) delete mode 100644 test_scripts/API/TTSChunks/common.lua rename test_scripts/{SDL4.0 => SDL4_0}/SDL4_0_Common_cases.lua (100%) rename test_scripts/{SDL4.0 => SDL4_0}/SDL4_0_Icons.lua (100%) rename test_scripts/{SDL4.0 => SDL4_0}/SDL4_0_JSON_Validation.lua (100%) rename test_scripts/{SDL4.0 => SDL4_0}/SDL4_0_OnSystemRequest_LAUNCH_APP.lua (100%) rename test_scripts/{SDL4.0 => SDL4_0}/SDL4_0_OnSystemRequest_QUERY_APPS.lua (100%) rename test_scripts/{SDL4.0 => SDL4_0}/SDL4_0_UpdateAppList.lua (100%) rename test_scripts/{SDL4.0 => SDL4_0}/SDL_4.0_Language_parameter.lua (100%) rename test_scripts/{API => SDL4_6}/TTSChunks/001_RegisterAppInterface.lua (97%) rename test_scripts/{API => SDL4_6}/TTSChunks/002_SetGlobalProperties.lua (52%) rename test_scripts/{API => SDL4_6}/TTSChunks/003_OnAppRegistered.lua (83%) rename test_scripts/{API => SDL4_6}/TTSChunks/004_Alert.lua (62%) rename test_scripts/{API => SDL4_6}/TTSChunks/005_ChangeRegistration.lua (64%) rename test_scripts/{API => SDL4_6}/TTSChunks/006_PerformInteraction.lua (53%) rename test_scripts/{API => SDL4_6}/TTSChunks/007_Speak.lua (62%) rename test_scripts/{API => SDL4_6}/TTSChunks/008_PerformAudioPassThru.lua (60%) rename test_scripts/{API => SDL4_6}/TTSChunks/009_AlertManeuver.lua (66%) create mode 100644 test_scripts/SDL4_6/TTSChunks/common.lua diff --git a/test_scripts/API/TTSChunks/common.lua b/test_scripts/API/TTSChunks/common.lua deleted file mode 100644 index f30f612053..0000000000 --- a/test_scripts/API/TTSChunks/common.lua +++ /dev/null @@ -1,23 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- Common module ---------------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.defaultProtocolVersion = 2 - ---[[ Required Shared libraries ]] -local actions = require("user_modules/sequences/actions") -local hmi_values = require('user_modules/hmi_values') - ---[[ Module ]] -local m = actions - -m.type = "FILE" - -local startOrigin = m.start -function m.start() - local params = hmi_values.getDefaultHMITable() - table.insert(params.TTS.GetCapabilities.params.speechCapabilities, m.type) - startOrigin(params) -end - -return m diff --git a/test_scripts/SDL4.0/SDL4_0_Common_cases.lua b/test_scripts/SDL4_0/SDL4_0_Common_cases.lua similarity index 100% rename from test_scripts/SDL4.0/SDL4_0_Common_cases.lua rename to test_scripts/SDL4_0/SDL4_0_Common_cases.lua diff --git a/test_scripts/SDL4.0/SDL4_0_Icons.lua b/test_scripts/SDL4_0/SDL4_0_Icons.lua similarity index 100% rename from test_scripts/SDL4.0/SDL4_0_Icons.lua rename to test_scripts/SDL4_0/SDL4_0_Icons.lua diff --git a/test_scripts/SDL4.0/SDL4_0_JSON_Validation.lua b/test_scripts/SDL4_0/SDL4_0_JSON_Validation.lua similarity index 100% rename from test_scripts/SDL4.0/SDL4_0_JSON_Validation.lua rename to test_scripts/SDL4_0/SDL4_0_JSON_Validation.lua diff --git a/test_scripts/SDL4.0/SDL4_0_OnSystemRequest_LAUNCH_APP.lua b/test_scripts/SDL4_0/SDL4_0_OnSystemRequest_LAUNCH_APP.lua similarity index 100% rename from test_scripts/SDL4.0/SDL4_0_OnSystemRequest_LAUNCH_APP.lua rename to test_scripts/SDL4_0/SDL4_0_OnSystemRequest_LAUNCH_APP.lua diff --git a/test_scripts/SDL4.0/SDL4_0_OnSystemRequest_QUERY_APPS.lua b/test_scripts/SDL4_0/SDL4_0_OnSystemRequest_QUERY_APPS.lua similarity index 100% rename from test_scripts/SDL4.0/SDL4_0_OnSystemRequest_QUERY_APPS.lua rename to test_scripts/SDL4_0/SDL4_0_OnSystemRequest_QUERY_APPS.lua diff --git a/test_scripts/SDL4.0/SDL4_0_UpdateAppList.lua b/test_scripts/SDL4_0/SDL4_0_UpdateAppList.lua similarity index 100% rename from test_scripts/SDL4.0/SDL4_0_UpdateAppList.lua rename to test_scripts/SDL4_0/SDL4_0_UpdateAppList.lua diff --git a/test_scripts/SDL4.0/SDL_4.0_Language_parameter.lua b/test_scripts/SDL4_0/SDL_4.0_Language_parameter.lua similarity index 100% rename from test_scripts/SDL4.0/SDL_4.0_Language_parameter.lua rename to test_scripts/SDL4_0/SDL_4.0_Language_parameter.lua diff --git a/test_scripts/API/TTSChunks/001_RegisterAppInterface.lua b/test_scripts/SDL4_6/TTSChunks/001_RegisterAppInterface.lua similarity index 97% rename from test_scripts/API/TTSChunks/001_RegisterAppInterface.lua rename to test_scripts/SDL4_6/TTSChunks/001_RegisterAppInterface.lua index 2a53878770..de8b190f21 100644 --- a/test_scripts/API/TTSChunks/001_RegisterAppInterface.lua +++ b/test_scripts/SDL4_6/TTSChunks/001_RegisterAppInterface.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/TTSChunks/common') +local common = require('test_scripts/SDL4_6/TTSChunks/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/API/TTSChunks/002_SetGlobalProperties.lua b/test_scripts/SDL4_6/TTSChunks/002_SetGlobalProperties.lua similarity index 52% rename from test_scripts/API/TTSChunks/002_SetGlobalProperties.lua rename to test_scripts/SDL4_6/TTSChunks/002_SetGlobalProperties.lua index 4494908537..8b5718b00e 100644 --- a/test_scripts/API/TTSChunks/002_SetGlobalProperties.lua +++ b/test_scripts/SDL4_6/TTSChunks/002_SetGlobalProperties.lua @@ -15,29 +15,61 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/TTSChunks/common') +local common = require('test_scripts/SDL4_6/TTSChunks/common') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'pathToFile1', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local putFileParams2 = { + requestParams = { + syncFileName = 'pathToFile2', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local params = { + helpPrompt = { + { type = common.type, text = "pathToFile1" } + }, + timeoutPrompt = { + { type = common.type, text = "pathToFile2" } + } +} + +local hmiParams = { + helpPrompt = { + { type = common.type, text = common.getPathToFileInStorage("pathToFile1") } + }, + timeoutPrompt = { + { type = common.type, text = common.getPathToFileInStorage("pathToFile2") } + } +} --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function sendSetGlobalProperties() - local params = { - helpPrompt = { - { type = common.type, text = "pathToFile1" } - }, - timeoutPrompt = { - { type = common.type, text = "pathToFile2" } - } - } +local function sendSetGlobalProperties_FILE_NOT_FOUND() + local corId = common.getMobileSession():SendRPC("SetGlobalProperties", params) + common.getMobileSession():ExpectResponse(corId, { success = false, resultCode = "FILE_NOT_FOUND" }) +end + +local function sendSetGlobalProperties_SUCCESS() local corId = common.getMobileSession():SendRPC("SetGlobalProperties", params) - common.getHMIConnection():ExpectRequest("UI.SetGlobalProperties") - :Do(function(_, data) - common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) - end) common.getHMIConnection():ExpectRequest("TTS.SetGlobalProperties", { - helpPrompt = params.helpPrompt, - timeoutPrompt = params.timeoutPrompt + helpPrompt = hmiParams.helpPrompt, + timeoutPrompt = hmiParams.timeoutPrompt }) :Do(function(_, data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) @@ -53,7 +85,10 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Title("Test") -runner.Step("Send SetGlobalProperties", sendSetGlobalProperties) +runner.Step("Send SetGlobalProperties FILE_NOT_FOUND response", sendSetGlobalProperties_FILE_NOT_FOUND) +runner.Step("Upload first icon file", common.putFile, { putFileParams }) +runner.Step("Upload second icon file", common.putFile, { putFileParams2 }) +runner.Step("Send SetGlobalProperties SUCCESS response", sendSetGlobalProperties_SUCCESS) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/TTSChunks/003_OnAppRegistered.lua b/test_scripts/SDL4_6/TTSChunks/003_OnAppRegistered.lua similarity index 83% rename from test_scripts/API/TTSChunks/003_OnAppRegistered.lua rename to test_scripts/SDL4_6/TTSChunks/003_OnAppRegistered.lua index 9dc63683ce..77c3c4f2bf 100644 --- a/test_scripts/API/TTSChunks/003_OnAppRegistered.lua +++ b/test_scripts/SDL4_6/TTSChunks/003_OnAppRegistered.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/TTSChunks/common') +local common = require('test_scripts/SDL4_6/TTSChunks/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -29,8 +29,13 @@ local function registerApp() { type = common.type, text = "pathToFile" } } local corId = common.getMobileSession():SendRPC("RegisterAppInterface", params) - common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", { ttsName = params.ttsName }) - common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", { + ttsName = { + { type = common.type, text = common.getPathToFileInStorage("pathToFile") } + } + }) + -- WARNINGS response is received since `pathToFile` is not a valid file + common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "WARNINGS" }) end) end diff --git a/test_scripts/API/TTSChunks/004_Alert.lua b/test_scripts/SDL4_6/TTSChunks/004_Alert.lua similarity index 62% rename from test_scripts/API/TTSChunks/004_Alert.lua rename to test_scripts/SDL4_6/TTSChunks/004_Alert.lua index 5e455da8bc..95a1aac831 100644 --- a/test_scripts/API/TTSChunks/004_Alert.lua +++ b/test_scripts/SDL4_6/TTSChunks/004_Alert.lua @@ -15,20 +15,43 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/TTSChunks/common') +local common = require('test_scripts/SDL4_6/TTSChunks/common') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'pathToFile', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local params = { + ttsChunks = { + { type = common.type, text = "pathToFile" } + } +} + +local hmiParams = { + ttsChunks = { + { type = common.type, text = common.getPathToFileInStorage("pathToFile") } + } +} --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function sendAlert() - local params = { - ttsChunks = { - { type = common.type, text = "pathToFile" } - } - } +local function sendAlert_FILE_NOT_FOUND() + local corId = common.getMobileSession():SendRPC("Alert", params) + common.getMobileSession():ExpectResponse(corId, { success = false, resultCode = "FILE_NOT_FOUND" }) +end + +local function sendAlert_SUCCESS() local corId = common.getMobileSession():SendRPC("Alert", params) - common.getHMIConnection():ExpectRequest("TTS.Speak", { ttsChunks = params.ttsChunks }) + common.getHMIConnection():ExpectRequest("TTS.Speak", { ttsChunks = hmiParams.ttsChunks }) :Do(function(_, data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) end) @@ -43,7 +66,9 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Title("Test") -runner.Step("Send Alert", sendAlert) +runner.Step("Send Alert FILE_NOT_FOUND response", sendAlert_FILE_NOT_FOUND) +runner.Step("Upload icon file", common.putFile, { putFileParams }) +runner.Step("Send Alert SUCCESS response", sendAlert_SUCCESS) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/TTSChunks/005_ChangeRegistration.lua b/test_scripts/SDL4_6/TTSChunks/005_ChangeRegistration.lua similarity index 64% rename from test_scripts/API/TTSChunks/005_ChangeRegistration.lua rename to test_scripts/SDL4_6/TTSChunks/005_ChangeRegistration.lua index 0792d8174d..b98034368e 100644 --- a/test_scripts/API/TTSChunks/005_ChangeRegistration.lua +++ b/test_scripts/SDL4_6/TTSChunks/005_ChangeRegistration.lua @@ -15,20 +15,43 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/TTSChunks/common') +local common = require('test_scripts/SDL4_6/TTSChunks/common') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'pathToFile', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local params = { + language = "EN-US", + hmiDisplayLanguage = "EN-US", + ttsName = { + { type = common.type, text = "pathToFile" } + } +} + +local hmiParams = { + ttsName = { + { type = common.type, text = common.getPathToFileInStorage("pathToFile") } + } +} --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function sendChangeRegistration() - local params = { - language = "EN-US", - hmiDisplayLanguage = "EN-US", - ttsName = { - { type = common.type, text = "pathToFile" } - } - } +local function sendChangeRegistration_FILE_NOT_FOUND() + local corId = common.getMobileSession():SendRPC("ChangeRegistration", params) + common.getMobileSession():ExpectResponse(corId, { success = false, resultCode = "FILE_NOT_FOUND" }) +end + +local function sendChangeRegistration_SUCCESS() local corId = common.getMobileSession():SendRPC("ChangeRegistration", params) common.getHMIConnection():ExpectRequest("UI.ChangeRegistration") :Do(function(_, data) @@ -38,7 +61,7 @@ local function sendChangeRegistration() :Do(function(_, data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) end) - common.getHMIConnection():ExpectRequest("TTS.ChangeRegistration", { ttsName = params.ttsName }) + common.getHMIConnection():ExpectRequest("TTS.ChangeRegistration", { ttsName = hmiParams.ttsName }) :Do(function(_, data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) end) @@ -53,7 +76,9 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Title("Test") -runner.Step("Send ChangeRegistration", sendChangeRegistration) +runner.Step("Send ChangeRegistration FILE_NOT_FOUND response", sendChangeRegistration_FILE_NOT_FOUND) +runner.Step("Upload icon file", common.putFile, { putFileParams }) +runner.Step("Send ChangeRegistration SUCCESS response", sendChangeRegistration_SUCCESS) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/TTSChunks/006_PerformInteraction.lua b/test_scripts/SDL4_6/TTSChunks/006_PerformInteraction.lua similarity index 53% rename from test_scripts/API/TTSChunks/006_PerformInteraction.lua rename to test_scripts/SDL4_6/TTSChunks/006_PerformInteraction.lua index 8dd6748356..f18c59c50f 100644 --- a/test_scripts/API/TTSChunks/006_PerformInteraction.lua +++ b/test_scripts/SDL4_6/TTSChunks/006_PerformInteraction.lua @@ -17,14 +17,74 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/TTSChunks/common') +local common = require('test_scripts/SDL4_6/TTSChunks/common') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'pathToFile1', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local putFileParams2 = { + requestParams = { + syncFileName = 'pathToFile2', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local putFileParams3 = { + requestParams = { + syncFileName = 'pathToFile3', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + + +local params = { + initialText = "StartPerformInteraction", + interactionMode = "VR_ONLY", + interactionChoiceSetIDList = { 100 }, + initialPrompt = { + { type = common.type, text = "pathToFile1" } + }, + helpPrompt = { + { type = common.type, text = "pathToFile2" } + }, + timeoutPrompt = { + { type = common.type, text = "pathToFile3" } + } +} + + +local hmiParams = { + initialPrompt = { + { type = common.type, text = common.getPathToFileInStorage("pathToFile1") } + }, + helpPrompt = { + { type = common.type, text = common.getPathToFileInStorage("pathToFile2") } + }, + timeoutPrompt = { + { type = common.type, text = common.getPathToFileInStorage("pathToFile3") } + } +} --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] local function createInteractionChoiceSet() - local params = { + local choiceParams = { interactionChoiceSetID = 100, choiceSet = { { @@ -34,7 +94,7 @@ local function createInteractionChoiceSet() } } } - local corId = common.getMobileSession():SendRPC("CreateInteractionChoiceSet", params) + local corId = common.getMobileSession():SendRPC("CreateInteractionChoiceSet", choiceParams) common.getHMIConnection():ExpectRequest("VR.AddCommand") :Do(function(_, data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) @@ -42,30 +102,21 @@ local function createInteractionChoiceSet() common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) end -local function sendPerformInteraction() - local params = { - initialText = "StartPerformInteraction", - interactionMode = "VR_ONLY", - interactionChoiceSetIDList = { 100 }, - initialPrompt = { - { type = common.type, text = "pathToFile1" } - }, - helpPrompt = { - { type = common.type, text = "pathToFile2" } - }, - timeoutPrompt = { - { type = common.type, text = "pathToFile3" } - } - } +local function sendPerformInteraction_FILE_NOT_FOUND() + local corId = common.getMobileSession():SendRPC("PerformInteraction", params) + common.getMobileSession():ExpectResponse(corId, { success = false, resultCode = "FILE_NOT_FOUND" }) +end + +local function sendPerformInteraction_SUCCESS() local corId = common.getMobileSession():SendRPC("PerformInteraction", params) common.getHMIConnection():ExpectRequest("UI.PerformInteraction") :Do(function(_, data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) end) common.getHMIConnection():ExpectRequest("VR.PerformInteraction", { - initialPrompt = params.initialPrompt, - helpPrompt = params.helpPrompt, - timeoutPrompt = params.timeoutPrompt + initialPrompt = hmiParams.initialPrompt, + helpPrompt = hmiParams.helpPrompt, + timeoutPrompt = hmiParams.timeoutPrompt }) :Do(function(_, data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) @@ -82,7 +133,11 @@ runner.Step("Activate App", common.activateApp) runner.Step("Create InteractionChoiceSet", createInteractionChoiceSet) runner.Title("Test") -runner.Step("Send PerformInteraction", sendPerformInteraction) +runner.Step("Send PerformInteraction FILE_NOT_FOUND response", sendPerformInteraction_FILE_NOT_FOUND) +runner.Step("Upload first icon file", common.putFile, { putFileParams }) +runner.Step("Upload second icon file", common.putFile, { putFileParams2 }) +runner.Step("Upload third icon file", common.putFile, { putFileParams3 }) +runner.Step("Send PerformInteraction SUCCESS response", sendPerformInteraction_SUCCESS) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/TTSChunks/007_Speak.lua b/test_scripts/SDL4_6/TTSChunks/007_Speak.lua similarity index 62% rename from test_scripts/API/TTSChunks/007_Speak.lua rename to test_scripts/SDL4_6/TTSChunks/007_Speak.lua index e210c4f63d..70cd8c63e9 100644 --- a/test_scripts/API/TTSChunks/007_Speak.lua +++ b/test_scripts/SDL4_6/TTSChunks/007_Speak.lua @@ -15,20 +15,43 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/TTSChunks/common') +local common = require('test_scripts/SDL4_6/TTSChunks/common') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'pathToFile', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local params = { + ttsChunks = { + { type = common.type, text = "pathToFile" } + } +} + +local hmiParams = { + ttsChunks = { + { type = common.type, text = common.getPathToFileInStorage("pathToFile") } + } +} --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function sendSpeak() - local params = { - ttsChunks = { - { type = common.type, text = "pathToFile" } - } - } +local function sendSpeak_FILE_NOT_FOUND() + local corId = common.getMobileSession():SendRPC("Speak", params) + common.getMobileSession():ExpectResponse(corId, { success = false, resultCode = "FILE_NOT_FOUND" }) +end + +local function sendSpeak_SUCCESS() local corId = common.getMobileSession():SendRPC("Speak", params) - common.getHMIConnection():ExpectRequest("TTS.Speak", { ttsChunks = params.ttsChunks }) + common.getHMIConnection():ExpectRequest("TTS.Speak", { ttsChunks = hmiParams.ttsChunks }) :Do(function(_, data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) end) @@ -43,7 +66,9 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Title("Test") -runner.Step("Send Speak", sendSpeak) +runner.Step("Send Speak FILE_NOT_FOUND response", sendSpeak_FILE_NOT_FOUND) +runner.Step("Upload icon file", common.putFile, { putFileParams }) +runner.Step("Send Speak SUCCESS response", sendSpeak_SUCCESS) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/TTSChunks/008_PerformAudioPassThru.lua b/test_scripts/SDL4_6/TTSChunks/008_PerformAudioPassThru.lua similarity index 60% rename from test_scripts/API/TTSChunks/008_PerformAudioPassThru.lua rename to test_scripts/SDL4_6/TTSChunks/008_PerformAudioPassThru.lua index 9e03035ce5..c09d8ee6ab 100644 --- a/test_scripts/API/TTSChunks/008_PerformAudioPassThru.lua +++ b/test_scripts/SDL4_6/TTSChunks/008_PerformAudioPassThru.lua @@ -15,28 +15,51 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/TTSChunks/common') +local common = require('test_scripts/SDL4_6/TTSChunks/common') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'pathToFile', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local params = { + samplingRate = "8KHZ", + maxDuration = 2000, + bitsPerSample = "8_BIT", + audioType = "PCM", + initialPrompt = { + { type = common.type, text = "pathToFile" } + } +} + +local hmiParams = { + initialPrompt = { + { type = common.type, text = common.getPathToFileInStorage("pathToFile") } + } +} --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function sendPerformAudioPassThru() - local params = { - samplingRate = "8KHZ", - maxDuration = 2000, - bitsPerSample = "8_BIT", - audioType = "PCM", - initialPrompt = { - { type = common.type, text = "pathToFile" } - } - } +local function sendPerformAudioPassThru_FILE_NOT_FOUND() + local corId = common.getMobileSession():SendRPC("PerformAudioPassThru", params) + common.getMobileSession():ExpectResponse(corId, { success = false, resultCode = "FILE_NOT_FOUND" }) +end + +local function sendPerformAudioPassThru_SUCCESS() local corId = common.getMobileSession():SendRPC("PerformAudioPassThru", params) common.getHMIConnection():ExpectRequest("UI.PerformAudioPassThru") :Do(function(_, data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) end) - common.getHMIConnection():ExpectRequest("TTS.Speak", { ttsChunks = params.initialPrompt }) + common.getHMIConnection():ExpectRequest("TTS.Speak", { ttsChunks = hmiParams.initialPrompt }) :Do(function(_, data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) end) @@ -51,7 +74,9 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Title("Test") -runner.Step("Send PerformAudioPassThru", sendPerformAudioPassThru) +runner.Step("Send PerformAudioPassThru FILE_NOT_FOUND response", sendPerformAudioPassThru_FILE_NOT_FOUND) +runner.Step("Upload icon file", common.putFile, { putFileParams }) +runner.Step("Send PerformAudioPassThru SUCCESS response", sendPerformAudioPassThru_SUCCESS) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/TTSChunks/009_AlertManeuver.lua b/test_scripts/SDL4_6/TTSChunks/009_AlertManeuver.lua similarity index 66% rename from test_scripts/API/TTSChunks/009_AlertManeuver.lua rename to test_scripts/SDL4_6/TTSChunks/009_AlertManeuver.lua index 7584873ce7..6560da0314 100644 --- a/test_scripts/API/TTSChunks/009_AlertManeuver.lua +++ b/test_scripts/SDL4_6/TTSChunks/009_AlertManeuver.lua @@ -15,7 +15,30 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/TTSChunks/common') +local common = require('test_scripts/SDL4_6/TTSChunks/common') + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'pathToFile', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local params = { + ttsChunks = { + { type = common.type, text = "pathToFile" } + } +} + +local hmiParams = { + ttsChunks = { + { type = common.type, text = common.getPathToFileInStorage("pathToFile") } + } +} --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -25,18 +48,18 @@ local function pTUpdateFunc(pTbl) table.insert(pTbl.policy_table.app_policies[common.getConfigAppParams().appID].groups, "Navigation-1") end -local function sendAlertManeuver() - local params = { - ttsChunks = { - { type = common.type, text = "pathToFile" } - } - } +local function sendAlertManeuver_FILE_NOT_FOUND() + local corId = common.getMobileSession():SendRPC("AlertManeuver", params) + common.getMobileSession():ExpectResponse(corId, { success = false, resultCode = "FILE_NOT_FOUND" }) +end + +local function sendAlertManeuver_SUCCESS() local corId = common.getMobileSession():SendRPC("AlertManeuver", params) common.getHMIConnection():ExpectRequest("Navigation.AlertManeuver") :Do(function(_, data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) end) - common.getHMIConnection():ExpectRequest("TTS.Speak", { ttsChunks = params.ttsChunks }) + common.getHMIConnection():ExpectRequest("TTS.Speak", { ttsChunks = hmiParams.ttsChunks }) :Do(function(_, data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) end) @@ -52,7 +75,9 @@ runner.Step("PTU", common.policyTableUpdate, { pTUpdateFunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") -runner.Step("Send AlertManeuver", sendAlertManeuver) +runner.Step("Send AlertManeuver FILE_NOT_FOUND response", sendAlertManeuver_FILE_NOT_FOUND) +runner.Step("Upload icon file", common.putFile, { putFileParams }) +runner.Step("Send AlertManeuver SUCCESS response", sendAlertManeuver_SUCCESS) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/SDL4_6/TTSChunks/common.lua b/test_scripts/SDL4_6/TTSChunks/common.lua new file mode 100644 index 0000000000..b2772ea258 --- /dev/null +++ b/test_scripts/SDL4_6/TTSChunks/common.lua @@ -0,0 +1,68 @@ +--------------------------------------------------------------------------------------------------- +-- Common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.mobileHost = "127.0.0.1" +config.defaultProtocolVersion = 2 + +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") +local hmi_values = require('user_modules/hmi_values') +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') + +--[[ Module ]] +local m = actions + +m.type = "FILE" + +local preconditionsOrig = m.preconditions + +--[[ @preconditions: Expand initial precondition with removing storage folder +--! @parameters: none +--! return: none +--]] +function m.preconditions() + preconditionsOrig() + local storage = commonPreconditions:GetPathToSDL() .. "storage" + os.execute("rm -rf " .. storage) +end + +local startOrigin = m.start +function m.start() + local params = hmi_values.getDefaultHMITable() + table.insert(params.TTS.GetCapabilities.params.speechCapabilities, m.type) + startOrigin(params) +end + +function m.putFile(params, pAppId, self) + if not pAppId then pAppId = 1 end + local mobileSession = m.getMobileSession(pAppId, self); + local cid = mobileSession:SendRPC("PutFile", params.requestParams, params.filePath) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +function m.getPathToFileInStorage(fileName) + return commonPreconditions:GetPathToSDL() .. "storage/" + .. m.getMobileAppId() .. "_" + .. m.getDeviceMAC() .. "/" .. fileName +end + +function m.getDeviceName() + return config.mobileHost .. ":" .. config.mobilePort +end + +function m.getDeviceMAC() + local cmd = "echo -n " .. m.getDeviceName() .. " | sha256sum | awk '{printf $1}'" + local handle = io.popen(cmd) + local result = handle:read("*a") + handle:close() + return result +end + +function m.getMobileAppId(pAppId) + if not pAppId then pAppId = 1 end + return config["application" .. pAppId].registerAppInterfaceParams.appID +end + +return m diff --git a/test_sets/audio_file_playback_tts_chunks.txt b/test_sets/audio_file_playback_tts_chunks.txt index 959c05f94c..f7b72404d6 100644 --- a/test_sets/audio_file_playback_tts_chunks.txt +++ b/test_sets/audio_file_playback_tts_chunks.txt @@ -1,9 +1,9 @@ -./test_scripts/API/TTSChunks/001_RegisterAppInterface.lua -./test_scripts/API/TTSChunks/002_SetGlobalProperties.lua -./test_scripts/API/TTSChunks/003_OnAppRegistered.lua -./test_scripts/API/TTSChunks/004_Alert.lua -./test_scripts/API/TTSChunks/005_ChangeRegistration.lua -./test_scripts/API/TTSChunks/006_PerformInteraction.lua -./test_scripts/API/TTSChunks/007_Speak.lua -./test_scripts/API/TTSChunks/008_PerformAudioPassThru.lua -./test_scripts/API/TTSChunks/009_AlertManeuver.lua +./test_scripts/SDL4_6/TTSChunks/001_RegisterAppInterface.lua +./test_scripts/SDL4_6/TTSChunks/002_SetGlobalProperties.lua +./test_scripts/SDL4_6/TTSChunks/003_OnAppRegistered.lua +./test_scripts/SDL4_6/TTSChunks/004_Alert.lua +./test_scripts/SDL4_6/TTSChunks/005_ChangeRegistration.lua +./test_scripts/SDL4_6/TTSChunks/006_PerformInteraction.lua +./test_scripts/SDL4_6/TTSChunks/007_Speak.lua +./test_scripts/SDL4_6/TTSChunks/008_PerformAudioPassThru.lua +./test_scripts/SDL4_6/TTSChunks/009_AlertManeuver.lua From 93d45d85315388b875d33965edfbeeb52506cfa3 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Mon, 11 Jun 2018 11:41:19 +0300 Subject: [PATCH 420/681] Fix syntax error in VehicleData scripts --- .../Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua | 2 +- .../API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua | 2 +- .../Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua index ab6ee8b20c..a31911a983 100644 --- a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua @@ -39,7 +39,7 @@ local VDValues = { rpm = "VEHICLEDATA_RPM", fuelLevel = "VEHICLEDATA_FUELLEVEL", fuelLevel_State = "VEHICLEDATA_FUELLEVEL_STATE", - fuelRange = "VEHICLEDATA_FUELRANGE" + fuelRange = "VEHICLEDATA_FUELRANGE", instantFuelConsumption = "VEHICLEDATA_FUELCONSUMPTION", externalTemperature = "VEHICLEDATA_EXTERNTEMP", prndl = "VEHICLEDATA_PRNDL", diff --git a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua index ac43225490..96924ec0d3 100644 --- a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua @@ -39,7 +39,7 @@ local VDValues = { rpm = "VEHICLEDATA_RPM", fuelLevel = "VEHICLEDATA_FUELLEVEL", fuelLevel_State = "VEHICLEDATA_FUELLEVEL_STATE", - fuelRange = "VEHICLEDATA_FUELRANGE" + fuelRange = "VEHICLEDATA_FUELRANGE", instantFuelConsumption = "VEHICLEDATA_FUELCONSUMPTION", externalTemperature = "VEHICLEDATA_EXTERNTEMP", prndl = "VEHICLEDATA_PRNDL", diff --git a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua index 74a9dc78db..085fd32155 100644 --- a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua @@ -63,7 +63,7 @@ local vehicleDataValues = { type = "GASOLINE", range = 400.5 } - } + }, instantFuelConsumption = 1000.5, externalTemperature = 55.5, vin = "123456", From a3b3f88981ebcf7ae2ed601d35bddf56d35609a6 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Mon, 11 Jun 2018 15:13:09 -0400 Subject: [PATCH 421/681] Address review comments --- files/hmi_capabilities_SearchButton.json | 869 +++++++++--------- files/hmi_capabilities_Without_PRESET9.json | 845 ++++++++--------- ..._SetDisplayLayout_DisplayNameParameter.lua | 191 ---- ...scribeVehicleData_PositiveCase_SUCCESS.lua | 2 +- ...scribeVehicleData_PositiveCase_SUCCESS.lua | 2 +- ...26_GetVehicleData_PositiveCase_SUCCESS.lua | 2 +- 6 files changed, 817 insertions(+), 1094 deletions(-) delete mode 100644 test_scripts/SDL4.6/DisplayName/001_SetDisplayLayout_DisplayNameParameter.lua diff --git a/files/hmi_capabilities_SearchButton.json b/files/hmi_capabilities_SearchButton.json index aa327865b7..681c39beed 100644 --- a/files/hmi_capabilities_SearchButton.json +++ b/files/hmi_capabilities_SearchButton.json @@ -1,460 +1,417 @@ { - "UI": - { - "language":"EN_US", - "languages":[ - "EN_US","ES_MX","FR_CA","DE_DE","ES_ES","EN_GB","RU_RU","TR_TR","PL_PL","FR_FR","IT_IT","SV_SE","PT_PT","NL_NL","ZH_TW", -"JA_JP","AR_SA","KO_KR","PT_BR","CS_CZ","DA_DK","NO_NO" - ], - "displayCapabilities": - { - "displayType":"GEN2_8_DMA", - "displayName":"GENERIC_DISPLAY", - "textFields": [{ - "name": "mainField1", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "mainField2", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "mainField3", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "mainField4", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "statusBar", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "mediaClock", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "mediaTrack", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "alertText1", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "alertText2", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "alertText3", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "scrollableMessageBody", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "initialInteractionText", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "navigationText1", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "navigationText2", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "ETA", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "totalDistance", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "navigationText", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "audioPassThruDisplayText1", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "audioPassThruDisplayText2", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "sliderHeader", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "sliderFooter", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "notificationText", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "menuName", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "secondaryText", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "tertiaryText", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "timeToDestination", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "turnText", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "menuTitle", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - } - ], - "imageFields": - [ - { - "name":"softButtonImage", - "imageTypeSupported": - [ - ], - "imageResolution": - { - "resolutionWidth":35, - "resolutionHeight":35 - } - }, - { - "name":"choiceImage", - "imageTypeSupported": - [ - ], - "imageResolution": - { - "resolutionWidth":35, - "resolutionHeight":35 - } - }, - { - "name":"choiceSecondaryImage", - "imageTypeSupported": - [ - ], - "imageResolution": - { - "resolutionWidth":35, - "resolutionHeight":35 - } - }, - { - "name":"menuIcon", - "imageTypeSupported": - [ - ], - "imageResolution": - { - "resolutionWidth":35, - "resolutionHeight":35 - } - }, - { - "name":"cmdIcon", - "imageTypeSupported": - [ - ], - "imageResolution": - { - "resolutionWidth":35, - "resolutionHeight":35 - } - }, - { - "name":"appIcon", - "imageTypeSupported": - [ - ], - "imageResolution": - { - "resolutionWidth":35, - "resolutionHeight":35 - } - }, - { - "name":"graphic", - "imageTypeSupported": - [ - - ], - "imageResolution": - { - "resolutionWidth":35, - "resolutionHeight":35 - } - }, - { - "name":"locationImage", - "imageTypeSupported": - [ - "GRAPHIC_PNG" - ], - "imageResolution": - { - "resolutionWidth":35, - "resolutionHeight":35 - } - } - - ], - "mediaClockFormats": - [ - "CLOCK1","CLOCK2","CLOCK3","CLOCKTEXT1","CLOCKTEXT2","CLOCKTEXT3","CLOCKTEXT4" - ], - "graphicSupported":true, - "templatesAvailable": - [ - - "DEFAULT","MEDIA","NON-MEDIA","ONSCREEN_PRESETS","NAV_FULLSCREEN_MAP","NAV_KEYBOARD", - "GRAPHIC_WITH_TEXT","TEXT_WITH_GRAPHIC","TILES_ONLY","TEXTBUTTONS_ONLY", - "GRAPHIC_WITH_TILES","TILES_WITH_GRAPHIC","GRAPHIC_WITH_TEXT_AND_SOFTBUTTONS", - "TEXT_AND_SOFTBUTTONS_WITH_GRAPHIC","GRAPHIC_WITH_TEXTBUTTONS", - "TEXTBUTTONS_WITH_GRAPHIC","LARGE_GRAPHIC_WITH_SOFTBUTTONS", - "DOUBLE_GRAPHIC_WITH_SOFTBUTTONS","LARGE_GRAPHIC_ONLY" - ], - "screenParams": - { - "resolution": - { - "resolutionWidth":800, - "resolutionHeight":350 - }, - "touchEventAvailable": - { - "pressAvailable":true, - "multiTouchAvailable":false, - "doublePressAvailable":false - } - }, - "numCustomPresetsAvailable":8, - "imageCapabilities": - [ - "DYNAMIC", - "STATIC" - ] - }, - "audioPassThruCapabilities": - { - "samplingRate" : "44KHZ", - "bitsPerSample" : "RATE_8_BIT", - "audioType" : "PCM" - }, - "hmiZoneCapabilities":"FRONT", - "softButtonCapabilities": - { - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true, - "imageSupported" :true - } + "UI": { + "language": "EN_US", + "languages": [ + "EN_US", "ES_MX", "FR_CA", "DE_DE", "ES_ES", "EN_GB", "RU_RU", "TR_TR", "PL_PL", "FR_FR", "IT_IT", "SV_SE", "PT_PT", "NL_NL", "ZH_TW", + "JA_JP", "AR_SA", "KO_KR", "PT_BR", "CS_CZ", "DA_DK", "NO_NO" + ], + "displayCapabilities": { + "displayType": "GEN2_8_DMA", + "displayName": "GENERIC_DISPLAY", + "textFields": [{ + "name": "mainField1", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "mainField2", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "mainField3", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "mainField4", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "statusBar", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "mediaClock", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "mediaTrack", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "alertText1", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "alertText2", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "alertText3", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "scrollableMessageBody", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "initialInteractionText", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "navigationText1", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "navigationText2", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "ETA", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "totalDistance", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "navigationText", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "audioPassThruDisplayText1", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "audioPassThruDisplayText2", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "sliderHeader", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "sliderFooter", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "notificationText", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "menuName", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "secondaryText", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "tertiaryText", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "timeToDestination", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "turnText", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "menuTitle", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + } + ], + "imageFields": [{ + "name": "softButtonImage", + "imageTypeSupported": [], + "imageResolution": { + "resolutionWidth": 35, + "resolutionHeight": 35 + } + }, + { + "name": "choiceImage", + "imageTypeSupported": [], + "imageResolution": { + "resolutionWidth": 35, + "resolutionHeight": 35 + } + }, + { + "name": "choiceSecondaryImage", + "imageTypeSupported": [], + "imageResolution": { + "resolutionWidth": 35, + "resolutionHeight": 35 + } + }, + { + "name": "menuIcon", + "imageTypeSupported": [], + "imageResolution": { + "resolutionWidth": 35, + "resolutionHeight": 35 + } + }, + { + "name": "cmdIcon", + "imageTypeSupported": [], + "imageResolution": { + "resolutionWidth": 35, + "resolutionHeight": 35 + } + }, + { + "name": "appIcon", + "imageTypeSupported": [], + "imageResolution": { + "resolutionWidth": 35, + "resolutionHeight": 35 + } + }, + { + "name": "graphic", + "imageTypeSupported": [ + + ], + "imageResolution": { + "resolutionWidth": 35, + "resolutionHeight": 35 + } + }, + { + "name": "locationImage", + "imageTypeSupported": [ + "GRAPHIC_PNG" + ], + "imageResolution": { + "resolutionWidth": 35, + "resolutionHeight": 35 + } + } + + ], + "mediaClockFormats": [ + "CLOCK1", "CLOCK2", "CLOCK3", "CLOCKTEXT1", "CLOCKTEXT2", "CLOCKTEXT3", "CLOCKTEXT4" + ], + "graphicSupported": true, + "templatesAvailable": [ + + "DEFAULT", "MEDIA", "NON-MEDIA", "ONSCREEN_PRESETS", "NAV_FULLSCREEN_MAP", "NAV_KEYBOARD", + "GRAPHIC_WITH_TEXT", "TEXT_WITH_GRAPHIC", "TILES_ONLY", "TEXTBUTTONS_ONLY", + "GRAPHIC_WITH_TILES", "TILES_WITH_GRAPHIC", "GRAPHIC_WITH_TEXT_AND_SOFTBUTTONS", + "TEXT_AND_SOFTBUTTONS_WITH_GRAPHIC", "GRAPHIC_WITH_TEXTBUTTONS", + "TEXTBUTTONS_WITH_GRAPHIC", "LARGE_GRAPHIC_WITH_SOFTBUTTONS", + "DOUBLE_GRAPHIC_WITH_SOFTBUTTONS", "LARGE_GRAPHIC_ONLY" + ], + "screenParams": { + "resolution": { + "resolutionWidth": 800, + "resolutionHeight": 350 + }, + "touchEventAvailable": { + "pressAvailable": true, + "multiTouchAvailable": false, + "doublePressAvailable": false + } + }, + "numCustomPresetsAvailable": 8, + "imageCapabilities": [ + "DYNAMIC", + "STATIC" + ] + }, + "audioPassThruCapabilities": { + "samplingRate": "44KHZ", + "bitsPerSample": "RATE_8_BIT", + "audioType": "PCM" + }, + "hmiZoneCapabilities": "FRONT", + "softButtonCapabilities": { + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true, + "imageSupported": true + } }, - "VR": - { - "capabilities":["TEXT"], - "language":"EN_US", - "languages": - [ - "EN_US","ES_MX","FR_CA","DE_DE","ES_ES","EN_GB","RU_RU","TR_TR","PL_PL","FR_FR","IT_IT","SV_SE","PT_PT","NL_NL","ZH_TW", -"JA_JP","AR_SA","KO_KR","PT_BR","CS_CZ","DA_DK","NO_NO" - ] -}, - "TTS": - { - "capabilities":"TEXT", - "language":"EN_US", - "languages": - [ - "EN_US","ES_MX","FR_CA","DE_DE","ES_ES","EN_GB","RU_RU","TR_TR","PL_PL","FR_FR","IT_IT","SV_SE","PT_PT","NL_NL","ZH_TW", -"JA_JP","AR_SA","KO_KR","PT_BR","CS_CZ","DA_DK","NO_NO" - ] + "VR": { + "capabilities": ["TEXT"], + "language": "EN_US", + "languages": [ + "EN_US", "ES_MX", "FR_CA", "DE_DE", "ES_ES", "EN_GB", "RU_RU", "TR_TR", "PL_PL", "FR_FR", "IT_IT", "SV_SE", "PT_PT", "NL_NL", "ZH_TW", + "JA_JP", "AR_SA", "KO_KR", "PT_BR", "CS_CZ", "DA_DK", "NO_NO" + ] }, - "Buttons": - { - "capabilities": - [ - { - "name":"PRESET_0", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"PRESET_1", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"PRESET_2", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"PRESET_3", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"PRESET_4", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"PRESET_5", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"PRESET_6", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"PRESET_7", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"PRESET_8", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"PRESET_9", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"OK", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"SEEKLEFT", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"SEEKRIGHT", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"TUNEUP", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"TUNEDOWN", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"SEARCH", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - } - - ], - "presetBankCapabilities": - { - "onScreenPresetsAvailable":true - } + "TTS": { + "capabilities": "TEXT", + "language": "EN_US", + "languages": [ + "EN_US", "ES_MX", "FR_CA", "DE_DE", "ES_ES", "EN_GB", "RU_RU", "TR_TR", "PL_PL", "FR_FR", "IT_IT", "SV_SE", "PT_PT", "NL_NL", "ZH_TW", + "JA_JP", "AR_SA", "KO_KR", "PT_BR", "CS_CZ", "DA_DK", "NO_NO" + ] }, - - "SyncMessageVersion": - { - "majorVersion": 3, - "minorVersion": 0 - } -} + "Buttons": { + "capabilities": [{ + "name": "PRESET_0", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "PRESET_1", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "PRESET_2", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "PRESET_3", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "PRESET_4", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "PRESET_5", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "PRESET_6", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "PRESET_7", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "PRESET_8", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "PRESET_9", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "OK", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "SEEKLEFT", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "SEEKRIGHT", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "TUNEUP", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "TUNEDOWN", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "SEARCH", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + } + + ], + "presetBankCapabilities": { + "onScreenPresetsAvailable": true + } + }, + + "SyncMessageVersion": { + "majorVersion": 3, + "minorVersion": 0 + } +} \ No newline at end of file diff --git a/files/hmi_capabilities_Without_PRESET9.json b/files/hmi_capabilities_Without_PRESET9.json index 5b4df0b338..835498abc3 100644 --- a/files/hmi_capabilities_Without_PRESET9.json +++ b/files/hmi_capabilities_Without_PRESET9.json @@ -1,448 +1,405 @@ { - "UI": - { - "language":"EN_US", - "languages":[ - "EN_US","ES_MX","FR_CA","DE_DE","ES_ES","EN_GB","RU_RU","TR_TR","PL_PL","FR_FR","IT_IT","SV_SE","PT_PT","NL_NL","ZH_TW", -"JA_JP","AR_SA","KO_KR","PT_BR","CS_CZ","DA_DK","NO_NO" - ], - "displayCapabilities": - { - "displayType":"GEN2_8_DMA", - "displayName":"GENERIC_DISPLAY", - "textFields": [{ - "name": "mainField1", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "mainField2", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "mainField3", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "mainField4", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "statusBar", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "mediaClock", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "mediaTrack", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "alertText1", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "alertText2", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "alertText3", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "scrollableMessageBody", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "initialInteractionText", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "navigationText1", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "navigationText2", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "ETA", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "totalDistance", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "navigationText", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "audioPassThruDisplayText1", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "audioPassThruDisplayText2", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "sliderHeader", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "sliderFooter", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "notificationText", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "menuName", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "secondaryText", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "tertiaryText", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "timeToDestination", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "turnText", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "menuTitle", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - } - ], - "imageFields": - [ - { - "name":"softButtonImage", - "imageTypeSupported": - [ - ], - "imageResolution": - { - "resolutionWidth":35, - "resolutionHeight":35 - } - }, - { - "name":"choiceImage", - "imageTypeSupported": - [ - ], - "imageResolution": - { - "resolutionWidth":35, - "resolutionHeight":35 - } - }, - { - "name":"choiceSecondaryImage", - "imageTypeSupported": - [ - ], - "imageResolution": - { - "resolutionWidth":35, - "resolutionHeight":35 - } - }, - { - "name":"menuIcon", - "imageTypeSupported": - [ - ], - "imageResolution": - { - "resolutionWidth":35, - "resolutionHeight":35 - } - }, - { - "name":"cmdIcon", - "imageTypeSupported": - [ - ], - "imageResolution": - { - "resolutionWidth":35, - "resolutionHeight":35 - } - }, - { - "name":"appIcon", - "imageTypeSupported": - [ - ], - "imageResolution": - { - "resolutionWidth":35, - "resolutionHeight":35 - } - }, - { - "name":"graphic", - "imageTypeSupported": - [ - - ], - "imageResolution": - { - "resolutionWidth":35, - "resolutionHeight":35 - } - }, - { - "name":"locationImage", - "imageTypeSupported": - [ - "GRAPHIC_PNG" - ], - "imageResolution": - { - "resolutionWidth":35, - "resolutionHeight":35 - } - } - - ], - "mediaClockFormats": - [ - "CLOCK1","CLOCK2","CLOCK3","CLOCKTEXT1","CLOCKTEXT2","CLOCKTEXT3","CLOCKTEXT4" - ], - "graphicSupported":true, - "templatesAvailable": - [ - - "DEFAULT","MEDIA","NON-MEDIA","ONSCREEN_PRESETS","NAV_FULLSCREEN_MAP","NAV_KEYBOARD", - "GRAPHIC_WITH_TEXT","TEXT_WITH_GRAPHIC","TILES_ONLY","TEXTBUTTONS_ONLY", - "GRAPHIC_WITH_TILES","TILES_WITH_GRAPHIC","GRAPHIC_WITH_TEXT_AND_SOFTBUTTONS", - "TEXT_AND_SOFTBUTTONS_WITH_GRAPHIC","GRAPHIC_WITH_TEXTBUTTONS", - "TEXTBUTTONS_WITH_GRAPHIC","LARGE_GRAPHIC_WITH_SOFTBUTTONS", - "DOUBLE_GRAPHIC_WITH_SOFTBUTTONS","LARGE_GRAPHIC_ONLY" - ], - "screenParams": - { - "resolution": - { - "resolutionWidth":800, - "resolutionHeight":350 - }, - "touchEventAvailable": - { - "pressAvailable":true, - "multiTouchAvailable":false, - "doublePressAvailable":false - } - }, - "numCustomPresetsAvailable":8, - "imageCapabilities": - [ - "DYNAMIC", - "STATIC" - ] - }, - "audioPassThruCapabilities": - { - "samplingRate" : "44KHZ", - "bitsPerSample" : "RATE_8_BIT", - "audioType" : "PCM" - }, - "hmiZoneCapabilities":"FRONT", - "softButtonCapabilities": - { - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true, - "imageSupported" :true - } + "UI": { + "language": "EN_US", + "languages": [ + "EN_US", "ES_MX", "FR_CA", "DE_DE", "ES_ES", "EN_GB", "RU_RU", "TR_TR", "PL_PL", "FR_FR", "IT_IT", "SV_SE", "PT_PT", "NL_NL", "ZH_TW", + "JA_JP", "AR_SA", "KO_KR", "PT_BR", "CS_CZ", "DA_DK", "NO_NO" + ], + "displayCapabilities": { + "displayType": "GEN2_8_DMA", + "displayName": "GENERIC_DISPLAY", + "textFields": [{ + "name": "mainField1", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "mainField2", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "mainField3", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "mainField4", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "statusBar", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "mediaClock", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "mediaTrack", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "alertText1", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "alertText2", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "alertText3", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "scrollableMessageBody", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "initialInteractionText", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "navigationText1", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "navigationText2", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "ETA", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "totalDistance", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "navigationText", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "audioPassThruDisplayText1", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "audioPassThruDisplayText2", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "sliderHeader", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "sliderFooter", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "notificationText", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "menuName", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "secondaryText", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "tertiaryText", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "timeToDestination", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "turnText", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + }, + { + "name": "menuTitle", + "characterSet": "TYPE2SET", + "width": 500, + "rows": 1 + } + ], + "imageFields": [{ + "name": "softButtonImage", + "imageTypeSupported": [], + "imageResolution": { + "resolutionWidth": 35, + "resolutionHeight": 35 + } + }, + { + "name": "choiceImage", + "imageTypeSupported": [], + "imageResolution": { + "resolutionWidth": 35, + "resolutionHeight": 35 + } + }, + { + "name": "choiceSecondaryImage", + "imageTypeSupported": [], + "imageResolution": { + "resolutionWidth": 35, + "resolutionHeight": 35 + } + }, + { + "name": "menuIcon", + "imageTypeSupported": [], + "imageResolution": { + "resolutionWidth": 35, + "resolutionHeight": 35 + } + }, + { + "name": "cmdIcon", + "imageTypeSupported": [], + "imageResolution": { + "resolutionWidth": 35, + "resolutionHeight": 35 + } + }, + { + "name": "appIcon", + "imageTypeSupported": [], + "imageResolution": { + "resolutionWidth": 35, + "resolutionHeight": 35 + } + }, + { + "name": "graphic", + "imageTypeSupported": [ + + ], + "imageResolution": { + "resolutionWidth": 35, + "resolutionHeight": 35 + } + }, + { + "name": "locationImage", + "imageTypeSupported": [ + "GRAPHIC_PNG" + ], + "imageResolution": { + "resolutionWidth": 35, + "resolutionHeight": 35 + } + } + + ], + "mediaClockFormats": [ + "CLOCK1", "CLOCK2", "CLOCK3", "CLOCKTEXT1", "CLOCKTEXT2", "CLOCKTEXT3", "CLOCKTEXT4" + ], + "graphicSupported": true, + "templatesAvailable": [ + + "DEFAULT", "MEDIA", "NON-MEDIA", "ONSCREEN_PRESETS", "NAV_FULLSCREEN_MAP", "NAV_KEYBOARD", + "GRAPHIC_WITH_TEXT", "TEXT_WITH_GRAPHIC", "TILES_ONLY", "TEXTBUTTONS_ONLY", + "GRAPHIC_WITH_TILES", "TILES_WITH_GRAPHIC", "GRAPHIC_WITH_TEXT_AND_SOFTBUTTONS", + "TEXT_AND_SOFTBUTTONS_WITH_GRAPHIC", "GRAPHIC_WITH_TEXTBUTTONS", + "TEXTBUTTONS_WITH_GRAPHIC", "LARGE_GRAPHIC_WITH_SOFTBUTTONS", + "DOUBLE_GRAPHIC_WITH_SOFTBUTTONS", "LARGE_GRAPHIC_ONLY" + ], + "screenParams": { + "resolution": { + "resolutionWidth": 800, + "resolutionHeight": 350 + }, + "touchEventAvailable": { + "pressAvailable": true, + "multiTouchAvailable": false, + "doublePressAvailable": false + } + }, + "numCustomPresetsAvailable": 8, + "imageCapabilities": [ + "DYNAMIC", + "STATIC" + ] + }, + "audioPassThruCapabilities": { + "samplingRate": "44KHZ", + "bitsPerSample": "RATE_8_BIT", + "audioType": "PCM" + }, + "hmiZoneCapabilities": "FRONT", + "softButtonCapabilities": { + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true, + "imageSupported": true + } }, - "VR": - { - "capabilities":["TEXT"], - "language":"EN_US", - "languages": - [ - "EN_US","ES_MX","FR_CA","DE_DE","ES_ES","EN_GB","RU_RU","TR_TR","PL_PL","FR_FR","IT_IT","SV_SE","PT_PT","NL_NL","ZH_TW", -"JA_JP","AR_SA","KO_KR","PT_BR","CS_CZ","DA_DK","NO_NO" - ] -}, - "TTS": - { - "capabilities":"TEXT", - "language":"EN_US", - "languages": - [ - "EN_US","ES_MX","FR_CA","DE_DE","ES_ES","EN_GB","RU_RU","TR_TR","PL_PL","FR_FR","IT_IT","SV_SE","PT_PT","NL_NL","ZH_TW", -"JA_JP","AR_SA","KO_KR","PT_BR","CS_CZ","DA_DK","NO_NO" - ] + "VR": { + "capabilities": ["TEXT"], + "language": "EN_US", + "languages": [ + "EN_US", "ES_MX", "FR_CA", "DE_DE", "ES_ES", "EN_GB", "RU_RU", "TR_TR", "PL_PL", "FR_FR", "IT_IT", "SV_SE", "PT_PT", "NL_NL", "ZH_TW", + "JA_JP", "AR_SA", "KO_KR", "PT_BR", "CS_CZ", "DA_DK", "NO_NO" + ] }, - "Buttons": - { - "capabilities": - [ - { - "name":"PRESET_0", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"PRESET_1", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"PRESET_2", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"PRESET_3", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"PRESET_4", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"PRESET_5", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"PRESET_6", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"PRESET_7", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"PRESET_8", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"OK", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"SEEKLEFT", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"SEEKRIGHT", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"TUNEUP", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - }, - { - "name":"TUNEDOWN", - "shortPressAvailable":true, - "longPressAvailable" :true, - "upDownAvailable" :true - } - - ], - "presetBankCapabilities": - { - "onScreenPresetsAvailable":true - } + "TTS": { + "capabilities": "TEXT", + "language": "EN_US", + "languages": [ + "EN_US", "ES_MX", "FR_CA", "DE_DE", "ES_ES", "EN_GB", "RU_RU", "TR_TR", "PL_PL", "FR_FR", "IT_IT", "SV_SE", "PT_PT", "NL_NL", "ZH_TW", + "JA_JP", "AR_SA", "KO_KR", "PT_BR", "CS_CZ", "DA_DK", "NO_NO" + ] }, - - "SyncMessageVersion": - { - "majorVersion": 3, - "minorVersion": 0 - } -} + "Buttons": { + "capabilities": [{ + "name": "PRESET_0", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "PRESET_1", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "PRESET_2", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "PRESET_3", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "PRESET_4", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "PRESET_5", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "PRESET_6", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "PRESET_7", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "PRESET_8", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "OK", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "SEEKLEFT", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "SEEKRIGHT", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "TUNEUP", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, + { + "name": "TUNEDOWN", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + } + + ], + "presetBankCapabilities": { + "onScreenPresetsAvailable": true + } + }, + + "SyncMessageVersion": { + "majorVersion": 3, + "minorVersion": 0 + } +} \ No newline at end of file diff --git a/test_scripts/SDL4.6/DisplayName/001_SetDisplayLayout_DisplayNameParameter.lua b/test_scripts/SDL4.6/DisplayName/001_SetDisplayLayout_DisplayNameParameter.lua deleted file mode 100644 index 5285d60d07..0000000000 --- a/test_scripts/SDL4.6/DisplayName/001_SetDisplayLayout_DisplayNameParameter.lua +++ /dev/null @@ -1,191 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0063-display-name-parameter.md --- --- Description: --- Add displayName to the displayCapabiilities response. Mobile will expect this field to be populated --- --- Steps: Send SetDisplayLayout request. --- --- Expected result: --- SDL Core returns SUCCESS with displayCapabilities: displayName: "GENERIC_DISPLAY" ---------------------------------------------------------------------------------------------------- - ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local commonSmoke = require('test_scripts/Smoke/commonSmoke') - -local function getRequestParams() - return { - displayLayout = "ONSCREEN_PRESETS" - } -end - -local function getDisplayCapTextFieldsValues() - -- some text fields are excluded due to SDL issue - local names = { - "alertText1", - "alertText2", - "alertText3", - "audioPassThruDisplayText1", - "audioPassThruDisplayText2", - "ETA", - "initialInteractionText", - -- "phoneNumber", - "mainField1", - "mainField2", - "mainField3", - "mainField4", - "mediaClock", - "mediaTrack", - "menuName", - "menuTitle", - -- "addressLines", - -- "locationName", - "navigationText1", - "navigationText2", - -- "locationDescription", - "scrollableMessageBody", - "secondaryText", - "sliderFooter", - "sliderHeader", - "statusBar", - "tertiaryText", - "totalDistance", - -- "notificationText", - -- "navigationText", - -- "timeToDestination", - -- "turnText" - } - local values = { } - for _, v in pairs(names) do - local item = { - characterSet = "TYPE2SET", - name = v, - rows = 1, - width = 500 - } - table.insert(values, item) - end - return values -end - -local function getDisplayCapImageFieldsValues() - local names = { - "softButtonImage", - "choiceImage", - "choiceSecondaryImage", - "vrHelpItem", - "turnIcon", - "menuIcon", - "cmdIcon", - "graphic", - "showConstantTBTIcon", - "showConstantTBTNextTurnIcon" - } - local values = { } - for _, v in pairs(names) do - local item = { - imageResolution = { - resolutionHeight = 64, - resolutionWidth = 64 - }, - imageTypeSupported = { - "GRAPHIC_BMP", - "GRAPHIC_JPEG", - "GRAPHIC_PNG" - }, - name = v - } - table.insert(values, item) - end - return values -end - -local function setDisplayWithDisplayNameSuccess(self) - local responseParams = { - displayCapabilities = { - displayType = "GEN2_8_DMA", - displayName = "GENERIC_DISPLAY", - graphicSupported = true, - imageFields = getDisplayCapImageFieldsValues(), - mediaClockFormats = { - "CLOCK1", - "CLOCK2", - "CLOCK3", - "CLOCKTEXT1", - "CLOCKTEXT2", - "CLOCKTEXT3", - "CLOCKTEXT4" - }, - numCustomPresetsAvailable = 10, - screenParams = { - resolution = { - resolutionHeight = 480, - resolutionWidth = 800 - }, - touchEventAvailable = { - doublePressAvailable = false, - multiTouchAvailable = true, - pressAvailable = true - } - }, - templatesAvailable = { - "ONSCREEN_PRESETS" - }, - textFields = getDisplayCapTextFieldsValues() - } - } - local cid = self.mobileSession1:SendRPC("SetDisplayLayout", getRequestParams()) - EXPECT_HMICALL("UI.SetDisplayLayout", getRequestParams()) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", responseParams) - end) - self.mobileSession1:ExpectResponse(cid, { - success = true, - resultCode = "SUCCESS", - displayCapabilities = { - displayType = "GEN2_8_DMA", - displayName = "GENERIC_DISPLAY", - graphicSupported = true, - imageFields = getDisplayCapImageFieldsValues(), - mediaClockFormats = { - "CLOCK1", - "CLOCK2", - "CLOCK3", - "CLOCKTEXT1", - "CLOCKTEXT2", - "CLOCKTEXT3", - "CLOCKTEXT4" - }, - numCustomPresetsAvailable = 10, - screenParams = { - resolution = { - resolutionHeight = 480, - resolutionWidth = 800 - }, - touchEventAvailable = { - doublePressAvailable = false, - multiTouchAvailable = true, - pressAvailable = true - } - }, - templatesAvailable = { - "ONSCREEN_PRESETS" - }, - textFields = getDisplayCapTextFieldsValues() - } - }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", commonSmoke.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) -runner.Step("RAI", commonSmoke.registerApp) -runner.Step("Activate App", commonSmoke.activateApp) - -runner.Title("Test") -runner.Step("Set displayLayout with display name Positive Case 1", setDisplayWithDisplayNameSuccess) - -runner.Title("Postconditions") -runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua index a31911a983..ab6ee8b20c 100644 --- a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua @@ -39,7 +39,7 @@ local VDValues = { rpm = "VEHICLEDATA_RPM", fuelLevel = "VEHICLEDATA_FUELLEVEL", fuelLevel_State = "VEHICLEDATA_FUELLEVEL_STATE", - fuelRange = "VEHICLEDATA_FUELRANGE", + fuelRange = "VEHICLEDATA_FUELRANGE" instantFuelConsumption = "VEHICLEDATA_FUELCONSUMPTION", externalTemperature = "VEHICLEDATA_EXTERNTEMP", prndl = "VEHICLEDATA_PRNDL", diff --git a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua index 96924ec0d3..ac43225490 100644 --- a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua @@ -39,7 +39,7 @@ local VDValues = { rpm = "VEHICLEDATA_RPM", fuelLevel = "VEHICLEDATA_FUELLEVEL", fuelLevel_State = "VEHICLEDATA_FUELLEVEL_STATE", - fuelRange = "VEHICLEDATA_FUELRANGE", + fuelRange = "VEHICLEDATA_FUELRANGE" instantFuelConsumption = "VEHICLEDATA_FUELCONSUMPTION", externalTemperature = "VEHICLEDATA_EXTERNTEMP", prndl = "VEHICLEDATA_PRNDL", diff --git a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua index 085fd32155..74a9dc78db 100644 --- a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua @@ -63,7 +63,7 @@ local vehicleDataValues = { type = "GASOLINE", range = 400.5 } - }, + } instantFuelConsumption = 1000.5, externalTemperature = 55.5, vin = "123456", From 732e0535ee065e8b1c5efdb6f5dd741a5932c052 Mon Sep 17 00:00:00 2001 From: Ashwin Karemore Date: Tue, 12 Jun 2018 15:02:42 +0200 Subject: [PATCH 422/681] test scripts for issue 334 --- test_scripts/API/ATF_SetMediaClockTimer.lua | 9240 +++++++++-------- .../API/ATF_SetMediaClockTimer_nonMedia.lua | 125 +- 2 files changed, 5105 insertions(+), 4260 deletions(-) diff --git a/test_scripts/API/ATF_SetMediaClockTimer.lua b/test_scripts/API/ATF_SetMediaClockTimer.lua index 6381f26edf..3c9eb1cb51 100644 --- a/test_scripts/API/ATF_SetMediaClockTimer.lua +++ b/test_scripts/API/ATF_SetMediaClockTimer.lua @@ -26,10 +26,12 @@ local arraySoftButtonsParameter = require('user_modules/shared_testcases/testCas --------------------------------------------------------------------------------------------- APIName = "SetMediaClockTimer" -- set request name -local iTimeout = 5000 +local iTimeout = 6000 local updateModeNotRequireStartEndTime = {"PAUSE", "RESUME", "CLEAR"} local updateMode = {"COUNTUP", "COUNTDOWN", "PAUSE", "RESUME", "CLEAR"} local updateModeCountUpDown = {"COUNTUP", "COUNTDOWN"} +local audioStreamingIndicatorStates={"PLAY_PAUSE","PLAY","PAUSE","STOP"} +local audioStreamingIndicatorValue = "PLAY_PAUSE"; local countDown = 0 local InBound60 = {0, 30, 59} local OutBound60 = {-1, 60} @@ -52,714 +54,903 @@ end --------------------------------------------------------------------------------------------- -------------------------------------------Preconditions------------------------------------- ---------------------------------------------------------------------------------------------- +--------------------------------------------------------------------------------------------- - --Print new line to separate Preconditions - commonFunctions:newTestCasesGroup("Preconditions") +--Print new line to separate Preconditions +commonFunctions:newTestCasesGroup("Preconditions") - --Delete app_info.dat, logs and policy table - commonSteps:DeleteLogsFileAndPolicyTable() +--Delete app_info.dat, logs and policy table +commonSteps:DeleteLogsFileAndPolicyTable() - --Activation App by sending SDL.ActivateApp +--Activation App by sending SDL.ActivateApp - function Test:ActivateApplication() - --HMI send ActivateApp request - local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications["Test Application"]}) - EXPECT_HMIRESPONSE(RequestId) - :Do(function(_,data) - if data.result.isSDLAllowed ~= true then - local RequestId = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) - -- TODO: update after resolving APPLINK-16094 EXPECT_HMIRESPONSE(RequestId,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) - EXPECT_HMIRESPONSE(RequestId) - :Do(function(_,data) - --hmi side: send request SDL.OnAllowSDLFunctionality - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) +function Test:ActivateApplication() + --HMI send ActivateApp request + local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications["Test Application"]}) + EXPECT_HMIRESPONSE(RequestId) + :Do(function(_,data) + if data.result.isSDLAllowed ~= true then + local RequestId = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) + -- TODO: update after resolving APPLINK-16094 EXPECT_HMIRESPONSE(RequestId,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) + EXPECT_HMIRESPONSE(RequestId) + :Do(function(_,data) + --hmi side: send request SDL.OnAllowSDLFunctionality + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = config.deviceMAC, name = "127.0.0.1"}}) - EXPECT_HMICALL("BasicCommunication.ActivateApp") - :Do(function(_,data) - self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) - end) - :Times(2) - end) + EXPECT_HMICALL("BasicCommunication.ActivateApp") + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) + end) + :Times(2) + end) - end - end) + end + end) - EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "FULL", systemContext = "MAIN"}) + EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "FULL", systemContext = "MAIN"}) - end +end - --2. Update policy to allow request - --TODO: Will be updated after policy flow implementation - policyTable:precondition_updatePolicy_AllowFunctionInHmiLeves({"BACKGROUND", "FULL", "LIMITED"}) +--2. Update policy to allow request +--TODO: Will be updated after policy flow implementation +policyTable:precondition_updatePolicy_AllowFunctionInHmiLeves({"BACKGROUND", "FULL", "LIMITED"},"SetMediaClockTimer") --------------------------------------------------------------------------------------------- -----------------------------------------I TEST BLOCK---------------------------------------- --CommonRequestCheck: Check of mandatory/conditional request's parameters (mobile protocol)-- --------------------------------------------------------------------------------------------- - --Begin test suit CommonRequestCheck - - --Print new line to separate test suite - commonFunctions:newTestCasesGroup("Test Suite For CommonRequestCheck") - - --Description: - -- request with all parameters - -- request with only mandatory parameters - -- request with all combinations of conditional-mandatory parameters (if exist) - -- request with one by one conditional parameters (each case - one conditional parameter) - -- request with missing mandatory parameters one by one (each case - missing one mandatory parameter) - -- request with all parameters are missing - -- request with fake parameters (fake - not from protocol, from another request) - -- request is sent with invalid JSON structure - -- different conditions of correlationID parameter (invalid, several the same etc.) - - --Begin test case CommonRequestCheck.1 - --Description: check request with all parameters - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-61 - - --Verification criteria: Sets the initial media clock value and automatic update method for HMI media screen with all parameters - - - for i=1,#updateModeCountUpDown do - Test["SetMediaClockTimer_PositiveCase_" .. tostring(updateModeCountUpDown[i]).."_SUCCESS"] = function(self) - countDown = 0 - if updateModeCountUpDown[i] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33 - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateModeCountUpDown[i] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33 - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateModeCountUpDown[i] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - :Timeout(iTimeout) - - end - end +--Begin test suit CommonRequestCheck + +--Print new line to separate test suite +commonFunctions:newTestCasesGroup("Test Suite For CommonRequestCheck") + +--Description: +-- request with all parameters +-- request with only mandatory parameters +-- request with all combinations of conditional-mandatory parameters (if exist) +-- request with one by one conditional parameters (each case - one conditional parameter) +-- request with missing mandatory parameters one by one (each case - missing one mandatory parameter) +-- request with all parameters are missing +-- request with fake parameters (fake - not from protocol, from another request) +-- request is sent with invalid JSON structure +-- different conditions of correlationID parameter (invalid, several the same etc.) + +--Begin test case CommonRequestCheck.1 +--Description: check request with all parameters + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-61 + +--Verification criteria: Sets the initial media clock value and automatic update method for HMI media screen with all parameters + + +for i=1,#updateModeCountUpDown do + Test["SetMediaClockTimer_PositiveCase_" .. tostring(updateModeCountUpDown[i]) .. "_SUCCESS"] = function(self) + countDown = 0 + if updateModeCountUpDown[i] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateModeCountUpDown[i] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateModeCountUpDown[i] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end +end + +for i=1,#updateMode do + for j=1,#audioStreamingIndicatorStates do + Test["SetMediaClockTimer_PositiveCase_" .. tostring(updateMode[i]) .. "_" .. tostring(audioStreamingIndicatorStates[j]) .. "_SUCCESS"] = function(self) + countDown = 0 + if updateMode[i] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[i], + audioStreamingIndicator = audioStreamingIndicatorStates[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[i], + audioStreamingIndicator = audioStreamingIndicatorStates[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end + end +end + +--End test case CommonRequestCheck.1 +----------------------------------------------------------------------------------------- + + +--Begin test case CommonRequestCheck.2 +--Description: check request with only mandatory parameters + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-61 + +--Verification criteria: Check request with mandatory parameter only: updateMode = "PAUSE", "RESUME" and "CLEAR" + +for i=1,#updateModeNotRequireStartEndTime do + Test["SetMediaClockTimer_OnlyMandatory_" .. tostring(updateModeNotRequireStartEndTime[i]).."_SUCCESS"] = function(self) + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + updateMode = updateModeNotRequireStartEndTime[i] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + updateMode = updateModeNotRequireStartEndTime[i] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end +end + +--End test case CommonRequestCheck.2 +----------------------------------------------------------------------------------------- + +--Skipped CommonRequestCheck.3-4: There next checks are not applicable: +-- request with all combinations of conditional-mandatory parameters (if exist) +-- request with one by one conditional parameters (each case - one conditional parameter) +----------------------------------------------------------------------------------------- + + +--Begin test case CommonRequestCheck.5 +--Description: check request with missing mandatory parameters one by one (each case - missing one mandatory parameter) + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-515 + +--Verification criteria: The request without "updateMode" is sent, the INVALID_DATA response code is returned. + +function Test:SetMediaClockTimer_missing_mandatory_parameters_updateMode_INVALID_DATA() + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 0, + minutes = 1, + seconds = 35 + } + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + +end + +function Test:SetMediaClockTimer_missing_updateMode_with_audioStreamingIndicator_INVALID_DATA() + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 0, + minutes = 1, + seconds = 35 + }, + audioStreamingIndicator="PLAY" + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + +end +--End test case CommonRequestCheck.5 +----------------------------------------------------------------------------------------- + +--Begin test case CommonRequestCheck.6 +--Description: check request with all parameters are missing + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-61 + +--Verification criteria: SDL responses invalid data + +function Test:SetMediaClockTimer_AllParameterAreMissed_INVALID_DATA() + + --mobile side: sending ReSetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { - --End test case CommonRequestCheck.1 - ----------------------------------------------------------------------------------------- + }) - --Begin test case CommonRequestCheck.2 - --Description: check request with only mandatory parameters + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-61 +end + +--End test case CommonRequestCheck.6 +----------------------------------------------------------------------------------------- + + +--Begin test case CommonRequestCheck.7 +--Description: check request with fake parameters (fake - not from protocol, from another request) + +--Requirement id in JAMA/or Jira ID: APPLINK-4518 + +--Verification criteria: According to xml tests by Ford team all fake parameters should be ignored by SDL + +--Begin test case CommonRequestCheck.7.1 +--Description: Check request with fake parameters and Audio Streaming Indicator + +for i=1,#updateMode do + Test["SetMediaClockTimer_FakeParameters_"..tostring(updateMode[i]).."_audioStreamingIndicatorValue_SUCCESS"] = function(self) + countDown = 0 + if i < 5 then + audioStreamingIndicatorValue = audioStreamingIndicatorStates[i] + else + audioStreamingIndicatorValue = "PLAY_PAUSE" + end + if updateMode[i] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + fakeParameter = "fakeParameter", + startTime = + { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[i], + audioStreamingIndicator=audioStreamingIndicatorValue + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[i], + audioStreamingIndicator=audioStreamingIndicatorValue + }) + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + if data.params.fakeParameter then + print("SDL resends fake parameter to HMI") + return false + else + return true + end + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end +end + +--End test case CommonRequestCheck.7.1 +----------------------------------------------------------------------------------------- + +--Begin test case CommonRequestCheck.7.2 +--Description: Check request with fake parameters + +for i=1,#updateMode do + Test["SetMediaClockTimer_FakeParameters_" .. tostring(updateMode[i]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[i] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + fakeParameter = "fakeParameter", + startTime = + { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[i] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[i] + }) + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + if data.params.fakeParameter then + print("SDL resends fake parameter to HMI") + return false + else + return true + end + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end +end - --Verification criteria: Check request with mandatory parameter only: updateMode = "PAUSE", "RESUME" and "CLEAR" +--End test case CommonRequestCheck.7.2 +----------------------------------------------------------------------------------------- + +--Begin test case CommonRequestCheck.7.3 +--Description: Check request with parameters of other request + +for i=1,#updateMode do + Test["SetMediaClockTimer_ParametersOfOtherRequest_" .. tostring(updateMode[i]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[i] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + syncFileName = "icon.png", --PutFile request + startTime = + { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[i], + audioStreamingIndicator=audioStreamingIndicatorValue + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[i], + audioStreamingIndicator=audioStreamingIndicatorValue + }) + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + if data.params.syncFileName then + print("SDL resends parameter of other request to HMI") + return false + else + return true + end + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end +end + +--End test case CommonRequestCheck.7.3 +----------------------------------------------------------------------------------------- - for i=1,#updateModeNotRequireStartEndTime do - Test["SetMediaClockTimer_OnlyMandatory_" .. tostring(updateModeNotRequireStartEndTime[i]).."_SUCCESS"] = function(self) +--End test case CommonRequestCheck.7 - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - updateMode = updateModeNotRequireStartEndTime[i] - }) +--Begin test case CommonRequestCheck.8 +--Description: Check request is sent with invalid JSON structure - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - updateMode = updateModeNotRequireStartEndTime[i] - }) - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-395 - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - :Timeout(iTimeout) +--Verification criteria: The request with wrong JSON syntax is sent, the response comes with INVALID_DATA result code. - end - end - - --End test case CommonRequestCheck.2 - ----------------------------------------------------------------------------------------- - - --Skipped CommonRequestCheck.3-4: There next checks are not applicable: - -- request with all combinations of conditional-mandatory parameters (if exist) - -- request with one by one conditional parameters (each case - one conditional parameter) - ----------------------------------------------------------------------------------------- - - - --Begin test case CommonRequestCheck.5 - --Description: check request with missing mandatory parameters one by one (each case - missing one mandatory parameter) - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-515 - - --Verification criteria: The request without "updateMode" is sent, the INVALID_DATA response code is returned. - - function Test:SetMediaClockTimer_missing_mandatory_parameters_updateMode_INVALID_DATA() - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33 - }, - endTime = - { - hours = 0, - minutes = 1, - seconds = 35 - } - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - - --End test case CommonRequestCheck.5 - ----------------------------------------------------------------------------------------- - - --Begin test case CommonRequestCheck.6 - --Description: check request with all parameters are missing - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-61 +function Test:SetMediaClockTimer_InvalidJSON_INVALID_DATA() - --Verification criteria: SDL responses invalid data + self.mobileSession.correlationId = self.mobileSession.correlationId + 1 - function Test:SetMediaClockTimer_AllParameterAreMissed_INVALID_DATA() + local msg = + { + serviceType = 7, + frameInfo = 0, + rpcType = 0, + rpcFunctionId = 15, --SetMediaClockTimerID + rpcCorrelationId = self.mobileSession.correlationId, + -- missing ':' after startTime + --payload = '{"startTime":{"seconds":34,"hours":0,"minutes":12},"endTime":{"seconds":33,"hours":11,"minutes":22},"updateMode":"COUNTUP"}' + payload = '{"startTime" {"seconds":34,"hours":0,"minutes":12},"endTime":{"seconds":33,"hours":11,"minutes":22},"updateMode":"COUNTUP","audioStreamingIndicator":"PLAY_PAUSE"}' + } + self.mobileSession:Send(msg) - --mobile side: sending ReSetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - - }) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - - --End test case CommonRequestCheck.6 - ----------------------------------------------------------------------------------------- - - - --Begin test case CommonRequestCheck.7 - --Description: check request with fake parameters (fake - not from protocol, from another request) - - --Requirement id in JAMA/or Jira ID: APPLINK-4518 - - --Verification criteria: According to xml tests by Ford team all fake parameters should be ignored by SDL - - --Begin test case CommonRequestCheck.7.1 - --Description: Check request with fake parameters - - for i=1,#updateMode do - Test["SetMediaClockTimer_FakeParameters_" .. tostring(updateMode[i]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[i] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - fakeParameter = "fakeParameter", - startTime = - { - hours = 0, - minutes = 1, - seconds = 33 - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[i] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33 - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[i] - }) - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - :ValidIf(function(_,data) - if data.params.fakeParameter then - print("SDL resends fake parameter to HMI") - return false - else - return true - end - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - :Timeout(iTimeout) - - end - end - - --End test case CommonRequestCheck.7.1 - ----------------------------------------------------------------------------------------- - - --Begin test case CommonRequestCheck.7.2 - --Description: Check request with parameters of other request - - for i=1,#updateMode do - Test["SetMediaClockTimer_ParametersOfOtherRequest_" .. tostring(updateMode[i]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[i] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - syncFileName = "icon.png", --PutFile request - startTime = - { - hours = 0, - minutes = 1, - seconds = 33 - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[i] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33 - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[i] - }) - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - :ValidIf(function(_,data) - if data.params.syncFileName then - print("SDL resends parameter of other request to HMI") - return false - else - return true - end - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - :Timeout(iTimeout) - - end - end - - --End test case CommonRequestCheck.7.2 - ----------------------------------------------------------------------------------------- - - --End test case CommonRequestCheck.7 - - - --Begin test case CommonRequestCheck.8 - --Description: Check request is sent with invalid JSON structure - - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-395 - - --Verification criteria: The request with wrong JSON syntax is sent, the response comes with INVALID_DATA result code. - - function Test:SetMediaClockTimer_InvalidJSON_INVALID_DATA() - - self.mobileSession.correlationId = self.mobileSession.correlationId + 1 - - local msg = - { - serviceType = 7, - frameInfo = 0, - rpcType = 0, - rpcFunctionId = 15, --SetMediaClockTimerID - rpcCorrelationId = self.mobileSession.correlationId, - -- missing ':' after startTime - --payload = '{"startTime":{"seconds":34,"hours":0,"minutes":12},"endTime":{"seconds":33,"hours":11,"minutes":22},"updateMode":"COUNTUP"}' - payload = '{"startTime" {"seconds":34,"hours":0,"minutes":12},"endTime":{"seconds":33,"hours":11,"minutes":22},"updateMode":"COUNTUP"}' - } - self.mobileSession:Send(msg) - - self.mobileSession:ExpectResponse(self.mobileSession.correlationId, { success = false, resultCode = "INVALID_DATA" }) - - end - - --End test case CommonRequestCheck.8 - ----------------------------------------------------------------------------------------- - - --Begin test case CommonRequestCheck.9 - --Description: CorrelationId is duplicated - - --Requirement id in JAMA/or Jira ID: - - --Verification criteria: response comes with SUCCESS result code. - - function Test:SetMediaClockTimer_CorrelationID_Duplicated_SUCCESS() - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33 - }, - endTime = - { - hours = 0, - minutes = 1, - seconds = 35 - }, - updateMode = "COUNTUP" - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33 - }, - endTime = - { - hours = 0, - minutes = 1, - seconds = 35 - }, - updateMode = "COUNTUP" - }) - :Times(2) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) - :Times(2) - :Do(function(exp,data) - if exp.occurences == 1 then - local msg = - { - serviceType = 7, - frameInfo = 0, - rpcType = 0, - rpcFunctionId = 15, --SetMediaClockTimerID - rpcCorrelationId = cid, - payload = '{"startTime":{"seconds":33,"hours":0,"minutes":1},"endTime":{"seconds":35,"hours":0,"minutes":1},"updateMode":"COUNTUP"}' - } - self.mobileSession:Send(msg) - end - end) - - end - - --End test case CommonRequestCheck.9 - ----------------------------------------------------------------------------------------- - - local function Task_APPLINK_15934() - - --Begin test case CommonRequestCheck.10 - --Description: StartTime without mandatory parameter - - --Requirement id in JAMA/or Jira ID: - --SDLAQ-CRS-61 - --SDLAQ-CRS-515 - - --Verification criteria: The request with "startTime" and without updateMode value is sent, the INVALID_DATA response code is returned. - - function Test:SetMediaClockTimer_StartTimeMandatoryMissing() - --mobile side: sending SetMediaClockTimer request with values of startTime only - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33 - } - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - end - --End of TC CommonRequestCheck.10 - ----------------------------------------------------------------------------------------- - - --Begin test case CommonRequestCheck.11 - --Description: check request with missing endTime - - --Requirement id in JAMA/or Jira ID: - --SDLAQ-CRS-61 - --SDLAQ-CRS-515 - - --Verification criteria: The request with "endTime" and without updateMode value is sent, the INVALID_DATA response code is returned. - function Test:SetMediaClockTimer_EndTimeMandatoryMissing() - --mobile side: sending SetMediaClockTimer request with values of endTime only - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - endTime = - { - hours = 0, - minutes = 1, - seconds = 35 - } - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - end - --End of TC CommonRequestCheck.11 - ----------------------------------------------------------------------------------------- - --Begin test case CommonRequestCheck.12 - --Description: endTime less than startTime for COUNTUP - - --Requirement id in JAMA/or Jira ID: - --SDLAQ-CRS-61 - --SDLAQ-CRS-515 - - --Verification criteria: The request with "endTime" provided for COUNTUP is less than startTime , the INVALID_DATA response code is returned. - - function Test:SetMediaClockTimer_endTimeLessStartTimeCOUNTUP() - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 12, - seconds = 34 - }, - endTime = - { - hours = 0, - minutes = 10, - seconds = 10 - }, - updateMode="COUNTUP" - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - end - --End of TC CommonRequestCheck.12 - ----------------------------------------------------------------------------------------- - --Begin test case CommonRequestCheck.13 - --Description: endTime less than startTime for COUNTDOWN - - --Requirement id in JAMA/or Jira ID: - --SDLAQ-CRS-61 - --SDLAQ-CRS-515 - - --Verification criteria: The request with "endTime" provided for COUNTDOWN is greater than startTime , the INVALID_DATA response code is returned. - - function Test:SetMediaClockTimer_endTimeGreaterStartTimeCOUNTDOWN() - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 12, - seconds = 34 - }, - endTime = - { - hours = 01, - minutes = 20, - seconds = 15 - }, - updateMode="COUNTDOWN" - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - end - --End of TC CommonRequestCheck.13 - ------------------------------------------------------------------------------------------------------- - - --Begin test case CommonRequestCheck.14 - --Description: Resuming CountUp/CountDown Timer - - --Requirement id in JAMA/or Jira ID: - --SDLAQ-CRS-61 - --SDLAQ-CRS-515 - - --Verification criteria: - --The request with "COUNTUP" or "COUNTDOWN" updateMode value is sent, the SUCCESS response code is returned. - --The request with "RESUME" updateMode value is sent, the IGNORED response code is returned. - - function Test:SetMediaClockTimer_ResumingCountUpDownTimer() - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 00, - minutes = 00, - seconds = 01 - }, - updateMode = "COUNTUP" - }) - - local cid1 = self.mobileSession:SendRPC("SetMediaClockTimer", - { - updateMode = "RESUME" - }) - - local cid2 = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 15, - minutes = 15, - seconds = 15 - }, - updateMode = "COUNTDOWN" - }) - - local cid3 = self.mobileSession:SendRPC("SetMediaClockTimer", - { - updateMode = "RESUME" - }) - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer") - :Times(4) - :Do(function(_,data) - if data.params.updateMode == "RESUME" then - --hmi side: sending UI.SetMediaClockTimer response IGNORED - self.hmiConnection:SendResponse(data.id, data.method, "IGNORED", {}) - else - --hmi side: sending UI.SetMediaClockTimer response SUCCESS - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - - end - end) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - :Timeout(iTimeout) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid1, { success = false, resultCode = "IGNORED", info = nil}) - :Timeout(iTimeout) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid2, { success = true, resultCode = "SUCCESS"}) - :Timeout(iTimeout) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid3, { success = false, resultCode = "IGNORED", info = nil}) - :Timeout(iTimeout) - - end - --End of TC CommonRequestCheck.14 - ------------------------------------------------------------------------------------------------------- - end - Task_APPLINK_15934() - - --End test suit CommonRequestCheck + self.mobileSession:ExpectResponse(self.mobileSession.correlationId, { success = false, resultCode = "INVALID_DATA" }) + +end + +--End test case CommonRequestCheck.8 +----------------------------------------------------------------------------------------- + +--Begin test case CommonRequestCheck.9 +--Description: CorrelationId is duplicated + +--Requirement id in JAMA/or Jira ID: + +--Verification criteria: response comes with SUCCESS result code. + +function Test:SetMediaClockTimer_CorrelationID_Duplicated_SUCCESS() + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 0, + minutes = 1, + seconds = 35 + }, + updateMode = "COUNTUP", + audioStreamingIndicator="PLAY_PAUSE" + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 0, + minutes = 1, + seconds = 35 + }, + updateMode = "COUNTUP", + audioStreamingIndicator="PLAY_PAUSE" + }) + :Times(2) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) + :Times(2) + :Do(function(exp,data) + if exp.occurences == 1 then + local msg = + { + serviceType = 7, + frameInfo = 0, + rpcType = 0, + rpcFunctionId = 15, --SetMediaClockTimerID + rpcCorrelationId = cid, + payload = '{"startTime":{"seconds":33,"hours":0,"minutes":1},"endTime":{"seconds":35,"hours":0,"minutes":1},"updateMode":"COUNTUP","audioStreamingIndicator":"PLAY_PAUSE"}' + } + self.mobileSession:Send(msg) + end + end) + +end + +--End test case CommonRequestCheck.9 +----------------------------------------------------------------------------------------- + +local function Task_APPLINK_15934() + + --Begin test case CommonRequestCheck.10 + --Description: StartTime without mandatory parameter + + --Requirement id in JAMA/or Jira ID: + --SDLAQ-CRS-61 + --SDLAQ-CRS-515 + + --Verification criteria: The request with "startTime" and without updateMode value is sent, the INVALID_DATA response code is returned. + + function Test:SetMediaClockTimer_StartTimeMandatoryMissing() + --mobile side: sending SetMediaClockTimer request with values of startTime only + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33 + } + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + end + --End of TC CommonRequestCheck.10 + ----------------------------------------------------------------------------------------- + + --Begin test case CommonRequestCheck.11 + --Description: check request with missing endTime + + --Requirement id in JAMA/or Jira ID: + --SDLAQ-CRS-61 + --SDLAQ-CRS-515 + + --Verification criteria: The request with "endTime" and without updateMode value is sent, the INVALID_DATA response code is returned. + function Test:SetMediaClockTimer_EndTimeMandatoryMissing() + --mobile side: sending SetMediaClockTimer request with values of endTime only + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + endTime = + { + hours = 0, + minutes = 1, + seconds = 35 + } + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + end + --End of TC CommonRequestCheck.11 + ----------------------------------------------------------------------------------------- + --Begin test case CommonRequestCheck.12 + --Description: endTime less than startTime for COUNTUP + + --Requirement id in JAMA/or Jira ID: + --SDLAQ-CRS-61 + --SDLAQ-CRS-515 + + --Verification criteria: The request with "endTime" provided for COUNTUP is less than startTime , the INVALID_DATA response code is returned. + + function Test:SetMediaClockTimer_endTimeLessStartTimeCOUNTUP() + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 12, + seconds = 34 + }, + endTime = + { + hours = 0, + minutes = 10, + seconds = 10 + }, + updateMode="COUNTUP" + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + end + --End of TC CommonRequestCheck.12 + ----------------------------------------------------------------------------------------- + --Begin test case CommonRequestCheck.13 + --Description: endTime less than startTime for COUNTDOWN + + --Requirement id in JAMA/or Jira ID: + --SDLAQ-CRS-61 + --SDLAQ-CRS-515 + + --Verification criteria: The request with "endTime" provided for COUNTDOWN is greater than startTime , the INVALID_DATA response code is returned. + + function Test:SetMediaClockTimer_endTimeGreaterStartTimeCOUNTDOWN() + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 12, + seconds = 34 + }, + endTime = + { + hours = 01, + minutes = 20, + seconds = 15 + }, + updateMode="COUNTDOWN" + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + end + --End of TC CommonRequestCheck.13 + ------------------------------------------------------------------------------------------------------- + + --Begin test case CommonRequestCheck.14 + --Description: Resuming CountUp/CountDown Timer + + --Requirement id in JAMA/or Jira ID: + --SDLAQ-CRS-61 + --SDLAQ-CRS-515 + + --Verification criteria: + --The request with "COUNTUP" or "COUNTDOWN" updateMode value is sent, the SUCCESS response code is returned. + --The request with "RESUME" updateMode value is sent, the IGNORED response code is returned. + + function Test:SetMediaClockTimer_ResumingCountUpDownTimer() + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 00, + minutes = 00, + seconds = 01 + }, + updateMode = "COUNTUP" + }) + + local cid1 = self.mobileSession:SendRPC("SetMediaClockTimer", + { + updateMode = "RESUME" + }) + + local cid2 = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 15, + minutes = 15, + seconds = 15 + }, + updateMode = "COUNTDOWN" + }) + + local cid3 = self.mobileSession:SendRPC("SetMediaClockTimer", + { + updateMode = "RESUME" + }) + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer") + :Times(4) + :Do(function(_,data) + if data.params.updateMode == "RESUME" then + --hmi side: sending UI.SetMediaClockTimer response IGNORED + self.hmiConnection:SendResponse(data.id, data.method, "IGNORED", {}) + else + --hmi side: sending UI.SetMediaClockTimer response SUCCESS + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + + end + end) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid1, { success = false, resultCode = "IGNORED", info = nil}) + :Timeout(iTimeout) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid2, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid3, { success = false, resultCode = "IGNORED", info = nil}) + :Timeout(iTimeout) + + end + --End of TC CommonRequestCheck.14 + ----------------------------------------------------------------------------------------- + + --Begin test case CommonRequestCheck.15 + --Description: check request with missing audioStreamingIndicator + + + --Verification criteria: The request with "audioStreamingIndicator" and without updateMode value is sent, the INVALID_DATA response code is returned. + function Test:SetMediaClockTimer_AudioStreamingIndicatorMandatoryMissing() + --mobile side: sending SetMediaClockTimer request with values of endTime only + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + audioStreamingIndicator="PLAY_PAUSE" + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + end + --End of TC CommonRequestCheck.15 + ----------------------------------------------------------------------------------------- +end +Task_APPLINK_15934() + +--End test suit CommonRequestCheck @@ -768,506 +959,929 @@ end ----------------------------------------Positive cases--------------------------------------- --------------------------------------------------------------------------------------------- - --=================================================================================-- - --------------------------------Positive request check------------------------------- - --=================================================================================-- - - - --Begin test suit PositiveRequestCheck - --Description: check of each request parameter value in bound and boundary conditions - - --Begin test case PositiveRequestCheck.1 - --Description: check of each request parameter value in bound and boundary conditions startTime parameter - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-2635 - - --Verification criteria: SDL re-sends startTime value to HMI within startTime parameter of UI.SetMediaClockTimer in case of any updateMode value that mobile app sends to SDL (that is, it is HMI`s responsibility to ignore startTime for PAUSE, RESUME, CLEAR and display the values correctly for COUNTUP and COUNTDOWN updateMode values). - - --Begin test case PositiveRequestCheck.1.1 - --Description: check startTime.seconds parameter value is in bound - - for i=1,#InBound60 do - for j =1, #updateMode do - Test["SetMediaClockTimer_startTime_seconds_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = InBound60[i] - }, - endTime = - { - hours = 1 + countDown, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = InBound60[i] - }, - endTime = - { - hours = 1 + countDown, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - :Timeout(iTimeout) - - end - end - end - - --End test case PositiveRequestCheck.1.1 - ----------------------------------------------------------------------------------------- - - --Begin test case PositiveRequestCheck.1.2 - --Description: check startTime.minutes parameter value is in bound - - for i=1,#InBound60 do - for j =1, #updateMode do - Test["SetMediaClockTimer_startTime_minutes_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = InBound60[i], - seconds = 3 - }, - endTime = - { - hours = 1 + countDown, - minutes = 0, - seconds = 1 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = InBound60[i], - seconds = 3 - }, - endTime = - { - hours = 1 + countDown, - minutes = 0, - seconds = 1 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - :Timeout(iTimeout) - - end - end - end - - --End test case PositiveRequestCheck.1.2 - ----------------------------------------------------------------------------------------- - - --Begin test case PositiveRequestCheck.1.3 - --Description: check startTime.hours parameter value is in bound - - for i=1,#InBound60 do - for j =1, #updateMode do - Test["SetMediaClockTimer_startTime_hours_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = InBound60[i], - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = InBound60[i], - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = InBound60[i], - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = InBound60[i], - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - :Timeout(iTimeout) - - end - end - end - - --End test case PositiveRequestCheck.1.3 - ----------------------------------------------------------------------------------------- - - --Begin test case PositiveRequestCheck.1.4 - --Description: check endTime.seconds parameter value is in bound - - for i=1,#InBound60 do - for j =1, #updateMode do - Test["SetMediaClockTimer_endTime_seconds_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 0 - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = InBound60[i] - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 0 - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = InBound60[i] - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - :Timeout(iTimeout) - - end - end - end - - --End test case PositiveRequestCheck.1.4 - ----------------------------------------------------------------------------------------- - - --Begin test case PositiveRequestCheck.1.5 - --Description: check endTime.minutes parameter value is in bound - - for i=1,#InBound60 do - for j =1, #updateMode do - Test["SetMediaClockTimer_endTime_minutes_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 1, - minutes = 0, - seconds = 3 - }, - endTime = - { - hours = 1 + countDown, - minutes = InBound60[i], - seconds = 4 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 1, - minutes = 0, - seconds = 3 - }, - endTime = - { - hours = 1 + countDown, - minutes = InBound60[i], - seconds = 4 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - :Timeout(iTimeout) - - end - end - end - - --End test case PositiveRequestCheck.1.5 - ----------------------------------------------------------------------------------------- - - --Begin test case PositiveRequestCheck.1.6 - --Description: check endTime.hours parameter value is in bound - - for i=1,#InBound60 do - for j =1, #updateMode do - Test["SetMediaClockTimer_endTime_hours_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = InBound60[i], - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = InBound60[i], - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = InBound60[i], - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = InBound60[i], - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - :Timeout(iTimeout) - - end - end - end - - - --End test case PositiveRequestCheck.1.6 - ----------------------------------------------------------------------------------------- - - --End test case PositiveRequestCheck.1 - - --End test suit PositiveRequestCheck - - - --=================================================================================-- - --------------------------------Positive response check------------------------------ - --=================================================================================-- - - --------Checks----------- - -- parameters with values in boundary conditions - - - --Begin test suit PositiveResponseCheck - --Description: Check positive responses - - - --Begin test case PositiveResponseCheck.1 - --Description: Check info parameter when UI.SetMediaClockTimer response with min-length, max-length - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 - - --Verification criteria: verify SDL forward info parameter from HMI response to Mobile - - for i=1,#info do - for j =1, #updateMode do - Test["UI_SetMediaClockTimer_Response_info_Parameter_InBound_" .. tostring(infoName[i]) .."_"..tostring(updateMode[j]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {info = info[i]}) - end) +--=================================================================================-- +--------------------------------Positive request check------------------------------- +--=================================================================================-- + + +--Begin test suit PositiveRequestCheck +--Description: check of each request parameter value in bound and boundary conditions + +--Begin test case PositiveRequestCheck.1 +--Description: check of each request parameter value in bound and boundary conditions startTime parameter + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-2635 + +--Verification criteria: SDL re-sends startTime value to HMI within startTime parameter of UI.SetMediaClockTimer in case of any updateMode value that mobile app sends to SDL (that is, it is HMI`s responsibility to ignore startTime for PAUSE, RESUME, CLEAR and display the values correctly for COUNTUP and COUNTDOWN updateMode values). + +--Begin test case PositiveRequestCheck.1.1 +--Description: check startTime.seconds parameter value is in bound + +for i=1,#InBound60 do + for j =1, #updateMode do + Test["SetMediaClockTimer_startTime_seconds_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = InBound60[i] + }, + endTime = + { + hours = 1 + countDown, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = InBound60[i] + }, + endTime = + { + hours = 1 + countDown, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end + end +end + +--End test case PositiveRequestCheck.1.1 +----------------------------------------------------------------------------------------- + +--Begin test case PositiveRequestCheck.1.2 +--Description: check startTime.minutes parameter value is in bound + +for i=1,#InBound60 do + for j =1, #updateMode do + Test["SetMediaClockTimer_startTime_minutes_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = InBound60[i], + seconds = 3 + }, + endTime = + { + hours = 1 + countDown, + minutes = 0, + seconds = 1 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = InBound60[i], + seconds = 3 + }, + endTime = + { + hours = 1 + countDown, + minutes = 0, + seconds = 1 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end + end +end +--End test case PositiveRequestCheck.1.2 +----------------------------------------------------------------------------------------- + +--Begin test case PositiveRequestCheck.1.3 +--Description: check startTime.hours parameter value is in bound + +for i=1,#InBound60 do + for j =1, #updateMode do + Test["SetMediaClockTimer_startTime_hours_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = InBound60[i], + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = InBound60[i], + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = InBound60[i], + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = InBound60[i], + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end + end +end - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", info = info[i]}) - :Timeout(iTimeout) +--End test case PositiveRequestCheck.1.3 +----------------------------------------------------------------------------------------- + +--Begin test case PositiveRequestCheck.1.4 +--Description: check endTime.seconds parameter value is in bound + +for i=1,#InBound60 do + for j =1, #updateMode do + Test["SetMediaClockTimer_endTime_seconds_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 0 + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = InBound60[i] + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 0 + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = InBound60[i] + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end + end +end + +--End test case PositiveRequestCheck.1.4 +----------------------------------------------------------------------------------------- + +--Begin test case PositiveRequestCheck.1.5 +--Description: check endTime.minutes parameter value is in bound + +for i=1,#InBound60 do + for j =1, #updateMode do + Test["SetMediaClockTimer_endTime_minutes_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 0, + seconds = 3 + }, + endTime = + { + hours = 1 + countDown, + minutes = InBound60[i], + seconds = 4 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 0, + seconds = 3 + }, + endTime = + { + hours = 1 + countDown, + minutes = InBound60[i], + seconds = 4 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end + end +end + +--End test case PositiveRequestCheck.1.5 +----------------------------------------------------------------------------------------- + +--Begin test case PositiveRequestCheck.1.6 +--Description: check endTime.hours parameter value is in bound + +for i=1,#InBound60 do + for j =1, #updateMode do + Test["SetMediaClockTimer_endTime_hours_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = InBound60[i], + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = InBound60[i], + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = InBound60[i], + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = InBound60[i], + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end + end +end + + +--End test case PositiveRequestCheck.1.6 +----------------------------------------------------------------------------------------- + +--End test case PositiveRequestCheck.2 + +--Begin test case PositiveRequestCheck.2.1 +--Description: check startTime.seconds parameter value is in bound with Audio Streaming Indicator + +for i=1,#InBound60 do + for j =1, #updateMode do + for k =1, #audioStreamingIndicatorStates do + Test["SetMediaClockTimer_startTime_seconds_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]) .."_"..tostring(audioStreamingIndicatorStates[k]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = InBound60[i] + }, + endTime = + { + hours = 1 + countDown, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = InBound60[i] + }, + endTime = + { + hours = 1 + countDown, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end + end + end +end + +--End test case PositiveRequestCheck.2.1 +----------------------------------------------------------------------------------------- + +--Begin test case PositiveRequestCheck.2.2 +--Description: check startTime.minutes parameter value is in bound with Audio Streaming Indicator + +for i=1,#InBound60 do + for j =1, #updateMode do + for k =1, #audioStreamingIndicatorStates do + Test["SetMediaClockTimer_startTime_minutes_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]) .."_"..tostring(audioStreamingIndicatorStates[k]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = InBound60[i], + seconds = 3 + }, + endTime = + { + hours = 1 + countDown, + minutes = 0, + seconds = 1 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = InBound60[i], + seconds = 3 + }, + endTime = + { + hours = 1 + countDown, + minutes = 0, + seconds = 1 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end + end + end +end + +--End test case PositiveRequestCheck.2.2 +----------------------------------------------------------------------------------------- + +--Begin test case PositiveRequestCheck.2.3 +--Description: check startTime.hours parameter value is in bound with Audio Streaming Indicator + +for i=1,#InBound60 do + for j =1, #updateMode do + for k =1, #audioStreamingIndicatorStates do + Test["SetMediaClockTimer_startTime_hours_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]) .."_"..tostring(audioStreamingIndicatorStates[k]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = InBound60[i], + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = InBound60[i], + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = InBound60[i], + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = InBound60[i], + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end + end + end +end + +--End test case PositiveRequestCheck.2.3 +----------------------------------------------------------------------------------------- + +--Begin test case PositiveRequestCheck.2.4 +--Description: check endTime.seconds parameter value is in bound with Audio Streaming Indicator + +for i=1,#InBound60 do + for j =1, #updateMode do + for k =1, #audioStreamingIndicatorStates do + Test["SetMediaClockTimer_endTime_seconds_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]) .."_"..tostring(audioStreamingIndicatorStates[k]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 0 + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = InBound60[i] + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 0 + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = InBound60[i] + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end + end + end +end + +--End test case PositiveRequestCheck.2.4 +----------------------------------------------------------------------------------------- + +--Begin test case PositiveRequestCheck.2.5 +--Description: check endTime.minutes parameter value is in bound with Audio Streaming Indicator + +for i=1,#InBound60 do + for j =1, #updateMode do + for k =1, #audioStreamingIndicatorStates do + Test["SetMediaClockTimer_endTime_minutes_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]) .."_"..tostring(audioStreamingIndicatorStates[k]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 0, + seconds = 3 + }, + endTime = + { + hours = 1 + countDown, + minutes = InBound60[i], + seconds = 4 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 0, + seconds = 3 + }, + endTime = + { + hours = 1 + countDown, + minutes = InBound60[i], + seconds = 4 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end + end + end +end + +--End test case PositiveRequestCheck.2.5 +----------------------------------------------------------------------------------------- + +--Begin test case PositiveRequestCheck.2.6 +--Description: check endTime.hours parameter value is in bound with Audio Streaming Indicator + +for i=1,#InBound60 do + for j =1, #updateMode do + for k =1, #audioStreamingIndicatorStates do + Test["SetMediaClockTimer_endTime_hours_InBound_" .. tostring(InBound60[i]) .."_"..tostring(updateMode[j]) .."_"..tostring(audioStreamingIndicatorStates[k]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = InBound60[i], + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = InBound60[i], + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = InBound60[i], + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = InBound60[i], + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + :Timeout(iTimeout) + + end + end + end +end - end - end - end - --End test case CommonRequestCheck.1 - ----------------------------------------------------------------------------------------- +--End test case PositiveRequestCheck.2.6 +----------------------------------------------------------------------------------------- - --End test suit PositiveResponseCheck +--End test case PositiveRequestCheck.2 + +--End test suit PositiveRequestCheck + + +--=================================================================================-- +--------------------------------Positive response check------------------------------ +--=================================================================================-- + +--------Checks----------- +-- parameters with values in boundary conditions + + +--Begin test suit PositiveResponseCheck +--Description: Check positive responses + + +--Begin test case PositiveResponseCheck.1 +--Description: Check info parameter when UI.SetMediaClockTimer response with min-length, max-length + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 + +--Verification criteria: verify SDL forward info parameter from HMI response to Mobile + +for i=1,#info do + for j =1, #updateMode do + Test["UI_SetMediaClockTimer_Response_info_Parameter_InBound_" .. tostring(infoName[i]) .."_"..tostring(updateMode[j]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {info = info[i]}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", info = info[i]}) + :Timeout(iTimeout) + + end + end +end + +--End test case CommonRequestCheck.1 +----------------------------------------------------------------------------------------- + +--End test suit PositiveResponseCheck ---------------------------------------------------------------------------------------------- @@ -1275,1914 +1889,2020 @@ end ----------------------------------------Negative cases---------------------------------------- ---------------------------------------------------------------------------------------------- - --=================================================================================-- - ---------------------------------Negative request check------------------------------ - --=================================================================================-- - --------Checks----------- - -- outbound values - -- invalid values(empty, missing, nonexistent, duplicate, invalid characters) - -- parameters with wrong type - -- invalid json - - --Begin test suit NegativeRequestCheck - --Description: check of each request parameter value out of bound, missing, with wrong type, empty, duplicate etc. - - - --Begin test case NegativeRequestCheck.1 - --Description: check of each request parameter value out bound and boundary conditions - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-2635, SDLAQ-CRS-515 - - --Verification criteria: - --2.1. The request with "hours" value out of bounds is sent, the response comes with INVALID_DATA result code (even if updateMode is not COUNTUP/COUNTDOWN). - --2.2. The request with "minutes" value out of bounds is sent, the response comes with INVALID_DATA result code (even if updateMode is not COUNTUP/COUNTDOWN). - --2.3. The request with "seconds" value out of bounds is sent, the response comes with INVALID_DATA result code (even if updateMode is not COUNTUP/COUNTDOWN). - --2.4. The request with wrong data in "updateMode" parameter (e.g. value which doesn't exist in "UpdateMode" enum) is sent , the response with INVALID_DATA result code is returned. - - --Begin test case NegativeRequestCheck.1.1 - --Description: Check startTime.seconds parameter value is in outbound - - - for i=1,#OutBound60 do - for j =1, #updateMode do - Test["SetMediaClockTimer_startTime_seconds_OutBound_" .. tostring(OutBound60[i]) .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = OutBound60[i] - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - end - - - --End test case NegativeRequestCheck.1.1 - ----------------------------------------------------------------------------------------- - - - --Begin test case NegativeRequestCheck.1.2 - --Description: Check startTime.minutes parameter value is in outbound - - for i=1,#OutBound60 do - for j =1, #updateMode do - Test["SetMediaClockTimer_startTime_minutes_OutBound_" .. tostring(OutBound60[i]) .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = OutBound60[i], - seconds = 3 - }, - endTime = - { - hours = 1 + countDown, - minutes = 0, - seconds = 1 - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - end - - - --End test case NegativeRequestCheck.1.2 - ----------------------------------------------------------------------------------------- - - --Begin test case NegativeRequestCheck.1.3 - --Description: Check startTime.hours parameter value is in outbound - - for i=1,#OutBound60 do - for j =1, #updateMode do - Test["SetMediaClockTimer_startTime_hours_OutBound_" .. tostring(OutBound60[i]) .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = OutBound60[i], - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = OutBound60[i], - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - end - - --End test case NegativeRequestCheck.1.3 - ----------------------------------------------------------------------------------------- - - - --Begin test case NegativeRequestCheck.1.4 - --Description: Check endTime.seconds parameter value is in outbound - - for i=1,#OutBound60 do - for j =1, #updateMode do - Test["SetMediaClockTimer_endTime_seconds_OutBound_" .. tostring(OutBound60[i]) .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 0 - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = OutBound60[i] - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - end - - --End test case NegativeRequestCheck.1.4 - ----------------------------------------------------------------------------------------- - - - --Begin test case NegativeRequestCheck.1.5 - --Description: Check endTime.minutes parameter value is in outbound - - for i=1,#OutBound60 do - for j =1, #updateMode do - Test["SetMediaClockTimer_endTime_minutes_OutBound_" .. tostring(OutBound60[i]) .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 1, - minutes = 0, - seconds = 3 - }, - endTime = - { - hours = 1 + countDown, - minutes = OutBound60[i], - seconds = 4 - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - end - - --End test case NegativeRequestCheck.1.5 - ----------------------------------------------------------------------------------------- - - --Begin test case NegativeRequestCheck.1.6 - --Description: Check endTime.hours parameter value is in outbound - - for i=1,#OutBound60 do - for j =1, #updateMode do - Test["SetMediaClockTimer_endTime_hours_OutBound_" .. tostring(OutBound60[i]) .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = OutBound60[i], - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = OutBound60[i], - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - end - - --End test case NegativeRequestCheck.1.6 - ----------------------------------------------------------------------------------------- - - --Begin test case NegativeRequestCheck.1.7 - --Description: check of each request parameter value out bound and boundary conditions updateMode parameter - - function Test:SetMediaClockTimer_updateMode_IsInvalidValue_WrongValue_Or_nonexistent_INVALID_DATA() - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 1, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 1, - minutes = 1, - seconds = 35 - }, - updateMode = "updateMode" - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - - --End test case NegativeRequestCheck.1.7 - ----------------------------------------------------------------------------------------- - - --End test case NegativeRequestCheck.1 - - - - --Begin test case NegativeRequestCheck.2 - --Description: invalid values(empty, missing, nonexistent, duplicate, invalid characters) - - --Begin test case NegativeRequestCheck.2.1 - --Description: invalid values(empty) - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-515 - - --Verification criteria: - --5.1.The request with empty "updateMode" is sent , the response with INVALID_DATA result code is returned. - --5.2.The request with empty "hours" value is sent , the response with INVALID_DATA result code is returned. - --5.3.The request with empty "minutes" value is sent, the response with INVALID_DATA result code is returned. - --5.4.The request with empty "seconds" value is sent, the response with INVALID_DATA result code is returned. - - --Begin test case NegativeRequestCheck.2.1.1 - --Description: 5.1.The request with empty "updateMode" is sent , the response with INVALID_DATA result code is returned. - - function Test:SetMediaClockTimer_updateMode_IsInvalidValue_Empty_INVALID_DATA() - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 1, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 1, - minutes = 1, - seconds = 35 - }, - updateMode = "" - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - - --End test case NegativeRequestCheck.2.1.1 - ----------------------------------------------------------------------------------------- - - - --Begin test case NegativeRequestCheck.2.1.2 - --Description: 5.2.The request with empty "hours" value is sent , the response with INVALID_DATA result code is returned. - - --startTime - for j =1, #updateMode do - Test["SetMediaClockTimer_startTime_hours_IsInvalidValue_Empty" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = "", - minutes = 1, - seconds = 33 - }, - endTime = - { - hours = 1, - minutes = 1, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - - --endTime - for j =1, #updateMode do - Test["SetMediaClockTimer_endTime_hours_IsInvalidValue_Empty" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 1, - minutes = 1, - seconds = 33 - }, - endTime = - { - hours = "", - minutes = 1, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - - - --End test case NegativeRequestCheck.2.1.2 - ----------------------------------------------------------------------------------------- - - --Begin test case NegativeRequestCheck.2.1.3 - --Description: 5.3.The request with empty "minutes" value is sent, the response with INVALID_DATA result code is returned. - - --startTime - for j =1, #updateMode do - Test["SetMediaClockTimer_startTime_minutes_IsInvalidValue_Empty" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = "", - seconds = 33 - }, - endTime = - { - hours = 1, - minutes = 1, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - - --endTime - for j =1, #updateMode do - Test["SetMediaClockTimer_endTime_minutes_IsInvalidValue_Empty" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33 - }, - endTime = - { - hours = 1, - minutes = "", - seconds = 35 - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - - --End test case NegativeRequestCheck.2.1.3 - ----------------------------------------------------------------------------------------- - - --Begin test case NegativeRequestCheck.2.1.4 - --Description: 5.4.The request with empty "seconds" value is sent, the response with INVALID_DATA result code is returned. - - --startTime - for j =1, #updateMode do - Test["SetMediaClockTimer_startTime_seconds_IsInvalidValue_Empty" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = "" - }, - endTime = - { - hours = 1, - minutes = 1, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - - --endTime - for j =1, #updateMode do - Test["SetMediaClockTimer_endTime_seconds_IsInvalidValue_Empty" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 1 - }, - endTime = - { - hours = 1, - minutes = 1, - seconds = "" - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - - --End test case NegativeRequestCheck.2.1.4 - ----------------------------------------------------------------------------------------- - - --End test case NegativeRequestCheck.2.1 - - - --Begin test case NegativeRequestCheck.2.2 - --Description: invalid values(missing) - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-515 - - --Verification criteria: - --3.1. The request without "updateMode" is sent, the INVALID_DATA response code is returned. - --3.2. The request without "startTime" and with "COUNTUP" updateMode value is sent, the INVALID_DATA response code is returned. - --3.3. The request without "startTime" and with "COUNTDOWN" updateMode value is sent, the INVALID_DATA response code is returned. - - --Begin test case NegativeRequestCheck.2.2.1 - --Description: 3.1. The request without "updateMode" is sent, the INVALID_DATA response code is returned. - - function Test:SetMediaClockTimer_updateMode_IsInvalidValue_missing_INVALID_DATA() - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 1, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 1, - minutes = 1, - seconds = 35 - } - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - - --End test case NegativeRequestCheck.2.2.1 - ----------------------------------------------------------------------------------------- - - --Begin test case NegativeRequestCheck.2.2.2 - --Description: - --3.2. The request without "startTime" and with "COUNTUP" updateMode value is sent, the INVALID_DATA response code is returned. - --3.3. The request without "startTime" and with "COUNTDOWN" updateMode value is sent, the INVALID_DATA response code is returned. - - --startTime - for j =1, #updateModeCountUpDown do - Test["SetMediaClockTimer_startTime_IsInvalidValue_missing" .."_"..tostring(updateModeCountUpDown[j]).."_INVALID_DATA"] = function(self) - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - endTime = - { - hours = 1, - minutes = 1, - seconds = 35 - }, - updateMode = updateModeCountUpDown[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - - --End test case NegativeRequestCheck.2.2.2 - ----------------------------------------------------------------------------------------- - - --End test case NegativeRequestCheck.2.2 - - --End test case NegativeRequestCheck.2 - - - --Begin test case NegativeRequestCheck.3 - --Description: parameters with wrong type - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-515 - - --Verification criteria: - --4.1. The request with wrong data in "hours" parameter (e.g. string value) is sent , the response with INVALID_DATA result code is returned. - --4.2. The request with wrong data in "minutes" parameter (e.g. string value) is sent , the response with INVALID_DATA result code is returned. - --4.3. The request with wrong data in "seconds" parameter (e.g. string value) is sent , the response with INVALID_DATA result code is returned. - --4.4. The request with wrong data in "updateMode" parameter (e.g. inetger value) is sent , the response with INVALID_DATA result code is returned. - - --Begin test case NegativeRequestCheck.3.1 - --Description: 4.1. The request with wrong data in "hours" parameter (e.g. string value) is sent , the response with INVALID_DATA result code is returned. - - --startTime - for j =1, #updateMode do - Test["SetMediaClockTimer_startTime_hours_IsInvalidValue_wrongType" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = "1", - minutes = 1, - seconds = 33 - }, - endTime = - { - hours = 1, - minutes = 1, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - - --endTime - for j =1, #updateMode do - Test["SetMediaClockTimer_endTime_hours_IsInvalidValue_WrongType" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 1, - minutes = 1, - seconds = 33 - }, - endTime = - { - hours = "1", - minutes = 1, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - - - --End test case NegativeRequestCheck.3.1 - ----------------------------------------------------------------------------------------- - - --Begin test case NegativeRequestCheck.3.2 - --Description: 4.2. The request with wrong data in "minutes" parameter (e.g. string value) is sent , the response with INVALID_DATA result code is returned. - - --startTime - for j =1, #updateMode do - Test["SetMediaClockTimer_startTime_minutes_IsInvalidValue_wrongType" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 1, - minutes = "1", - seconds = 33 - }, - endTime = - { - hours = 1, - minutes = 1, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - - --endTime - for j =1, #updateMode do - Test["SetMediaClockTimer_endTime_minutes_IsInvalidValue_WrongType" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 1, - minutes = 1, - seconds = 33 - }, - endTime = - { - hours = 1, - minutes = "1", - seconds = 35 - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - - - --End test case NegativeRequestCheck.3.2 - ----------------------------------------------------------------------------------------- - - - --Begin test case NegativeRequestCheck.3.2 - --Description: 4.3. The request with wrong data in "seconds" parameter (e.g. string value) is sent , the response with INVALID_DATA result code is returned. - - --startTime - for j =1, #updateMode do - Test["SetMediaClockTimer_startTime_seconds_IsInvalidValue_wrongType" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 1, - minutes = 1, - seconds = "33" - }, - endTime = - { - hours = 1, - minutes = 1, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - - --endTime - for j =1, #updateMode do - Test["SetMediaClockTimer_endTime_seconds_IsInvalidValue_WrongType" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 1, - minutes = 1, - seconds = 33 - }, - endTime = - { - hours = 1, - minutes = 1, - seconds = "35" - }, - updateMode = updateMode[j] - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - end - - - --End test case NegativeRequestCheck.3.2 - ----------------------------------------------------------------------------------------- - - --Begin test case NegativeRequestCheck.3.3 - --Description: 4.4. The request with wrong data in "updateMode" parameter (e.g. integer value) is sent , the response with INVALID_DATA result code is returned. - - function Test:SetMediaClockTimer_updateMode_IsInvalidValue_WrongType_INVALID_DATA() - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 1, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 1, - minutes = 1, - seconds = 35 - }, - updateMode = 1 - }) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(iTimeout) - - end - - --End test case NegativeRequestCheck.3.3 - ----------------------------------------------------------------------------------------- - - --End test case NegativeRequestCheck.3 - - - --End test suit NegativeRequestCheck - - - --=================================================================================-- - ---------------------------------Negative response check------------------------------ - --=================================================================================-- - - --------Checks----------- - -- outbound values - -- invalid values(empty, missing, nonexistent, invalid characters) - -- parameters with wrong type - -- invalid json - - --Begin test suit NegativeResponseCheck - --Description: check negative response - - - --Begin test case NegativeResponseCheck.1 - --Description: Check info parameter when UI.SetMediaClockTimer response with outbound values +--=================================================================================-- +---------------------------------Negative request check------------------------------ +--=================================================================================-- +--------Checks----------- +-- outbound values +-- invalid values(empty, missing, nonexistent, duplicate, invalid characters) +-- parameters with wrong type +-- invalid json + +--Begin test suit NegativeRequestCheck +--Description: check of each request parameter value out of bound, missing, with wrong type, empty, duplicate etc. + + +--Begin test case NegativeRequestCheck.1 +--Description: check of each request parameter value out bound and boundary conditions + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-2635, SDLAQ-CRS-515 + +--Verification criteria: +--2.1. The request with "hours" value out of bounds is sent, the response comes with INVALID_DATA result code (even if updateMode is not COUNTUP/COUNTDOWN). +--2.2. The request with "minutes" value out of bounds is sent, the response comes with INVALID_DATA result code (even if updateMode is not COUNTUP/COUNTDOWN). +--2.3. The request with "seconds" value out of bounds is sent, the response comes with INVALID_DATA result code (even if updateMode is not COUNTUP/COUNTDOWN). +--2.4. The request with wrong data in "updateMode" parameter (e.g. value which doesn't exist in "UpdateMode" enum) is sent , the response with INVALID_DATA result code is returned. + +--Begin test case NegativeRequestCheck.1.1 +--Description: Check startTime.seconds parameter value is in outbound + + +for i=1,#OutBound60 do + for j =1, #updateMode do + Test["SetMediaClockTimer_startTime_seconds_OutBound_" .. tostring(OutBound60[i]) .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = OutBound60[i] + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end + end +end + + +--End test case NegativeRequestCheck.1.1 +----------------------------------------------------------------------------------------- + + +--Begin test case NegativeRequestCheck.1.2 +--Description: Check startTime.minutes parameter value is in outbound + +for i=1,#OutBound60 do + for j =1, #updateMode do + Test["SetMediaClockTimer_startTime_minutes_OutBound_" .. tostring(OutBound60[i]) .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = OutBound60[i], + seconds = 3 + }, + endTime = + { + hours = 1 + countDown, + minutes = 0, + seconds = 1 + }, + updateMode = updateMode[j] + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end + end +end + + +--End test case NegativeRequestCheck.1.2 +----------------------------------------------------------------------------------------- + +--Begin test case NegativeRequestCheck.1.3 +--Description: Check startTime.hours parameter value is in outbound + +for i=1,#OutBound60 do + for j =1, #updateMode do + Test["SetMediaClockTimer_startTime_hours_OutBound_" .. tostring(OutBound60[i]) .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = OutBound60[i], + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = OutBound60[i], + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end + end +end + +--End test case NegativeRequestCheck.1.3 +----------------------------------------------------------------------------------------- + + +--Begin test case NegativeRequestCheck.1.4 +--Description: Check endTime.seconds parameter value is in outbound + +for i=1,#OutBound60 do + for j =1, #updateMode do + Test["SetMediaClockTimer_endTime_seconds_OutBound_" .. tostring(OutBound60[i]) .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 0 + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = OutBound60[i] + }, + updateMode = updateMode[j] + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end + end +end + +--End test case NegativeRequestCheck.1.4 +----------------------------------------------------------------------------------------- + + +--Begin test case NegativeRequestCheck.1.5 +--Description: Check endTime.minutes parameter value is in outbound + +for i=1,#OutBound60 do + for j =1, #updateMode do + Test["SetMediaClockTimer_endTime_minutes_OutBound_" .. tostring(OutBound60[i]) .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 0, + seconds = 3 + }, + endTime = + { + hours = 1 + countDown, + minutes = OutBound60[i], + seconds = 4 + }, + updateMode = updateMode[j] + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end + end +end + +--End test case NegativeRequestCheck.1.5 +----------------------------------------------------------------------------------------- + +--Begin test case NegativeRequestCheck.1.6 +--Description: Check endTime.hours parameter value is in outbound + +for i=1,#OutBound60 do + for j =1, #updateMode do + Test["SetMediaClockTimer_endTime_hours_OutBound_" .. tostring(OutBound60[i]) .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = OutBound60[i], + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = OutBound60[i], + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end + end +end + +--End test case NegativeRequestCheck.1.6 +----------------------------------------------------------------------------------------- + +--Begin test case NegativeRequestCheck.1.7 +--Description: check of each request parameter value out bound and boundary conditions updateMode parameter + +function Test:SetMediaClockTimer_updateMode_IsInvalidValue_WrongValue_Or_nonexistent_INVALID_DATA() + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 1, + minutes = 1, + seconds = 35 + }, + updateMode = "updateMode" + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + +end + +--End test case NegativeRequestCheck.1.7 +----------------------------------------------------------------------------------------- + + +--Begin test case NegativeRequestCheck.1.8 +--Description: check of each request parameter value out bound and boundary conditions updateMode parameter + +function Test:SetMediaClockTimer_updateMode_IsInvalidValue_WrongValue_Or_nonexistent_AudioStreamingIndicator_INVALID_DATA() + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 1, + minutes = 1, + seconds = 35 + }, + updateMode = "updateMode", + audioStreamingIndicator="PLAY_PAUSE" + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + +end + +--End test case NegativeRequestCheck.1.8 +----------------------------------------------------------------------------------------- + +--End test case NegativeRequestCheck.1 + + + +--Begin test case NegativeRequestCheck.2 +--Description: invalid values(empty, missing, nonexistent, duplicate, invalid characters) + +--Begin test case NegativeRequestCheck.2.1 +--Description: invalid values(empty) + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-515 + +--Verification criteria: +--5.1.The request with empty "updateMode" is sent , the response with INVALID_DATA result code is returned. +--5.2.The request with empty "hours" value is sent , the response with INVALID_DATA result code is returned. +--5.3.The request with empty "minutes" value is sent, the response with INVALID_DATA result code is returned. +--5.4.The request with empty "seconds" value is sent, the response with INVALID_DATA result code is returned. + +--Begin test case NegativeRequestCheck.2.1.1 +--Description: 5.1.The request with empty "updateMode" is sent , the response with INVALID_DATA result code is returned. + +function Test:SetMediaClockTimer_updateMode_IsInvalidValue_Empty_INVALID_DATA() + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 1, + minutes = 1, + seconds = 35 + }, + updateMode = "", + audioStreamingIndicator="PLAY_PAUSE" + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + +end + +--End test case NegativeRequestCheck.2.1.1 +----------------------------------------------------------------------------------------- + + +--Begin test case NegativeRequestCheck.2.1.2 +--Description: 5.2.The request with empty "hours" value is sent , the response with INVALID_DATA result code is returned. + +--startTime +for j =1, #updateMode do + Test["SetMediaClockTimer_startTime_hours_IsInvalidValue_Empty" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = "", + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 1, + minutes = 1, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator="PLAY_PAUSE" + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end +end + +--endTime +for j =1, #updateMode do + Test["SetMediaClockTimer_endTime_hours_IsInvalidValue_Empty" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = "", + minutes = 1, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator="PLAY_PAUSE" + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end +end + + +--End test case NegativeRequestCheck.2.1.2 +----------------------------------------------------------------------------------------- + +--Begin test case NegativeRequestCheck.2.1.3 +--Description: 5.3.The request with empty "minutes" value is sent, the response with INVALID_DATA result code is returned. + +--startTime +for j =1, #updateMode do + Test["SetMediaClockTimer_startTime_minutes_IsInvalidValue_Empty" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = "", + seconds = 33 + }, + endTime = + { + hours = 1, + minutes = 1, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator="PLAY_PAUSE" + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end +end + +--endTime +for j =1, #updateMode do + Test["SetMediaClockTimer_endTime_minutes_IsInvalidValue_Empty" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 1, + minutes = "", + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator="PLAY_PAUSE" + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end +end + +--End test case NegativeRequestCheck.2.1.3 +----------------------------------------------------------------------------------------- + +--Begin test case NegativeRequestCheck.2.1.4 +--Description: 5.4.The request with empty "seconds" value is sent, the response with INVALID_DATA result code is returned. + +--startTime +for j =1, #updateMode do + Test["SetMediaClockTimer_startTime_seconds_IsInvalidValue_Empty" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = "" + }, + endTime = + { + hours = 1, + minutes = 1, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end +end + +--endTime +for j =1, #updateMode do + Test["SetMediaClockTimer_endTime_seconds_IsInvalidValue_Empty" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 1 + }, + endTime = + { + hours = 1, + minutes = 1, + seconds = "" + }, + updateMode = updateMode[j] + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end +end + +--End test case NegativeRequestCheck.2.1.4 +----------------------------------------------------------------------------------------- + +--Begin test case NegativeRequestCheck.2.1.5 +--Description: 5.1.The request with empty "audioStreamingIndicator" is sent , the response with INVALID_DATA result code is returned. + +function Test:SetMediaClockTimer_audioStreamingIndicator_IsInvalidValue_Empty_INVALID_DATA() + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 1, + minutes = 1, + seconds = 35 + }, + updateMode = "COUNTUP", + audioStreamingIndicator="" + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + +end + +--End test case NegativeRequestCheck.2.1.5 +----------------------------------------------------------------------------------------- + +--End test case NegativeRequestCheck.2.1 + + +--Begin test case NegativeRequestCheck.2.2 +--Description: invalid values(missing) + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-515 + +--Verification criteria: +--3.1. The request without "updateMode" is sent, the INVALID_DATA response code is returned. +--3.2. The request without "startTime" and with "COUNTUP" updateMode value is sent, the INVALID_DATA response code is returned. +--3.3. The request without "startTime" and with "COUNTDOWN" updateMode value is sent, the INVALID_DATA response code is returned. + +--Begin test case NegativeRequestCheck.2.2.1 +--Description: 3.1. The request without "updateMode" is sent, the INVALID_DATA response code is returned. + +function Test:SetMediaClockTimer_updateMode_IsInvalidValue_missing_INVALID_DATA() + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 1, + minutes = 1, + seconds = 35 + } + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + +end + +--End test case NegativeRequestCheck.2.2.1 +----------------------------------------------------------------------------------------- + +--Begin test case NegativeRequestCheck.2.2.2 +--Description: +--3.2. The request without "startTime" and with "COUNTUP" updateMode value is sent, the INVALID_DATA response code is returned. +--3.3. The request without "startTime" and with "COUNTDOWN" updateMode value is sent, the INVALID_DATA response code is returned. + +--startTime +for j =1, #updateModeCountUpDown do + Test["SetMediaClockTimer_startTime_IsInvalidValue_missing" .."_"..tostring(updateModeCountUpDown[j]).."_INVALID_DATA"] = function(self) + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + endTime = + { + hours = 1, + minutes = 1, + seconds = 35 + }, + updateMode = updateModeCountUpDown[j] + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end +end + +--End test case NegativeRequestCheck.2.2.2 +----------------------------------------------------------------------------------------- + +--End test case NegativeRequestCheck.2.2 + +--End test case NegativeRequestCheck.2 + + +--Begin test case NegativeRequestCheck.3 +--Description: parameters with wrong type + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-515 + +--Verification criteria: +--4.1. The request with wrong data in "hours" parameter (e.g. string value) is sent , the response with INVALID_DATA result code is returned. +--4.2. The request with wrong data in "minutes" parameter (e.g. string value) is sent , the response with INVALID_DATA result code is returned. +--4.3. The request with wrong data in "seconds" parameter (e.g. string value) is sent , the response with INVALID_DATA result code is returned. +--4.4. The request with wrong data in "updateMode" parameter (e.g. inetger value) is sent , the response with INVALID_DATA result code is returned. + +--Begin test case NegativeRequestCheck.3.1 +--Description: 4.1. The request with wrong data in "hours" parameter (e.g. string value) is sent , the response with INVALID_DATA result code is returned. + +--startTime +for j =1, #updateMode do + Test["SetMediaClockTimer_startTime_hours_IsInvalidValue_wrongType" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = "1", + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 1, + minutes = 1, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end +end + +--endTime +for j =1, #updateMode do + Test["SetMediaClockTimer_endTime_hours_IsInvalidValue_WrongType" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = "1", + minutes = 1, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end +end + + +--End test case NegativeRequestCheck.3.1 +----------------------------------------------------------------------------------------- + +--Begin test case NegativeRequestCheck.3.2 +--Description: 4.2. The request with wrong data in "minutes" parameter (e.g. string value) is sent , the response with INVALID_DATA result code is returned. + +--startTime +for j =1, #updateMode do + Test["SetMediaClockTimer_startTime_minutes_IsInvalidValue_wrongType" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = "1", + seconds = 33 + }, + endTime = + { + hours = 1, + minutes = 1, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end +end + +--endTime +for j =1, #updateMode do + Test["SetMediaClockTimer_endTime_minutes_IsInvalidValue_WrongType" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 1, + minutes = "1", + seconds = 35 + }, + updateMode = updateMode[j] + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end +end + + +--End test case NegativeRequestCheck.3.2 +----------------------------------------------------------------------------------------- + + +--Begin test case NegativeRequestCheck.3.2 +--Description: 4.3. The request with wrong data in "seconds" parameter (e.g. string value) is sent , the response with INVALID_DATA result code is returned. + +--startTime +for j =1, #updateMode do + Test["SetMediaClockTimer_startTime_seconds_IsInvalidValue_wrongType" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 1, + seconds = "33" + }, + endTime = + { + hours = 1, + minutes = 1, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end +end + +--endTime +for j =1, #updateMode do + Test["SetMediaClockTimer_endTime_seconds_IsInvalidValue_WrongType" .."_"..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 1, + minutes = 1, + seconds = "35" + }, + updateMode = updateMode[j] + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end +end + + +--End test case NegativeRequestCheck.3.2 +----------------------------------------------------------------------------------------- + +--Begin test case NegativeRequestCheck.3.3 +--Description: 4.4. The request with wrong data in "updateMode" parameter (e.g. integer value) is sent , the response with INVALID_DATA result code is returned. + +function Test:SetMediaClockTimer_updateMode_IsInvalidValue_WrongType_INVALID_DATA() + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 1, + minutes = 1, + seconds = 35 + }, + updateMode = 1 + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + +end + +--End test case NegativeRequestCheck.3.3 +----------------------------------------------------------------------------------------- + + +--Begin test case NegativeRequestCheck.3.4 +--Description: 4.4. The request with wrong data in "audioStreamingIndicator" parameter (e.g. integer value) is sent , the response with INVALID_DATA result code is returned. + +function Test:SetMediaClockTimer_audioStreamingIndicator_IsInvalidValue_WrongType_INVALID_DATA() + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 1, + minutes = 1, + seconds = 35 + }, + updateMode = "COUNTUP", + audioStreamingIndicator="FAKE" + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + +end + +--End test case NegativeRequestCheck.3.4 +------------------------------------------------------------------------------------------- + +--End test case NegativeRequestCheck.3 + + +--End test suit NegativeRequestCheck + + +--=================================================================================-- +---------------------------------Negative response check------------------------------ +--=================================================================================-- + +--------Checks----------- +-- outbound values +-- invalid values(empty, missing, nonexistent, invalid characters) +-- parameters with wrong type +-- invalid json + +--Begin test suit NegativeResponseCheck +--Description: check negative response + + +--Begin test case NegativeResponseCheck.1 +--Description: Check info parameter when UI.SetMediaClockTimer response with outbound values --[[ToDO: will be updated according to APPLINK-14765: Processing invalid messages from HMI - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62, APPLINK-14551 - - --Verification criteria: verify SDL truncates info parameter then forwards it to Mobile - - for i=1,#infoOutBound do - for j =1, #updateMode do - Test["UI_SetMediaClockTimer_Response_info_Parameter_OutBound_" .. tostring(infoOutBound[i]) .."_"..tostring(updateMode[j]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - --self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {info = infoOutBound[i]}) - self.hmiConnection:SendError(data.id, data.method, "GENERIC_ERROR", infoOutBound[i]) - end) - - - --mobile side: expect SetMediaClockTimer response - --EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", info = infoOutBound_ToMobile[i]}) - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = infoOutBound_ToMobile[i]}) - - - end - end - end - - --End test case CommonRequestCheck.1 - ----------------------------------------------------------------------------------------- - - - --Begin test case NegativeResponseCheck.2 - --Description: check negative response with invalid values(empty, missing, nonexistent, invalid characters) - - - --Begin test case NegativeResponseCheck.2.1 - --Description: check negative response from UI with invalid values(info is empty) - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 - - --Verification criteria: SDL does not forward empty value of info to Mobile - - for j =1, #updateMode do - Test["UI_SetMediaClockTimer_Response_info_Parameter_Empty_" ..tostring(updateMode[j]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - --self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {info = ""}) - self.hmiConnection:SendError(data.id, data.method, "GENERIC_ERROR", "") - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) - :ValidIf (function(_,data) - if data.payload.info then - print(" SDL resends empty value of info parameter to mobile app ") - return false - else - return true - end - end) - - end - end - - - --End test case NegativeResponseCheck.2.1 - ----------------------------------------------------------------------------------------- - - --Begin test case NegativeResponseCheck.2.2 - --Description: check negative response from UI with invalid values(resultCode is empty) - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 - - --Verification criteria: SDL responses INVALID_DATA to Mobile - - for j =1, #updateMode do - Test["UI_SetMediaClockTimer_Response_resultCode_Parameter_Empty_" ..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "", {}) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - - end - end - - - --End test case NegativeResponseCheck.2.2 - ----------------------------------------------------------------------------------------- - - - - --Begin test case NegativeResponseCheck.2.3 - --Description: check negative response from UI with invalid values(info is missed) - - --It is covered by test case SetMediaClockTimer_PositiveCase - - --End test case NegativeResponseCheck.2.3 - ----------------------------------------------------------------------------------------- - - --Begin test case NegativeResponseCheck.2.4 - --Description: check negative response from UI with invalid values(method is missed) - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 - - --Verification criteria: SDL responses GENERIC_ERROR to Mobile - - for j =1, #updateMode do - Test["UI_SetMediaClockTimer_Response_method_Parameter_Missed_" ..tostring(updateMode[j]).."_GENERIC_ERROR"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:Send('{"jsonrpc":"2.0","id":'..data.id..',"result":{"code":0}}') - - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) - :Timeout(12000) - - end - end - - - --End test case NegativeResponseCheck.2.4 - ----------------------------------------------------------------------------------------- - - --Begin test case NegativeResponseCheck.2.5 - --Description: check negative response from UI with invalid values(resultCode is missed) - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 - - --Verification criteria: SDL responses INVALID_DATA to Mobile - - for j =1, #updateMode do - Test["UI_SetMediaClockTimer_Response_resultCode_Parameter_Missed_" ..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:Send('{"jsonrpc":"2.0","id":'..data.id..',"result":{"method":"UI.SetMediaClockTimer"}}') - - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - - end - end - - - --End test case NegativeResponseCheck.2.5 - ----------------------------------------------------------------------------------------- - - --Begin test case NegativeResponseCheck.2.6 - --Description: check negative response from UI with invalid values(mandatory parameters is missed) - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 - - --Verification criteria: SDL responses GENERIC_ERROR to Mobile - - for j =1, #updateMode do - Test["UI_SetMediaClockTimer_Response_Mandatory_Parameters_Missed_" ..tostring(updateMode[j]).."_GENERIC_ERROR"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:Send('{"jsonrpc":"2.0","id":'..data.id..',"result":{}}') - - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) - :Timeout(12000) - - end - end - - - --End test case NegativeResponseCheck.2.6 - ----------------------------------------------------------------------------------------- - - --Begin test case NegativeResponseCheck.2.7 - --Description: check negative response from UI with invalid values(all parameters is missed) - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 - - --Verification criteria: SDL responses INVALID_DATA to Mobile - - for j =1, #updateMode do - Test["UI_SetMediaClockTimer_Response_All_Parameters_Missed_" ..tostring(updateMode[j]).."_GENERIC_ERROR"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:Send('{}') - - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) - :Timeout(12000) - - end - end - - - --End test case NegativeResponseCheck.2.7 - ----------------------------------------------------------------------------------------- - - --Begin test case NegativeResponseCheck.2.8 - --Description: check negative response from UI with invalid values(nonexistent of resultCode) - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 - - --Verification criteria: SDL responses INVALID_DATA to Mobile - - for j =1, #updateMode do - Test["UI_SetMediaClockTimer_Response_resultCode_Parameter_nonexistent_" ..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:Send('{"jsonrpc":"2.0","id":'..data.id..',"result":{"code": 555, "method":"UI.SetMediaClockTimer"}}') - - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - :Timeout(12000) - - end - end - - - --End test case NegativeResponseCheck.2.8 - ----------------------------------------------------------------------------------------- - - - --Begin test case NegativeResponseCheck.2.9 - --Description: check negative response from UI with invalid values(invalid characters) - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 - - --Verification criteria: SDL does not forward invalid characters value of info to Mobile - - -- Tab character - for j =1, #updateMode do - Test["UI_SetMediaClockTimer_Response_info_Parameter_Invalid_Character_Tab_" ..tostring(updateMode[j]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - --self.hmiConnection:SendResponse(data.id, data.method, "GENERIC_ERROR", {info = "in\tfo"}) - self.hmiConnection:SendError(data.id, data.method, "GENERIC_ERROR", "in\tfo") - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) - :ValidIf (function(_,data) - if data.payload.info then - print(" SDL resends invalid value of info parameter to mobile app ") - return false - else - return true - end - end) - - end - end - - -- Newline character - for j =1, #updateMode do - Test["UI_SetMediaClockTimer_Response_info_Parameter_Invalid_Character_NewLine_" ..tostring(updateMode[j]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - --self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {info = "in\nfo"}) - self.hmiConnection:SendError(data.id, data.method, "GENERIC_ERROR", "in\nfo") - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) - :ValidIf (function(_,data) - if data.payload.info then - print(" SDL resends invalid value of info parameter to mobile app ") - return false - else - return true - end - end) - - end - end - - --End test case NegativeResponseCheck.2.9 - ----------------------------------------------------------------------------------------- - - --End test case NegativeResponseCheck.2 - - - --Begin test case NegativeResponseCheck.3 - --Description: check negative response with wrong type - - --Begin test case NegativeResponseCheck.3.1 - --Description: check info parameter is wrong type - - --Requirement id in JAMA/or Jira ID: APPLINK-13276 - - --Verification criteria: SDL should not send "info" to app if received "message" is invalid - - for j =1, #updateMode do - Test["UI_SetMediaClockTimer_Response_info_Parameter_WrongType_" ..tostring(updateMode[j]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - --self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {info = 123}) - self.hmiConnection:SendError(data.id, data.method, "GENERIC_ERROR", 123) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) - :ValidIf (function(_,data) - if data.payload.info then - print(" SDL resends info parameter which is wrong data type to mobile app ") - return false - else - return true - end - end) - - - end - end - - - --End test case NegativeResponseCheck.3.1 - ----------------------------------------------------------------------------------------- - - --Begin test case NegativeResponseCheck.3.2 - --Description: check method parameter is wrong type - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 - - --Verification criteria: SDL returns INVALID_DATA - - for j =1, #updateMode do - Test["UI_SetMediaClockTimer_Response_method_Parameter_WrongType_" ..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, 123, "SUCCESS", {}) - end) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - - end - end - - - --End test case NegativeResponseCheck.3.2 - ----------------------------------------------------------------------------------------- - - --Begin test case NegativeResponseCheck.3.3 - --Description: Check resultCode parameter is wrong type - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 - - --Verification criteria: SDL will response INVALID_DATA if HMI responses with invalid resultCode parameter - - for j =1, #updateMode do - Test["UI_SetMediaClockTimer_Response_resultCode_Parameter_WrongType_" ..tostring(updateMode[j]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, true, {}) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) - - end - end - - - --End test case NegativeResponseCheck.3.3 - ----------------------------------------------------------------------------------------- - - --End test case NegativeResponseCheck.3 - -]] - --Begin test case NegativeResponseCheck.4 - --Description: check negative response with invalid json from UI - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 - - --Verification criteria: The response with wrong JSON syntax is sent, the response comes to Mobile with INVALID_DATA result code. + --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62, APPLINK-14551 + + --Verification criteria: verify SDL truncates info parameter then forwards it to Mobile + + for i=1,#infoOutBound do + for j =1, #updateMode do + Test["UI_SetMediaClockTimer_Response_info_Parameter_OutBound_" .. tostring(infoOutBound[i]) .."_"..tostring(updateMode[j]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + --self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {info = infoOutBound[i]}) + self.hmiConnection:SendError(data.id, data.method, "GENERIC_ERROR", infoOutBound[i]) + end) + + + --mobile side: expect SetMediaClockTimer response + --EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", info = infoOutBound_ToMobile[i]}) + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = infoOutBound_ToMobile[i]}) + + + end + end + end + + --End test case CommonRequestCheck.1 + ----------------------------------------------------------------------------------------- + + + --Begin test case NegativeResponseCheck.2 + --Description: check negative response with invalid values(empty, missing, nonexistent, invalid characters) + + + --Begin test case NegativeResponseCheck.2.1 + --Description: check negative response from UI with invalid values(info is empty) + + --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 + + --Verification criteria: SDL does not forward empty value of info to Mobile + + for j =1, #updateMode do + Test["UI_SetMediaClockTimer_Response_info_Parameter_Empty_" ..tostring(updateMode[j]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + --self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {info = ""}) + self.hmiConnection:SendError(data.id, data.method, "GENERIC_ERROR", "") + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + :ValidIf (function(_,data) + if data.payload.info then + print(" SDL resends empty value of info parameter to mobile app ") + return false + else + return true + end + end) + + end + end + + + --End test case NegativeResponseCheck.2.1 + ----------------------------------------------------------------------------------------- + + --Begin test case NegativeResponseCheck.2.2 + --Description: check negative response from UI with invalid values(resultCode is empty) + + --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 + + --Verification criteria: SDL responses INVALID_DATA to Mobile + + for j =1, #updateMode do + Test["UI_SetMediaClockTimer_Response_resultCode_Parameter_Empty_" ..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + + end + end + + + --End test case NegativeResponseCheck.2.2 + ----------------------------------------------------------------------------------------- + + + + --Begin test case NegativeResponseCheck.2.3 + --Description: check negative response from UI with invalid values(info is missed) + + --It is covered by test case SetMediaClockTimer_PositiveCase + + --End test case NegativeResponseCheck.2.3 + ----------------------------------------------------------------------------------------- + + --Begin test case NegativeResponseCheck.2.4 + --Description: check negative response from UI with invalid values(method is missed) + + --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 + + --Verification criteria: SDL responses GENERIC_ERROR to Mobile + + for j =1, #updateMode do + Test["UI_SetMediaClockTimer_Response_method_Parameter_Missed_" ..tostring(updateMode[j]).."_GENERIC_ERROR"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:Send('{"jsonrpc":"2.0","id":'..data.id..',"result":{"code":0}}') + + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + :Timeout(12000) + + end + end + + + --End test case NegativeResponseCheck.2.4 + ----------------------------------------------------------------------------------------- + + --Begin test case NegativeResponseCheck.2.5 + --Description: check negative response from UI with invalid values(resultCode is missed) + + --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 + + --Verification criteria: SDL responses INVALID_DATA to Mobile + + for j =1, #updateMode do + Test["UI_SetMediaClockTimer_Response_resultCode_Parameter_Missed_" ..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:Send('{"jsonrpc":"2.0","id":'..data.id..',"result":{"method":"UI.SetMediaClockTimer"}}') + + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + + end + end + + + --End test case NegativeResponseCheck.2.5 + ----------------------------------------------------------------------------------------- + + --Begin test case NegativeResponseCheck.2.6 + --Description: check negative response from UI with invalid values(mandatory parameters is missed) + + --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 + + --Verification criteria: SDL responses GENERIC_ERROR to Mobile + + for j =1, #updateMode do + Test["UI_SetMediaClockTimer_Response_Mandatory_Parameters_Missed_" ..tostring(updateMode[j]).."_GENERIC_ERROR"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:Send('{"jsonrpc":"2.0","id":'..data.id..',"result":{}}') + + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + :Timeout(12000) + + end + end + + + --End test case NegativeResponseCheck.2.6 + ----------------------------------------------------------------------------------------- + + --Begin test case NegativeResponseCheck.2.7 + --Description: check negative response from UI with invalid values(all parameters is missed) + + --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 + + --Verification criteria: SDL responses INVALID_DATA to Mobile + + for j =1, #updateMode do + Test["UI_SetMediaClockTimer_Response_All_Parameters_Missed_" ..tostring(updateMode[j]).."_GENERIC_ERROR"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:Send('{}') + + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + :Timeout(12000) + + end + end + + + --End test case NegativeResponseCheck.2.7 + ----------------------------------------------------------------------------------------- + + --Begin test case NegativeResponseCheck.2.8 + --Description: check negative response from UI with invalid values(nonexistent of resultCode) + + --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 + + --Verification criteria: SDL responses INVALID_DATA to Mobile + + for j =1, #updateMode do + Test["UI_SetMediaClockTimer_Response_resultCode_Parameter_nonexistent_" ..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:Send('{"jsonrpc":"2.0","id":'..data.id..',"result":{"code": 555, "method":"UI.SetMediaClockTimer"}}') + + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(12000) + + end + end + + + --End test case NegativeResponseCheck.2.8 + ----------------------------------------------------------------------------------------- + + + --Begin test case NegativeResponseCheck.2.9 + --Description: check negative response from UI with invalid values(invalid characters) + + --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 + + --Verification criteria: SDL does not forward invalid characters value of info to Mobile + + -- Tab character + for j =1, #updateMode do + Test["UI_SetMediaClockTimer_Response_info_Parameter_Invalid_Character_Tab_" ..tostring(updateMode[j]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + --self.hmiConnection:SendResponse(data.id, data.method, "GENERIC_ERROR", {info = "in\tfo"}) + self.hmiConnection:SendError(data.id, data.method, "GENERIC_ERROR", "in\tfo") + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + :ValidIf (function(_,data) + if data.payload.info then + print(" SDL resends invalid value of info parameter to mobile app ") + return false + else + return true + end + end) + + end + end + + -- Newline character + for j =1, #updateMode do + Test["UI_SetMediaClockTimer_Response_info_Parameter_Invalid_Character_NewLine_" ..tostring(updateMode[j]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + --self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {info = "in\nfo"}) + self.hmiConnection:SendError(data.id, data.method, "GENERIC_ERROR", "in\nfo") + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + :ValidIf (function(_,data) + if data.payload.info then + print(" SDL resends invalid value of info parameter to mobile app ") + return false + else + return true + end + end) + + end + end + + --End test case NegativeResponseCheck.2.9 + ----------------------------------------------------------------------------------------- + + --End test case NegativeResponseCheck.2 + + + --Begin test case NegativeResponseCheck.3 + --Description: check negative response with wrong type + + --Begin test case NegativeResponseCheck.3.1 + --Description: check info parameter is wrong type + + --Requirement id in JAMA/or Jira ID: APPLINK-13276 + + --Verification criteria: SDL should not send "info" to app if received "message" is invalid + + for j =1, #updateMode do + Test["UI_SetMediaClockTimer_Response_info_Parameter_WrongType_" ..tostring(updateMode[j]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + --self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {info = 123}) + self.hmiConnection:SendError(data.id, data.method, "GENERIC_ERROR", 123) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR"}) + :ValidIf (function(_,data) + if data.payload.info then + print(" SDL resends info parameter which is wrong data type to mobile app ") + return false + else + return true + end + end) + + + end + end + + + --End test case NegativeResponseCheck.3.1 + ----------------------------------------------------------------------------------------- + + --Begin test case NegativeResponseCheck.3.2 + --Description: check method parameter is wrong type + + --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 + + --Verification criteria: SDL returns INVALID_DATA + + for j =1, #updateMode do + Test["UI_SetMediaClockTimer_Response_method_Parameter_WrongType_" ..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, 123, "SUCCESS", {}) + end) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + + end + end + + + --End test case NegativeResponseCheck.3.2 + ----------------------------------------------------------------------------------------- + + --Begin test case NegativeResponseCheck.3.3 + --Description: Check resultCode parameter is wrong type + + --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 + + --Verification criteria: SDL will response INVALID_DATA if HMI responses with invalid resultCode parameter + + for j =1, #updateMode do + Test["UI_SetMediaClockTimer_Response_resultCode_Parameter_WrongType_" ..tostring(updateMode[j]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, true, {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + + end + end + + + --End test case NegativeResponseCheck.3.3 + ----------------------------------------------------------------------------------------- + + --End test case NegativeResponseCheck.3 + + ]] +--Begin test case NegativeResponseCheck.4 +--Description: check negative response with invalid json from UI + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 + +--Verification criteria: The response with wrong JSON syntax is sent, the response comes to Mobile with INVALID_DATA result code. --APPLINK-13418: SDL ignores all responses from HMI after received response with invalid JSON syntax --Solution: After run this test case, remove it and run next test cases again. --[[ - for j =1, #updateMode do - Test["UI_SetMediaClockTimer_Response_Invalid_JSON_" ..tostring(updateMode[j]).."_GENERIC_ERROR"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - --self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {info = 123}) - - --change ":" by " " after "code" - --self.hmiConnection:Send('{"jsonrpc":"2.0","id":'..tostring(data.id)..',"result":{"code":0,"method":"UI.SetMediaClockTimer"}}') - self.hmiConnection:Send('{"jsonrpc":"2.0","id":'..tostring(data.id)..',"result" {"code":0,"method":"UI.SetMediaClockTimer"}}') - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = nil}) - :Timeout(15000) - - end - end -]]-- - --End test case NegativeResponseCheck.4 - ----------------------------------------------------------------------------------------- - - --End test suit NegativeResponseCheck + for j =1, #updateMode do + Test["UI_SetMediaClockTimer_Response_Invalid_JSON_" ..tostring(updateMode[j]).."_GENERIC_ERROR"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + --self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {info = 123}) + + --change ":" by " " after "code" + --self.hmiConnection:Send('{"jsonrpc":"2.0","id":'..tostring(data.id)..',"result":{"code":0,"method":"UI.SetMediaClockTimer"}}') + self.hmiConnection:Send('{"jsonrpc":"2.0","id":'..tostring(data.id)..',"result" {"code":0,"method":"UI.SetMediaClockTimer"}}') + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = nil}) + :Timeout(15000) + + end + end + ]]-- +--End test case NegativeResponseCheck.4 +----------------------------------------------------------------------------------------- + +--End test suit NegativeResponseCheck @@ -3191,811 +3911,843 @@ end ---------------------------------------Result code check-------------------------------------- ---------------------------------------------------------------------------------------------- - --Check all uncovered pairs resultCodes+success - - --Begin test suit ResultCodeCheck - --Description: check result code of response to Mobile - - - --Begin test case ResultCodeCheck.1 - --Description: Check UI returns different resultCode to SDL - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-513, SDLAQ-CRS-514, SDLAQ-CRS-515, SDLAQ-CRS-516, SDLAQ-CRS-517, SDLAQ-CRS-518, SDLAQ-CRS-519, SDLAQ-CRS-520, SDLAQ-CRS-521, SDLAQ-CRS-2629 - - --Verification criteria: SDL forwards resultCode to Mobile - - for i = 1, #resultCode do - for j =1, #updateMode do - Test["UI_SetMediaClockTimer_Response_resultCode_".. tostring(resultCode[i]) .."_"..tostring(updateMode[j]).."_"..tostring(resultCode[i]) ] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, resultCode[i], {}) - end) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = success[i], resultCode = resultCode[i]}) - :Timeout(iTimeout) - - end - end - end - - --End test case ResultCodeCheck.1 - ----------------------------------------------------------------------------------------- - - --Begin test case ResultCodeCheck.2 - --Description: A command can not be executed because no application has been registered with RegisterAppInterface. - - --Requirement id in JAMA: SDLAQ-CRS-518 - - --Verification criteria: SDL sends APPLICATION_NOT_REGISTERED code when the app sends a request within the same connection before RegisterAppInterface has been performed yet. - - --Precondition: Create new session - function Test:Precondition_CreationNewSession() - -- Connected expectation - self.mobileSession2 = mobile_session.MobileSession( - self, - self.mobileConnection) - end - - - for j =1, #updateMode do - Test["UI_SetMediaClockTimer_resultCode_APPLICATION_NOT_REGISTERED".."_"..tostring(updateMode[j])] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession2:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --mobile side: expect SetMediaClockTimer response - self.mobileSession2:ExpectResponse(cid, { success = false, resultCode = "APPLICATION_NOT_REGISTERED" }) - end - - end - - --End test case ResultCodeCheck.2 - - --End test suit ResultCodeCheck +--Check all uncovered pairs resultCodes+success + +--Begin test suit ResultCodeCheck +--Description: check result code of response to Mobile + + +--Begin test case ResultCodeCheck.1 +--Description: Check UI returns different resultCode to SDL + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-513, SDLAQ-CRS-514, SDLAQ-CRS-515, SDLAQ-CRS-516, SDLAQ-CRS-517, SDLAQ-CRS-518, SDLAQ-CRS-519, SDLAQ-CRS-520, SDLAQ-CRS-521, SDLAQ-CRS-2629 + +--Verification criteria: SDL forwards resultCode to Mobile + +for i = 1, #resultCode do + for j =1, #updateMode do + Test["UI_SetMediaClockTimer_Response_resultCode_".. tostring(resultCode[i]) .."_"..tostring(updateMode[j]).."_"..tostring(resultCode[i]) .. "_" .. tostring(audioStreamingIndicatorStates[k]) ] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, resultCode[i], {}) + end) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = success[i], resultCode = resultCode[i]}) + :Timeout(iTimeout) + + end + end +end + +--End test case ResultCodeCheck.1 +----------------------------------------------------------------------------------------- + +--Begin test case ResultCodeCheck.2 +--Description: A command can not be executed because no application has been registered with RegisterAppInterface. + +--Requirement id in JAMA: SDLAQ-CRS-518 + +--Verification criteria: SDL sends APPLICATION_NOT_REGISTERED code when the app sends a request within the same connection before RegisterAppInterface has been performed yet. + +--Precondition: Create new session +function Test:Precondition_CreationNewSession() + -- Connected expectation + self.mobileSession2 = mobile_session.MobileSession( + self, + self.mobileConnection) +end + + +for j =1, #updateMode do + for k =1, #audioStreamingIndicatorStates do + Test["UI_SetMediaClockTimer_resultCode_APPLICATION_NOT_REGISTERED".."_"..tostring(updateMode[j]).."_" .. tostring(audioStreamingIndicatorStates[k])] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession2:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + + --mobile side: expect SetMediaClockTimer response + self.mobileSession2:ExpectResponse(cid, { success = false, resultCode = "APPLICATION_NOT_REGISTERED" }) + end + end +end + +--End test case ResultCodeCheck.2 + +--End test suit ResultCodeCheck ---------------------------------------------------------------------------------------------- -----------------------------------------V TEST BLOCK----------------------------------------- ---------------------------------------HMI negative cases------------------------------------- ---------------------------------------------------------------------------------------------- - --------Checks----------- - -- requests without responses from HMI - -- invalid structure os response - -- several responses from HMI to one request - -- fake parameters - -- HMI correlation id check - -- wrong response with correct HMI id - - - --Begin test suit HMINegativeCheck - --Description: Check negative response from HMI - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 - - --Verification criteria: The response contains 2 mandatory parameters "success" and "resultCode", "info" is sent if there is any additional information about the resultCode - - - --Begin test case HMINegativeCheck.1 - --Description: check requests without responses from HMI - - for j =1, #updateMode do - Test["SetMediaClockTimer_RequestWithoutUIResponsesFromHMI_" ..tostring(updateMode[j]).."_GENERIC_ERROR"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - :Timeout(iTimeout) - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = nil}) - :Timeout(15000) - - end - end - - - --End test case HMINegativeCheck.1 - ----------------------------------------------------------------------------------------- - - - --Begin test case HMINegativeCheck.2 - --Description: invalid structure of response - - for j =1, #updateMode do - Test["SetMediaClockTimer_UI_InvalidStructureOfResponse_" ..tostring(updateMode[j]).."_GENERIC_ERROR"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response --self.hmiConnection:Send('{"jsonrpc":"2.0","id":'..tostring(data.id)..',"result":{"code":0,"method":"UI.SetMediaClockTimer"}}') - self.hmiConnection:Send('{"jsonrpc":"2.0","id":'..tostring(data.id)..',"result":{"code":0}, "method":"UI.SetMediaClockTimer"}') - - - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = nil}) - :Timeout(15000) - - end - end - - - --End test case HMINegativeCheck.2.1 - ----------------------------------------------------------------------------------------- - - - --Begin test case HMINegativeCheck.3 - --Description: several responses from HMI to one request - - for j =1, #updateMode do - Test["SetMediaClockTimer_UI_SeveralResponseToOneRequest_" ..tostring(updateMode[j]).."_INVALID_DATA"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "INVALID_DATA", {}) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA", info = nil}) - :Timeout(iTimeout) - - end - end - - --End test case HMINegativeCheck.3 - ----------------------------------------------------------------------------------------- - - - --Begin test case HMINegativeCheck.4 - --Description: check response with fake parameters - - --Begin test case HMINegativeCheck.4.1 - --Description: Check responses from HMI (UI) with fake parameter - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 - - --Verification criteria: SDL does not resend fake parameters to mobile. - - for j =1, #updateMode do - Test["SetMediaClockTimer_UI_ResponseWithFakeParamater" ..tostring(updateMode[j]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS",{fake = "fake"}) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", info = nil}) - :ValidIf (function(_,data) - if data.payload.fake then - print(" SDL resends fake parameter to mobile app ") - return false - else - return true - end - end) - - end - end - - --End test case HMINegativeCheck.4.1 - ----------------------------------------------------------------------------------------- - - --Begin test case HMINegativeCheck.4.2 - --Description: Check responses from HMI (UI) with parameters of other request - - --Requirement id in JAMA/or Jira ID: - - --Verification criteria: - - for j =1, #updateMode do - Test["SetMediaClockTimer_UI_ResponseWithParamatersOfOtherRequest" ..tostring(updateMode[j]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - --self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS",{sliderPosition = 5}) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", info = nil}) - :ValidIf (function(_,data) - if data.payload.sliderPosition then - print(" SDL resends sliderPosition parameter to mobile app ") - return false - else - return true - end - end) - - end - end - - --End test case HMINegativeCheck.4.2 - ----------------------------------------------------------------------------------------- - - --End test case HMINegativeCheck.4 - - - --Begin test case HMINegativeCheck.5 - --Description: Check UI wrong response with wrong HMI correlation id - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 - - --Verification criteria: SDL responses GENERIC_ERROR to mobile - - for j =1, #updateMode do - Test["SetMediaClockTimer_UI_ResponseWithWrongHMICorrelationId_" ..tostring(updateMode[j]).."_GENERIC_ERROR"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - --self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {} - self.hmiConnection:SendResponse(data.id + 1, data.method, "SUCCESS", {}) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = nil}) - :Timeout(12000) - - end - end - - --End test case HMINegativeCheck.5 - ---------------------------------------------------------------------------------------- - - - --Begin test case HMINegativeCheck.6 - --Description: Check UI wrong response with correct HMI id - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 - - --Verification criteria: SDL responses GENERIC_ERROR to mobile - - for j =1, #updateMode do - Test["SetMediaClockTimer_UI_WrongResponseWithCorrectHMICorrelationId_" ..tostring(updateMode[j]).."_GENERIC_ERROR"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - --self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - self.hmiConnection:SendResponse(data.id, "UI.Show", "SUCCESS", {}) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = nil}) - :Timeout(12000) - - end - end - - --End test case HMINegativeCheck.6 - ---------------------------------------------------------------------------------------- - - - --End test suit HMINegativeCheck +--------Checks----------- +-- requests without responses from HMI +-- invalid structure os response +-- several responses from HMI to one request +-- fake parameters +-- HMI correlation id check +-- wrong response with correct HMI id + + +--Begin test suit HMINegativeCheck +--Description: Check negative response from HMI + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 + +--Verification criteria: The response contains 2 mandatory parameters "success" and "resultCode", "info" is sent if there is any additional information about the resultCode + + +--Begin test case HMINegativeCheck.1 +--Description: check requests without responses from HMI + +for j =1, #updateMode do + for k =1, #audioStreamingIndicatorStates do + Test["SetMediaClockTimer_RequestWithoutUIResponsesFromHMI_" ..tostring(updateMode[j]).."_" .. tostring(audioStreamingIndicatorStates[k]) .. "_GENERIC_ERROR"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + :Timeout(iTimeout) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = nil}) + :Timeout(15000) + + end + end +end + + +--End test case HMINegativeCheck.1 +----------------------------------------------------------------------------------------- + + +--Begin test case HMINegativeCheck.2 +--Description: invalid structure of response + +for j =1, #updateMode do + for k =1, #audioStreamingIndicatorStates do + Test["SetMediaClockTimer_UI_InvalidStructureOfResponse_" ..tostring(updateMode[j]).."_" .. tostring(audioStreamingIndicatorStates[k]).."_GENERIC_ERROR"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response --self.hmiConnection:Send('{"jsonrpc":"2.0","id":'..tostring(data.id)..',"result":{"code":0,"method":"UI.SetMediaClockTimer"}}') + self.hmiConnection:Send('{"jsonrpc":"2.0","id":'..tostring(data.id)..',"result":{"code":0}, "method":"UI.SetMediaClockTimer"}') + + + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = nil}) + :Timeout(15000) + + end + end +end + + +--End test case HMINegativeCheck.2.1 +----------------------------------------------------------------------------------------- + + +--Begin test case HMINegativeCheck.3 +--Description: several responses from HMI to one request + +for j =1, #updateMode do + for k =1, #audioStreamingIndicatorStates do + Test["SetMediaClockTimer_UI_SeveralResponseToOneRequest_" ..tostring(updateMode[j]).."_" .. tostring(audioStreamingIndicatorStates[k]) .. "_INVALID_DATA"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "INVALID_DATA", {}) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA", info = nil}) + :Timeout(iTimeout) + + end + end +end + +--End test case HMINegativeCheck.3 +----------------------------------------------------------------------------------------- + + +--Begin test case HMINegativeCheck.4 +--Description: check response with fake parameters + +--Begin test case HMINegativeCheck.4.1 +--Description: Check responses from HMI (UI) with fake parameter + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 + +--Verification criteria: SDL does not resend fake parameters to mobile. + +for j =1, #updateMode do + for k =1, #audioStreamingIndicatorStates do + Test["SetMediaClockTimer_UI_ResponseWithFakeParamater" ..tostring(updateMode[j]).."_" .. tostring(audioStreamingIndicatorStates[k]) .. "_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS",{fake = "fake"}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", info = nil}) + :ValidIf (function(_,data) + if data.payload.fake then + print(" SDL resends fake parameter to mobile app ") + return false + else + return true + end + end) + + end + end +end + +--End test case HMINegativeCheck.4.1 +----------------------------------------------------------------------------------------- + +--Begin test case HMINegativeCheck.4.2 +--Description: Check responses from HMI (UI) with parameters of other request + +--Requirement id in JAMA/or Jira ID: + +--Verification criteria: + +for j =1, #updateMode do + for k =1, #audioStreamingIndicatorStates do + Test["SetMediaClockTimer_UI_ResponseWithParamatersOfOtherRequest" ..tostring(updateMode[j]).."_" .. tostring(audioStreamingIndicatorStates[k]) .. "_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + --self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS",{sliderPosition = 5}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", info = nil}) + :ValidIf (function(_,data) + if data.payload.sliderPosition then + print(" SDL resends sliderPosition parameter to mobile app ") + return false + else + return true + end + end) + + end + end +end + +--End test case HMINegativeCheck.4.2 +----------------------------------------------------------------------------------------- + +--End test case HMINegativeCheck.4 + + +--Begin test case HMINegativeCheck.5 +--Description: Check UI wrong response with wrong HMI correlation id + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 + +--Verification criteria: SDL responses GENERIC_ERROR to mobile + +for j =1, #updateMode do + for k =1, #audioStreamingIndicatorStates do + Test["SetMediaClockTimer_UI_ResponseWithWrongHMICorrelationId_" ..tostring(updateMode[j]).."_" .. tostring(audioStreamingIndicatorStates[k]) .. "_GENERIC_ERROR"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + --self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {} + self.hmiConnection:SendResponse(data.id + 1, data.method, "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = nil}) + :Timeout(12000) + + end + end +end + +--End test case HMINegativeCheck.5 +---------------------------------------------------------------------------------------- + + +--Begin test case HMINegativeCheck.6 +--Description: Check UI wrong response with correct HMI id + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-62 + +--Verification criteria: SDL responses GENERIC_ERROR to mobile + +for j =1, #updateMode do + for k =1, #audioStreamingIndicatorStates do + Test["SetMediaClockTimer_UI_WrongResponseWithCorrectHMICorrelationId_" ..tostring(updateMode[j]).."_" .. tostring(audioStreamingIndicatorStates[k]).. "_GENERIC_ERROR"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + --self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + self.hmiConnection:SendResponse(data.id, "UI.Show", "SUCCESS", {}) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "GENERIC_ERROR", info = nil}) + :Timeout(12000) + + end + end +end + +--End test case HMINegativeCheck.6 +---------------------------------------------------------------------------------------- + + +--End test suit HMINegativeCheck ---------------------------------------------------------------------------------------------- -----------------------------------------VI TEST BLOCK---------------------------------------- -------------------------Sequence with emulating of user's action(s)-------------------------- ---------------------------------------------------------------------------------------------- - --Begin test suit SequenceCheck - --Description: TC's checks SDL behavior by processing - -- different request sequence with timeout - -- with emulating of user's actions - - - --Begin test case SequenceCheck.1-5 - --Description: check scenario in test cases: - --TC_SetMediaClockTimer_01: Call SetMediaClockTimer request from mobile app on HMI with COUNTUP parameter - --TC_SetMediaClockTimer_02: Call SetMediaClockTimer request from mobile app on HMI with COUNTDOWN parameter - --TC_SetMediaClockTimer_03: Call SetMediaClockTimer request from mobile app on HMI with PAUSE parameter - --TC_SetMediaClockTimer_04: Call SetMediaClockTimer request from mobile app on HMI with RESUME parameter - --TC_SetMediaClockTimer_05: Call SetMediaClockTimer request from mobile app on HMI with CLEAR parameter - - --It is covered by TC SetMediaClockTimer_PositiveCase - - --End test case SequenceCheck.1-5 - ----------------------------------------------------------------------------------------- - - --Begin test case SequenceCheck.6 - --Description: check scenario in test case TC_SetMediaClockTimer_06: Call SetMediaClockTimer request from mobile app on HMI with CLEAR parameter when UI Media clock timer is in default state (empty) - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-61 - - --Verification criteria: returns SUCCESS - - --Precondition: Clear SetMediaClockTimer to change UI Media clock timer is in default state (empty) - function Test:SetMediaClockTimer_TC_SetMediaClockTimer_06_Precondition() - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 01, - minutes = 02, - seconds = 03, - }, - updateMode = "CLEAR" - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 01, - minutes = 02, - seconds = 03, - }, - updateMode = "CLEAR" - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {} ) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", info = nil}) - :Timeout(iTimeout) - end - - function Test:SetMediaClockTimer_TC_SetMediaClockTimer_06_CLEAR_SUCCESS() +--Begin test suit SequenceCheck +--Description: TC's checks SDL behavior by processing +-- different request sequence with timeout +-- with emulating of user's actions + + +--Begin test case SequenceCheck.1-5 +--Description: check scenario in test cases: +--TC_SetMediaClockTimer_01: Call SetMediaClockTimer request from mobile app on HMI with COUNTUP parameter +--TC_SetMediaClockTimer_02: Call SetMediaClockTimer request from mobile app on HMI with COUNTDOWN parameter +--TC_SetMediaClockTimer_03: Call SetMediaClockTimer request from mobile app on HMI with PAUSE parameter +--TC_SetMediaClockTimer_04: Call SetMediaClockTimer request from mobile app on HMI with RESUME parameter +--TC_SetMediaClockTimer_05: Call SetMediaClockTimer request from mobile app on HMI with CLEAR parameter + +--It is covered by TC SetMediaClockTimer_PositiveCase + +--End test case SequenceCheck.1-5 +----------------------------------------------------------------------------------------- + +--Begin test case SequenceCheck.6 +--Description: check scenario in test case TC_SetMediaClockTimer_06: Call SetMediaClockTimer request from mobile app on HMI with CLEAR parameter when UI Media clock timer is in default state (empty) + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-61 + +--Verification criteria: returns SUCCESS + +--Precondition: Clear SetMediaClockTimer to change UI Media clock timer is in default state (empty) +function Test:SetMediaClockTimer_TC_SetMediaClockTimer_06_Precondition() + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 01, + minutes = 02, + seconds = 03, + }, + updateMode = "CLEAR", + audioStreamingIndicator="PLAY_PAUSE" + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 01, + minutes = 02, + seconds = 03, + }, + updateMode = "CLEAR", + audioStreamingIndicator="PLAY_PAUSE" + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {} ) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", info = nil}) + :Timeout(iTimeout) +end - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 04, - minutes = 04, - seconds = 04, - }, - updateMode = "CLEAR" - }) +function Test:SetMediaClockTimer_TC_SetMediaClockTimer_06_CLEAR_SUCCESS() + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 04, + minutes = 04, + seconds = 04, + }, + updateMode = "CLEAR" + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 04, + minutes = 04, + seconds = 04, + }, + updateMode = "CLEAR" + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {} ) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", info = nil}) + :Timeout(iTimeout) +end +--End test case SequenceCheck.6 +----------------------------------------------------------------------------------------- - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 04, - minutes = 04, - seconds = 04, - }, - updateMode = "CLEAR" - }) - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {} ) - end) +--Begin test case SequenceCheck.7 +--Description: When SetMediaClockTimer with updateMode="RESUME" is sent and the media clock timer is already cleared with the previous request, the IGNORED result code is returned by SDL. General result success=false. +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-520 - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", info = nil}) - :Timeout(iTimeout) - end +--Verification criteria: returns IGNORED - --End test case SequenceCheck.6 - ----------------------------------------------------------------------------------------- - - - --Begin test case SequenceCheck.7 - --Description: When SetMediaClockTimer with updateMode="RESUME" is sent and the media clock timer is already cleared with the previous request, the IGNORED result code is returned by SDL. General result success=false. +function Test:SetMediaClockTimer_RESUME_IGNORED() - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-520 + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 01, + minutes = 02, + seconds = 03, + }, + updateMode = "RESUME" + }) - --Verification criteria: returns IGNORED - function Test:SetMediaClockTimer_RESUME_IGNORED() + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 01, + minutes = 02, + seconds = 03, + }, + updateMode = "RESUME" + }) - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 01, - minutes = 02, - seconds = 03, - }, - updateMode = "RESUME" - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 01, - minutes = 02, - seconds = 03, - }, - updateMode = "RESUME" - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "IGNORED", {} ) - end) + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "IGNORED", {} ) + end) - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "IGNORED", info = nil}) - :Timeout(iTimeout) - end + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "IGNORED", info = nil}) + :Timeout(iTimeout) +end - --End test case SequenceCheck.7 - ----------------------------------------------------------------------------------------- +--End test case SequenceCheck.7 +----------------------------------------------------------------------------------------- - --End test suit SequenceCheck +--End test suit SequenceCheck @@ -4004,391 +4756,391 @@ end -----------------------------------------VII TEST BLOCK--------------------------------------- --------------------------------------Different HMIStatus------------------------------------- ---------------------------------------------------------------------------------------------- - --Description: processing of request/response in different HMIlevels, SystemContext, AudioStreamingState - - --Begin test suit DifferentHMIlevel - --Description: processing API in different HMILevel - - --Begin test case DifferentHMIlevel.1 - --Description: Check SetMediaClockTimer request when application is in LIMITTED HMI level - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-782 - - --Verification criteria: SetMediaClockTimer is allowed in LIMITED HMI level according to policy - - -- Precondition: Change app to LIMITED HMI status - function Test:ChangeHMIToLimited() - --hmi side: sending BasicCommunication.OnAppDeactivated request - local cid = self.hmiConnection:SendNotification("BasicCommunication.OnAppDeactivated", - { - appID = self.applications["Test Application"], - reason = "GENERAL" - }) - - --mobile side: expect OnHMIStatus notification - EXPECT_NOTIFICATION("OnHMIStatus",{hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN"}) - - end - - for j =1, #updateMode do - Test["SetMediaClockTimer_LIMITED_" ..tostring(updateMode[j]).."_SUCCESS"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {} ) - end) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", info = nil}) - :Timeout(iTimeout) - - end - end - - --End test case DifferentHMIlevel.1 - ----------------------------------------------------------------------------------------- - - --Begin test case DifferentHMIlevel.2 - --Description: Check SetMediaClockTimer request when application is in NONE HMI level - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-782 - - --Verification criteria: SetMediaClockTimer is NOT allowed in NONE HMI level - - - --Precondition: Change app to FULL HMI status - function Test:ActivateApplication() - --HMI send ActivateApp request - local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications["Test Application"]}) - EXPECT_HMIRESPONSE(RequestId) - :Do(function(_,data) - if data.result.isSDLAllowed ~= true then - local RequestId = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) - EXPECT_HMIRESPONSE(RequestId,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) - :Do(function(_,data) - --hmi side: send request SDL.OnAllowSDLFunctionality - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = 1, name = "127.0.0.1"}}) - end) - - EXPECT_HMICALL("BasicCommunication.ActivateApp") - :Do(function(_,data) - self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) - end) - :Times(2) - end - end) - - EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "FULL", systemContext = "MAIN"}) - - end - - --Precondition: Change app to None HMI status - function Test:ExitApplication() - - local function sendUserExit() - --hmi side: sending BasicCommunication.OnExitApplication request - local cid = self.hmiConnection:SendNotification("BasicCommunication.OnExitApplication", - { - appID = self.applications["Test Application"], - reason = "USER_EXIT" - }) - end - - local function SendOnSystemContext1() - --hmi side: sending UI.OnSystemContext request - SendOnSystemContext(self,"MAIN") - end - - local function sendOnAppDeactivate() - --hmi side: sending BasicCommunication.OnAppDeactivated request - local cid = self.hmiConnection:SendNotification("BasicCommunication.OnAppDeactivated", - { - appID = self.applications["Test Application"], - reason = "GENERAL" - }) - end - - --hmi side: sending BasicCommunication.OnSystemContext request - SendOnSystemContext(self,"MENU") - - --hmi side: sending BasicCommunication.OnExitApplication request - RUN_AFTER(sendUserExit, 1000) - - --hmi side: sending UI.OnSystemContext request = MAIN - RUN_AFTER(SendOnSystemContext1, 2000) - - --hmi side: sending BasicCommunication.OnAppDeactivated request - RUN_AFTER(sendOnAppDeactivate, 3000) - - - --mobile side: OnHMIStatus notifications - EXPECT_NOTIFICATION("OnHMIStatus", - { systemContext = "MENU", hmiLevel = "FULL"}, - { systemContext = "MENU", hmiLevel = "NONE"}, - { systemContext = "MAIN", hmiLevel = "NONE"}) - :Times(3) - - end - - - for j =1, #updateMode do - Test["SetMediaClockTimer_NONE_" ..tostring(updateMode[j]).."_DISALLOWED"] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - :Timeout(iTimeout) - :Times(0) - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED", info = nil}) - :Timeout(iTimeout) - - end - end - - --End test case DifferentHMIlevel.2 - ----------------------------------------------------------------------------------------- - - --Begin test case DifferentHMIlevel.3 - --Description: Check SetMediaClockTimer request when application is in BACKGOUND HMI level - - --Requirement id in JAMA/or Jira ID: SDLAQ-CRS-782 - - --Verification criteria: SetMediaClockTimer is allowed in BACKGOUND HMI level according to policy - - --Precondition: Change app to FULL HMI status - function Test:ActivateApplication() - --HMI send ActivateApp request - local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications["Test Application"]}) - EXPECT_HMIRESPONSE(RequestId) - :Do(function(_,data) - if data.result.isSDLAllowed ~= true then - local RequestId = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) - EXPECT_HMIRESPONSE(RequestId,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) - :Do(function(_,data) - --hmi side: send request SDL.OnAllowSDLFunctionality - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = 1, name = "127.0.0.1"}}) - end) - - EXPECT_HMICALL("BasicCommunication.ActivateApp") - :Do(function(_,data) - self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) - end) - :Times(2) - end - end) - - EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "FULL", systemContext = "MAIN"}) - - end - - --Precondition: Create the second session - function Test:CreateTheSecondSession() - --mobile side: start new session - self.mobileSession1 = mobile_session.MobileSession( - self, - self.mobileConnection) - - end - - --Precondition: Register application the second session - function Test:RegisterAppInTheSecondSession() - --mobile side: start new - self.mobileSession1:StartService(7) - :Do(function() - local CorIdRegister = self.mobileSession1:SendRPC("RegisterAppInterface", - { - syncMsgVersion = - { - majorVersion = 3, - minorVersion = 0 - }, - appName = "Test Application2", - isMediaApplication = true, - languageDesired = 'EN-US', - hmiDisplayLanguageDesired = 'EN-US', - appHMIType = { "NAVIGATION" }, - appID = "1" - }) - - --hmi side: expect BasicCommunication.OnAppRegistered request - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", - { - application = - { - appName = "Test Application2" - } - }) - :Do(function(_,data) - appId2 = data.params.application.appID - end) - - --mobile side: expect response - self.mobileSession1:ExpectResponse(CorIdRegister, { success = true, resultCode = "SUCCESS" }) - :Timeout(2000) - end) - - end - - --Precondition: Activate second app - function Test:ActivateSecondApp() - --hmi side: sending SDL.ActivateApp request - local rid = self.hmiConnection:SendRequest("SDL.ActivateApp",{appID = appId2}) - EXPECT_HMIRESPONSE(rid) - - --mobile side: expect notification from 2 app - self.mobileSession1:ExpectNotification("OnHMIStatus",{hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN"}) - self.mobileSession:ExpectNotification("OnHMIStatus",{hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) - - end - - for j =1, #updateMode do - Test["SetMediaClockTimer_BACKGROUND_" ..tostring(updateMode[j])] = function(self) - countDown = 0 - if updateMode[j] == "COUNTDOWN" then - countDown = -1 - end - - --mobile side: sending SetMediaClockTimer request - local cid = self.mobileSession:SendRPC("SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - - - --hmi side: expect UI.SetMediaClockTimer request - EXPECT_HMICALL("UI.SetMediaClockTimer", - { - startTime = - { - hours = 0, - minutes = 1, - seconds = 33, - }, - endTime = - { - hours = 0, - minutes = 1 + countDown, - seconds = 35 - }, - updateMode = updateMode[j] - }) - :Do(function(_,data) - --hmi side: sending UI.SetMediaClockTimer response - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {} ) - end) - :Timeout(iTimeout) - - - - --mobile side: expect SetMediaClockTimer response - EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) - --:Timeout(iTimeout) - :Timeout(11000) - - end - end - - - --End test case DifferentHMIlevel.3 - ----------------------------------------------------------------------------------------- - - --End test suit DifferentHMIlevel +--Description: processing of request/response in different HMIlevels, SystemContext, AudioStreamingState + +--Begin test suit DifferentHMIlevel +--Description: processing API in different HMILevel + +--Begin test case DifferentHMIlevel.1 +--Description: Check SetMediaClockTimer request when application is in LIMITTED HMI level + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-782 + +--Verification criteria: SetMediaClockTimer is allowed in LIMITED HMI level according to policy + +-- Precondition: Change app to LIMITED HMI status +function Test:ChangeHMIToLimited() + --hmi side: sending BasicCommunication.OnAppDeactivated request + local cid = self.hmiConnection:SendNotification("BasicCommunication.OnAppDeactivated", + { + appID = self.applications["Test Application"], + reason = "GENERAL" + }) + + --mobile side: expect OnHMIStatus notification + EXPECT_NOTIFICATION("OnHMIStatus",{hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN"}) + +end + +for j =1, #updateMode do + Test["SetMediaClockTimer_LIMITED_" ..tostring(updateMode[j]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {} ) + end) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS", info = nil}) + :Timeout(iTimeout) + + end +end + +--End test case DifferentHMIlevel.1 +----------------------------------------------------------------------------------------- + +--Begin test case DifferentHMIlevel.2 +--Description: Check SetMediaClockTimer request when application is in NONE HMI level + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-782 + +--Verification criteria: SetMediaClockTimer is NOT allowed in NONE HMI level + + +--Precondition: Change app to FULL HMI status +function Test:ActivateApplication() + --HMI send ActivateApp request + local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications["Test Application"]}) + EXPECT_HMIRESPONSE(RequestId) + :Do(function(_,data) + if data.result.isSDLAllowed ~= true then + local RequestId = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) + EXPECT_HMIRESPONSE(RequestId,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) + :Do(function(_,data) + --hmi side: send request SDL.OnAllowSDLFunctionality + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = 1, name = "127.0.0.1"}}) + end) + + EXPECT_HMICALL("BasicCommunication.ActivateApp") + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) + end) + :Times(2) + end + end) + + EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "FULL", systemContext = "MAIN"}) + +end + +--Precondition: Change app to None HMI status +function Test:ExitApplication() + + local function sendUserExit() + --hmi side: sending BasicCommunication.OnExitApplication request + local cid = self.hmiConnection:SendNotification("BasicCommunication.OnExitApplication", + { + appID = self.applications["Test Application"], + reason = "USER_EXIT" + }) + end + + local function SendOnSystemContext1() + --hmi side: sending UI.OnSystemContext request + SendOnSystemContext(self,"MAIN") + end + + local function sendOnAppDeactivate() + --hmi side: sending BasicCommunication.OnAppDeactivated request + local cid = self.hmiConnection:SendNotification("BasicCommunication.OnAppDeactivated", + { + appID = self.applications["Test Application"], + reason = "GENERAL" + }) + end + + --hmi side: sending BasicCommunication.OnSystemContext request + SendOnSystemContext(self,"MENU") + + --hmi side: sending BasicCommunication.OnExitApplication request + RUN_AFTER(sendUserExit, 1000) + + --hmi side: sending UI.OnSystemContext request = MAIN + RUN_AFTER(SendOnSystemContext1, 2000) + + --hmi side: sending BasicCommunication.OnAppDeactivated request + RUN_AFTER(sendOnAppDeactivate, 3000) + + + --mobile side: OnHMIStatus notifications + EXPECT_NOTIFICATION("OnHMIStatus", + { systemContext = "MENU", hmiLevel = "FULL"}, + { systemContext = "MENU", hmiLevel = "NONE"}, + { systemContext = "MAIN", hmiLevel = "NONE"}) + :Times(3) + +end + + +for j =1, #updateMode do + Test["SetMediaClockTimer_NONE_" ..tostring(updateMode[j]).."_DISALLOWED"] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + :Timeout(iTimeout) + :Times(0) + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED", info = nil}) + :Timeout(iTimeout) + + end +end + +--End test case DifferentHMIlevel.2 +----------------------------------------------------------------------------------------- + +--Begin test case DifferentHMIlevel.3 +--Description: Check SetMediaClockTimer request when application is in BACKGOUND HMI level + +--Requirement id in JAMA/or Jira ID: SDLAQ-CRS-782 + +--Verification criteria: SetMediaClockTimer is allowed in BACKGOUND HMI level according to policy + +--Precondition: Change app to FULL HMI status +function Test:ActivateApplication() + --HMI send ActivateApp request + local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications["Test Application"]}) + EXPECT_HMIRESPONSE(RequestId) + :Do(function(_,data) + if data.result.isSDLAllowed ~= true then + local RequestId = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) + EXPECT_HMIRESPONSE(RequestId,{result = {code = 0, method = "SDL.GetUserFriendlyMessage"}}) + :Do(function(_,data) + --hmi side: send request SDL.OnAllowSDLFunctionality + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = 1, name = "127.0.0.1"}}) + end) + + EXPECT_HMICALL("BasicCommunication.ActivateApp") + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) + end) + :Times(2) + end + end) + + EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "FULL", systemContext = "MAIN"}) + +end + +--Precondition: Create the second session +function Test:CreateTheSecondSession() + --mobile side: start new session + self.mobileSession1 = mobile_session.MobileSession( + self, + self.mobileConnection) + +end + +--Precondition: Register application the second session +function Test:RegisterAppInTheSecondSession() + --mobile side: start new + self.mobileSession1:StartService(7) + :Do(function() + local CorIdRegister = self.mobileSession1:SendRPC("RegisterAppInterface", + { + syncMsgVersion = + { + majorVersion = 3, + minorVersion = 0 + }, + appName = "Test Application2", + isMediaApplication = true, + languageDesired = 'EN-US', + hmiDisplayLanguageDesired = 'EN-US', + appHMIType = { "NAVIGATION" }, + appID = "1" + }) + + --hmi side: expect BasicCommunication.OnAppRegistered request + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { + application = + { + appName = "Test Application2" + } + }) + :Do(function(_,data) + appId2 = data.params.application.appID + end) + + --mobile side: expect response + self.mobileSession1:ExpectResponse(CorIdRegister, { success = true, resultCode = "SUCCESS" }) + :Timeout(2000) + end) + +end + +--Precondition: Activate second app +function Test:ActivateSecondApp() + --hmi side: sending SDL.ActivateApp request + local rid = self.hmiConnection:SendRequest("SDL.ActivateApp",{appID = appId2}) + EXPECT_HMIRESPONSE(rid) + + --mobile side: expect notification from 2 app + self.mobileSession1:ExpectNotification("OnHMIStatus",{hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN"}) + self.mobileSession:ExpectNotification("OnHMIStatus",{hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) + +end + +for j =1, #updateMode do + Test["SetMediaClockTimer_BACKGROUND_" ..tostring(updateMode[j])] = function(self) + countDown = 0 + if updateMode[j] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + + + --hmi side: expect UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer", + { + startTime = + { + hours = 0, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[j] + }) + :Do(function(_,data) + --hmi side: sending UI.SetMediaClockTimer response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {} ) + end) + :Timeout(iTimeout) + + + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS"}) + --:Timeout(iTimeout) + :Timeout(11000) + + end +end + + +--End test case DifferentHMIlevel.3 +----------------------------------------------------------------------------------------- + +--End test suit DifferentHMIlevel @@ -4396,13 +5148,13 @@ end -------------------------------------------Postcondition------------------------------------- --------------------------------------------------------------------------------------------- - --Print new line to separate Postconditions - commonFunctions:newTestCasesGroup("Postconditions") +--Print new line to separate Postconditions +commonFunctions:newTestCasesGroup("Postconditions") - --Restore sdl_preloaded_pt.json - policyTable:Restore_preloaded_pt() +--Restore sdl_preloaded_pt.json +policyTable:Restore_preloaded_pt() - return Test +return Test diff --git a/test_scripts/API/ATF_SetMediaClockTimer_nonMedia.lua b/test_scripts/API/ATF_SetMediaClockTimer_nonMedia.lua index 801c7bf44e..702342bf38 100644 --- a/test_scripts/API/ATF_SetMediaClockTimer_nonMedia.lua +++ b/test_scripts/API/ATF_SetMediaClockTimer_nonMedia.lua @@ -51,10 +51,12 @@ local arraySoftButtonsParameter = require('user_modules/shared_testcases/testCas --------------------------------------------------------------------------------------------- APIName = "SetMediaClockTimer" -- set request name -local iTimeout = 5000 +local iTimeout = 6000 local updateModeNotRequireStartEndTime = {"PAUSE", "RESUME", "CLEAR"} local updateMode = {"COUNTUP", "COUNTDOWN", "PAUSE", "RESUME", "CLEAR"} local updateModeCountUpDown = {"COUNTUP", "COUNTDOWN"} +local audioStreamingIndicatorStates={"PLAY_PAUSE","PLAY","PAUSE","STOP"} +local audioStreamingIndicatorValue = "PLAY_PAUSE"; local countDown = 0 local InBound60 = {0, 30, 59} local OutBound60 = {-1, 60} @@ -119,8 +121,7 @@ end --2. Update policy to allow request --TODO: Will be updated after policy flow implementation - policyTable:precondition_updatePolicy_AllowFunctionInHmiLeves({"BACKGROUND", "FULL", "LIMITED"}) - + policyTable:precondition_updatePolicy_AllowFunctionInHmiLeves({"BACKGROUND", "FULL", "LIMITED"},"SetMediaClockTimer_nonMedia") --------------------------------------------------------------------------------------------- -----------------------------------------I TEST BLOCK---------------------------------------- @@ -308,11 +309,16 @@ end --Verification criteria: According to xml tests by Ford team all fake parameters should be ignored by SDL --Begin test case CommonRequestCheck.7.1 - --Description: Check request with fake parameters + --Description: Check request with fake parameters and Audio Streaming Indicator for i=1,#updateMode do - Test["SetMediaClockTimer_FakeParameters_" .. tostring(updateMode[i]).."_REJECTED"] = function(self) + Test["SetMediaClockTimer_FakeParameters_"..tostring(updateMode[i]).."_audioStreamingIndicatorValue_SUCCESS"] = function(self) countDown = 0 + if i < 5 then + audioStreamingIndicatorValue = audioStreamingIndicatorStates[i] + else + audioStreamingIndicatorValue = "PLAY_PAUSE" + end if updateMode[i] == "COUNTDOWN" then countDown = -1 end @@ -333,7 +339,8 @@ end minutes = 1 + countDown, seconds = 35 }, - updateMode = updateMode[i] + updateMode = updateMode[i], + audioStreamingIndicator=audioStreamingIndicatorValue }) --hmi side: expect absence of UI.SetMediaClockTimer request @@ -395,6 +402,51 @@ end --End test case CommonRequestCheck.7.2 ----------------------------------------------------------------------------------------- + --Begin test case CommonRequestCheck.7.3 + --Description: Check request with parameters of other request + + for i=1,#updateMode do + Test["SetMediaClockTimer_ParametersOfOtherRequest_" .. tostring(updateMode[i]).."_SUCCESS"] = function(self) + countDown = 0 + if updateMode[i] == "COUNTDOWN" then + countDown = -1 + end + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + syncFileName = "icon.png", --PutFile request + startTime = + { + hours = 0, + minutes = 1, + seconds = 33 + }, + endTime = + { + hours = 0, + minutes = 1 + countDown, + seconds = 35 + }, + updateMode = updateMode[i], + audioStreamingIndicator=audioStreamingIndicatorValue + }) + + + --hmi side: expect absence of UI.SetMediaClockTimer request + EXPECT_HMICALL("UI.SetMediaClockTimer") + :Timeout(iTimeout) + :Times(0) + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "REJECTED"}) + :Timeout(iTimeout) + + end + end + + --End test case CommonRequestCheck.7.3 + ----------------------------------------------------------------------------------------- + --End test case CommonRequestCheck.7 @@ -419,7 +471,7 @@ end rpcCorrelationId = self.mobileSession.correlationId, -- missing ':' after startTime --payload = '{"startTime":{"seconds":34,"hours":0,"minutes":12},"endTime":{"seconds":33,"hours":11,"minutes":22},"updateMode":"COUNTUP"}' - payload = '{"startTime" {"seconds":34,"hours":0,"minutes":12},"endTime":{"seconds":33,"hours":11,"minutes":22},"updateMode":"COUNTUP"}' + payload = '{"startTime" {"seconds":34,"hours":0,"minutes":12},"endTime":{"seconds":33,"hours":11,"minutes":22},"updateMode":"COUNTUP","audioStreamingIndicator":"PLAY_PAUSE"}' } self.mobileSession:Send(msg) @@ -459,7 +511,8 @@ end minutes = 1, seconds = 35 }, - updateMode = "COUNTUP" + updateMode = "COUNTUP", + audioStreamingIndicator="PLAY_PAUSE" }) --hmi side: expect absence of UI.SetMediaClockTimer request @@ -479,7 +532,7 @@ end rpcType = 0, rpcFunctionId = 15, --SetMediaClockTimerID rpcCorrelationId = cid, - payload = '{"startTime":{"seconds":33,"hours":0,"minutes":1},"endTime":{"seconds":35,"hours":0,"minutes":1},"updateMode":"COUNTUP"}' + payload = '{"startTime":{"seconds":33,"hours":0,"minutes":1},"endTime":{"seconds":35,"hours":0,"minutes":1},"updateMode":"COUNTUP","audioStreamingIndicator":"PLAY_PAUSE"}' } self.mobileSession:Send(msg) end @@ -1228,7 +1281,8 @@ end minutes = 1, seconds = 35 }, - updateMode = updateMode[j] + updateMode = updateMode[j], + audioStreamingIndicator="PLAY_PAUSE" }) --hmi side: expect absence of UI.SetMediaClockTimer request @@ -1262,7 +1316,8 @@ end minutes = 1, seconds = 35 }, - updateMode = updateMode[j] + updateMode = updateMode[j], + audioStreamingIndicator="PLAY_PAUSE" }) --hmi side: expect absence of UI.SetMediaClockTimer request @@ -1303,7 +1358,8 @@ end minutes = 1, seconds = 35 }, - updateMode = updateMode[j] + updateMode = updateMode[j], + audioStreamingIndicator="PLAY_PAUSE" }) --hmi side: expect absence of UI.SetMediaClockTimer request @@ -1337,7 +1393,8 @@ end minutes = "", seconds = 35 }, - updateMode = updateMode[j] + updateMode = updateMode[j], + audioStreamingIndicator="PLAY_PAUSE" }) --hmi side: expect absence of UI.SetMediaClockTimer request @@ -1793,6 +1850,40 @@ end --End test case NegativeRequestCheck.3.3 ----------------------------------------------------------------------------------------- + + --Begin test case NegativeRequestCheck.3.4 + --Description: 4.4. The request with wrong data in "audioStreamingIndicator" parameter (e.g. integer value) is sent , the response with INVALID_DATA result code is returned. + + function Test:SetMediaClockTimer_audioStreamingIndicator_IsInvalidValue_WrongType_INVALID_DATA() + + --mobile side: sending SetMediaClockTimer request + local cid = self.mobileSession:SendRPC("SetMediaClockTimer", + { + startTime = + { + hours = 1, + minutes = 1, + seconds = 33, + }, + endTime = + { + hours = 1, + minutes = 1, + seconds = 35 + }, + updateMode = "COUNTUP", + audioStreamingIndicator="FAKE" + }) + + --mobile side: expect SetMediaClockTimer response + EXPECT_RESPONSE(cid, { success = false, resultCode = "INVALID_DATA"}) + :Timeout(iTimeout) + + end + + --End test case NegativeRequestCheck.3.4 + ------------------------------------------------------------------------------------------- + --End test case NegativeRequestCheck.3 @@ -1845,7 +1936,8 @@ end for j =1, #updateMode do - Test["UI_SetMediaClockTimer_resultCode_APPLICATION_NOT_REGISTERED".."_"..tostring(updateMode[j])] = function(self) + for k =1, #audioStreamingIndicatorStates do + Test["UI_SetMediaClockTimer_resultCode_APPLICATION_NOT_REGISTERED".."_"..tostring(updateMode[j]).."_" .. tostring(audioStreamingIndicatorStates[k])] = function(self) countDown = 0 if updateMode[j] == "COUNTDOWN" then countDown = -1 @@ -1866,7 +1958,8 @@ end minutes = 1 + countDown, seconds = 35 }, - updateMode = updateMode[j] + updateMode = updateMode[j], + audioStreamingIndicator=audioStreamingIndicatorStates[k] }) --hmi side: expect absence of UI.SetMediaClockTimer request @@ -1877,7 +1970,7 @@ end --mobile side: expect SetMediaClockTimer response self.mobileSession2:ExpectResponse(cid, { success = false, resultCode = "APPLICATION_NOT_REGISTERED" }) end - + end end --End test case ResultCodeCheck.1 From a5bdd126c7325f16394e5ccf5bb60d1e7a323b36 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 12 Jun 2018 22:54:37 +0300 Subject: [PATCH 423/681] Add scripts with reduced number of test cases for Mobile Projection 2 feature --- .../smoke/001_audioStreamingState_001-009.lua | 48 ++++ .../smoke/002_audioStreamingState_010-068.lua | 61 ++++ .../smoke/003_audioStreamingState_069-103.lua | 52 ++++ .../smoke/004_audioStreamingState_104-110.lua | 66 +++++ .../smoke/005_audioStreamingState_111-118.lua | 80 ++++++ .../smoke/006_videoStreamingState_001-006.lua | 47 ++++ .../smoke/007_videoStreamingState_007-030.lua | 58 ++++ .../smoke/008_videoStreamingState_031-042.lua | 50 ++++ .../Phase2/smoke/009_hmiLevel_001-032.lua | 153 ++++++++++ ...0_single_app_audio_and_video_streaming.lua | 76 +++++ .../smoke/012_single_app_deactivation.lua | 75 +++++ .../Phase2/smoke/013_two_apps_interaction.lua | 129 +++++++++ ...o_010-068_video_007-030_states_LIMITED.lua | 109 +++++++ ..._097-103_video_031-038_states_not_FULL.lua | 81 ++++++ .../smoke/016_BACKGROUND_not_changed.lua | 65 +++++ .../smoke/017_two_apps_and_one_app_exits.lua | 56 ++++ .../018_two_apps_and_one_app_unregister.lua | 57 ++++ .../Phase2/smoke/019_SDL_stop_audio_video.lua | 115 ++++++++ .../020_different_types_apps_interactions.lua | 265 ++++++++++++++++++ .../smoke/021_two_apps_and_deactivation.lua | 91 ++++++ ..._proj_media_and_deactivation_streaming.lua | 108 +++++++ ...s_navi_comm_and_deactivation_streaming.lua | 104 +++++++ test_sets/mobile_projection_2_smoke.txt | 22 ++ 23 files changed, 1968 insertions(+) create mode 100644 test_scripts/MobileProjection/Phase2/smoke/001_audioStreamingState_001-009.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/002_audioStreamingState_010-068.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/003_audioStreamingState_069-103.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/004_audioStreamingState_104-110.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/005_audioStreamingState_111-118.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/006_videoStreamingState_001-006.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/007_videoStreamingState_007-030.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/008_videoStreamingState_031-042.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/009_hmiLevel_001-032.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/010_single_app_audio_and_video_streaming.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/012_single_app_deactivation.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/013_two_apps_interaction.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/014_audio_010-068_video_007-030_states_LIMITED.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/015_audio_083-089_097-103_video_031-038_states_not_FULL.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/016_BACKGROUND_not_changed.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/017_two_apps_and_one_app_exits.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/018_two_apps_and_one_app_unregister.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/019_SDL_stop_audio_video.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/020_different_types_apps_interactions.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/021_two_apps_and_deactivation.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/022_two_apps_proj_media_and_deactivation_streaming.lua create mode 100644 test_scripts/MobileProjection/Phase2/smoke/023_two_apps_navi_comm_and_deactivation_streaming.lua create mode 100644 test_sets/mobile_projection_2_smoke.txt diff --git a/test_scripts/MobileProjection/Phase2/smoke/001_audioStreamingState_001-009.lua b/test_scripts/MobileProjection/Phase2/smoke/001_audioStreamingState_001-009.lua new file mode 100644 index 0000000000..b67fc58d0d --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/001_audioStreamingState_001-009.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) Mobile app is activated +-- SDL must: +-- 1) Send OnHMIStatus notification with appropriate value of 'audioStreamingState' parameter +-- Particular value depends on app's 'appHMIType' and 'isMediaApplication' flag, and described in 'testCases' table below +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [001] = { t = "PROJECTION", m = false, s = "NOT_AUDIBLE" }, + [003] = { t = "NAVIGATION", m = false, s = "AUDIBLE" }, + [005] = { t = "NAVIGATION", m = true, s = "AUDIBLE" }, + [007] = { t = "PROJECTION", m = true, s = "AUDIBLE" } +} + +--[[ Local Functions ]] +local function activateApp(pTC, pAudioSS) + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId() }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, "App1", pAudioSS, data.payload.audioStreamingState) + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp) + runner.Step("Activate App, audioState:" .. tc.s, activateApp, { n, tc.s }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/smoke/002_audioStreamingState_010-068.lua b/test_scripts/MobileProjection/Phase2/smoke/002_audioStreamingState_010-068.lua new file mode 100644 index 0000000000..3626003f3c --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/002_audioStreamingState_010-068.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps: +-- app1: is audio source ('audioStreamingState' = AUDIBLE) +-- app2: is not audio source ('audioStreamingState' = NOT_AUDIBLE) +-- 2) Mobile app2 is activated +-- SDL must: +-- 1) Send OnHMIStatus notification for both apps with appropriate value of 'audioStreamingState' parameter +-- Particular value depends on app's 'appHMIType' and 'isMediaApplication' flag, and described in 'testCases' table below +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [010] = { [1] = { t = "NAVIGATION", m = false, s = "AUDIBLE" }, [2] = { t = "PROJECTION", m = false, s = "NOT_AUDIBLE" }}, + [024] = { [1] = { t = "NAVIGATION", m = false, s = "NOT_AUDIBLE" }, [2] = { t = "NAVIGATION", m = false, s = "AUDIBLE" } }, + [032] = { [1] = { t = "NAVIGATION", m = false, s = "AUDIBLE" }, [2] = { t = "PROJECTION", m = true, s = "AUDIBLE" } }, + [048] = { [1] = { t = "PROJECTION", m = true, s = "AUDIBLE" }, [2] = { t = "NAVIGATION", m = false, s = "AUDIBLE" } }, + [060] = { [1] = { t = "PROJECTION", m = true, s = "NOT_AUDIBLE" }, [2] = { t = "PROJECTION", m = true, s = "AUDIBLE" } } +} + +--[[ Local Functions ]] +local function activateApp2(pTC, pAudioSSApp1, pAudioSSApp2) + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId(2) }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, "App1", pAudioSSApp1, data.payload.audioStreamingState) + end) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, "App2", pAudioSSApp2, data.payload.audioStreamingState) + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Activate App 2, audioStates: app1 " .. tc[1].s .. ", app2 " .. tc[2].s, activateApp2, + { n, tc[1].s, tc[2].s }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/smoke/003_audioStreamingState_069-103.lua b/test_scripts/MobileProjection/Phase2/smoke/003_audioStreamingState_069-103.lua new file mode 100644 index 0000000000..57b1431023 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/003_audioStreamingState_069-103.lua @@ -0,0 +1,52 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) Mobile app is audio source ('audioStreamingState' = AUDIBLE) +-- 2) One of the event below is received from HMI within 'BC.OnEventChanged' notification: +-- PHONE_CALL, EMERGENCY_EVENT, AUDIO_SOURCE, EMBEDDED_NAVI, DEACTIVATE_HMI +-- SDL must: +-- 1) Send OnHMIStatus notification with 'audioStreamingState' = NOT_AUDIBLE +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [073] = { t = "PROJECTION", m = true, s = "NOT_AUDIBLE", e = "PHONE_CALL" }, + [080] = { t = "PROJECTION", m = true, s = "NOT_AUDIBLE", e = "EMERGENCY_EVENT" }, + [087] = { t = "PROJECTION", m = true, s = "NOT_AUDIBLE", e = "AUDIO_SOURCE" }, + [094] = { t = "PROJECTION", m = true, s = "NOT_AUDIBLE", e = "EMBEDDED_NAVI" }, + [101] = { t = "PROJECTION", m = true, s = "NOT_AUDIBLE", e = "DEACTIVATE_HMI" } +} + +--[[ Local Functions ]] +local function sendEvent(pTC, pEvent, pAudioSS) + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = pEvent, + isActive = true }) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, "App1", pAudioSS, data.payload.audioStreamingState) + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. ", event:" .. tc.e .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp) + runner.Step("Activate App", common.activateApp) + runner.Step("Send event from HMI: " .. tc.e, sendEvent, { n, tc.e, tc.s }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/smoke/004_audioStreamingState_104-110.lua b/test_scripts/MobileProjection/Phase2/smoke/004_audioStreamingState_104-110.lua new file mode 100644 index 0000000000..5cb1963aa8 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/004_audioStreamingState_104-110.lua @@ -0,0 +1,66 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) Mobile app is audio source ('audioStreamingState' = AUDIBLE) +-- 2) And TTS is started +-- SDL must: +-- 1) Send OnHMIStatus notification with 'audioStreamingState' = ATTENUATED +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [108] = { t = "PROJECTION", m = true } +} + +--[[ Local Functions ]] +local function sendSpeak(pTC) + local request = { + ttsChunks = { + { text ="Text1", type ="TEXT" } + } + } + local cid = common.getMobileSession():SendRPC("Speak", request) + common.getHMIConnection():ExpectRequest("TTS.Speak") + :Do(function(_, data) + common.getHMIConnection():SendNotification("TTS.Started") + local function speakResponse() + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { }) + common.getHMIConnection():SendNotification("TTS.Stopped") + end + RUN_AFTER(speakResponse, 1000) + end) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + + common.getMobileSession():ExpectNotification("OnHMIStatus") + :ValidIf(function(e, data) + if e.occurences == 1 then + return common.checkAudioSS(pTC, "App1", "ATTENUATED", data.payload.audioStreamingState) + else + return common.checkAudioSS(pTC, "App1", "AUDIBLE", data.payload.audioStreamingState) + end + end) + :Times(2) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp) + runner.Step("Activate App", common.activateApp) + runner.Step("Send Speak, audioState:ATTENUATED", sendSpeak, { n }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/smoke/005_audioStreamingState_111-118.lua b/test_scripts/MobileProjection/Phase2/smoke/005_audioStreamingState_111-118.lua new file mode 100644 index 0000000000..c3d5d4e1e2 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/005_audioStreamingState_111-118.lua @@ -0,0 +1,80 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps: +-- app1: NAVIGATION, is audio source ('audioStreamingState' = AUDIBLE) +-- app2: MEDIA, is audio source ('audioStreamingState' = AUDIBLE) +-- 2) And NAVI app starts streaming +-- SDL must: +-- 1) Not change the value of 'audioStreamingState' parameter for NAVI app +-- 2) Change 'audioStreamingState' parameter for MEDIA app to: +-- ATTENUATED - in case if MixingAudioSupported = true +-- NOT_AUDIBLE - in case if MixingAudioSupported = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') +local hmi_values = require('user_modules/hmi_values') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.defaultProtocolVersion = 3 + +--[[ Local Variables ]] +local testCases = { + [111] = { + [1] = { t = "NAVIGATION", m = false }, + [2] = { t = "MEDIA", m = true }, + a = 1, s = "ATTENUATED", mix = true + } +} + +--[[ Local Functions ]] +local function getHMIParams(pIsMixingSupported) + local hmiParams = hmi_values.getDefaultHMITable() + hmiParams.BasicCommunication.MixingAudioSupported.params.attenuatedSupported = pIsMixingSupported + return hmiParams +end + +local function appStartStreaming(pTC, pStreamingAppId, pAudioSSApp) + common.getMobileSession(pStreamingAppId):StartService(10) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartAudioStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession(pStreamingAppId):StartStreaming(10, "files/MP3_1140kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = true }) + end) + end) + local notStreamingAppId + if pStreamingAppId == 1 then notStreamingAppId = 2 else notStreamingAppId = 1 end + common.getMobileSession(pStreamingAppId):ExpectNotification("OnHMIStatus") + :Times(0) + common.getMobileSession(notStreamingAppId):ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + common.getMobileSession(pStreamingAppId):StopStreaming("files/MP3_1140kb.mp3") + return common.checkAudioSS(pTC, "App" .. notStreamingAppId, pAudioSSApp, data.payload.audioStreamingState) + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: isMixing:" .. tostring(tc.mix) .. ", " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session, isMixingSupported:" .. tostring(tc.mix), + common.start, { getHMIParams(tc.mix) }) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Activate App 2", common.activateApp, { 2 }) + runner.Step("App " .. tc.a .. " starts streaming", appStartStreaming, { n, tc.a, tc.s }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/smoke/006_videoStreamingState_001-006.lua b/test_scripts/MobileProjection/Phase2/smoke/006_videoStreamingState_001-006.lua new file mode 100644 index 0000000000..e926222463 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/006_videoStreamingState_001-006.lua @@ -0,0 +1,47 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) Mobile app is activated +-- SDL must: +-- 1) Send OnHMIStatus notification with appropriate value of 'videoStreamingState' parameter +-- Particular value depends on app's 'appHMIType' and described in 'testCases' table below +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [001] = { t = "MEDIA", m = true, s = "NOT_STREAMABLE" }, + [005] = { t = "PROJECTION", m = true, s = "STREAMABLE" }, + [006] = { t = "PROJECTION", m = false, s = "STREAMABLE" } +} + +--[[ Local Functions ]] +local function activateApp(pTC, pVideoSS) + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId() }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, "App1", pVideoSS, data.payload.videoStreamingState) + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp) + runner.Step("Activate App, videoState:" .. tc.s, activateApp, { n, tc.s }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/smoke/007_videoStreamingState_007-030.lua b/test_scripts/MobileProjection/Phase2/smoke/007_videoStreamingState_007-030.lua new file mode 100644 index 0000000000..0202721bf3 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/007_videoStreamingState_007-030.lua @@ -0,0 +1,58 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps: +-- app1: is video source ('videoStreamingState' = STREAMABLE) +-- app2: is not video source ('audioStreamingState' = NOT_STREAMABLE) +-- 2) Mobile app2 is activated +-- SDL must: +-- 1) Send OnHMIStatus notification for both apps with appropriate value of 'videoStreamingState' parameter +-- Particular value depends on app's 'appHMIType' and described in 'testCases' table below +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [010] = { [1] = { t = "PROJECTION", m = false, s = "STREAMABLE" }, [2] = { t = "MEDIA", m = true, s = "NOT_STREAMABLE" }}, + [019] = { [1] = { t = "PROJECTION", m = true, s = "NOT_STREAMABLE" }, [2] = { t = "NAVIGATION", m = true, s = "STREAMABLE" }} +} + +--[[ Local Functions ]] +local function activateApp2(pTC, pVideoSSApp1, pVideoSSApp2) + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId(2) }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, "App1", pVideoSSApp1, data.payload.videoStreamingState) + end) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, "App2", pVideoSSApp2, data.payload.videoStreamingState) + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Activate App 2, videoStates: app1 " .. tc[1].s .. ", app2 " .. tc[2].s, activateApp2, + { n, tc[1].s, tc[2].s }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/smoke/008_videoStreamingState_031-042.lua b/test_scripts/MobileProjection/Phase2/smoke/008_videoStreamingState_031-042.lua new file mode 100644 index 0000000000..94158bbc30 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/008_videoStreamingState_031-042.lua @@ -0,0 +1,50 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) Mobile app is video source ('videoStreamingState' = STREAMABLE) +-- 2) One of the event below is received from HMI within 'BC.OnEventChanged' notification: +-- DEACTIVATE_HMI, AUDIO_SOURCE, EMBEDDED_NAVI +-- SDL must: +-- 1) Send OnHMIStatus notification with 'videoStreamingState' = NOT_STREAMABLE +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [033] = { t = "PROJECTION", m = true, s = "NOT_STREAMABLE", e = "DEACTIVATE_HMI" }, + [037] = { t = "PROJECTION", m = true, s = "NOT_STREAMABLE", e = "AUDIO_SOURCE" }, + [041] = { t = "PROJECTION", m = true, s = "NOT_STREAMABLE", e = "EMBEDDED_NAVI" } +} + +--[[ Local Functions ]] +local function sendEvent(pTC, pEvent, pVideoSS) + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = pEvent, + isActive = true }) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, "App1", pVideoSS, data.payload.videoStreamingState) + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. ", event:" .. tc.e .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp) + runner.Step("Activate App", common.activateApp) + runner.Step("Send event from HMI: " .. tc.e, sendEvent, { n, tc.e, tc.s }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/smoke/009_hmiLevel_001-032.lua b/test_scripts/MobileProjection/Phase2/smoke/009_hmiLevel_001-032.lua new file mode 100644 index 0000000000..3c7fb1cab8 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/009_hmiLevel_001-032.lua @@ -0,0 +1,153 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) Mobile app is in some state +-- 2) Mobile app is moving to another state by one of the events: +-- App activation, App deactivation, Deactivation of HMI, User exit +-- SDL must: +-- 1) Send (or not send) OnHMIStatus notification with appropriate value of 'hmiLevel' parameter +-- Particular behavior and value depends on initial state and event, and described in 'testCases' table below +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.checkAllValidations = true + +--[[ Event Functions ]] +local action = { + activateApp = { + name = "Activation", + func = function() + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { + appID = common.getHMIAppId() }) + common.getHMIConnection():ExpectResponse(requestId) + end + }, + deactivateApp = { + name = "De-activation", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId() }) + end + }, + deactivateHMI = { + name = "HMI De-activation", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "DEACTIVATE_HMI", + isActive = true }) + end + }, + activateHMI = { + name = "HMI Activation", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "DEACTIVATE_HMI", + isActive = false }) + end + }, + exitApp = { + name = "User Exit", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnExitApplication", { + appID = common.getHMIAppId(), + reason = "USER_EXIT" }) + end + } +} + +--[[ Local Variables ]] +local testCases = { + [002] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateApp, l = "LIMITED", a = "NOT_AUDIBLE", v = "STREAMABLE" } + }}, + [004] = { t = "DEFAULT", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [2] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [006] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [009] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateApp, l = "LIMITED", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [3] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [012] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.exitApp, l = "NONE", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [014] = { t = "DEFAULT", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [2] = { e = action.exitApp, l = "NONE", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [016] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" } + }}, + [018] = { t = "DEFAULT", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [020] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateApp, l = "LIMITED", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [3] = { e = action.exitApp, l = "NONE", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [023] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [3] = { e = action.exitApp, l = "NONE", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }}, + [027] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateApp, l = "LIMITED", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [3] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" } + }}, + [030] = { t = "PROJECTION", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" }, + [2] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [3] = { e = action.activateHMI, l = "FULL", a = "NOT_AUDIBLE", v = "STREAMABLE" } + }}, + [032] = { t = "DEFAULT", m = false, s = { + [1] = { e = action.activateApp, l = "FULL", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [2] = { e = action.deactivateHMI, l = "BACKGROUND", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" }, + [3] = { e = action.activateHMI, l = "FULL", a = "NOT_AUDIBLE", v = "NOT_STREAMABLE" } + }} +} + +--[[ Local Functions ]] +local function doAction(pTC, pSS) + pSS.e.func() + common.getMobileSession():ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, pSS.e.name, pSS.a, data.payload.audioStreamingState) + end) + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, pSS.e.name, pSS.v, data.payload.videoStreamingState) + end) + :ValidIf(function(_, data) + return common.checkHMILevel(pTC, pSS.e.name, pSS.l, data.payload.hmiLevel) + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp) + for i = 1, #tc.s do + runner.Step("Action:" .. tc.s[i].e.name .. ",hmiLevel:" .. tc.s[i].l, doAction, { n, tc.s[i] }) + end + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/smoke/010_single_app_audio_and_video_streaming.lua b/test_scripts/MobileProjection/Phase2/smoke/010_single_app_audio_and_video_streaming.lua new file mode 100644 index 0000000000..ef77b2408c --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/010_single_app_audio_and_video_streaming.lua @@ -0,0 +1,76 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There is a mobile app which is audio/video source +-- 2) And this app starts Audio/Video streaming +-- 3) And this app stops Audio/Video streaming +-- SDL must: +-- 1) Not send 'OnHMIStatus' when Audio/Video streaming is started or stopped +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.defaultProtocolVersion = 3 + +--[[ Local Variables ]] +local testCases = { + [001] = { t = "PROJECTION", m = true }, + [002] = { t = "NAVIGATION", m = true }, +} + +--[[ Local Functions ]] +local function appStartAudioStreaming() + common.getMobileSession():StartService(10) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartAudioStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(10,"files/MP3_1140kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = true }) + end) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function appStartVideoStreaming() + common.getMobileSession():StartService(11) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(11, "files/MP3_4555kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = true }) + end) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function appStopStreaming() + common.getMobileSession():StopStreaming("files/MP3_1140kb.mp3") + common.getMobileSession():StopStreaming("files/MP3_4555kb.mp3") + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp, { 1 }) + runner.Step("Activate App", common.activateApp, { 1 }) + runner.Step("App starts Audio streaming", appStartAudioStreaming) + runner.Step("App starts Video streaming", appStartVideoStreaming) + runner.Step("App stops streaming", appStopStreaming) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end diff --git a/test_scripts/MobileProjection/Phase2/smoke/012_single_app_deactivation.lua b/test_scripts/MobileProjection/Phase2/smoke/012_single_app_deactivation.lua new file mode 100644 index 0000000000..d6f8b98711 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/012_single_app_deactivation.lua @@ -0,0 +1,75 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There is a mobile app which is video source +-- 2) And this app starts Audio/Video streaming +-- 3) And this app is deactivated +-- SDL must: +-- 1) Not change the value of 'audioStreamingState' and 'videoStreamingState' parameters in 'OnHMIStatus' +-- 2) Change the value of 'hmiLevel' to LIMITED +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.defaultProtocolVersion = 3 + +--[[ Local Variables ]] +local testCases = { + [001] = { t = "PROJECTION", m = true } +} + +--[[ Local Functions ]] +local function appStartAudioStreaming() + common.getMobileSession():StartService(10) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartAudioStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(10,"files/MP3_1140kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = true }) + end) + end) +end + +local function appStartVideoStreaming() + common.getMobileSession():StartService(11) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(11, "files/MP3_4555kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = true }) + end) + end) +end + +local function deactivateApp() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { appID = common.getHMIAppId() }) + common.getMobileSession():ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "AUDIBLE", + videoStreamingState = "STREAMABLE" + }) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp, { 1 }) + runner.Step("Activate App", common.activateApp, { 1 }) + runner.Step("App starts Audio streaming", appStartAudioStreaming) + runner.Step("App starts Video streaming", appStartVideoStreaming) + runner.Step("Deactivate App", deactivateApp) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end diff --git a/test_scripts/MobileProjection/Phase2/smoke/013_two_apps_interaction.lua b/test_scripts/MobileProjection/Phase2/smoke/013_two_apps_interaction.lua new file mode 100644 index 0000000000..583b2b5b06 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/013_two_apps_interaction.lua @@ -0,0 +1,129 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) Mobile app1 is registered and activated +-- 2) Mobile app2 is registered +-- 3) Mobile app1 is deactivated +-- 4) Mobile app2 is activated +-- SDL must: +-- 1) Send 'OnHMIStatus' notification to app1 with appropriate values for 'audioStreamingState' +-- and 'videoStreamingState' parameters when app1 is deactivated +-- 2) Send 'OnHMIStatus' notification to app1 and app2 with appropriate values for 'audioStreamingState' +-- and 'videoStreamingState' parameters when app2 is activated +-- Particular values depends on app's 'appHMIType' and described in 'testCases' table below +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.defaultProtocolVersion = 3 + +--[[ Local Variables ]] +local testCases = { + [001] = { + [1] = { t = "PROJECTION", m = true }, [2] = { t = "PROJECTION", m = false }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" } + }, + [002] = { + [1] = { t = "PROJECTION", m = true }, [2] = { t = "NAVIGATION", m = false }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" } + }, + [003] = { + [1] = { t = "PROJECTION", m = false }, [2] = { t = "PROJECTION", m = false }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "BACKGROUND", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" } + }, + [004] = { + [1] = { t = "PROJECTION", m = false }, [2] = { t = "PROJECTION", m = true }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "BACKGROUND", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" } + }, + [005] = { + [1] = { t = "PROJECTION", m = false }, [2] = { t = "NAVIGATION", m = false }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "BACKGROUND", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" } + }, + [006] = { + [1] = { t = "NAVIGATION", m = false }, [2] = { t = "PROJECTION", m = false }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" } + }, + [007] = { + [1] = { t = "NAVIGATION", m = false }, [2] = { t = "PROJECTION", m = true }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" } + }, + [008] = { + [1] = { t = "PROJECTION", m = true }, [2] = { t = "PROJECTION", m = true }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "BACKGROUND", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" } + }, + [009] = { + [1] = { t = "NAVIGATION", m = false }, [2] = { t = "NAVIGATION", m = false }, + ohs1_1 = { l = "LIMITED", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" }, + ohs1_2 = { l = "BACKGROUND", sc = "MAIN", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + ohs2_1 = { l = "FULL", sc = "MAIN", aSS = "AUDIBLE", vSS = "STREAMABLE" } + } +} + +--[[ Local Functions ]] +local function deactivateApp(pApp1OHS) + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(1) + }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", { + hmiLevel = pApp1OHS.l, + systemContext = pApp1OHS.sc, + audioStreamingState = pApp1OHS.aSS, + videoStreamingState = pApp1OHS.vSS + }) +end + +local function activateApp(pApp1OHS, pApp2OHS) + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId(2) }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { + hmiLevel = pApp2OHS.l, + systemContext = pApp2OHS.sc, + audioStreamingState = pApp2OHS.aSS, + videoStreamingState = pApp2OHS.vSS + }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", { + hmiLevel = pApp1OHS.l, + systemContext = pApp1OHS.sc, + audioStreamingState = pApp1OHS.aSS, + videoStreamingState = pApp1OHS.vSS + }) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Deactivate App 1", deactivateApp, { tc.ohs1_1 }) + runner.Step("Activate App 2", activateApp, { tc.ohs1_2, tc.ohs2_1 }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end diff --git a/test_scripts/MobileProjection/Phase2/smoke/014_audio_010-068_video_007-030_states_LIMITED.lua b/test_scripts/MobileProjection/Phase2/smoke/014_audio_010-068_video_007-030_states_LIMITED.lua new file mode 100644 index 0000000000..0315e9bd7b --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/014_audio_010-068_video_007-030_states_LIMITED.lua @@ -0,0 +1,109 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps: +-- app1: is video source ('videoStreamingState' = STREAMABLE) +-- app2: is not video source ('audioStreamingState' = NOT_STREAMABLE) +-- 2) Mobile app1 is deactivated +-- 3) Mobile app2 is activated +-- SDL must: +-- 1) Send OnHMIStatus notification for both apps with appropriate value of 'videoStreamingState' parameter +-- Particular value depends on app's 'appHMIType' and described in 'testCases' table below +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [010] = { + [1] = { t = "NAVIGATION", m = false, aSS = { "AUDIBLE", "AUDIBLE" }, vSS = { "STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "PROJECTION", m = false, aSS = { nil, "NOT_AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [024] = { + [1] = { t = "NAVIGATION", m = false, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "NAVIGATION", m = false, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [032] = { + [1] = { t = "NAVIGATION", m = false, aSS = { "AUDIBLE", "AUDIBLE" }, vSS = { "STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "PROJECTION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [048] = { + [1] = { t = "PROJECTION", m = true, aSS = { "AUDIBLE", "AUDIBLE" }, vSS = { "STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "NAVIGATION", m = false, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + }, + [060] = { + [1] = { t = "PROJECTION", m = true, aSS = { "AUDIBLE", "NOT_AUDIBLE" }, vSS = { "STREAMABLE", "NOT_STREAMABLE" } }, + [2] = { t = "PROJECTION", m = true, aSS = { nil, "AUDIBLE" }, vSS = { nil, "STREAMABLE" } } + } +} + +--[[ Local Functions ]] +local function activateApp2(pTC, pAudioSSApp1, pVideoSSApp1, pAudioSSApp2, pVideoSSApp2) + local count = 1 + if pAudioSSApp1 == nil and pVideoSSApp1 == nil then count = 0 end + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId(2) }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, "App1", pAudioSSApp1, data.payload.audioStreamingState) + end) + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, "App1", pVideoSSApp1, data.payload.videoStreamingState) + end) + :Times(count) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, "App2", pAudioSSApp2, data.payload.audioStreamingState) + end) + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, "App2", pVideoSSApp2, data.payload.videoStreamingState) + end) +end + +local function deactivateApp1(pTC, pAudioSSApp1, pVideoSSApp1) + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { appID = common.getHMIAppId() }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, "App1", pAudioSSApp1, data.payload.audioStreamingState) + end) + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, "App1", pVideoSSApp1, data.payload.videoStreamingState) + end) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function getMsg(pTC, pAppId, pNotifId) + if pTC[pAppId].aSS[pNotifId] == nil and pTC[pAppId].vSS[pNotifId] == nil then + return "NO" + else + return pTC[pAppId].aSS[pNotifId] .. ":" .. pTC[pAppId].vSS[pNotifId] + end +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Deact. App 1:" .. "App1:" .. getMsg(tc, 1, 1) .. " App2:" .. getMsg(tc, 2, 1), + deactivateApp1, { n, tc[1].aSS[1], tc[1].vSS[1] }) + runner.Step("Act. App 2:" .. "App1:" .. getMsg(tc, 1, 2) .. " App2:" .. getMsg(tc, 2, 2), + activateApp2, { n, tc[1].aSS[2], tc[1].vSS[2], tc[2].aSS[2], tc[2].vSS[2] }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/smoke/015_audio_083-089_097-103_video_031-038_states_not_FULL.lua b/test_scripts/MobileProjection/Phase2/smoke/015_audio_083-089_097-103_video_031-038_states_not_FULL.lua new file mode 100644 index 0000000000..4823e9dd78 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/015_audio_083-089_097-103_video_031-038_states_not_FULL.lua @@ -0,0 +1,81 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) Mobile app is audio/video source +-- 2) Mobile app is deactivated +-- 3) One of the event below is received from HMI within 'BC.OnEventChanged' (isActive = true) notification: +-- DEACTIVATE_HMI, AUDIO_SOURCE +-- 4) The same event notification (isActive = false) is received +-- SDL must: +-- 1) Send OnHMIStatus notification with 'audioStreamingState' = NOT_AUDIBLE and 'videoStreamingState' = NOT_STREAMABLE +-- 2) Restore original state of mobile app +-- Particular value depends on app's 'appHMIType' and described in 'testCases' table below +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local onHMIStatusData = {} +local testCases = { + [001] = { t = "NAVIGATION", m = true, e = "DEACTIVATE_HMI" }, + [003] = { t = "PROJECTION", m = true, e = "DEACTIVATE_HMI" }, + [012] = { t = "NAVIGATION", m = false, e = "AUDIO_SOURCE" }, + [014] = { t = "PROJECTION", m = false, e = "AUDIO_SOURCE" } +} + +--[[ Local Functions ]] +local function sendEvent(pTC, pEvent, pIsActive) + local count = 1 + if onHMIStatusData.hmiL == "BACKGROUND" then count = 0 end + local status = common.cloneTable(onHMIStatusData) + if pIsActive == true then + status.hmiL = "BACKGROUND" + status.aSS = "NOT_AUDIBLE" + status.vSS = "NOT_STREAMABLE" + end + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = pEvent, + isActive = pIsActive }) + common.getMobileSession():ExpectNotification("OnHMIStatus", { hmiLevel = status.hmiL }) + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, "App1", status.aSS, data.payload.audioStreamingState) + end) + :ValidIf(function(_, data) + return common.checkVideoSS(pTC, "App1", status.vSS, data.payload.videoStreamingState) + end) + :Times(count) + common.wait(500) +end + +local function deactivateApp() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { appID = common.getHMIAppId() }) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Do(function(_, data) + onHMIStatusData.hmiL = data.payload.hmiLevel + onHMIStatusData.aSS = data.payload.audioStreamingState + onHMIStatusData.vSS = data.payload.videoStreamingState + end) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. ", event:" .. tc.e .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp) + runner.Step("Activate App", common.activateApp) + runner.Step("Deactivate App", deactivateApp) + runner.Step("Send event from HMI isActive: true", sendEvent, { n, tc.e, true }) + runner.Step("Send event from HMI isActive: false", sendEvent, { n, tc.e, false }) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/smoke/016_BACKGROUND_not_changed.lua b/test_scripts/MobileProjection/Phase2/smoke/016_BACKGROUND_not_changed.lua new file mode 100644 index 0000000000..40911507f0 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/016_BACKGROUND_not_changed.lua @@ -0,0 +1,65 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps registered: +-- app1: is not audio/video source +-- app2: is NAVIGATION +-- 2) Mobile app1 is activated +-- 3) Mobile app1 is deactivated (moved to BACKGROUND) +-- 4) Mobile app2 is activated +-- SDL must: +-- 1) Not send 'OnHMIStatus' notification to app1 +-- 2) Send 'OnHMIStatus' notification to app2 with 'hmiLevel' = FULL +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [001] = { [1] = { t = "MEDIA", m = false }, [2] = { t = "NAVIGATION", m = false }}, + [005] = { [1] = { t = "MEDIA", m = false }, [2] = { t = "PROJECTION", m = false }} +} + +--[[ Local Functions ]] +local function activateApp2() + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId(2) }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { hmiLevel = "FULL" }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function setApp1ToBACKGROUND() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { appID = common.getHMIAppId() }) + common.getMobileSession():ExpectNotification("OnHMIStatus", { + hmiLevel = "BACKGROUND", + systemContext = "MAIN", + audioStreamingState = "NOT_AUDIBLE", + videoStreamingState = "NOT_STREAMABLE" + }) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Set App 1 to BACKGROUND", setApp1ToBACKGROUND) + runner.Step("Activate App 2", activateApp2) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/smoke/017_two_apps_and_one_app_exits.lua b/test_scripts/MobileProjection/Phase2/smoke/017_two_apps_and_one_app_exits.lua new file mode 100644 index 0000000000..844af85fbe --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/017_two_apps_and_one_app_exits.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps registered: PROJECTION and NAVIGATION +-- 2) Mobile app1 is activated +-- 3) Mobile app2 is activated +-- 4) HMI sends 'BC.OnExitApplication' (USER_EXIT) for app2 +-- SDL must: +-- 1) Not send 'OnHMIStatus' notification to app1 +-- 2) Send 'OnHMIStatus' notification to app2 with 'hmiLevel' = NONE +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [001] = { [1] = { t = "NAVIGATION", m = false }, [2] = { t = "PROJECTION", m = true }}, + [005] = { [1] = { t = "PROJECTION", m = false }, [2] = { t = "NAVIGATION", m = true }}, + [009] = { [1] = { t = "NAVIGATION", m = false }, [2] = { t = "NAVIGATION", m = false }}, + [013] = { [1] = { t = "PROJECTION", m = false }, [2] = { t = "PROJECTION", m = false }} +} + +--[[ Local Functions ]] +local function exitApp2() + common.getHMIConnection():SendNotification("BasicCommunication.OnExitApplication", { + appID = common.getHMIAppId(2), + reason = "USER_EXIT" }) + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { hmiLevel = "NONE" }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Activate App 2", common.activateApp, { 2 }) + runner.Step("Exit App 2", exitApp2) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/smoke/018_two_apps_and_one_app_unregister.lua b/test_scripts/MobileProjection/Phase2/smoke/018_two_apps_and_one_app_unregister.lua new file mode 100644 index 0000000000..dbf0163f98 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/018_two_apps_and_one_app_unregister.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps registered: PROJECTION and NAVIGATION +-- 2) Mobile app1 is activated +-- 3) Mobile app2 is activated +-- 4) Mobile App2 is unregistered +-- SDL must: +-- 1) Not send 'OnHMIStatus' notification to app1 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [001] = { [1] = { t = "NAVIGATION", m = false }, [2] = { t = "PROJECTION", m = true }}, + [005] = { [1] = { t = "PROJECTION", m = false }, [2] = { t = "NAVIGATION", m = true }}, + [009] = { [1] = { t = "NAVIGATION", m = false }, [2] = { t = "NAVIGATION", m = false }}, + [013] = { [1] = { t = "PROJECTION", m = false }, [2] = { t = "PROJECTION", m = false }} +} + +--[[ Local Functions ]] +local function unregisterApp2() + local cid = common.getMobileSession(2):SendRPC("UnregisterAppInterface", {}) + common.getMobileSession(2):ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppUnregistered", { + appID = common.getHMIAppId(2), + unexpectedDisconnect = false + }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Activate App 2", common.activateApp, { 2 }) + runner.Step("Unregister App 2", unregisterApp2) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end +runner.Step("Print failed TCs", common.printFailedTCs) diff --git a/test_scripts/MobileProjection/Phase2/smoke/019_SDL_stop_audio_video.lua b/test_scripts/MobileProjection/Phase2/smoke/019_SDL_stop_audio_video.lua new file mode 100644 index 0000000000..67b8c2ce32 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/019_SDL_stop_audio_video.lua @@ -0,0 +1,115 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There is a mobile app which is audio/video source +-- 2) And this app starts Audio/Video streaming +-- 3) And HMI sends 'BC.OnEventChanged' (AUDIO_SOURCE) +-- 4) And app still continue streaming +-- SDL must: +-- 1) Send to HMI: +-- Navigation.OnAudioDataStreaming(available = false) +-- Navigation.OnVideoDataStreaming(available = false) +-- Navigation.StopAudioStream +-- Navigation.StopStream +-- 2) Send End Audio/Video service control messages to app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') +local events = require("events") +local constants = require("protocol_handler/ford_protocol_constants") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.defaultProtocolVersion = 3 + +--[[ Local Variables ]] +local testCases = { + [001] = { t = "PROJECTION", m = true }, + [002] = { t = "NAVIGATION", m = true }, +} + +--[[ Local Functions ]] +local function appStartAudioStreaming() + common.getMobileSession():StartService(10) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartAudioStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(10,"files/MP3_1140kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = true }) + end) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function appStartVideoStreaming() + common.getMobileSession():StartService(11) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(11, "files/MP3_4555kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = true }) + end) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function appStopStreaming() + common.getMobileSession():StopStreaming("files/MP3_1140kb.mp3") + common.getMobileSession():StopStreaming("files/MP3_4555kb.mp3") + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function expectEndService(pServiceId) + local event = events.Event() + event.matches = function(_, data) + return data.frameType == constants.FRAME_TYPE.CONTROL_FRAME + and data.serviceType == pServiceId + and data.sessionId == common.getMobileSession().mobile_session_impl.control_services.session.sessionId.get() + and data.frameInfo == constants.FRAME_INFO.END_SERVICE + end + return common.getMobileSession():ExpectEvent(event, "EndService") +end + +local function changeAudioSource() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true }) + common.getMobileSession():ExpectNotification("OnHMIStatus", { + hmiLevel = "BACKGROUND", + systemContext = "MAIN", + audioStreamingState = "NOT_AUDIBLE", + videoStreamingState = "NOT_STREAMABLE" + }) + common.wait(2000) + common.getHMIConnection():SendNotification("Navigation.OnAudioDataStreaming", { available = false }) + common.getHMIConnection():SendNotification("Navigation.OnVideoDataStreaming", { available = false }) + common.getHMIConnection():SendNotification("Navigation.StopAudioStream", { appID = common.getHMIAppId() }) + common.getHMIConnection():SendNotification("Navigation.StopStream", { appID = common.getHMIAppId() }) + expectEndService(10) + expectEndService(11) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "[hmiType:" .. tc.t .. ", isMedia:" .. tostring(tc.m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App Config", common.setAppConfig, { 1, tc.t, tc.m }) + runner.Step("Register App", common.registerApp, { 1 }) + runner.Step("Activate App", common.activateApp, { 1 }) + runner.Step("App starts Audio streaming", appStartAudioStreaming) + runner.Step("App starts Video streaming", appStartVideoStreaming) + runner.Step("Change Audio Source", changeAudioSource) + runner.Step("Stop A/V streaming", appStopStreaming) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end diff --git a/test_scripts/MobileProjection/Phase2/smoke/020_different_types_apps_interactions.lua b/test_scripts/MobileProjection/Phase2/smoke/020_different_types_apps_interactions.lua new file mode 100644 index 0000000000..de6daf3164 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/020_different_types_apps_interactions.lua @@ -0,0 +1,265 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 4 mobile apps: +-- MEDIA (isMediaApplication = true) +-- PROJECTION (isMediaApplication = false) +-- DEFAULT (isMediaApplication = false) +-- NAVIGATION (isMediaApplication = true) +-- 2) And there is the following sequence of actions: +-- Activation of app1 +-- Activation of app2 +-- Activation of app3 +-- Activation of app4 +-- HMI sends PHONE_CALL event (active/inactive) +-- Activation of app2 +-- HMI sends EMBEDDED_NAVI event (active/inactive) +-- SDL must: +-- 1) Send (or not send) 'OnHMIStatus' notification to all apps with appropriate value for +-- 'hmiLevel', 'audioStreamingState' and 'videoStreamingState' parameters +-- Particular values depends on app's 'appHMIType', 'isMediaApplication' flag, current app's state +-- and described in 'testCases' table below +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.defaultProtocolVersion = 3 + +--[[ Local Variables ]] +local actions = { + activateApp = { + name = "Activation", + func = function(pAppId) + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { + appID = common.getHMIAppId(pAppId) }) + common.getHMIConnection():ExpectResponse(requestId) + end + }, + deactivateApp = { + name = "De-activation", + func = function(pAppId) + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(pAppId) }) + end + }, + phoneCallStart = { + name = "Phone call start", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "PHONE_CALL", + isActive = true }) + end + }, + phoneCallEnd = { + name = "Phone call end", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "PHONE_CALL", + isActive = false }) + end + }, + embeddedNaviActivate = { + name = "Embedded navigation activation", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "EMBEDDED_NAVI", + isActive = true }) + end + }, + embeddedNaviDeactivate = { + name = "Embedded navigation deactivation", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "EMBEDDED_NAVI", + isActive = false }) + end + }, + deactivateHMI = { + name = "HMI De-activation", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "DEACTIVATE_HMI", + isActive = true }) + end + }, + activateHMI = { + name = "HMI Activation", + func = function() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "DEACTIVATE_HMI", + isActive = false }) + end + }, + exitApp = { + name = "User Exit", + func = function(pAppId) + common.getHMIConnection():SendNotification("BasicCommunication.OnExitApplication", { + appID = common.getHMIAppId(), + reason = "USER_EXIT" }) + end + } +} + +local testCases = { + [001] = { -- testcase + apps = { + [1] = { t = "MEDIA", m = true }, + [2] = { t = "PROJECTION", m = false }, + [3] = { t = "DEFAULT", m = false }, + [4] = { t = "NAVIGATION", m = true } + }, + steps = { + [1] = { + action = { event = actions.activateApp, appId = 1 }, + checks = { + ohs = { + [1] = { hLvl = "FULL", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" }, + [2] = { }, -- hLvl = "NONE", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [3] = { }, -- hLvl = "NONE", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [4] = { } -- hLvl = "NONE", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + } + } + }, + [2] = { + action = { event = actions.activateApp, appId = 2 }, + checks = { + ohs = { + [1] = { hLvl = "LIMITED", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" }, + [2] = { hLvl = "FULL", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" }, + [3] = { }, -- hLvl = "NONE", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [4] = { } -- hLvl = "NONE", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + } + } + }, + [3] = { + action = { event = actions.activateApp, appId = 3 }, + checks = { + ohs = { + [1] = { }, -- hLvl = "LIMITED", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" + [2] = { hLvl = "LIMITED", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" }, + [3] = { hLvl = "FULL", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + [4] = { } -- hLvl = "NONE", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + } + } + }, + [4] = { + action = { event = actions.activateApp, appId = 4 }, + checks = { + ohs = { + [1] = { }, -- hLvl = "LIMITED", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" + [2] = { hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + [3] = { hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + [4] = { hLvl = "FULL", aSS = "AUDIBLE", vSS = "STREAMABLE" } + } + } + }, + [5] = { + action = { event = actions.phoneCallStart, appId = "none" }, + checks = { + ohs = { + [1] = { hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + [2] = { }, -- hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [3] = { }, -- hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [4] = { hLvl = "LIMITED", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" } + } + } + }, + [6] = { + action = { event = actions.phoneCallEnd, appId = "none" }, + checks = { + ohs = { + [1] = { hLvl = "LIMITED", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" }, + [2] = { }, -- hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [3] = { }, -- hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [4] = { hLvl = "FULL", aSS = "AUDIBLE", vSS = "STREAMABLE" } + } + } + }, + [7] = { + action = { event = actions.activateApp, appId = 2 }, + checks = { + ohs = { + [1] = { }, -- hLvl = "LIMITED", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" + [2] = { hLvl = "FULL", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" }, + [3] = { }, -- hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [4] = { hLvl = "LIMITED", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" } + } + } + }, + [8] = { + action = { event = actions.embeddedNaviActivate, appId = "none" }, + checks = { + ohs = { + [1] = { hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, -- + [2] = { hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" }, + [3] = { }, -- hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [4] = { hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" } + } + } + }, + [9] = { + action = { event = actions.embeddedNaviDeactivate, appId = "none" }, + checks = { + ohs = { + [1] = { hLvl = "LIMITED", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" }, -- + [2] = { hLvl = "FULL", aSS = "NOT_AUDIBLE", vSS = "STREAMABLE" }, + [3] = { }, -- hLvl = "BACKGROUND", aSS = "NOT_AUDIBLE", vSS = "NOT_STREAMABLE" + [4] = { hLvl = "LIMITED", aSS = "AUDIBLE", vSS = "NOT_STREAMABLE" } + } + } + } + } + }, +} + + +local function performChecks(pTestCaseNum, pStep, pAppId, pExpectVal) + local exp = common.getMobileSession(pAppId):ExpectNotification("OnHMIStatus") + if pExpectVal.hLvl then + exp:ValidIf(function(_, data) + return common.checkAudioSS(pTestCaseNum, pStep.action.event.name, pExpectVal.aSS, data.payload.audioStreamingState) + end) + exp:ValidIf(function(_, data) + return common.checkVideoSS(pTestCaseNum, pStep.action.event.name, pExpectVal.vSS, data.payload.videoStreamingState) + end) + exp:ValidIf(function(_, data) + return common.checkHMILevel(pTestCaseNum, pStep.action.event.name, pExpectVal.hLvl, data.payload.hmiLevel) + end) + else + exp:Times(0) + end +end + +local function doAction(pTestCaseNum, pStep) + pStep.action.event.func(pStep.action.appId) + for appId, ohsChecks in ipairs(pStep.checks.ohs) do + performChecks(pTestCaseNum, pStep, appId, ohsChecks) + end +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc.apps[1].t, tc.apps[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc.apps[2].t, tc.apps[2].m }) + runner.Step("Set App 3 Config", common.setAppConfig, { 3, tc.apps[3].t, tc.apps[3].m }) + runner.Step("Set App 4 Config", common.setAppConfig, { 4, tc.apps[4].t, tc.apps[4].m }) + + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Register App 3", common.registerApp, { 3 }) + runner.Step("Register App 4", common.registerApp, { 4 }) + + for i = 1, #tc.steps do + runner.Step("Action:" .. tc.steps[i].action.event.name .. " app " .. tc.steps[i].action.appId, doAction, { n, tc.steps[i] }) + end + + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end diff --git a/test_scripts/MobileProjection/Phase2/smoke/021_two_apps_and_deactivation.lua b/test_scripts/MobileProjection/Phase2/smoke/021_two_apps_and_deactivation.lua new file mode 100644 index 0000000000..71a8fe7f0e --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/021_two_apps_and_deactivation.lua @@ -0,0 +1,91 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps: +-- app1: PROJECTION, isMediaApplication = true +-- app2: MEDIA, isMediaApplication = true +-- 2) And app1 activated and then deactivated +-- 3) And app2 activated and then deactivated +-- SDL must: (in case of deactivation of app1) +-- 1) Send 'OnHMIStatus' notification to app1: 'audioStreamingState' = AUDIBLE and 'videoStreamingState' = STREAMABLE +-- 2) Not send 'OnHMIStatus' notification to app2 +-- SDL must: (in case of deactivation of app2) +-- 1) Not send 'OnHMIStatus' notification to app1 +-- 2) Send 'OnHMIStatus' notification to app2: 'audioStreamingState' = AUDIBLE and 'videoStreamingState' = NOT_STREAMABLE +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [001] = { [1] = { t = "PROJECTION", m = true }, [2] = { t = "MEDIA", m = true }}, +} + +--[[ Local Functions ]] +local function deactivateApp1() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(1) }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "AUDIBLE", + videoStreamingState = "STREAMABLE" + }) + :Times(1) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function deactivateApp2() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(2) }) + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "AUDIBLE", + videoStreamingState = "NOT_STREAMABLE" + }) + :Times(1) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function onHMIStatus2Apps() + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { + hmiLevel = "FULL", + systemContext = "MAIN", + audioStreamingState = "AUDIBLE", + videoStreamingState = "NOT_STREAMABLE" + }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "NOT_AUDIBLE", + videoStreamingState = "STREAMABLE" + }) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("Deactivate App 1", deactivateApp1) + runner.Step("Activate App 2", common.activateAppCustomOnHMIStatusExpectation, { 2, onHMIStatus2Apps }) + runner.Step("Deactivate App 2", deactivateApp2) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end diff --git a/test_scripts/MobileProjection/Phase2/smoke/022_two_apps_proj_media_and_deactivation_streaming.lua b/test_scripts/MobileProjection/Phase2/smoke/022_two_apps_proj_media_and_deactivation_streaming.lua new file mode 100644 index 0000000000..8f67e004ef --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/022_two_apps_proj_media_and_deactivation_streaming.lua @@ -0,0 +1,108 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps: +-- app1: PROJECTION, isMediaApplication = true +-- app2: MEDIA, isMediaApplication = true +-- 2) And app1 activated, starts Video streaming and then deactivated +-- 3) And app2 activated and then deactivated +-- SDL must: (in case of deactivation of app1) +-- 1) Send 'OnHMIStatus' notification to app1: 'audioStreamingState' = AUDIBLE and 'videoStreamingState' = STREAMABLE +-- 2) Not send 'OnHMIStatus' notification to app2 +-- SDL must: (in case of deactivation of app2) +-- 1) Not send 'OnHMIStatus' notification to app1 +-- 2) Send 'OnHMIStatus' notification to app2: 'audioStreamingState' = AUDIBLE and 'videoStreamingState' = NOT_STREAMABLE +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [001] = { [1] = { t = "PROJECTION", m = true }, [2] = { t = "MEDIA", m = true }}, +} + +--[[ Local Functions ]] +local function deactivateApp1() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(1) }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "AUDIBLE", + videoStreamingState = "STREAMABLE" + }) + :Times(1) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function deactivateApp2() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(2) }) + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "AUDIBLE", + videoStreamingState = "NOT_STREAMABLE" + }) + :Times(1) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function appStartVideoStreaming() + common.getMobileSession():StartService(11) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(11, "files/MP3_4555kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = true }) + end) + end) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function onHMIStatus2Apps() + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { + hmiLevel = "FULL", + systemContext = "MAIN", + audioStreamingState = "AUDIBLE", + videoStreamingState = "NOT_STREAMABLE" + }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "NOT_AUDIBLE", + videoStreamingState = "STREAMABLE" + }) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("App 1 starts Video streaming", appStartVideoStreaming) + runner.Step("Deactivate App 1", deactivateApp1) + runner.Step("Activate App 2", common.activateAppCustomOnHMIStatusExpectation, { 2, onHMIStatus2Apps }) + runner.Step("Deactivate App 2", deactivateApp2) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end diff --git a/test_scripts/MobileProjection/Phase2/smoke/023_two_apps_navi_comm_and_deactivation_streaming.lua b/test_scripts/MobileProjection/Phase2/smoke/023_two_apps_navi_comm_and_deactivation_streaming.lua new file mode 100644 index 0000000000..4f70ce5872 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/smoke/023_two_apps_navi_comm_and_deactivation_streaming.lua @@ -0,0 +1,104 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2129 +--------------------------------------------------------------------------------------------------- +-- Description: +-- In case: +-- 1) There are 2 mobile apps: +-- app1: NAVIGATION, isMediaApplication = true +-- app2: COMMUNICATION, isMediaApplication = false +-- 2) And app1 activated, starts Video streaming and then deactivated +-- 3) And app2 activated and then deactivated +-- SDL must: (in case of deactivation of app1) +-- 1) Send 'OnHMIStatus' notification to app1: 'audioStreamingState' = AUDIBLE and 'videoStreamingState' = STREAMABLE +-- 2) Not send 'OnHMIStatus' notification to app2 +-- SDL must: (in case of deactivation of app2) +-- 1) Not send 'OnHMIStatus' notification to app1 +-- 2) Send 'OnHMIStatus' notification to app2: 'audioStreamingState' = ATTENUATED and 'videoStreamingState' = NOT_STREAMABLE +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local testCases = { + [001] = { [1] = { t = "NAVIGATION", m = true }, [2] = { t = "COMMUNICATION", m = false }}, +} + +--[[ Local Functions ]] +local function deactivateApp1() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(1) }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "AUDIBLE", + videoStreamingState = "STREAMABLE" + }) + :Times(1) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function deactivateApp2() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(2) }) + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { + hmiLevel = "LIMITED", + systemContext = "MAIN", + audioStreamingState = "ATTENUATED", + videoStreamingState = "NOT_STREAMABLE" + }) + :Times(1) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function appStartVideoStreaming() + common.getMobileSession():StartService(11) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(11, "files/MP3_4555kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = true }) + end) + end) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function onHMIStatus2Apps() + common.getMobileSession(2):ExpectNotification("OnHMIStatus", { + hmiLevel = "FULL", + systemContext = "MAIN", + audioStreamingState = "ATTENUATED", + videoStreamingState = "NOT_STREAMABLE" + }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus") + :Times(0) +end + +--[[ Scenario ]] +for n, tc in common.spairs(testCases) do + runner.Title("TC[" .. string.format("%03d", n) .. "]: " + .. "App1[hmiType:" .. tc[1].t .. ", isMedia:" .. tostring(tc[1].m) .. "], " + .. "App2[hmiType:" .. tc[2].t .. ", isMedia:" .. tostring(tc[2].m) .. "]") + runner.Step("Clean environment", common.preconditions) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("Set App 1 Config", common.setAppConfig, { 1, tc[1].t, tc[1].m }) + runner.Step("Set App 2 Config", common.setAppConfig, { 2, tc[2].t, tc[2].m }) + runner.Step("Register App 1", common.registerApp, { 1 }) + runner.Step("Register App 2", common.registerApp, { 2 }) + runner.Step("Activate App 1", common.activateApp, { 1 }) + runner.Step("App 1 starts Video streaming", appStartVideoStreaming) + runner.Step("Deactivate App 1", deactivateApp1) + runner.Step("Activate App 2", common.activateAppCustomOnHMIStatusExpectation, { 2, onHMIStatus2Apps }) + runner.Step("Deactivate App 2", deactivateApp2) + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end diff --git a/test_sets/mobile_projection_2_smoke.txt b/test_sets/mobile_projection_2_smoke.txt new file mode 100644 index 0000000000..9afa00eb91 --- /dev/null +++ b/test_sets/mobile_projection_2_smoke.txt @@ -0,0 +1,22 @@ +./test_scripts/MobileProjection/Phase2/smoke/001_audioStreamingState_001-009.lua +./test_scripts/MobileProjection/Phase2/smoke/002_audioStreamingState_010-068.lua +./test_scripts/MobileProjection/Phase2/smoke/003_audioStreamingState_069-103.lua +./test_scripts/MobileProjection/Phase2/smoke/004_audioStreamingState_104-110.lua +./test_scripts/MobileProjection/Phase2/smoke/005_audioStreamingState_111-118.lua +./test_scripts/MobileProjection/Phase2/smoke/006_videoStreamingState_001-006.lua +./test_scripts/MobileProjection/Phase2/smoke/007_videoStreamingState_007-030.lua +./test_scripts/MobileProjection/Phase2/smoke/008_videoStreamingState_031-042.lua +./test_scripts/MobileProjection/Phase2/smoke/009_hmiLevel_001-032.lua +./test_scripts/MobileProjection/Phase2/smoke/010_single_app_audio_and_video_streaming.lua +./test_scripts/MobileProjection/Phase2/smoke/012_single_app_deactivation.lua +./test_scripts/MobileProjection/Phase2/smoke/013_two_apps_interaction.lua +./test_scripts/MobileProjection/Phase2/smoke/014_audio_010-068_video_007-030_states_LIMITED.lua +./test_scripts/MobileProjection/Phase2/smoke/015_audio_083-089_097-103_video_031-038_states_not_FULL.lua +./test_scripts/MobileProjection/Phase2/smoke/016_BACKGROUND_not_changed.lua +./test_scripts/MobileProjection/Phase2/smoke/017_two_apps_and_one_app_exits.lua +./test_scripts/MobileProjection/Phase2/smoke/018_two_apps_and_one_app_unregister.lua +./test_scripts/MobileProjection/Phase2/smoke/019_SDL_stop_audio_video.lua +./test_scripts/MobileProjection/Phase2/smoke/020_different_types_apps_interactions.lua +./test_scripts/MobileProjection/Phase2/smoke/021_two_apps_and_deactivation.lua +./test_scripts/MobileProjection/Phase2/smoke/022_two_apps_proj_media_and_deactivation_streaming.lua +./test_scripts/MobileProjection/Phase2/smoke/023_two_apps_navi_comm_and_deactivation_streaming.lua From 3758adba35b32b137bd058bb04e59f39dc5623d7 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 14 Jun 2018 11:42:31 +0300 Subject: [PATCH 424/681] Get rid off startServiceSecuredWitTimeoutWithoutGetSTResp() function --- ...etSystemTime_without_response_from_HMI.lua | 14 ++++++-- ...emTime_with_response_from_HMI_in_9_sec.lua | 21 ++++++++++-- .../Security/GetSystemTime/common.lua | 33 ++----------------- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/test_scripts/Security/GetSystemTime/023_GetSystemTime_without_response_from_HMI.lua b/test_scripts/Security/GetSystemTime/023_GetSystemTime_without_response_from_HMI.lua index ed395e93bd..2e92029c1f 100644 --- a/test_scripts/Security/GetSystemTime/023_GetSystemTime_without_response_from_HMI.lua +++ b/test_scripts/Security/GetSystemTime/023_GetSystemTime_without_response_from_HMI.lua @@ -35,6 +35,17 @@ local function ptUpdate(pTbl) pTbl.policy_table.module_config.certificate = crt end +local function startServiceSecuredWithoutGSTResponse() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, pData) + :Timeout(11500) + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate") + :Times(0) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + EXPECT_HMICALL("BasicCommunication.GetSystemTime") +end + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) @@ -45,8 +56,7 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdate }) -runner.Step("Handshake without BC.GetSystemTime response from HMI", common.startServiceSecuredWitTimeoutWithoutGetSTResp, - { pData, serviceId }) +runner.Step("Handshake without BC.GetSystemTime response from HMI", startServiceSecuredWithoutGSTResponse) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/024_GetSystemTime_with_response_from_HMI_in_9_sec.lua b/test_scripts/Security/GetSystemTime/024_GetSystemTime_with_response_from_HMI_in_9_sec.lua index 01eb43ff09..7588d2bb48 100644 --- a/test_scripts/Security/GetSystemTime/024_GetSystemTime_with_response_from_HMI_in_9_sec.lua +++ b/test_scripts/Security/GetSystemTime/024_GetSystemTime_with_response_from_HMI_in_9_sec.lua @@ -35,6 +35,24 @@ local function ptUpdate(pTbl) pTbl.policy_table.module_config.certificate = crt end +local function startServiceSecuredWithDelayedGSTResponse() + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, pData) + :Timeout(11500) + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate") + :Times(0) + common.getMobileSession():ExpectHandshakeMessage() + :Times(1) + EXPECT_HMICALL("BasicCommunication.GetSystemTime") + :Do(function(_,data) + local function GetSystemTimeResponse() + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + systemTime = common.getSystemTimeValue() }) + end + RUN_AFTER(GetSystemTimeResponse, 8000) + end) +end + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) @@ -45,8 +63,7 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdate }) -runner.Step("Handshake with response BC.GetSystemTime in 9 sec from HMI", common.startServiceSecuredWitTimeoutWithoutGetSTResp, - { pData, serviceId, 8000 }) +runner.Step("Handshake with response BC.GetSystemTime in 9 sec from HMI", startServiceSecuredWithDelayedGSTResponse) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/common.lua b/test_scripts/Security/GetSystemTime/common.lua index 0d7af20c0a..9f61c76fa6 100644 --- a/test_scripts/Security/GetSystemTime/common.lua +++ b/test_scripts/Security/GetSystemTime/common.lua @@ -1,4 +1,4 @@ ---------------------------------------------------------------------------------------------------- +-------------------------------------------------------------------------------------------------- -- Common module --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] @@ -30,7 +30,7 @@ m.delayedExp = utils.wait m.readFile = utils.readFile --[[ Functions ]] -local function getSystemTimeValue() +function m.getSystemTimeValue() local dd = os.date("*t") return { millisecond = 0, @@ -89,7 +89,7 @@ end function m.expectHandshakeMessage(pGetSystemTimeOccur, pTime, pHandshakeOccurences) if not pTime then - pTime = getSystemTimeValue() + pTime = m.getSystemTimeValue() end if not pHandshakeOccurences then pHandshakeOccurences = 1 end if pGetSystemTimeOccur == 0 then @@ -134,31 +134,4 @@ function m.startServiceSecuredwithPTU(pData, pServiceId, pGetSystemTimeOccur, pT m.expectHandshakeMessage(pGetSystemTimeOccur, pTime, pHandshakeOccurences) end -function m.startServiceSecuredWitTimeoutWithoutGetSTResp(pData, pServiceId, pTimeout) - m.getMobileSession():StartSecureService(pServiceId) - m.getMobileSession():ExpectControlMessage(pServiceId, pData) - :Timeout(11500) - - m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate") - :Times(0) - - local handshakeOccurences = 0 - if pTimeout then - handshakeOccurences = 1 - end - m.getMobileSession():ExpectHandshakeMessage() - :Times(handshakeOccurences) - - EXPECT_HMICALL("BasicCommunication.GetSystemTime") - :Do(function(_,data) - if pTimeout then - local function GetSystemTimeResponse() - m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { systemTime = getSystemTimeValue() }) - end - RUN_AFTER(GetSystemTimeResponse, pTimeout) - end - end) - -end - return m From 6f18f5479f35cc104078126b5946e554099b50e9 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 14 Jun 2018 11:44:19 +0300 Subject: [PATCH 425/681] Get rid off duplicated function --- ...3_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua b/test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua index f02bea84f0..8a944ee10d 100644 --- a/test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua +++ b/test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua @@ -47,12 +47,6 @@ local function ptUpdateWithNotActualCer(pTbl) pTbl.policy_table.module_config.certificate = crt end -local function ptUpdateWithExpiredCer(pTbl) - local filePath = "./files/Security/GetSystemTime_certificates/client_credential_0312_17.pem" - local crt = common.readFile(filePath) - pTbl.policy_table.module_config.certificate = crt -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) @@ -64,7 +58,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdateWithExpiredCer, 0 }) + { pData, serviceId, 1, systemTime, ptUpdateWithNotActualCer, 0 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) From ba19427f6f547eaba6cbfecc26cd8fe8e00a612b Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 14 Jun 2018 11:47:09 +0300 Subject: [PATCH 426/681] Rename function --- ...ime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua index 8242787023..2a9541c45e 100644 --- a/test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua @@ -46,7 +46,7 @@ local systemTime = { } --[[ Local Functions ]] -local function ptUpdateWithNotActualCer(pTbl) +local function ptUpdateWithNotYetValidCer(pTbl) local filePath = "./files/Security/GetSystemTime_certificates/client_credential.pem" local crt = common.readFile(filePath) pTbl.policy_table.module_config.certificate = crt @@ -61,7 +61,7 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) +runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdateWithNotYetValidCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, { pData, serviceId, 1, systemTime }) From 649be65c42d84594c9b21d5166198fd9cc6ee678 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 14 Jun 2018 13:07:54 +0300 Subject: [PATCH 427/681] Change generated GetSystemTime value to hardcoded one --- .../Security/GetSystemTime/common.lua | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/test_scripts/Security/GetSystemTime/common.lua b/test_scripts/Security/GetSystemTime/common.lua index 9f61c76fa6..8f1376098c 100644 --- a/test_scripts/Security/GetSystemTime/common.lua +++ b/test_scripts/Security/GetSystemTime/common.lua @@ -31,17 +31,16 @@ m.readFile = utils.readFile --[[ Functions ]] function m.getSystemTimeValue() - local dd = os.date("*t") return { - millisecond = 0, - second = dd.sec, - minute = dd.min, - hour = dd.hour, - day = dd.day, - month = dd.month, - year = dd.year, - tz_hour = 2, - tz_minute = 0 + millisecond = 100, + second = 30, + minute = 29, + hour = 15, + day = 20, + month = 3, + year = 2018, + tz_hour = -3, + tz_minute = 10 } end From 8764567ca4574886c20f4c61b72d6b3412e19f55 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 14 Jun 2018 16:47:27 +0300 Subject: [PATCH 428/681] Get rid of default parameters --- .../001_GetSystemTime_is_sent.lua | 3 ++- .../002_GetSystemTime_is_not_sent.lua | 3 ++- ...ile_is_not_valid_sdl_cer_becomes_valid.lua | 2 +- ...SystemTime_mobile_sdl_cer_become_valid.lua | 2 +- ..._mobile_sdl_cer_become_valid_after_PTU.lua | 2 +- ...mTime_mobile_cer_expired_sdl_cer_valid.lua | 2 +- ...mobile_cer_not_valid_yet_sdl_cer_valid.lua | 2 +- ...mobile_cer_becomes_valid_sdl_cer_valid.lua | 2 +- ...mobile_cer_valid_sdl_cer_becomes_valid.lua | 2 +- ...ecomes_not_valid_sdl_cer_becomes_valid.lua | 2 +- ...t_valid_sdl_cer_becomes_valid_with_PTU.lua | 2 +- ...ystemTime_mobile_cer_and_sdl_cer_valid.lua | 2 +- ...er_becomes_not_valid_and_sdl_cer_valid.lua | 2 +- ...ecomes_yet_not_valid_and_sdl_cer_valid.lua | 2 +- .../025_GetSystemTime_is_sent_later.lua | 12 ++++++++-- .../Security/GetSystemTime/common.lua | 22 +++++-------------- 16 files changed, 32 insertions(+), 32 deletions(-) diff --git a/test_scripts/Security/GetSystemTime/001_GetSystemTime_is_sent.lua b/test_scripts/Security/GetSystemTime/001_GetSystemTime_is_sent.lua index ac4c3cc52d..d387020ede 100644 --- a/test_scripts/Security/GetSystemTime/001_GetSystemTime_is_sent.lua +++ b/test_scripts/Security/GetSystemTime/001_GetSystemTime_is_sent.lua @@ -45,7 +45,8 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with certificate", common.policyTableUpdate, { ptUpdate }) -runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, { pData, serviceId, 1 }) +runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, + { pData, serviceId, 1, common.getSystemTimeValue(), 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/002_GetSystemTime_is_not_sent.lua b/test_scripts/Security/GetSystemTime/002_GetSystemTime_is_not_sent.lua index 6ddf4f9729..b7d991ad2f 100644 --- a/test_scripts/Security/GetSystemTime/002_GetSystemTime_is_not_sent.lua +++ b/test_scripts/Security/GetSystemTime/002_GetSystemTime_is_not_sent.lua @@ -44,7 +44,8 @@ runner.Title("Test") runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with certificate", common.policyTableUpdate, { ptUpdate }) -runner.Step("Handshake without BC.GetSystemTime request from SDL", common.startServiceSecured, { pData, serviceId, 0 }) +runner.Step("Handshake without BC.GetSystemTime request from SDL", common.startServiceSecured, + { pData, serviceId, 0, common.getSystemTimeValue(), 0 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua b/test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua index 0d48462e4d..acc084468a 100644 --- a/test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua +++ b/test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua @@ -63,7 +63,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime, 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_sdl_cer_become_valid.lua b/test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_sdl_cer_become_valid.lua index 5aa7380ebb..f7ed89d154 100644 --- a/test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_sdl_cer_become_valid.lua +++ b/test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_sdl_cer_become_valid.lua @@ -63,7 +63,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime, 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua b/test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua index b7b65fe953..df7cc786a2 100644 --- a/test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua +++ b/test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua @@ -69,7 +69,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotValidCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdateWithValidCer }) + { pData, serviceId, 1, systemTime, ptUpdateWithValidCer, 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua index b9cbc63a1b..eaeab98418 100644 --- a/test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua @@ -63,7 +63,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime, 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua index 5fd5518558..5fda70f5e7 100644 --- a/test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua @@ -63,7 +63,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime, 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua index afba0dc844..04cb3b0ec0 100644 --- a/test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua @@ -63,7 +63,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime, 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua b/test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua index c2a8fb9d46..478bf90118 100644 --- a/test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua +++ b/test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua @@ -58,7 +58,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime, 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua b/test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua index 31cf4b5e36..9e3bdae2dd 100644 --- a/test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua +++ b/test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua @@ -63,7 +63,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime, 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua b/test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua index 9df7e14b65..7945561ecf 100644 --- a/test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua +++ b/test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua @@ -69,7 +69,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with not valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecuredwithPTU, - { pData, serviceId, 1, systemTime, ptUpdateWithActualCer }) + { pData, serviceId, 1, systemTime, ptUpdateWithActualCer, 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua index b844f447a2..896f9fa7a3 100644 --- a/test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua @@ -58,7 +58,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime, 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua index e53415fd2c..09e64ebf85 100644 --- a/test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua @@ -63,7 +63,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdateWithNotActualCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime, 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua b/test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua index 2a9541c45e..aebefd0aae 100644 --- a/test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua +++ b/test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua @@ -63,7 +63,7 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with valid certificate", common.policyTableUpdate, { ptUpdateWithNotYetValidCer }) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, - { pData, serviceId, 1, systemTime }) + { pData, serviceId, 1, systemTime, 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/025_GetSystemTime_is_sent_later.lua b/test_scripts/Security/GetSystemTime/025_GetSystemTime_is_sent_later.lua index e0c952deb0..6ea0da5d50 100644 --- a/test_scripts/Security/GetSystemTime/025_GetSystemTime_is_sent_later.lua +++ b/test_scripts/Security/GetSystemTime/025_GetSystemTime_is_sent_later.lua @@ -48,10 +48,18 @@ runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) runner.Step("PolicyTableUpdate with certificate", common.policyTableUpdate, { ptUpdate }) runner.Step("Handshake without BC.GetSystemTime request from SDL", common.startServiceSecured, { - { frameInfo = common.frameInfo.START_SERVICE_NACK, encryption = false }, serviceId, 0 }) + { frameInfo = common.frameInfo.START_SERVICE_NACK, encryption = false }, + serviceId, + 0, + common.getSystemTimeValue(), + 0 }) runner.Step("Send BC.OnSystemTimeReady from HMI", sendOnSystemTimeReady) runner.Step("Handshake with BC.GetSystemTime request from SDL", common.startServiceSecured, { - { frameInfo = common.frameInfo.START_SERVICE_ACK, encryption = true }, serviceId, 1 }) + { frameInfo = common.frameInfo.START_SERVICE_ACK, encryption = true }, + serviceId, + 1, + common.getSystemTimeValue(), + 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Security/GetSystemTime/common.lua b/test_scripts/Security/GetSystemTime/common.lua index 8f1376098c..4442de67e2 100644 --- a/test_scripts/Security/GetSystemTime/common.lua +++ b/test_scripts/Security/GetSystemTime/common.lua @@ -44,10 +44,6 @@ function m.getSystemTimeValue() } end -function m.setForceProtectedServiceParam(pParamValue) - m.setSDLIniParameter("ForceProtectedService", pParamValue) -end - function m.getAppID(pAppId) return m.getConfigAppParams(pAppId).appID end @@ -86,16 +82,10 @@ function m.start(pOnSystemTime, pHMIParams) end) end -function m.expectHandshakeMessage(pGetSystemTimeOccur, pTime, pHandshakeOccurences) - if not pTime then - pTime = m.getSystemTimeValue() - end - if not pHandshakeOccurences then pHandshakeOccurences = 1 end - if pGetSystemTimeOccur == 0 then - pHandshakeOccurences = pGetSystemTimeOccur - end +local function expectHandshakeMessage(pGetSystemTimeOccur, pTime, pHandshakeOccurences) m.getMobileSession():ExpectHandshakeMessage() - :Times(pHandshakeOccurences) + :Times(pHandshakeOccurences) + EXPECT_HMICALL("BasicCommunication.GetSystemTime") :Do(function(_, d) m.getHMIConnection():SendResponse(d.id, d.method, "SUCCESS", { systemTime = pTime }) @@ -103,14 +93,14 @@ function m.expectHandshakeMessage(pGetSystemTimeOccur, pTime, pHandshakeOccurenc :Times(pGetSystemTimeOccur) end -function m.startServiceSecured(pData, pServiceId, pGetSystemTimeOccur, pTime) +function m.startServiceSecured(pData, pServiceId, pGetSystemTimeOccur, pTime, pHandshakeOccurences) m.getMobileSession():StartSecureService(pServiceId) m.getMobileSession():ExpectControlMessage(pServiceId, pData) m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate") :Times(0) - m.expectHandshakeMessage(pGetSystemTimeOccur, pTime) + expectHandshakeMessage(pGetSystemTimeOccur, pTime, pHandshakeOccurences) end local function expNotDuringPTU() @@ -130,7 +120,7 @@ function m.startServiceSecuredwithPTU(pData, pServiceId, pGetSystemTimeOccur, pT end end) - m.expectHandshakeMessage(pGetSystemTimeOccur, pTime, pHandshakeOccurences) + expectHandshakeMessage(pGetSystemTimeOccur, pTime, pHandshakeOccurences) end return m From a8c559dea17e631c04645f03ea4cbf2f79713501 Mon Sep 17 00:00:00 2001 From: HSavynetska Date: Fri, 15 Jun 2018 13:07:06 +0300 Subject: [PATCH 429/681] Script for reproducing issue 1032 --- ...uplicate_vrCommands_menuName_inside_it.lua | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 test_scripts/Defects/4_6/1032_CreateInteractionChoiceSet_core_successfully_creates_choice_set_with_duplicate_vrCommands_menuName_inside_it.lua diff --git a/test_scripts/Defects/4_6/1032_CreateInteractionChoiceSet_core_successfully_creates_choice_set_with_duplicate_vrCommands_menuName_inside_it.lua b/test_scripts/Defects/4_6/1032_CreateInteractionChoiceSet_core_successfully_creates_choice_set_with_duplicate_vrCommands_menuName_inside_it.lua new file mode 100644 index 0000000000..768d05e9de --- /dev/null +++ b/test_scripts/Defects/4_6/1032_CreateInteractionChoiceSet_core_successfully_creates_choice_set_with_duplicate_vrCommands_menuName_inside_it.lua @@ -0,0 +1,51 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/1032 +-- +-- Precondition: +-- 1) Core, HMI started. +-- 2) Application is registered, HMI level = FULL. +-- Description: +-- Steps to reproduce: +-- 1) Send CreateInteractionChoiceSet with duplicate vrCommands, other parameters are valid. +-- Expected: +-- 1) Choice set isn't created and SDL response resultCode = DUPLICATE_NAME, success=false to mobile. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/commonDefects') + +--[[ Local Functions ]] +local function createInteractionChoiceSetDuplicateName(self) + local params = { + interactionChoiceSetID = 100, + choiceSet = { + { + choiceID = 111, + menuName = "Choice111", + vrCommands = { "Choice111" } + }, + { + choiceID = 112, + menuName = "Choice112", + vrCommands = { "Choice111" } + } + } + } + local cid = self.mobileSession1:SendRPC("CreateInteractionChoiceSet", params) + EXPECT_HMICALL("VR.AddCommand") + :Times(0) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DUPLICATE_NAME" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.rai_n) +runner.Step("Activate App", common.activate_app) + +runner.Title("Test") +runner.Step("CreateInteractionChoiceSet with vrCommands duplicate", createInteractionChoiceSetDuplicateName) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From 3c27fb748fec013adce3f0372407708d40f7b253 Mon Sep 17 00:00:00 2001 From: HSavynetska Date: Fri, 15 Jun 2018 15:29:39 +0300 Subject: [PATCH 430/681] Script for reproducing issue 1218 --- ...ovided_in_response_for_PutFile_request.lua | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 test_scripts/Defects/4_6/1218_Mandatory_parameter_spaceAvailable_is_not_provided_in_response_for_PutFile_request.lua diff --git a/test_scripts/Defects/4_6/1218_Mandatory_parameter_spaceAvailable_is_not_provided_in_response_for_PutFile_request.lua b/test_scripts/Defects/4_6/1218_Mandatory_parameter_spaceAvailable_is_not_provided_in_response_for_PutFile_request.lua new file mode 100644 index 0000000000..afbf57d188 --- /dev/null +++ b/test_scripts/Defects/4_6/1218_Mandatory_parameter_spaceAvailable_is_not_provided_in_response_for_PutFile_request.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/SmartDeviceLink/sdl_core/issues/1218 +-- +-- Precondition: +-- 1) SDL is built with EXTERNAL_PROPRIETARY flag. +-- 2) SDL and HMI are started. First ignition cycle. +-- 3) Connect device +-- 4) Register new application + +-- Description: +-- Steps to reproduce: +-- 1) App sends valid "PutFile" request +-- Expected: +-- 1) Successful process PutFile{ success = true, resultCode = "SUCCESS", spaceAvailable=xxx}. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/commonDefects') + +--[[ Local Functions ]] +local function putFileSUCCESS(self) + local paramsSend = { + syncFileName = "icon.png", + fileType = "GRAPHIC_PNG" + } + local cid = self.mobileSession1:SendRPC( "PutFile", paramsSend, "files/icon.png") + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + :ValidIf(function(_, data) + if data.payload.spaceAvailable ~= nil then + return true + else + return false, "PutFile response does not contain spaceAvailable parameter." + end + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.rai_ptu_n) +runner.Step("Activate App", common.activate_app) + +runner.Title("Test") +runner.Step("Successful processing PutFile", putFileSUCCESS) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From ef46a311125f089ccb7ea33617d3ed99e4e11c38 Mon Sep 17 00:00:00 2001 From: HSavynetska Date: Fri, 15 Jun 2018 15:34:26 +0300 Subject: [PATCH 431/681] Script for reproducing issue 972 --- ..._in_case_vi_interface_is_not_available.lua | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 test_scripts/Defects/4_6/972_SDL_should_respond_IGNORED_with_correct_result_code_for_UnSubscribeVehicleData_in_case_vi_interface_is_not_available.lua diff --git a/test_scripts/Defects/4_6/972_SDL_should_respond_IGNORED_with_correct_result_code_for_UnSubscribeVehicleData_in_case_vi_interface_is_not_available.lua b/test_scripts/Defects/4_6/972_SDL_should_respond_IGNORED_with_correct_result_code_for_UnSubscribeVehicleData_in_case_vi_interface_is_not_available.lua new file mode 100644 index 0000000000..2b67483aae --- /dev/null +++ b/test_scripts/Defects/4_6/972_SDL_should_respond_IGNORED_with_correct_result_code_for_UnSubscribeVehicleData_in_case_vi_interface_is_not_available.lua @@ -0,0 +1,84 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/972 +-- +-- Precondition: +-- 1) Move IsReady_Template folder into sdl_atf\user_modules +-- 2) SubscribeVehicleData and UnSubscribeVehicleData are allowed in PT +-- Description: +-- Steps to reproduce: +-- 1) RegisterApp incase HMI does not respond. +-- 2) Activate app. +-- 3) Send SubscribeVehicleData with gps = true +-- 4) Send UnSubscribeVehicleData with gps = true +-- Expected: +-- 1) SDL send UNSUPPORTED_RESOURCE to mobile app +-- 2) SDL respond "{success = false, resultCode = "IGNORED", info = "Some provided VehicleData was not subscribed."}" code to mobile app. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/commonDefects') +local hmi_values = require('user_modules/hmi_values') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") + +--[[ Local Functions ]] +local function getHMIValues() + local params = hmi_values.getDefaultHMITable() + params.VehicleInfo.IsReady.params.available = false + params.VehicleInfo.GetVehicleType = nil + params.VehicleInfo.GetVehicleData = nil + return params +end + +local function start(getHMIParams, self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady(getHMIParams) + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + self:connectMobile() + :Do(function() + commonFunctions:userPrint(35, "Mobile connected") + common.allow_sdl(self) + end) + end) + end) + end) +end + +local function pTUpdateFunc(tbl) + table.insert(tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].groups, "Location-1") +end + +local function setSubscribeVehicleDataUnsupportedResource(self) + local params = { gps = true } + local cid = self.mobileSession1:SendRPC("SubscribeVehicleData", params) + EXPECT_HMICALL("VehicleInfo.SubscribeVehicleData") + :Times(0) + self.mobileSession1:ExpectResponse(cid, {success = false, resultCode = "UNSUPPORTED_RESOURCE"}) +end + +local function setUnsubscribeVehicleDataIgnored(self) + local pParams = { gps = true } + local cid = self.mobileSession1:SendRPC("UnsubscribeVehicleData", pParams) + EXPECT_HMICALL("VehicleInfo.UnsubscribeVehicleData") + :Times(0) + self.mobileSession1:ExpectResponse(cid, {success = false, resultCode = "IGNORED", info = "Some provided VehicleData was not subscribed."}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", start, { getHMIValues() }) +runner.Step("App registration, PTU", common.rai_ptu, {pTUpdateFunc}) +runner.Step("Activate App", common.activate_app) + +runner.Title("Test") +runner.Step("SubscribeVehicleData with resultCode = UNSUPPORTED_RESOURCE", setSubscribeVehicleDataUnsupportedResource) +runner.Step("UnSubscribeVehicleData with resultCode = IGNORED", setUnsubscribeVehicleDataIgnored) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From f4afd89f55515ba1cba372cc0ccaf0dba424ace7 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 28 Mar 2018 11:32:33 +0300 Subject: [PATCH 432/681] Initial version of the scripts for DTLS encryption --- .../Security/DTLS/001_StartRPC_service.lua | 32 +++ .../Security/DTLS/002_Start_Audio_service.lua | 32 +++ .../Security/DTLS/003_Start_Video_service.lua | 32 +++ .../Security/DTLS/004_Processing_of_RPC.lua | 49 ++++ .../DTLS/005_Ignore_malformed_packet.lua | 50 ++++ .../DTLS/006_Ignore_unexpected_packet.lua | 50 ++++ .../DTLS/007_Processing_multiple_frames.lua | 37 +++ test_scripts/Security/DTLS/common.lua | 224 ++++++++++++++++++ test_sets/dtls_encryption.txt | 7 + 9 files changed, 513 insertions(+) create mode 100644 test_scripts/Security/DTLS/001_StartRPC_service.lua create mode 100644 test_scripts/Security/DTLS/002_Start_Audio_service.lua create mode 100644 test_scripts/Security/DTLS/003_Start_Video_service.lua create mode 100644 test_scripts/Security/DTLS/004_Processing_of_RPC.lua create mode 100644 test_scripts/Security/DTLS/005_Ignore_malformed_packet.lua create mode 100644 test_scripts/Security/DTLS/006_Ignore_unexpected_packet.lua create mode 100644 test_scripts/Security/DTLS/007_Processing_multiple_frames.lua create mode 100644 test_scripts/Security/DTLS/common.lua create mode 100644 test_sets/dtls_encryption.txt diff --git a/test_scripts/Security/DTLS/001_StartRPC_service.lua b/test_scripts/Security/DTLS/001_StartRPC_service.lua new file mode 100644 index 0000000000..6dfb198cd6 --- /dev/null +++ b/test_scripts/Security/DTLS/001_StartRPC_service.lua @@ -0,0 +1,32 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1) SDL is configured with parameter ‘Protocol = DTLSv1.0’ +-- 2) SDL has up-to-date certificates in Policy Table +-- 3) And app is configured to use DTLS protocol for communication with SDL +-- 4) And this app is registered and RPC service is started in unprotected mode +-- 5) And this app is try to switch RPC service to protected mode +-- SDL does: +-- 1) Perform protected service handshake +-- 2) Reply with StartServiceACK encryption = true +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Security/DTLS/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set DTLS protocol in SDL", common.setSDLIniParameter, { "Protocol", "DTLSv1.0" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Policy Table Update Certificate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Start RPC Service protected", common.startServiceProtected, { 7 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL, restore SDL settings", common.postconditions) diff --git a/test_scripts/Security/DTLS/002_Start_Audio_service.lua b/test_scripts/Security/DTLS/002_Start_Audio_service.lua new file mode 100644 index 0000000000..c0758bc913 --- /dev/null +++ b/test_scripts/Security/DTLS/002_Start_Audio_service.lua @@ -0,0 +1,32 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1) SDL is configured with parameter ‘Protocol = DTLSv1.0’ +-- 2) SDL has up-to-date certificates in Policy Table +-- 3) And app is configured to use DTLS protocol for communication with SDL +-- 4) And this app is registered and RPC service is started in unprotected mode +-- 5) And this app is try to start Audio/Video service in protected mode +-- SDL does: +-- 1) Perform protected service handshake +-- 2) Reply with StartServiceACK encryption = true +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Security/DTLS/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set DTLS protocol in SDL", common.setSDLIniParameter, { "Protocol", "DTLSv1.0" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Policy Table Update Certificate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Start Audio Service protected", common.startServiceProtected, { 10 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL, restore SDL settings", common.postconditions) diff --git a/test_scripts/Security/DTLS/003_Start_Video_service.lua b/test_scripts/Security/DTLS/003_Start_Video_service.lua new file mode 100644 index 0000000000..38a25b619b --- /dev/null +++ b/test_scripts/Security/DTLS/003_Start_Video_service.lua @@ -0,0 +1,32 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1) SDL is configured with parameter ‘Protocol = DTLSv1.0’ +-- 2) SDL has up-to-date certificates in Policy Table +-- 3) And app is configured to use DTLS protocol for communication with SDL +-- 4) And this app is registered and RPC service is started in unprotected mode +-- 5) And this app is try to start Audio/Video service in protected mode +-- SDL does: +-- 1) Perform protected service handshake +-- 2) Reply with StartServiceACK encryption = true +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Security/DTLS/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set DTLS protocol in SDL", common.setSDLIniParameter, { "Protocol", "DTLSv1.0" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Policy Table Update Certificate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Start Video Service protected", common.startServiceProtected, { 11 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL, restore SDL settings", common.postconditions) diff --git a/test_scripts/Security/DTLS/004_Processing_of_RPC.lua b/test_scripts/Security/DTLS/004_Processing_of_RPC.lua new file mode 100644 index 0000000000..dbb4b25728 --- /dev/null +++ b/test_scripts/Security/DTLS/004_Processing_of_RPC.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1) SDL is configured with parameter ‘Protocol = DTLSv1.0’ +-- 2) And app is configured to use DTLS protocol for communication with SDL +-- 3) And this app is registered and RPC service is started in protected mode +-- 4) And app tries to send any RPC +-- SDL does: +-- 1) Process this RPC successfully in protected mode +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Security/DTLS/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function rpcInProtectedModeSuccess() + local params = { + cmdID = 1, + menuParams = { + position = 1, + menuName = "Command_1" + } + } + local cid = common.getMobileSession():SendEncryptedRPC("AddCommand", params) + common.getHMIConnection():ExpectRequest("UI.AddCommand", params) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { }) + end) + common.getMobileSession():ExpectEncryptedResponse(cid, { success = true, resultCode = "SUCCESS" }) + common.getMobileSession():ExpectEncryptedNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set DTLS protocol in SDL", common.setSDLIniParameter, { "Protocol", "DTLSv1.0" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Policy Table Update Certificate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Start RPC Service protected", common.startServiceProtected, { 7 }) +runner.Step("Process RPC in protected mode", rpcInProtectedModeSuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL, restore SDL settings", common.postconditions) diff --git a/test_scripts/Security/DTLS/005_Ignore_malformed_packet.lua b/test_scripts/Security/DTLS/005_Ignore_malformed_packet.lua new file mode 100644 index 0000000000..c054ffc7f3 --- /dev/null +++ b/test_scripts/Security/DTLS/005_Ignore_malformed_packet.lua @@ -0,0 +1,50 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1) SDL is configured with parameter ‘Protocol = DTLSv1.0’ +-- 2) And app is configured to use DTLS protocol for communication with SDL +-- 3) And this app is registered and RPC service is started in protected mode +-- 4) And this app tries to send multi-packet RPC (e.g. PutFile) +-- 5) And while sending at least one of the encrypted packet is malformed (or unexpected) +-- SDL does: +-- 1) Ignore malformed (or unexpected) packet +-- 2) Process this RPC successfully in protected mode +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Security/DTLS/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set DTLS protocol in SDL", common.setSDLIniParameter, { "Protocol", "DTLSv1.0" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Policy Table Update Certificate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("PutFile. Session Insecure. Sent data UNprotected", common.putFileByFrames, { + { isSessionEncrypted = false, isSentDataEncrypted = false } +}) +runner.Step("PutFile. Session Insecure. Sent data UNprotected + Malformed frame", common.putFileByFrames, { + { isSessionEncrypted = false, isSentDataEncrypted = false, isMalformedFrameInserted = true } +}) +runner.Step("Switch RPC service to Protected mode", common.startServiceProtected, { 7 }) +runner.Step("PutFile. Session Secure. Sent data UNprotected", common.putFileByFrames, { + { isSessionEncrypted = true, isSentDataEncrypted = false } +}) +runner.Step("PutFile. Session Secure. Sent data UNprotected + Malformed frame", common.putFileByFrames, { + { isSessionEncrypted = true, isSentDataEncrypted = false, isMalformedFrameInserted = true } +}) +runner.Step("PutFile. Session Secure. Sent data Protected", common.putFileByFrames, { + { isSessionEncrypted = true, isSentDataEncrypted = true } +}) +runner.Step("PutFile. Session Secure. Sent data Protected + Malformed frame", common.putFileByFrames, { + { isSessionEncrypted = true, isSentDataEncrypted = true, isMalformedFrameInserted = true } +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL, restore SDL settings", common.postconditions) diff --git a/test_scripts/Security/DTLS/006_Ignore_unexpected_packet.lua b/test_scripts/Security/DTLS/006_Ignore_unexpected_packet.lua new file mode 100644 index 0000000000..9ea1548c8a --- /dev/null +++ b/test_scripts/Security/DTLS/006_Ignore_unexpected_packet.lua @@ -0,0 +1,50 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1) SDL is configured with parameter ‘Protocol = DTLSv1.0’ +-- 2) And app is configured to use DTLS protocol for communication with SDL +-- 3) And this app is registered and RPC service is started in protected mode +-- 4) And this app tries to send multi-packet RPC (e.g. PutFile) +-- 5) And while sending at least one of the encrypted packet is malformed (or unexpected) +-- SDL does: +-- 1) Ignore malformed (or unexpected) packet +-- 2) Process this RPC successfully in protected mode +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Security/DTLS/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set DTLS protocol in SDL", common.setSDLIniParameter, { "Protocol", "DTLSv1.0" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Policy Table Update Certificate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("PutFile. Session Insecure. Sent data UNprotected", common.putFileByFrames, { + { isSessionEncrypted = false, isSentDataEncrypted = false } +}) +runner.Step("PutFile. Session Insecure. Sent data UNprotected + Unexpected frame", common.putFileByFrames, { + { isSessionEncrypted = false, isSentDataEncrypted = false, isUnexpectedFrameInserted = true } +}) +runner.Step("Switch RPC service to Protected mode", common.startServiceProtected, { 7 }) +runner.Step("PutFile. Session Secure. Sent data UNprotected", common.putFileByFrames, { + { isSessionEncrypted = true, isSentDataEncrypted = false } +}) +runner.Step("PutFile. Session Secure. Sent data UNprotected + Unexpected frame", common.putFileByFrames, { + { isSessionEncrypted = true, isSentDataEncrypted = false, isUnexpectedFrameInserted = true } +}) +runner.Step("PutFile. Session Secure. Sent data Protected", common.putFileByFrames, { + { isSessionEncrypted = true, isSentDataEncrypted = true } +}) +runner.Step("PutFile. Session Secure. Sent data Protected + Unexpected frame", common.putFileByFrames, { + { isSessionEncrypted = true, isSentDataEncrypted = true, isUnexpectedFrameInserted = true } +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL, restore SDL settings", common.postconditions) diff --git a/test_scripts/Security/DTLS/007_Processing_multiple_frames.lua b/test_scripts/Security/DTLS/007_Processing_multiple_frames.lua new file mode 100644 index 0000000000..7f69fc13e9 --- /dev/null +++ b/test_scripts/Security/DTLS/007_Processing_multiple_frames.lua @@ -0,0 +1,37 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1) SDL is configured with parameter ‘Protocol = DTLSv1.0’ +-- 2) And app is configured to use DTLS protocol for communication with SDL +-- 3) And this app is registered and RPC service is started in protected mode +-- 4) And this app tries to send multi-packet RPC (e.g. PutFile) +-- 5) And 1st frame is non-encrypted (or encrypted) and other frames are encrypted +-- SDL does: +-- 1) Process this RPC successfully in protected mode +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Security/DTLS/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set DTLS protocol in SDL", common.setSDLIniParameter, { "Protocol", "DTLSv1.0" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Policy Table Update Certificate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Switch RPC service to Protected mode", common.startServiceProtected, { 7 }) +runner.Step("PutFile. Session Secure. Sent data Protected. 1st frame UNprotected", common.putFileByFrames, { + { isSessionEncrypted = true, isSentDataEncrypted = true, isFirstFrameEncrypted = false } +}) +runner.Step("PutFile. Session Secure. Sent data Protected. 1st frame Protected", common.putFileByFrames, { + { isSessionEncrypted = true, isSentDataEncrypted = true, isFirstFrameEncrypted = true } +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL, restore SDL settings", common.postconditions) diff --git a/test_scripts/Security/DTLS/common.lua b/test_scripts/Security/DTLS/common.lua new file mode 100644 index 0000000000..fea7155acf --- /dev/null +++ b/test_scripts/Security/DTLS/common.lua @@ -0,0 +1,224 @@ +--------------------------------------------------------------------------------------------------- +-- Navigation common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.SecurityProtocol = "DTLS" +config.application1.registerAppInterfaceParams.appName = "server" +config.application1.registerAppInterfaceParams.appID = "SPT" +-- config.cipherListString = ":SSLv2:AES256-GCM-SHA384" + +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") +local security = require("user_modules/sequences/security") +local utils = require("user_modules/utils") +local json = require("modules/json") +local constants = require('protocol_handler/ford_protocol_constants') +constants.FRAME_SIZE["P9"] = 131084 -- add unsupported SDL protocol version + +--[[ Module ]] +local m = actions + +m.frameInfo = security.frameInfo + +--[[ Constants ]] +local fileName = "files/action.png" + +--[[ Variables ]] +local msgId = 1000 + +--[[ Functions ]] + +--[[ @ptUpdate: add certificate to policy table +--! @parameters: +--! pTbl - policy table to update +--! @return: none +--]] +function m.ptUpdate(pTbl) + local filePath = "./files/Security/client_credential.pem" + local crt = utils.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt +end + +--[[ @bytesToInt32: convert bytes to int32 +--! @parameters: +--! val - value to convert +--! offset - offset +--! @return: value in int32 +--]] +local function bytesToInt32(pVal, pOffset) + local res = bit32.lshift(string.byte(pVal, pOffset), 24) + + bit32.lshift(string.byte(pVal, pOffset + 1), 16) + + bit32.lshift(string.byte(pVal, pOffset + 2), 8) + + string.byte(pVal, pOffset + 3) + return res +end + +--[[ @int32ToBytes: convert int32 to bytes +--! @parameters: +--! val - value to convert +--! @return: value in bytes +--]] +local function int32ToBytes(pVal) + local res = string.char( + bit32.rshift(bit32.band(pVal, 0xff000000), 24), + bit32.rshift(bit32.band(pVal, 0xff0000), 16), + bit32.rshift(bit32.band(pVal, 0xff00), 8), + bit32.band(pVal, 0xff) + ) + return res +end + +--[[ @rpcPayload: create payload for RPC +--! @parameters: +--! msg - message table to populate +--! @return: populated message +--]] +local function rpcPayload(pMsg) + pMsg.payload = pMsg.payload or "" + pMsg.binaryData = pMsg.binaryData or "" + local res = string.char( + bit32.lshift(pMsg.rpcType, 4) + bit32.band(bit32.rshift(pMsg.rpcFunctionId, 24), 0x0f), + bit32.rshift(bit32.band(pMsg.rpcFunctionId, 0xff0000), 16), + bit32.rshift(bit32.band(pMsg.rpcFunctionId, 0xff00), 8), + bit32.band(pMsg.rpcFunctionId, 0xff)) .. + int32ToBytes(pMsg.rpcCorrelationId) .. + int32ToBytes(#pMsg.payload) .. + pMsg.payload .. pMsg.binaryData + return res +end + +--[[ @putFileByFrames: process PutFile RPC frame by frame +--! @parameters: +--! pParams - table with parameters (file, isSentDataEncrypted, isUnexpectedFrameInserted, isMalformedFrameInserted) +--]] +function m.putFileByFrames(pParams) + msgId = msgId + 1 + + local putFileParams = { + syncFileName = "action_" .. msgId .. " .png", + fileType = "GRAPHIC_PNG", + persistentFile = true, + systemFile = false, + } + + local correlationId = m.getMobileSession().correlationId + 1 + + local msg = { + version = config.defaultProtocolVersion, + encryption = pParams.isSentDataEncrypted, + frameType = 0x01, + serviceType = 0x07, + frameInfo = 0x0, + sessionId = m.getMobileSession().sessionId, + messageId = msgId, + rpcType = 0x0, + rpcFunctionId = 32, -- PutFile + rpcCorrelationId = correlationId, + payload = json.encode(putFileParams) + } + + local file = fileName + if pParams.file then file = pParams.file end + + local f = assert(io.open(file)) + msg.binaryData = f:read("*all") + io.close(f) + + msg.binaryData = rpcPayload(msg) + + local frames = {} + local binaryDataSize = #msg.binaryData + local max_size = 1400 + local frameMessage = { + version = msg.version, + encryption = msg.encryption, + serviceType = msg.serviceType, + sessionId = msg.sessionId, + messageId = msg.messageId + } + if binaryDataSize > max_size then + local countOfDataFrames = 0 + -- Create messages consecutive frames + while #msg.binaryData > 0 do + countOfDataFrames = countOfDataFrames + 1 + + local dataPart = string.sub(msg.binaryData, 1, max_size) + msg.binaryData = string.sub(msg.binaryData, max_size + 1) + + local frame_info = 0 -- last frame + if #msg.binaryData > 0 then + frame_info = ((countOfDataFrames - 1) % 255) + 1 + end + + local consecutiveFrameMessage = utils.cloneTable(frameMessage) + consecutiveFrameMessage.frameType = 0x03 + consecutiveFrameMessage.frameInfo = frame_info + consecutiveFrameMessage.binaryData = dataPart + table.insert(frames, consecutiveFrameMessage) + end + + -- Create message firstframe + local firstFrameMessage = utils.cloneTable(frameMessage) + firstFrameMessage.frameType = 0x02 + firstFrameMessage.frameInfo = 0 + firstFrameMessage.binaryData = int32ToBytes(binaryDataSize) .. int32ToBytes(countOfDataFrames) + if pParams.isFirstFrameEncrypted ~= nil then + firstFrameMessage.encryption = pParams.isFirstFrameEncrypted + end + table.insert(frames, 1, firstFrameMessage) + else + table.insert(frames, msg) + end + + m.getMobileSession().mobile_session_impl.rpc_services:CheckCorrelationID(msg) + + if pParams.isUnexpectedFrameInserted == true then + frames[4] = frames[3] + frames[3] = utils.cloneTable(frames[2]) + frames[3].binaryData = '123' + end + + if pParams.isMalformedFrameInserted == true then + frames[4] = frames[3] + frames[3] = utils.cloneTable(frames[2]) + frames[2].version = 9 -- incorrect protocol version + end + + for _, frame in pairs(frames) do + m.getMobileSession():SendPacket(frame) + end + + if pParams.isSessionEncrypted == false then + m.getMobileSession():ExpectResponse(correlationId, { success = true, resultCode = "SUCCESS"}) + else + m.getMobileSession():ExpectEncryptedResponse(correlationId, { success = true, resultCode = "SUCCESS"}) + end + + m.getMobileSession():ExpectPacket({ + sessionId = m.getMobileSession().sessionId, + frameType = 0x01, + serviceType = 0x07 + }, + function(binaryData) + local rpcFunctionId = bit32.band(bytesToInt32(binaryData, 1), 0x0fffffff) + local rpcCorrelationId = bytesToInt32(binaryData, 5) + if rpcFunctionId ~= 32 or rpcCorrelationId ~= correlationId then return false end + return true + end) +end + +--[[ @startServiceProtected: start (or switch) service in protected mode +--! @parameters: +--! pServiceId - service id +--! @return: none +--]] +function m.startServiceProtected(pServiceId) + m.getMobileSession():StartSecureService(pServiceId) + m.getMobileSession():ExpectHandshakeMessage() + m.getMobileSession():ExpectControlMessage(pServiceId, { + frameInfo = m.frameInfo.START_SERVICE_ACK, + encryption = true + }) +end + +return m diff --git a/test_sets/dtls_encryption.txt b/test_sets/dtls_encryption.txt new file mode 100644 index 0000000000..e9c79d6866 --- /dev/null +++ b/test_sets/dtls_encryption.txt @@ -0,0 +1,7 @@ +./test_scripts/Security/DTLS/001_StartRPC_service.lua +./test_scripts/Security/DTLS/002_Start_Audio_service.lua +./test_scripts/Security/DTLS/003_Start_Video_service.lua +./test_scripts/Security/DTLS/004_Processing_of_RPC.lua +./test_scripts/Security/DTLS/005_Ignore_malformed_packet.lua +./test_scripts/Security/DTLS/006_Ignore_unexpected_packet.lua +./test_scripts/Security/DTLS/007_Processing_multiple_frames.lua From dd984fcbf2cd777ac85678c68c7e63abdf5263e5 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 25 May 2018 14:50:48 +0300 Subject: [PATCH 433/681] Update DTLS and GST common modules --- test_scripts/Security/DTLS/common.lua | 9 +++++++++ test_scripts/Security/GetSystemTime/common.lua | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/test_scripts/Security/DTLS/common.lua b/test_scripts/Security/DTLS/common.lua index fea7155acf..3a52ff7cbb 100644 --- a/test_scripts/Security/DTLS/common.lua +++ b/test_scripts/Security/DTLS/common.lua @@ -13,6 +13,7 @@ local security = require("user_modules/sequences/security") local utils = require("user_modules/utils") local json = require("modules/json") local constants = require('protocol_handler/ford_protocol_constants') +local common = require("test_scripts/Security/common") constants.FRAME_SIZE["P9"] = 131084 -- add unsupported SDL protocol version --[[ Module ]] @@ -221,4 +222,12 @@ function m.startServiceProtected(pServiceId) }) end +m.postconditions = common.postconditions + +local preconditionsOrig = m.preconditions +function m.preconditions() + preconditionsOrig() + common.initSDLCertificates("./files/Security/client_credential.pem", false) +end + return m diff --git a/test_scripts/Security/GetSystemTime/common.lua b/test_scripts/Security/GetSystemTime/common.lua index 4442de67e2..8508ee1f5c 100644 --- a/test_scripts/Security/GetSystemTime/common.lua +++ b/test_scripts/Security/GetSystemTime/common.lua @@ -7,6 +7,7 @@ local security = require("user_modules/sequences/security") local utils = require("user_modules/utils") local test = require("user_modules/dummy_connecttest") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local common = require("test_scripts/Security/common") --[[ General configuration parameters ]] config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential.pem" @@ -123,4 +124,12 @@ function m.startServiceSecuredwithPTU(pData, pServiceId, pGetSystemTimeOccur, pT expectHandshakeMessage(pGetSystemTimeOccur, pTime, pHandshakeOccurences) end +m.postconditions = common.postconditions + +local preconditionsOrig = m.preconditions +function m.preconditions() + preconditionsOrig() + common.initSDLCertificates("./files/Security/client_credential.pem", false) +end + return m From 3f2f8324776b91df4f83803e9056f9ddd8949b15 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 25 May 2018 12:54:21 +0300 Subject: [PATCH 434/681] Add scripts to check sending of RPC in Protected mode --- files/Security/client_credential_expired.pem | 95 +++++++++ ...001_Navi_Predefined_cert_valid_SUCCESS.lua | 42 ++++ ...ed_cert_expired_PTU_cert_valid_SUCCESS.lua | 48 +++++ ...ned_cert_expired_PTU_cert_missing_NACK.lua | 44 +++++ ...ned_cert_expired_PTU_cert_expired_NACK.lua | 46 +++++ ...ed_cert_missing_PTU_cert_valid_SUCCESS.lua | 48 +++++ ...ned_cert_missing_PTU_cert_missing_NACK.lua | 44 +++++ ...ned_cert_missing_PTU_cert_expired_NACK.lua | 46 +++++ ...Non-Navi_Predefined_cert_valid_SUCCESS.lua | 42 ++++ ...ed_cert_expired_PTU_cert_valid_SUCCESS.lua | 48 +++++ ...ned_cert_expired_PTU_cert_missing_NACK.lua | 44 +++++ ...ned_cert_expired_PTU_cert_expired_NACK.lua | 46 +++++ ...ed_cert_missing_PTU_cert_valid_SUCCESS.lua | 48 +++++ ...ned_cert_missing_PTU_cert_missing_NACK.lua | 44 +++++ ...ned_cert_missing_PTU_cert_expired_NACK.lua | 46 +++++ test_scripts/Security/common.lua | 185 ++++++++++++++++++ 16 files changed, 916 insertions(+) create mode 100644 files/Security/client_credential_expired.pem create mode 100644 test_scripts/Security/001_Navi_Predefined_cert_valid_SUCCESS.lua create mode 100644 test_scripts/Security/002_Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua create mode 100644 test_scripts/Security/003_Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua create mode 100644 test_scripts/Security/004_Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua create mode 100644 test_scripts/Security/005_Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua create mode 100644 test_scripts/Security/006_Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua create mode 100644 test_scripts/Security/007_Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua create mode 100644 test_scripts/Security/008_Non-Navi_Predefined_cert_valid_SUCCESS.lua create mode 100644 test_scripts/Security/009_Non-Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua create mode 100644 test_scripts/Security/010_Non-Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua create mode 100644 test_scripts/Security/011_Non-Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua create mode 100644 test_scripts/Security/012_Non-Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua create mode 100644 test_scripts/Security/013_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua create mode 100644 test_scripts/Security/014_Non-Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua create mode 100644 test_scripts/Security/common.lua diff --git a/files/Security/client_credential_expired.pem b/files/Security/client_credential_expired.pem new file mode 100644 index 0000000000..c2e3a9c81d --- /dev/null +++ b/files/Security/client_credential_expired.pem @@ -0,0 +1,95 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAznGdnfv++nWKzo/jLB1GMHAj4IV/9qXP0pw3XilPII6fvIXe +q0OOR+PKAtg3UNKrBnJpOIcFHO3YFv8OJUBxDaX8V4j3enRfpPwEh3RVU0A3HBgY +Tq4FVffYPOr1vNBiyf2eEe3m2ArBGQxo2nj+d8qI2k+59sKstw6v/2X1dQH8C21F +OLrPot6HxupbktYYaIxy8fo82uDPxaA6U2Ev3bzXJlGOmEe/ZPlx318+rhb24y2z +FIid/+jfWrumVhRcth7pYTWXUqsHpnfWzJY7KAkUmzNQV60T2aGSauy6OfJMCiQF +vyI4taWIah1oVxYSEHnXYgsz/U9H8sEKUL01DwIDAQABAoIBABXN9kHbfeDiTVjn +5ayhIuq2zXNHZm6csMij600su8jKh6CX2x7nsb1yF8IZKC6HMb0qlGZ+DFIz5OD4 +63uPxOEWKQLt2oW6iOeaHrhX1zNF0wxKlzaoNrQPy20TvATHVcfT28A1Cm7DJAYL +Q3/fy7DHWZEFXrTrduaWzIwDLtu+uxZK29ZPDQMPkobIrBuWzGYJtyPJkAHag0lt +cw8YtDcl8mVmu/npF9A9DTnvESwNancNzGbzU7/p9YNlAu+B1LRRbPx0HBEkIR0+ +JkPilX7cqKTv04Y1n3k1wHqCEEA8g+QR+Q9YYzkjjF9D0Dnhapu6vBjRZI7f1sQP +yWqQVRECgYEA/zjfcn5RCgmgaZ7Rkp7rwZWDiimPBh/jZ2EZuKmXvUNons5ZVrE5 +AlpWtjX+jQWSbAKBjnRx7i/rL6ZL28RRES634VDavKCPV/onPLN+RhU+aoZXSUFq +ofMtRD1mg43wdNPU6YXZxCnAwujSK50HA4wIwx5d4gP1+p0C2w0BFtMCgYEAzxKv +eS9Sf1NlaNmlu7P5bcwT4wgnBhTqIlkbdUpgz0n+qDS4L5grTMjF4x+j455czZQb +Ve8FgCG8PyafVwN+8Q/K/Jp8HsXsj0x7E8XGd/EOlZuJPdI9y/YXC2A+4ZlD43gS +Hp2tQFfdw0GHBXwWb3IfRyuVJ/Nqspl57q2qO1UCgYEArYXvdhqn4pk09VrDxlpC +lDWhX3huA43+wLTmFgVIY6fHI+HMIAMSbaUaO3xue1cEfGcfysklBPqTfqwj+2F4 +dKQ85PZiIclQbFJqBv1Kpz+eVjLMecP+SenaJwFQB7WjfOrhYXxd2N9CbcJ50qlK +sYCuHGszDY3/2cqSvHgU+30CgYApOuY3ceWyNm+1rchjFFWwt/apuMDUZCuuRSHD +e9jEzU3oPf8CcwEEG+HS9ETUmH6P7FJ5DMuClLT/uff2AlsvMl7PZw8ZrX0Jl0fW +SwXWcefegAaWiZsGVmyGNlau4q5yx0CMWgbaDeS48P4qaGerLwTtTc84Ei6Heymd +DXUctQKBgG0VCx7B4KVnkln0T0zDPQAh+oqSU7Bx9YN/VlS/4obam58clq4SA3HR +PS5OXBkIGk5F6hi5F47qe7VuYPqbRAAGOQ58GPSQMuYrYw5BOdNMIEz9f6lcjlHG +oYb5xMAEw9S2YNKnP13Z2DTNWNIAFEiFdza5e++pZlMj71IScELj +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDojCCAooCAQEwDQYJKoZIhvcNAQEEBQAwgZgxCzAJBgNVBAYTAlVTMREwDwYD +VQQIDAhNaWNoaWdhbjEQMA4GA1UEBwwHRGV0cm9pdDEUMBIGA1UECgwLRk9SRF9D +TElFTlQxGDAWBgNVBAsMD0ZPUkRfU0RMX0NMSUVOVDEUMBIGA1UEAwwLRk9SRF9D +TElFTlQxHjAcBgkqhkiG9w0BCQEWD3NhbXBsZUBmb3JkLmNvbTAeFw0xNTAxMDEw +MDAwMDBaFw0xNTAzMTQwOTI2NTNaMIGUMQswCQYDVQQGEwJSVTEPMA0GA1UECAwG +UnVzc2lhMRcwFQYDVQQHDA5TdC4gUGV0ZXJzYnVyZzEPMA0GA1UECgwGTHV4b2Z0 +MRcwFQYDVQQLDA5Nb2JpbGVfZXhwaXJlZDEPMA0GA1UEAwwGY2xpZW50MSAwHgYJ +KoZIhvcNAQkBFhFzYW1wbGVAbHV4b2Z0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAM5xnZ37/vp1is6P4ywdRjBwI+CFf/alz9KcN14pTyCOn7yF +3qtDjkfjygLYN1DSqwZyaTiHBRzt2Bb/DiVAcQ2l/FeI93p0X6T8BId0VVNANxwY +GE6uBVX32Dzq9bzQYsn9nhHt5tgKwRkMaNp4/nfKiNpPufbCrLcOr/9l9XUB/Att +RTi6z6Leh8bqW5LWGGiMcvH6PNrgz8WgOlNhL9281yZRjphHv2T5cd9fPq4W9uMt +sxSInf/o31q7plYUXLYe6WE1l1KrB6Z31syWOygJFJszUFetE9mhkmrsujnyTAok +Bb8iOLWliGodaFcWEhB512ILM/1PR/LBClC9NQ8CAwEAATANBgkqhkiG9w0BAQQF +AAOCAQEALuP1z2o4dR09J+cWeApZaADCn24sWSFd24LzIMZUGw+fRUE6b+5zdyFr +So1zNR3RQY5ATm+BBAFg7WfBx6b9fBaistWGMoCpDVvO94toEpVivkD0wG7zmcif +ejBJJcJt5zn2uLJle3UL9NA3DhxIcTHE7yPYhIr5lr9c6wT2HAJc6dii6uHPc3Bj ++UapOB02eOOhtIhitrLvniXnjhpb5k/gQL0UTzWRVo1W0jXz9fkntfvr3O0Unmor +kiBpN3nF888liPtOeUtYbdTYoAgH5fLpUBA9QJ7T6WQwJRe1lBy8uyTpCz/slucE +2GhFcT2V+jJ1NRTxJtLcPr6WG/oDmA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgIJAITI5lAQ6iOFMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEXMBUGA1UEBwwOU2lsaWNvbiBW +YWxsZXkxEzARBgNVBAoMCkNBY2VydC5vcmcxDzANBgNVBAsMBkNBY2VydDEUMBIG +A1UEAwwLc2VydmVyX3Jvb3QxIDAeBgkqhkiG9w0BCQEWEXNhbXBsZUBjYWNlcnQu +b3JnMB4XDTE3MTIwMTEzNDYzNloXDTQ1MDQxODEzNDYzNlowgZkxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRcwFQYDVQQHDA5TaWxpY29uIFZhbGxl +eTETMBEGA1UECgwKQ0FjZXJ0Lm9yZzEPMA0GA1UECwwGQ0FjZXJ0MRQwEgYDVQQD +DAtzZXJ2ZXJfcm9vdDEgMB4GCSqGSIb3DQEJARYRc2FtcGxlQGNhY2VydC5vcmcw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAmyE96hjM8RbFpV3ISy6K +ACXcq3CSS4JjiBMlIbwNydE2rd6aznEdSo1Usi44dhl47tw6H3YetD1d3BbQiIZV +brH8RyAPWNlFhpv6LiVSbsigXp4aGnS876zE3urDz0ov/SqWpBSNNcflqaak+TH1 +VWJnkZyWcEv27laI2HSFvhcxsXOw+BKbkBu7WpnTybHMQGBHQNLhP3sKdcJUPzZa +9Fc3UbITMpq3p92J155BEVtuEGVti3osKe4Rr2UB8D8hQLUQ4tYH4yx1dZHdfSRJ +fUY6l42rupCW/VRGtY7fF/ZH6AlBZbA5dYFVC2y0PUIAgPnGJ6/wprpeJtZDXyUD +AgMBAAGjUDBOMB0GA1UdDgQWBBQz72vddo+HSnyy/vAW5b6O4x3PyjAfBgNVHSME +GDAWgBQz72vddo+HSnyy/vAW5b6O4x3PyjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQA3nZjVmizW85OPK9PoAMQYb6t8PFmTY+UTl4G20AKvMIkxv4rk +5CF4JOqCYvv7bzsLKOsHI/rbYTTmJFQuUXNjPBysPX/lT+mBK2o6k7TanCw7IgIb +1mV3LzCV1vY3K8DpaeTabK/HcCbgLIqVvULyo1HsWzpdOtcCaWt5Ssz4/ZqP3eaR +N6j3V4YeTvKZPx9oxcgIaNY6eLCt0c0mlx5XHAHoeaF1MXLgjIkITPOUSZNUB04G +OD9UhOZVMpHWTSpsVZryWiUpZiLz301RXGti7FbrC/9yHF5UycJ3SfCheBxy4Pqa +Zt0ck3RykZ+v3GwSY+39Oo3mBbLNiB+9668W +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDqDCCApACCQC/Ty1f/qRtejANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMC +VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFzAVBgNVBAcMDlNpbGljb24gVmFsbGV5 +MRMwEQYDVQQKDApDQWNlcnQub3JnMQ8wDQYDVQQLDAZDQWNlcnQxFDASBgNVBAMM +C3NlcnZlcl9yb290MSAwHgYJKoZIhvcNAQkBFhFzYW1wbGVAY2FjZXJ0Lm9yZzAe +Fw0xNzEyMDExMzQ2MzZaFw00NTA0MTgxMzQ2MzZaMIGRMQswCQYDVQQGEwJVUzER +MA8GA1UECAwITWljaGlnYW4xEDAOBgNVBAcMB0RldHJvaXQxFDASBgNVBAoMC0ZP +UkRfU0VSVkVSMRgwFgYDVQQLDA9GT1JEX1NETF9TRVJWRVIxDTALBgNVBAMMBEZP +UkQxHjAcBgkqhkiG9w0BCQEWD3NhbXBsZUBmb3JkLmNvbTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAMcLS+D5+pJ9dM9K3gifVsUXwSC3YT3kj4M26rqk +8IRJNB/zBbwjOVhG5f0wrm+JFn3TETB8QTet4seKWCHBGy3lXeKHPNZeXee/RLUf +BDWtytEaYvAuS0VQkktYlR2GDd28TmwK8ALyeZ8qyk6+MyddSYrkwNfISIcxIjwB +0sNPNskYXQXwjOB1rkaWTUM+0Y8RDyVjNmef9X8ZfQpP0o9K+feEoE+GL8Gw0dTr +D3S8exfB9STLuNNxn2KNKXT7G+YAqTrRwNZATfwII6EZv3GQVNS9DVGM3UyG9Gyg +tAYIEZJpll+HPqAaZ0Sm1mTC4uDYrSgLy+HdkiYyj1HaJCkCAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEAk9L6Njo8nNt9rSgqUyD1fcT7w+BRQ48Kjk20nl/865uLlI16 +eLV9v/Fy2ojyewhhGwesL6oQOzVn4uQ8w2Yn6F7YGM8KOzI4fkCm9uJHIS0DaSY9 +BwwIg75rUtFhifTFCyD+onuBbFN1JHG7hMC1KHEoWNYfIL2J5JudvwnyODnLqbLF +Ox0GBk0lsYMMaiDmEReZLayzGGMoF4zNAmKXHQTuAbseNhlaKuzK3KkttX9S5Dge +qHpnAvu8dt0Y9Qnc3cRBVpOeifyyVVJd5YBX4MHl7SWOgR7AVdQw8DBqvIbSXrAd ++B7gbCcDklgOacyCfNcQuNvcxbEjU20ATt38bg== +-----END CERTIFICATE----- diff --git a/test_scripts/Security/001_Navi_Predefined_cert_valid_SUCCESS.lua b/test_scripts/Security/001_Navi_Predefined_cert_valid_SUCCESS.lua new file mode 100644 index 0000000000..7279654541 --- /dev/null +++ b/test_scripts/Security/001_Navi_Predefined_cert_valid_SUCCESS.lua @@ -0,0 +1,42 @@ +--------------------------------------------------------------------------------------------------- +-- Issues: +-- https://github.com/smartdevicelink/sdl_core/issues/2190 +-- https://github.com/smartdevicelink/sdl_core/issues/2191 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/common") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "NAVIGATION" } + +--[[ Local Variables ]] + +--[[ Local Functions ]] +local function startServiceProtectedACK() + local serviceId = 7 + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(1) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Clean-up certificates", common.cleanUpCertificates) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential.pem" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("Switch RPC Service to Protected mode ACK", startServiceProtectedACK) +runner.Step("Activate App Protected", common.activateAppProtected) +runner.Step("AddCommand Protected", common.sendAddCommandProtected) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) diff --git a/test_scripts/Security/002_Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua b/test_scripts/Security/002_Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua new file mode 100644 index 0000000000..c6afb6d17c --- /dev/null +++ b/test_scripts/Security/002_Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- Issues: +-- https://github.com/smartdevicelink/sdl_core/issues/2190 +-- https://github.com/smartdevicelink/sdl_core/issues/2191 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/common") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "NAVIGATION" } + +--[[ Local Variables ]] + +--[[ Local Functions ]] +local function startServiceSecuredACK() + local serviceId = 7 + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(1) + local function ptUpdate(pTbl) + local filePath = "./files/Security/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + end + common.policyTableUpdateSuccess(ptUpdate) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential_expired.pem" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Switch RPC Service to Protected mode ACK", startServiceSecuredACK) +runner.Step("Activate App Protected", common.activateAppProtected) +runner.Step("AddCommand Protected", common.sendAddCommandProtected) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) diff --git a/test_scripts/Security/003_Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua b/test_scripts/Security/003_Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua new file mode 100644 index 0000000000..748911c467 --- /dev/null +++ b/test_scripts/Security/003_Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------------------------------- +-- Issues: +-- https://github.com/smartdevicelink/sdl_core/issues/2190 +-- https://github.com/smartdevicelink/sdl_core/issues/2191 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/common") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "NAVIGATION" } + +--[[ Local Variables ]] + +--[[ Local Functions ]] +local function startServiceSecuredNACK() + local serviceId = 7 + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil + end + common.policyTableUpdateSuccess(ptUpdate) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential_expired.pem" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Switch RPC Service to Protected mode NACK", startServiceSecuredNACK) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) diff --git a/test_scripts/Security/004_Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua b/test_scripts/Security/004_Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua new file mode 100644 index 0000000000..a6e1757902 --- /dev/null +++ b/test_scripts/Security/004_Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua @@ -0,0 +1,46 @@ +--------------------------------------------------------------------------------------------------- +-- Issues: +-- https://github.com/smartdevicelink/sdl_core/issues/2190 +-- https://github.com/smartdevicelink/sdl_core/issues/2191 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/common") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "NAVIGATION" } + +--[[ Local Variables ]] + +--[[ Local Functions ]] +local function startServiceSecuredNACK() + local serviceId = 7 + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + local function ptUpdate(pTbl) + local filePath = "./files/Security/client_credential_expired.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + end + common.policyTableUpdateSuccess(ptUpdate) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential_expired.pem" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Switch RPC Service to Protected mode NACK", startServiceSecuredNACK) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) diff --git a/test_scripts/Security/005_Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua b/test_scripts/Security/005_Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua new file mode 100644 index 0000000000..22993b5f82 --- /dev/null +++ b/test_scripts/Security/005_Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- Issues: +-- https://github.com/smartdevicelink/sdl_core/issues/2190 +-- https://github.com/smartdevicelink/sdl_core/issues/2191 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/common") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "NAVIGATION" } + +--[[ Local Variables ]] + +--[[ Local Functions ]] +local function startServiceSecuredACK() + local serviceId = 7 + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(1) + local function ptUpdate(pTbl) + local filePath = "./files/Security/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + end + common.policyTableUpdateSuccess(ptUpdate) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential_expired.pem", false }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Switch RPC Service to Protected mode ACK", startServiceSecuredACK) +runner.Step("Activate App Protected", common.activateAppProtected) +runner.Step("AddCommand Protected", common.sendAddCommandProtected) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) diff --git a/test_scripts/Security/006_Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua b/test_scripts/Security/006_Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua new file mode 100644 index 0000000000..5ea4fc1445 --- /dev/null +++ b/test_scripts/Security/006_Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------------------------------- +-- Issues: +-- https://github.com/smartdevicelink/sdl_core/issues/2190 +-- https://github.com/smartdevicelink/sdl_core/issues/2191 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/common") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "NAVIGATION" } + +--[[ Local Variables ]] + +--[[ Local Functions ]] +local function startServiceSecuredNACK() + local serviceId = 7 + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil + end + common.policyTableUpdateSuccess(ptUpdate) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential_expired.pem", false }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Switch RPC Service to Protected mode NACK", startServiceSecuredNACK) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) diff --git a/test_scripts/Security/007_Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua b/test_scripts/Security/007_Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua new file mode 100644 index 0000000000..272f4acbc2 --- /dev/null +++ b/test_scripts/Security/007_Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua @@ -0,0 +1,46 @@ +--------------------------------------------------------------------------------------------------- +-- Issues: +-- https://github.com/smartdevicelink/sdl_core/issues/2190 +-- https://github.com/smartdevicelink/sdl_core/issues/2191 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/common") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "NAVIGATION" } + +--[[ Local Variables ]] + +--[[ Local Functions ]] +local function startServiceSecuredNACK() + local serviceId = 7 + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + local function ptUpdate(pTbl) + local filePath = "./files/Security/client_credential_expired.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + end + common.policyTableUpdateSuccess(ptUpdate) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential_expired.pem", false }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Switch RPC Service to Protected mode NACK", startServiceSecuredNACK) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) diff --git a/test_scripts/Security/008_Non-Navi_Predefined_cert_valid_SUCCESS.lua b/test_scripts/Security/008_Non-Navi_Predefined_cert_valid_SUCCESS.lua new file mode 100644 index 0000000000..5c0cbe5985 --- /dev/null +++ b/test_scripts/Security/008_Non-Navi_Predefined_cert_valid_SUCCESS.lua @@ -0,0 +1,42 @@ +--------------------------------------------------------------------------------------------------- +-- Issues: +-- https://github.com/smartdevicelink/sdl_core/issues/2190 +-- https://github.com/smartdevicelink/sdl_core/issues/2191 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/common") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Variables ]] + +--[[ Local Functions ]] +local function startServiceProtectedACK() + local serviceId = 7 + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(1) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Clean-up certificates", common.cleanUpCertificates) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential.pem" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("Switch RPC Service to Protected mode ACK", startServiceProtectedACK) +runner.Step("Activate App Protected", common.activateAppProtected) +runner.Step("AddCommand Protected", common.sendAddCommandProtected) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) diff --git a/test_scripts/Security/009_Non-Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua b/test_scripts/Security/009_Non-Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua new file mode 100644 index 0000000000..523569aa2e --- /dev/null +++ b/test_scripts/Security/009_Non-Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- Issues: +-- https://github.com/smartdevicelink/sdl_core/issues/2190 +-- https://github.com/smartdevicelink/sdl_core/issues/2191 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/common") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Variables ]] + +--[[ Local Functions ]] +local function startServiceSecuredACK() + local serviceId = 7 + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(1) + local function ptUpdate(pTbl) + local filePath = "./files/Security/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + end + common.policyTableUpdateSuccess(ptUpdate) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential_expired.pem" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Switch RPC Service to Protected mode ACK", startServiceSecuredACK) +runner.Step("Activate App Protected", common.activateAppProtected) +runner.Step("AddCommand Protected", common.sendAddCommandProtected) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) diff --git a/test_scripts/Security/010_Non-Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua b/test_scripts/Security/010_Non-Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua new file mode 100644 index 0000000000..7ea8a63cb0 --- /dev/null +++ b/test_scripts/Security/010_Non-Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------------------------------- +-- Issues: +-- https://github.com/smartdevicelink/sdl_core/issues/2190 +-- https://github.com/smartdevicelink/sdl_core/issues/2191 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/common") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Variables ]] + +--[[ Local Functions ]] +local function startServiceSecuredNACK() + local serviceId = 7 + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil + end + common.policyTableUpdateSuccess(ptUpdate) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential_expired.pem" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Switch RPC Service to Protected mode NACK", startServiceSecuredNACK) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) diff --git a/test_scripts/Security/011_Non-Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua b/test_scripts/Security/011_Non-Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua new file mode 100644 index 0000000000..1dc528182d --- /dev/null +++ b/test_scripts/Security/011_Non-Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua @@ -0,0 +1,46 @@ +--------------------------------------------------------------------------------------------------- +-- Issues: +-- https://github.com/smartdevicelink/sdl_core/issues/2190 +-- https://github.com/smartdevicelink/sdl_core/issues/2191 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/common") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Variables ]] + +--[[ Local Functions ]] +local function startServiceSecuredNACK() + local serviceId = 7 + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + local function ptUpdate(pTbl) + local filePath = "./files/Security/client_credential_expired.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + end + common.policyTableUpdateSuccess(ptUpdate) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential_expired.pem" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Switch RPC Service to Protected mode NACK", startServiceSecuredNACK) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) diff --git a/test_scripts/Security/012_Non-Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua b/test_scripts/Security/012_Non-Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua new file mode 100644 index 0000000000..4f13fd1bd8 --- /dev/null +++ b/test_scripts/Security/012_Non-Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- Issues: +-- https://github.com/smartdevicelink/sdl_core/issues/2190 +-- https://github.com/smartdevicelink/sdl_core/issues/2191 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/common") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Variables ]] + +--[[ Local Functions ]] +local function startServiceSecuredACK() + local serviceId = 7 + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(1) + local function ptUpdate(pTbl) + local filePath = "./files/Security/client_credential.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + end + common.policyTableUpdateSuccess(ptUpdate) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential_expired.pem", false }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Switch RPC Service to Protected mode ACK", startServiceSecuredACK) +runner.Step("Activate App Protected", common.activateAppProtected) +runner.Step("AddCommand Protected", common.sendAddCommandProtected) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) diff --git a/test_scripts/Security/013_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua b/test_scripts/Security/013_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua new file mode 100644 index 0000000000..933a6174dd --- /dev/null +++ b/test_scripts/Security/013_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua @@ -0,0 +1,44 @@ +s--------------------------------------------------------------------------------------------------- +-- Issues: +-- https://github.com/smartdevicelink/sdl_core/issues/2190 +-- https://github.com/smartdevicelink/sdl_core/issues/2191 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/common") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Variables ]] + +--[[ Local Functions ]] +local function startServiceSecuredNACK() + local serviceId = 7 + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + local function ptUpdate(pTbl) + pTbl.policy_table.module_config.certificate = nil + end + common.policyTableUpdateSuccess(ptUpdate) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential_expired.pem", false }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Switch RPC Service to Protected mode NACK", startServiceSecuredNACK) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) diff --git a/test_scripts/Security/014_Non-Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua b/test_scripts/Security/014_Non-Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua new file mode 100644 index 0000000000..8964b61417 --- /dev/null +++ b/test_scripts/Security/014_Non-Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua @@ -0,0 +1,46 @@ +--------------------------------------------------------------------------------------------------- +-- Issues: +-- https://github.com/smartdevicelink/sdl_core/issues/2190 +-- https://github.com/smartdevicelink/sdl_core/issues/2191 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/common") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Variables ]] + +--[[ Local Functions ]] +local function startServiceSecuredNACK() + local serviceId = 7 + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + local function ptUpdate(pTbl) + local filePath = "./files/Security/client_credential_expired.pem" + local crt = common.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt + end + common.policyTableUpdateSuccess(ptUpdate) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential_expired.pem", false }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Switch RPC Service to Protected mode NACK", startServiceSecuredNACK) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) diff --git a/test_scripts/Security/common.lua b/test_scripts/Security/common.lua new file mode 100644 index 0000000000..2691821a68 --- /dev/null +++ b/test_scripts/Security/common.lua @@ -0,0 +1,185 @@ +--------------------------------------------------------------------------------------------------- +-- Common module +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") +local security = require("user_modules/sequences/security") +local utils = require("user_modules/utils") +local test = require("user_modules/dummy_connecttest") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') + +--[[ General configuration parameters ]] +config.SecurityProtocol = "DTLS" +config.application1.registerAppInterfaceParams.appName = "server" +config.application1.registerAppInterfaceParams.appID = "SPT" + +--[[ Module ]] +local m = actions + +m.frameInfo = security.frameInfo +m.readFile = utils.readFile + +--[[ Functions ]] +local function getSystemTimeValue() + local dd = os.date("*t") + return { + millisecond = 0, + second = dd.sec, + minute = dd.min, + hour = dd.hour, + day = dd.day, + month = dd.month, + year = dd.year, + tz_hour = 2, + tz_minute = 0 + } +end + +local function registerGetSystemTimeResponse() + actions.getHMIConnection():ExpectRequest("BasicCommunication.GetSystemTime") + :Do(function(_, data) + actions.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { systemTime = getSystemTimeValue() }) + end) + :Pin() + :Times(AnyNumber()) +end + +function m.allowSDL() + actions.getHMIConnection():SendNotification("SDL.OnAllowSDLFunctionality", { + allowed = true, + source = "GUI", + device = { + id = utils.getDeviceMAC(), + name = utils.getDeviceName() + } + }) +end + +function m.start() + test:runSDL() + commonFunctions:waitForSDLStart(test) + :Do(function() + test:initHMI() + :Do(function() + local rid = actions.getHMIConnection():SendRequest("MB.subscribeTo", { + propertyName = "BasicCommunication.OnSystemTimeReady" }) + actions.getHMIConnection():ExpectResponse(rid) + :Do(function() + utils.cprint(35, "HMI initialized") + test:initHMI_onReady() + :Do(function() + utils.cprint(35, "HMI is ready") + actions.getHMIConnection():SendNotification("BasicCommunication.OnSystemTimeReady") + registerGetSystemTimeResponse() + test:connectMobile() + :Do(function() + utils.cprint(35, "Mobile connected") + m.allowSDL() + end) + end) + end) + end) + end) +end + +function m.sendAddCommandProtected() + local params = { + cmdID = 1, + menuParams = { + position = 1, + menuName = "Command_1" + } + } + local cid = m.getMobileSession():SendEncryptedRPC("AddCommand", params) + m.getHMIConnection():ExpectRequest("UI.AddCommand", params) + :Do(function(_, data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { }) + end) + m.getMobileSession():ExpectEncryptedResponse(cid, { success = true, resultCode = "SUCCESS" }) + m.getMobileSession():ExpectEncryptedNotification("OnHashChange") +end + +function m.activateAppProtected() + local rid = m.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = m.getHMIAppId() }) + m.getHMIConnection():ExpectResponse(rid) + m.getMobileSession():ExpectEncryptedNotification("OnHMIStatus", { + hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) +end + +local function saveFile(pContent, pFileName) + local f = io.open(pFileName, "w") + f:write(pContent) + f:close() +end + +local function getAllCrtsFromPEM(pCrtsFileName) + local crts = utils.readFile(pCrtsFileName) + local o = {} + local i = 1 + local s = crts:find("-----BEGIN RSA PRIVATE KEY-----", i, true) + local _, e = crts:find("-----END RSA PRIVATE KEY-----", i, true) + o.key = crts:sub(s, e) .. "\n" + for _, v in pairs({ "crt", "rootCA", "issuingCA" }) do + i = e + s = crts:find("-----BEGIN CERTIFICATE-----", i, true) + _, e = crts:find("-----END CERTIFICATE-----", i, true) + o[v] = crts:sub(s, e) .. "\n" + end + return o +end + +local function createCrtHashes() + local sdlBin = commonPreconditions:GetPathToSDL() + os.execute("cd " .. sdlBin .. " && c_rehash .") +end + +local function updateSDLIniFile() + m.setSDLIniParameter("KeyPath", "module_key.pem") + m.setSDLIniParameter("CertificatePath", "module_crt.pem") +end + +function m.initSDLCertificates(pCrtsFileName, pIsModuleCrtDefined) + if pIsModuleCrtDefined == nil then pIsModuleCrtDefined = true end + local allCrts = getAllCrtsFromPEM(pCrtsFileName) + local sdlBin = commonPreconditions:GetPathToSDL() + saveFile(allCrts.rootCA, sdlBin .. "rootCA.pem") + saveFile(allCrts.issuingCA, sdlBin .. "issuingCA.pem") + createCrtHashes() + if pIsModuleCrtDefined then + saveFile(allCrts.key, sdlBin .. "module_key.pem") + saveFile(allCrts.crt, sdlBin .. "module_crt.pem") + end + updateSDLIniFile() +end + +function m.cleanUpCertificates() + local sdlBin = commonPreconditions:GetPathToSDL() + os.execute("cd " .. sdlBin .. " && find . -type l -exec rm -f {} \\;") + os.execute("cd " .. sdlBin .. " && rm -rf *.pem") +end + +local preconditionsOrig = m.preconditions +local postconditionsOrig = m.postconditions + +function m.preconditions() + preconditionsOrig() + m.cleanUpCertificates() +end + +function m.postconditions() + postconditionsOrig() + m.cleanUpCertificates() +end + +function m.policyTableUpdateSuccess(pPTUpdateFunc) + local function expNotificationFunc() + m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) + :Times(3) + m.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) + end + m.policyTableUpdate(pPTUpdateFunc, expNotificationFunc) +end + +return m From e2dbbe57d8cfde0be85d302dd75206eb0451f88a Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 25 May 2018 19:45:02 +0300 Subject: [PATCH 435/681] Fix issues --- ...3_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua | 2 +- test_scripts/Security/GetSystemTime/common.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test_scripts/Security/013_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua b/test_scripts/Security/013_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua index 933a6174dd..1e383799fe 100644 --- a/test_scripts/Security/013_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua +++ b/test_scripts/Security/013_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua @@ -1,4 +1,4 @@ -s--------------------------------------------------------------------------------------------------- +--------------------------------------------------------------------------------------------------- -- Issues: -- https://github.com/smartdevicelink/sdl_core/issues/2190 -- https://github.com/smartdevicelink/sdl_core/issues/2191 diff --git a/test_scripts/Security/GetSystemTime/common.lua b/test_scripts/Security/GetSystemTime/common.lua index 8508ee1f5c..13b4421d4e 100644 --- a/test_scripts/Security/GetSystemTime/common.lua +++ b/test_scripts/Security/GetSystemTime/common.lua @@ -129,7 +129,7 @@ m.postconditions = common.postconditions local preconditionsOrig = m.preconditions function m.preconditions() preconditionsOrig() - common.initSDLCertificates("./files/Security/client_credential.pem", false) + common.initSDLCertificates("./files/Security/GetSystemTime_certificates/client_credential.pem", false) end return m From 799c82cf2a18d6ebf9bcf46f7742e47e3a791e4a Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 25 May 2018 20:36:53 +0300 Subject: [PATCH 436/681] Move scripts --- test_scripts/Security/DTLS/common.lua | 2 +- test_scripts/Security/GetSystemTime/common.lua | 2 +- .../001_Navi_Predefined_cert_valid_SUCCESS.lua | 3 +-- ...002_Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua | 2 +- .../003_Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua | 2 +- .../004_Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua | 2 +- ...005_Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua | 2 +- .../006_Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua | 2 +- .../007_Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua | 2 +- .../008_Non-Navi_Predefined_cert_valid_SUCCESS.lua | 3 +-- ...Non-Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua | 2 +- ..._Non-Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua | 2 +- ..._Non-Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua | 2 +- ...Non-Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua | 2 +- ..._Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua | 2 +- ..._Non-Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua | 2 +- test_scripts/Security/{ => SSLHandshakeFlow}/common.lua | 0 17 files changed, 16 insertions(+), 18 deletions(-) rename test_scripts/Security/{ => SSLHandshakeFlow}/001_Navi_Predefined_cert_valid_SUCCESS.lua (93%) rename test_scripts/Security/{ => SSLHandshakeFlow}/002_Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua (96%) rename test_scripts/Security/{ => SSLHandshakeFlow}/003_Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua (95%) rename test_scripts/Security/{ => SSLHandshakeFlow}/004_Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua (96%) rename test_scripts/Security/{ => SSLHandshakeFlow}/005_Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua (96%) rename test_scripts/Security/{ => SSLHandshakeFlow}/006_Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua (95%) rename test_scripts/Security/{ => SSLHandshakeFlow}/007_Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua (96%) rename test_scripts/Security/{ => SSLHandshakeFlow}/008_Non-Navi_Predefined_cert_valid_SUCCESS.lua (93%) rename test_scripts/Security/{ => SSLHandshakeFlow}/009_Non-Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua (96%) rename test_scripts/Security/{ => SSLHandshakeFlow}/010_Non-Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua (95%) rename test_scripts/Security/{ => SSLHandshakeFlow}/011_Non-Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua (96%) rename test_scripts/Security/{ => SSLHandshakeFlow}/012_Non-Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua (96%) rename test_scripts/Security/{ => SSLHandshakeFlow}/013_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua (95%) rename test_scripts/Security/{ => SSLHandshakeFlow}/014_Non-Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua (96%) rename test_scripts/Security/{ => SSLHandshakeFlow}/common.lua (100%) diff --git a/test_scripts/Security/DTLS/common.lua b/test_scripts/Security/DTLS/common.lua index 3a52ff7cbb..fbf4ce0d3c 100644 --- a/test_scripts/Security/DTLS/common.lua +++ b/test_scripts/Security/DTLS/common.lua @@ -13,7 +13,7 @@ local security = require("user_modules/sequences/security") local utils = require("user_modules/utils") local json = require("modules/json") local constants = require('protocol_handler/ford_protocol_constants') -local common = require("test_scripts/Security/common") +local common = require("test_scripts/Security/SSLHandshakeFlow/common") constants.FRAME_SIZE["P9"] = 131084 -- add unsupported SDL protocol version --[[ Module ]] diff --git a/test_scripts/Security/GetSystemTime/common.lua b/test_scripts/Security/GetSystemTime/common.lua index 13b4421d4e..c740341cdf 100644 --- a/test_scripts/Security/GetSystemTime/common.lua +++ b/test_scripts/Security/GetSystemTime/common.lua @@ -7,7 +7,7 @@ local security = require("user_modules/sequences/security") local utils = require("user_modules/utils") local test = require("user_modules/dummy_connecttest") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local common = require("test_scripts/Security/common") +local common = require("test_scripts/Security/SSLHandshakeFlow/common") --[[ General configuration parameters ]] config.serverCertificatePath = "./files/Security/GetSystemTime_certificates/spt_credential.pem" diff --git a/test_scripts/Security/001_Navi_Predefined_cert_valid_SUCCESS.lua b/test_scripts/Security/SSLHandshakeFlow/001_Navi_Predefined_cert_valid_SUCCESS.lua similarity index 93% rename from test_scripts/Security/001_Navi_Predefined_cert_valid_SUCCESS.lua rename to test_scripts/Security/SSLHandshakeFlow/001_Navi_Predefined_cert_valid_SUCCESS.lua index 7279654541..7d587385f5 100644 --- a/test_scripts/Security/001_Navi_Predefined_cert_valid_SUCCESS.lua +++ b/test_scripts/Security/SSLHandshakeFlow/001_Navi_Predefined_cert_valid_SUCCESS.lua @@ -5,7 +5,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require("test_scripts/Security/common") +local common = require("test_scripts/Security/SSLHandshakeFlow/common") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -28,7 +28,6 @@ end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Clean-up certificates", common.cleanUpCertificates) runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential.pem" }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Security/002_Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua b/test_scripts/Security/SSLHandshakeFlow/002_Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua similarity index 96% rename from test_scripts/Security/002_Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua rename to test_scripts/Security/SSLHandshakeFlow/002_Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua index c6afb6d17c..9816d4bd61 100644 --- a/test_scripts/Security/002_Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua +++ b/test_scripts/Security/SSLHandshakeFlow/002_Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua @@ -5,7 +5,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require("test_scripts/Security/common") +local common = require("test_scripts/Security/SSLHandshakeFlow/common") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Security/003_Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua b/test_scripts/Security/SSLHandshakeFlow/003_Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua similarity index 95% rename from test_scripts/Security/003_Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua rename to test_scripts/Security/SSLHandshakeFlow/003_Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua index 748911c467..4d168b0f70 100644 --- a/test_scripts/Security/003_Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua +++ b/test_scripts/Security/SSLHandshakeFlow/003_Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua @@ -5,7 +5,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require("test_scripts/Security/common") +local common = require("test_scripts/Security/SSLHandshakeFlow/common") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Security/004_Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua b/test_scripts/Security/SSLHandshakeFlow/004_Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua similarity index 96% rename from test_scripts/Security/004_Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua rename to test_scripts/Security/SSLHandshakeFlow/004_Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua index a6e1757902..170cb1f6f1 100644 --- a/test_scripts/Security/004_Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua +++ b/test_scripts/Security/SSLHandshakeFlow/004_Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua @@ -5,7 +5,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require("test_scripts/Security/common") +local common = require("test_scripts/Security/SSLHandshakeFlow/common") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Security/005_Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua b/test_scripts/Security/SSLHandshakeFlow/005_Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua similarity index 96% rename from test_scripts/Security/005_Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua rename to test_scripts/Security/SSLHandshakeFlow/005_Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua index 22993b5f82..b8e28b1e3b 100644 --- a/test_scripts/Security/005_Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua +++ b/test_scripts/Security/SSLHandshakeFlow/005_Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua @@ -5,7 +5,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require("test_scripts/Security/common") +local common = require("test_scripts/Security/SSLHandshakeFlow/common") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Security/006_Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua b/test_scripts/Security/SSLHandshakeFlow/006_Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua similarity index 95% rename from test_scripts/Security/006_Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua rename to test_scripts/Security/SSLHandshakeFlow/006_Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua index 5ea4fc1445..9c00473be4 100644 --- a/test_scripts/Security/006_Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua +++ b/test_scripts/Security/SSLHandshakeFlow/006_Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua @@ -5,7 +5,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require("test_scripts/Security/common") +local common = require("test_scripts/Security/SSLHandshakeFlow/common") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Security/007_Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua b/test_scripts/Security/SSLHandshakeFlow/007_Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua similarity index 96% rename from test_scripts/Security/007_Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua rename to test_scripts/Security/SSLHandshakeFlow/007_Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua index 272f4acbc2..03c426082e 100644 --- a/test_scripts/Security/007_Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua +++ b/test_scripts/Security/SSLHandshakeFlow/007_Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua @@ -5,7 +5,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require("test_scripts/Security/common") +local common = require("test_scripts/Security/SSLHandshakeFlow/common") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Security/008_Non-Navi_Predefined_cert_valid_SUCCESS.lua b/test_scripts/Security/SSLHandshakeFlow/008_Non-Navi_Predefined_cert_valid_SUCCESS.lua similarity index 93% rename from test_scripts/Security/008_Non-Navi_Predefined_cert_valid_SUCCESS.lua rename to test_scripts/Security/SSLHandshakeFlow/008_Non-Navi_Predefined_cert_valid_SUCCESS.lua index 5c0cbe5985..64c3c1b9dd 100644 --- a/test_scripts/Security/008_Non-Navi_Predefined_cert_valid_SUCCESS.lua +++ b/test_scripts/Security/SSLHandshakeFlow/008_Non-Navi_Predefined_cert_valid_SUCCESS.lua @@ -5,7 +5,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require("test_scripts/Security/common") +local common = require("test_scripts/Security/SSLHandshakeFlow/common") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -28,7 +28,6 @@ end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Clean-up certificates", common.cleanUpCertificates) runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential.pem" }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) diff --git a/test_scripts/Security/009_Non-Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua b/test_scripts/Security/SSLHandshakeFlow/009_Non-Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua similarity index 96% rename from test_scripts/Security/009_Non-Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua rename to test_scripts/Security/SSLHandshakeFlow/009_Non-Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua index 523569aa2e..76961a8ee3 100644 --- a/test_scripts/Security/009_Non-Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua +++ b/test_scripts/Security/SSLHandshakeFlow/009_Non-Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua @@ -5,7 +5,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require("test_scripts/Security/common") +local common = require("test_scripts/Security/SSLHandshakeFlow/common") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Security/010_Non-Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua b/test_scripts/Security/SSLHandshakeFlow/010_Non-Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua similarity index 95% rename from test_scripts/Security/010_Non-Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua rename to test_scripts/Security/SSLHandshakeFlow/010_Non-Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua index 7ea8a63cb0..ce788a408e 100644 --- a/test_scripts/Security/010_Non-Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua +++ b/test_scripts/Security/SSLHandshakeFlow/010_Non-Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua @@ -5,7 +5,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require("test_scripts/Security/common") +local common = require("test_scripts/Security/SSLHandshakeFlow/common") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Security/011_Non-Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua b/test_scripts/Security/SSLHandshakeFlow/011_Non-Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua similarity index 96% rename from test_scripts/Security/011_Non-Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua rename to test_scripts/Security/SSLHandshakeFlow/011_Non-Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua index 1dc528182d..8fe03a1046 100644 --- a/test_scripts/Security/011_Non-Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua +++ b/test_scripts/Security/SSLHandshakeFlow/011_Non-Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua @@ -5,7 +5,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require("test_scripts/Security/common") +local common = require("test_scripts/Security/SSLHandshakeFlow/common") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Security/012_Non-Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua b/test_scripts/Security/SSLHandshakeFlow/012_Non-Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua similarity index 96% rename from test_scripts/Security/012_Non-Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua rename to test_scripts/Security/SSLHandshakeFlow/012_Non-Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua index 4f13fd1bd8..ee0d56133f 100644 --- a/test_scripts/Security/012_Non-Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua +++ b/test_scripts/Security/SSLHandshakeFlow/012_Non-Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua @@ -5,7 +5,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require("test_scripts/Security/common") +local common = require("test_scripts/Security/SSLHandshakeFlow/common") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Security/013_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua b/test_scripts/Security/SSLHandshakeFlow/013_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua similarity index 95% rename from test_scripts/Security/013_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua rename to test_scripts/Security/SSLHandshakeFlow/013_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua index 1e383799fe..122a42326e 100644 --- a/test_scripts/Security/013_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua +++ b/test_scripts/Security/SSLHandshakeFlow/013_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua @@ -5,7 +5,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require("test_scripts/Security/common") +local common = require("test_scripts/Security/SSLHandshakeFlow/common") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Security/014_Non-Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua b/test_scripts/Security/SSLHandshakeFlow/014_Non-Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua similarity index 96% rename from test_scripts/Security/014_Non-Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua rename to test_scripts/Security/SSLHandshakeFlow/014_Non-Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua index 8964b61417..c0cb3b2992 100644 --- a/test_scripts/Security/014_Non-Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua +++ b/test_scripts/Security/SSLHandshakeFlow/014_Non-Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua @@ -5,7 +5,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require("test_scripts/Security/common") +local common = require("test_scripts/Security/SSLHandshakeFlow/common") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Security/common.lua b/test_scripts/Security/SSLHandshakeFlow/common.lua similarity index 100% rename from test_scripts/Security/common.lua rename to test_scripts/Security/SSLHandshakeFlow/common.lua From 781948dfa16e8b55b554b44d3fe682f1e6df9cc9 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 29 May 2018 13:13:17 +0300 Subject: [PATCH 437/681] Add new scripts on PTU start --- ...edefined_cert_valid_PTU_is_not_started.lua | 41 +++++++++++++++++++ ...edefined_cert_valid_PTU_is_not_started.lua | 41 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 test_scripts/Security/SSLHandshakeFlow/015_Navi-Predefined_cert_valid_PTU_is_not_started.lua create mode 100644 test_scripts/Security/SSLHandshakeFlow/016_Non-Navi-Predefined_cert_valid_PTU_is_not_started.lua diff --git a/test_scripts/Security/SSLHandshakeFlow/015_Navi-Predefined_cert_valid_PTU_is_not_started.lua b/test_scripts/Security/SSLHandshakeFlow/015_Navi-Predefined_cert_valid_PTU_is_not_started.lua new file mode 100644 index 0000000000..a4bedae038 --- /dev/null +++ b/test_scripts/Security/SSLHandshakeFlow/015_Navi-Predefined_cert_valid_PTU_is_not_started.lua @@ -0,0 +1,41 @@ +--------------------------------------------------------------------------------------------------- +-- Issues: +-- https://github.com/smartdevicelink/sdl_core/issues/2190 +-- https://github.com/smartdevicelink/sdl_core/issues/2191 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/SSLHandshakeFlow/common") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "NAVIGATION" } + +local function unregisterApp() + local cid = common.getMobileSession():SendRPC("UnregisterAppInterface", {}) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppUnregistered") +end + +local function registerApp() + local cid = common.getMobileSession():SendRPC("RegisterAppInterface", common.getConfigAppParams()) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered") + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential.pem" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Disconnect App", unregisterApp) +runner.Step("Connect App PTU is not started", registerApp) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) diff --git a/test_scripts/Security/SSLHandshakeFlow/016_Non-Navi-Predefined_cert_valid_PTU_is_not_started.lua b/test_scripts/Security/SSLHandshakeFlow/016_Non-Navi-Predefined_cert_valid_PTU_is_not_started.lua new file mode 100644 index 0000000000..634c460208 --- /dev/null +++ b/test_scripts/Security/SSLHandshakeFlow/016_Non-Navi-Predefined_cert_valid_PTU_is_not_started.lua @@ -0,0 +1,41 @@ +--------------------------------------------------------------------------------------------------- +-- Issues: +-- https://github.com/smartdevicelink/sdl_core/issues/2190 +-- https://github.com/smartdevicelink/sdl_core/issues/2191 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/SSLHandshakeFlow/common") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +local function unregisterApp() + local cid = common.getMobileSession():SendRPC("UnregisterAppInterface", {}) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppUnregistered") +end + +local function registerApp() + local cid = common.getMobileSession():SendRPC("RegisterAppInterface", common.getConfigAppParams()) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered") + common.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential.pem" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Disconnect App", unregisterApp) +runner.Step("Connect App PTU is not started", registerApp) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) From 1209635280e52dcce62f5c76a47c4d537a9e7732 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 29 May 2018 18:53:02 +0300 Subject: [PATCH 438/681] Adopt scripts to EXTERNAL_PROPRIETARY flow Refactoring --- .../Security/SSLHandshakeFlow/common.lua | 17 ++- user_modules/sequences/actions.lua | 134 ++++++++++++------ 2 files changed, 103 insertions(+), 48 deletions(-) diff --git a/test_scripts/Security/SSLHandshakeFlow/common.lua b/test_scripts/Security/SSLHandshakeFlow/common.lua index 2691821a68..5cf228d63d 100644 --- a/test_scripts/Security/SSLHandshakeFlow/common.lua +++ b/test_scripts/Security/SSLHandshakeFlow/common.lua @@ -174,12 +174,21 @@ end function m.policyTableUpdateSuccess(pPTUpdateFunc) local function expNotificationFunc() - m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", - { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) - :Times(3) + m.getHMIConnection():ExpectRequest("BasicCommunication.DecryptCertificate") + :Do(function(_, d) + m.getHMIConnection():SendResponse(d.id, d.method, "SUCCESS", { }) + end) + :Times(AnyNumber()) m.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) end - m.policyTableUpdate(pPTUpdateFunc, expNotificationFunc) + m.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") + :Do(function(e, d) + if e.occurences == 1 then + m.getHMIConnection():SendResponse(d.id, d.method, "SUCCESS", { }) + m.setPTUTable(utils.jsonFileToTable(d.params.file)) + m.policyTableUpdate(pPTUpdateFunc, expNotificationFunc) + end + end) end return m diff --git a/user_modules/sequences/actions.lua b/user_modules/sequences/actions.lua index cf66229ee0..51c0c4cd15 100644 --- a/user_modules/sequences/actions.lua +++ b/user_modules/sequences/actions.lua @@ -68,17 +68,14 @@ end function m.policyTableUpdate(pPTUpdateFunc, pExpNotificationFunc) if pExpNotificationFunc then pExpNotificationFunc() - else - test.hmiConnection:ExpectNotification("SDL.OnStatusUpdate", { status = "UP_TO_DATE" }) - test.hmiConnection:ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) end local ptsFileName = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") local ptuFileName = os.tmpname() - local requestId = test.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - test.hmiConnection:ExpectResponse(requestId) + local requestId = m.getHMIConnection():SendRequest("SDL.GetURLS", { service = 7 }) + m.getHMIConnection():ExpectResponse(requestId) :Do(function() - test.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + m.getHMIConnection():SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = ptsFileName }) getPTUFromPTS(ptuTable) for i = 1, m.getAppsCount() do @@ -90,21 +87,24 @@ function m.policyTableUpdate(pPTUpdateFunc, pExpNotificationFunc) utils.tableToJsonFile(ptuTable, ptuFileName) local event = events.Event() event.matches = function(e1, e2) return e1 == e2 end - EXPECT_EVENT(event, "PTU event") + m.getHMIConnection():ExpectEvent(event, "PTU event") for id = 1, m.getAppsCount() do - local session = m.getMobileSession(id) - session:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + m.getMobileSession(id):ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) :Do(function() + if not pExpNotificationFunc then + m.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) + m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate", { status = "UP_TO_DATE" }) + end utils.cprint(35, "App ".. id .. " was used for PTU") - RAISE_EVENT(event, event, "PTU event") - local corIdSystemRequest = session:SendRPC("SystemRequest", - { requestType = "PROPRIETARY" }, ptuFileName) - EXPECT_HMICALL("BasicCommunication.SystemRequest") + m.getHMIConnection():RaiseEvent(event, "PTU event") + local corIdSystemRequest = m.getMobileSession(id):SendRPC("SystemRequest", { + requestType = "PROPRIETARY" }, ptuFileName) + m.getHMIConnection():ExpectRequest("BasicCommunication.SystemRequest") :Do(function(_, d3) - test.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) - test.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = d3.params.fileName }) + m.getHMIConnection():SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) + m.getHMIConnection():SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = d3.params.fileName }) end) - session:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) + m.getMobileSession(id):ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) :Do(function() os.remove(ptuFileName) end) end) :Times(AtMost(1)) @@ -154,8 +154,8 @@ end --]] function m.activateApp(pAppId) if not pAppId then pAppId = 1 end - local requestId = test.hmiConnection:SendRequest("SDL.ActivateApp", { appID = m.getHMIAppId(pAppId) }) - test.hmiConnection:ExpectResponse(requestId) + local requestId = m.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = m.getHMIAppId(pAppId) }) + m.getHMIConnection():ExpectResponse(requestId) m.getMobileSession(pAppId):ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) utils.wait() @@ -201,27 +201,25 @@ end --]] function m.registerApp(pAppId) if not pAppId then pAppId = 1 end - local mobSession = m.getMobileSession(pAppId) - mobSession:StartService(7) + m.getMobileSession(pAppId):StartService(7) :Do(function() - local corId = mobSession:SendRPC("RegisterAppInterface", m.getConfigAppParams(pAppId)) - test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", + local corId = m.getMobileSession(pAppId):SendRPC("RegisterAppInterface", m.getConfigAppParams(pAppId)) + m.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", { application = { appName = m.getConfigAppParams(pAppId).appName } }) :Do(function(_, d1) - hmiAppIds[m.getConfigAppParams(pAppId).appID] = d1.params.application.appID - test.hmiConnection:ExpectNotification("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) - :Times(2) - test.hmiConnection:ExpectRequest("BasicCommunication.PolicyUpdate") + m.setHMIAppId(d1.params.application.appID, pAppId) + m.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") :Do(function(_, d2) - test.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) + m.getHMIConnection():SendResponse(d2.id, d2.method, "SUCCESS", { }) ptuTable = utils.jsonFileToTable(d2.params.file) end) end) - mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + m.getMobileSession(pAppId):ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() - mobSession:ExpectNotification("OnHMIStatus", + m.getMobileSession(pAppId):ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - mobSession:ExpectNotification("OnPermissionsChange") + m.getMobileSession(pAppId):ExpectNotification("OnPermissionsChange") + :Times(AnyNumber()) end) end) end @@ -233,20 +231,19 @@ end --]] function m.registerAppWOPTU(pAppId) if not pAppId then pAppId = 1 end - local mobSession = m.getMobileSession(pAppId) - mobSession:StartService(7) + m.getMobileSession(pAppId):StartService(7) :Do(function() - local corId = mobSession:SendRPC("RegisterAppInterface", m.getConfigAppParams(pAppId)) - test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", + local corId = m.getMobileSession(pAppId):SendRPC("RegisterAppInterface", m.getConfigAppParams(pAppId)) + m.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", { application = { appName = m.getConfigAppParams(pAppId).appName } }) :Do(function(_, d1) hmiAppIds[m.getConfigAppParams(pAppId).appID] = d1.params.application.appID end) - mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + m.getMobileSession(pAppId):ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() - mobSession:ExpectNotification("OnHMIStatus", + m.getMobileSession(pAppId):ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - mobSession:ExpectNotification("OnPermissionsChange") + m.getMobileSession(pAppId):ExpectNotification("OnPermissionsChange") end) end) end @@ -272,12 +269,12 @@ function m.start(pHMIParams) :Do(function() utils.cprint(35, "Mobile connected") allowSDL(test) - RAISE_EVENT(event, event) + m.getHMIConnection():RaiseEvent(event, event) end) end) end) end) - return EXPECT_EVENT(event, "Start event") + return m.getHMIConnection():ExpectEvent(event, "Start event") end --[[ @ExpectRequest: register expectation for request on HMI connection @@ -376,6 +373,36 @@ function test.hmiConnection:ExpectResponse(pId, ...) return ret end +function test.hmiConnection:RaiseEvent(pEvent, pEventName) + if pEventName == nil then pEventName = "noname" end + reporter.AddMessage(debug.getinfo(1, "n").name, pEventName) + event_dispatcher:RaiseEvent(self, pEvent) +end + +function test.hmiConnection:ExpectEvent(pEvent, pEventName) + if pEventName == nil then pEventName = "noname" end + local ret = expectations.Expectation(pEventName, self) + ret.event = pEvent + event_dispatcher:AddEvent(self, pEvent, ret) + test:AddExpectation(ret) + return ret +end + +function test.mobileConnection:RaiseEvent(pEvent, pEventName) + if pEventName == nil then pEventName = "noname" end + reporter.AddMessage(debug.getinfo(1, "n").name, pEventName) + event_dispatcher:RaiseEvent(self, pEvent) +end + +function test.mobileConnection:ExpectEvent(pEvent, pEventName) + if pEventName == nil then pEventName = "noname" end + local ret = expectations.Expectation(pEventName, self) + ret.event = pEvent + event_dispatcher:AddEvent(self, pEvent, ret) + test:AddExpectation(ret) + return ret +end + --[[ @getMobileConnection: return Mobile connection object --! @parameters: none --! @return: Mobile connection object @@ -432,15 +459,34 @@ end --[[ @getPathToFileInStorage: full path to file in storage folder --! @parameters: ---! @pFileName = file name ---! @pAppId = application number (1, 2, etc.) +--! @pFileName - file name +--! @pAppId - application number (1, 2, etc.) --! @return: path --]] function m.getPathToFileInStorage(pFileName, pAppId) if not pAppId then pAppId = 1 end - return commonPreconditions:GetPathToSDL() .. "storage/" - .. m.getConfigAppParams( pAppId ).appID .. "_" - .. utils.getDeviceMAC() .. "/" .. pFileName + return commonPreconditions:GetPathToSDL() .. "storage/" .. m.getConfigAppParams( pAppId ).appID .. "_" + .. utils.getDeviceMAC() .. "/" .. pFileName +end + +--[[ @setPTUTable: set PTU table that is used in Policy Table Update sequence +--! @parameters: +--! @pPTUTable - PTU table +--! @return: none +--]] +function m.setPTUTable(pPTUTable) + ptuTable = pPTUTable +end + +--[[ @setHMIAppId: set HMI application identifier +--! @parameters: +--! pHMIAppId - HMI application identifier +--! pAppId - application number (1, 2, etc.) +--! @return: none +--]] +function m.setHMIAppId(pHMIAppId, pAppId) + if not pAppId then pAppId = 1 end + hmiAppIds[m.getConfigAppParams(pAppId).appID] = pHMIAppId end return m From 7c6a4d2d674bddf2c3baa2934d2e7a686dc49e51 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 4 Jun 2018 01:50:48 +0300 Subject: [PATCH 439/681] Add additional script to check no impact of App Name on SSL Handshake --- .../017_App_Name_no_impact_SUCCESS.lua | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 test_scripts/Security/SSLHandshakeFlow/017_App_Name_no_impact_SUCCESS.lua diff --git a/test_scripts/Security/SSLHandshakeFlow/017_App_Name_no_impact_SUCCESS.lua b/test_scripts/Security/SSLHandshakeFlow/017_App_Name_no_impact_SUCCESS.lua new file mode 100644 index 0000000000..fc1b2c3129 --- /dev/null +++ b/test_scripts/Security/SSLHandshakeFlow/017_App_Name_no_impact_SUCCESS.lua @@ -0,0 +1,39 @@ +--------------------------------------------------------------------------------------------------- +-- Issues: +-- https://github.com/smartdevicelink/sdl_core/issues/1617 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/SSLHandshakeFlow/common") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appName = "Test Application" + +--[[ Local Variables ]] + +--[[ Local Functions ]] +local function startServiceProtectedACK() + local serviceId = 7 + common.getMobileSession():StartSecureService(serviceId) + common.getMobileSession():ExpectControlMessage(serviceId, { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true + }) + common.getMobileSession():ExpectHandshakeMessage() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential.pem" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("Switch RPC Service to Protected mode ACK", startServiceProtectedACK) +runner.Step("Activate App Protected", common.activateAppProtected) +runner.Step("AddCommand Protected", common.sendAddCommandProtected) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) From 2ffa338a0a98c4cfa65995c187dcc03a4f0e0da0 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 4 Jun 2018 01:51:15 +0300 Subject: [PATCH 440/681] Add complete test set for Security --- test_sets/security.txt | 49 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 test_sets/security.txt diff --git a/test_sets/security.txt b/test_sets/security.txt new file mode 100644 index 0000000000..4058923bad --- /dev/null +++ b/test_sets/security.txt @@ -0,0 +1,49 @@ +./test_scripts/Security/DTLS/001_StartRPC_service.lua +./test_scripts/Security/DTLS/002_Start_Audio_service.lua +./test_scripts/Security/DTLS/003_Start_Video_service.lua +./test_scripts/Security/DTLS/004_Processing_of_RPC.lua +./test_scripts/Security/DTLS/005_Ignore_malformed_packet.lua +./test_scripts/Security/DTLS/006_Ignore_unexpected_packet.lua +./test_scripts/Security/DTLS/007_Processing_multiple_frames.lua +./test_scripts/Security/GetSystemTime/001_GetSystemTime_is_sent.lua +./test_scripts/Security/GetSystemTime/002_GetSystemTime_is_not_sent.lua +./test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_expired.lua +./test_scripts/Security/GetSystemTime/004_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua +./test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua +./test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_sdl_cer_become_valid.lua +./test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua +./test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua +./test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua +./test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua +./test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua +./test_scripts/Security/GetSystemTime/015_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua +./test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua +./test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua +./test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/021_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua +./test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua +./test_scripts/Security/GetSystemTime/023_GetSystemTime_without_response_from_HMI.lua +./test_scripts/Security/GetSystemTime/024_GetSystemTime_with_response_from_HMI_in_9_sec.lua +./test_scripts/Security/GetSystemTime/025_GetSystemTime_is_sent_later.lua +./test_scripts/Security/SSLHandshakeFlow/001_Navi_Predefined_cert_valid_SUCCESS.lua +./test_scripts/Security/SSLHandshakeFlow/002_Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua +./test_scripts/Security/SSLHandshakeFlow/003_Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua +./test_scripts/Security/SSLHandshakeFlow/004_Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua +./test_scripts/Security/SSLHandshakeFlow/005_Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua +./test_scripts/Security/SSLHandshakeFlow/006_Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua +./test_scripts/Security/SSLHandshakeFlow/007_Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua +./test_scripts/Security/SSLHandshakeFlow/008_Non-Navi_Predefined_cert_valid_SUCCESS.lua +./test_scripts/Security/SSLHandshakeFlow/009_Non-Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua +./test_scripts/Security/SSLHandshakeFlow/010_Non-Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua +./test_scripts/Security/SSLHandshakeFlow/011_Non-Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua +./test_scripts/Security/SSLHandshakeFlow/012_Non-Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua +./test_scripts/Security/SSLHandshakeFlow/013_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua +./test_scripts/Security/SSLHandshakeFlow/014_Non-Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua +./test_scripts/Security/SSLHandshakeFlow/015_Navi-Predefined_cert_valid_PTU_is_not_started.lua +./test_scripts/Security/SSLHandshakeFlow/016_Non-Navi-Predefined_cert_valid_PTU_is_not_started.lua +./test_scripts/Security/SSLHandshakeFlow/017_App_Name_no_impact_SUCCESS.lua From 35f2857bc038c13fde73366667481a872c72c456 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 5 Jun 2018 15:09:13 +0300 Subject: [PATCH 441/681] Add additional script to check V5 SDL protocol --- .../018_V5_happy_path_SUCCESS.lua | 95 +++++++++++++++++++ .../Security/SSLHandshakeFlow/common.lua | 35 +++++++ user_modules/hmi_values.lua | 14 +++ 3 files changed, 144 insertions(+) create mode 100644 test_scripts/Security/SSLHandshakeFlow/018_V5_happy_path_SUCCESS.lua diff --git a/test_scripts/Security/SSLHandshakeFlow/018_V5_happy_path_SUCCESS.lua b/test_scripts/Security/SSLHandshakeFlow/018_V5_happy_path_SUCCESS.lua new file mode 100644 index 0000000000..590ba57748 --- /dev/null +++ b/test_scripts/Security/SSLHandshakeFlow/018_V5_happy_path_SUCCESS.lua @@ -0,0 +1,95 @@ +--------------------------------------------------------------------------------------------------- +-- Issues: https://github.com/smartdevicelink/sdl_core/issues/2142 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/Security/SSLHandshakeFlow/common") +local bson = require('bson4lua') +local constants = require("protocol_handler/ford_protocol_constants") +local utils = require("user_modules/utils") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.defaultProtocolVersion = 5 +constants.FRAME_SIZE.P5 = 131084 + +--[[ Local Variables ]] +local bsonType = { + DOUBLE = 0x01, + STRING = 0x02, + DOCUMENT = 0x03, + ARRAY = 0x04, + BOOLEAN = 0x08, + INT32 = 0x10, + INT64 = 0x12 +} + +--[[ Local Functions ]] +local function startServiceProtectedACK(pServiceId, pRequestPayload, pResponsePayload) + common.getMobileSession():StartSecureService(pServiceId, bson.to_bytes(pRequestPayload)) + common.getMobileSession():ExpectControlMessage(pServiceId, { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true + }) + :ValidIf(function(_, data) + local actPayload = bson.to_table(data.binaryData) + utils.printTable(actPayload) + return compareValues(pResponsePayload, actPayload, "binaryData") + end) + if pServiceId == 7 then + common.getMobileSession():ExpectHandshakeMessage() + elseif pServiceId == 11 then + common.getHMIConnection():ExpectRequest("Navigation.SetVideoConfig") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + end +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Init SDL certificates", common.initSDLCertificates, { "./files/Security/client_credential.pem" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("Switch RPC Service to Protected mode ACK", startServiceProtectedACK, { + constants.SERVICE_TYPE.RPC, + { + protocolVersion = { type = bsonType.STRING, value = "5.0.0" } + }, + { + hashId = { type = bsonType.INT32, value = 0 }, + mtu = { type = bsonType.INT64, value = 131072 }, + protocolVersion = { type = bsonType.STRING, value = "5.0.0" } + } +}) +runner.Step("Start Audio Service in Protected mode ACK", startServiceProtectedACK, { + constants.SERVICE_TYPE.PCM, + { + }, + { + mtu = { type = bsonType.INT64, value = 131072 } + } +}) +runner.Step("Start Video Service in Protected mode ACK", startServiceProtectedACK, { + constants.SERVICE_TYPE.VIDEO, + { + height = { type = bsonType.INT32, value = 350 }, + width = { type = bsonType.INT32, value = 800 }, + videoProtocol = { type = bsonType.STRING, value = "RAW" }, + videoCodec = { type = bsonType.STRING, value = "H264" }, + }, + { + mtu = { type = bsonType.INT64, value = 131072 }, + height = { type = bsonType.INT32, value = 350 }, + width = { type = bsonType.INT32, value = 800 }, + videoProtocol = { type = bsonType.STRING, value = "RAW" }, + videoCodec = { type = bsonType.STRING, value = "H264" }, + } +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL, clean-up certificates", common.postconditions) diff --git a/test_scripts/Security/SSLHandshakeFlow/common.lua b/test_scripts/Security/SSLHandshakeFlow/common.lua index 5cf228d63d..dd351d5819 100644 --- a/test_scripts/Security/SSLHandshakeFlow/common.lua +++ b/test_scripts/Security/SSLHandshakeFlow/common.lua @@ -8,6 +8,7 @@ local utils = require("user_modules/utils") local test = require("user_modules/dummy_connecttest") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local constants = require("protocol_handler/ford_protocol_constants") --[[ General configuration parameters ]] config.SecurityProtocol = "DTLS" @@ -191,4 +192,38 @@ function m.policyTableUpdateSuccess(pPTUpdateFunc) end) end + +local function registerStartSecureServiceFunc(pMobSession) + function pMobSession.mobile_session_impl.control_services:StartSecureService(pServiceId, pPayload) + local msg = { + serviceType = pServiceId, + frameInfo = constants.FRAME_INFO.START_SERVICE, + sessionId = self.session.sessionId.get(), + encryption = true, + binaryData = pPayload + } + self:Send(msg) + end + function pMobSession.mobile_session_impl:StartSecureService(pServiceId, pPayload) + if not self.isSecuredSession then + self.security:registerSessionSecurity() + self.security:prepareToHandshake() + end + return self.control_services:StartSecureService(pServiceId, pPayload) + end + function pMobSession:StartSecureService(pServiceId, pPayload) + return self.mobile_session_impl:StartSecureService(pServiceId, pPayload) + end +end + +local origGetMobileSession = actions.getMobileSession +function actions.getMobileSession(pAppId) + if not pAppId then pAppId = 1 end + if not test.mobileSession[pAppId] then + local session = origGetMobileSession(pAppId) + registerStartSecureServiceFunc(session) + end + return origGetMobileSession(pAppId) +end + return m diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index 9c375a8bd1..35eda6d132 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -258,6 +258,20 @@ function module.getDefaultHMITable() }, phoneCapability = { dialNumberEnabled = true + }, + videoStreamingCapability = { + preferredResolution = { + resolutionWidth = 800, + resolutionHeight = 350 + }, + maxBitrate = 10000, + supportedFormats = { + { + protocol = "RAW", + codec = "H264" + } + }, + hapticSpatialDataSupported = false } } }, From f95449cb814ca484bab80dc8b0d1d37f491ef873 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 6 Jun 2018 11:27:30 +0300 Subject: [PATCH 442/681] Add possibility to skip test in case if BSON library is not available --- .../018_V5_happy_path_SUCCESS.lua | 8 +++++++- user_modules/script_runner.lua | 19 +++++++++++++++---- user_modules/utils.lua | 15 +++++++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/test_scripts/Security/SSLHandshakeFlow/018_V5_happy_path_SUCCESS.lua b/test_scripts/Security/SSLHandshakeFlow/018_V5_happy_path_SUCCESS.lua index 590ba57748..4c8c4a7b23 100644 --- a/test_scripts/Security/SSLHandshakeFlow/018_V5_happy_path_SUCCESS.lua +++ b/test_scripts/Security/SSLHandshakeFlow/018_V5_happy_path_SUCCESS.lua @@ -4,9 +4,15 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require("test_scripts/Security/SSLHandshakeFlow/common") -local bson = require('bson4lua') local constants = require("protocol_handler/ford_protocol_constants") local utils = require("user_modules/utils") +local bson + +if utils.isFileExist("modules/libbson4lua.so") then + bson = require('bson4lua') +else + runner.skipTest("'bson4lua' library is not available in ATF") +end --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/user_modules/script_runner.lua b/user_modules/script_runner.lua index 0d29900b4d..5f51ff4718 100644 --- a/user_modules/script_runner.lua +++ b/user_modules/script_runner.lua @@ -5,6 +5,8 @@ local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local isInitialStep = true local idx = 1 +local skipReason = nil + local runner = {} runner.testSettings = testSettings @@ -109,12 +111,14 @@ local function isTestApplicable(testApplicableSdlSettings) end local function skipTest(reason) + Test.caseTitles[idx] = nil + Test.caseTitles[idx] = {} runner.Title("TEST SKIPPED") runner.Step( "Skip reason", - function(skipReason, self) - commonFunctions:userPrint(consts.color.cyan, skipReason) - self:SkipTest() + function(skipRsn) + commonFunctions:userPrint(consts.color.cyan, skipRsn) + Test:SkipTest() end, { reason } ) @@ -150,7 +154,10 @@ function runner.Step(testStepName, testStepImplFunction, paramsTable) local filler = "=" if isInitialStep then printTestInformation() - if not isTestApplicable(runner.testSettings.restrictions.sdlBuildOptions) then + if skipReason ~= nil then + isInitialStep = false + skipTest(skipReason) + elseif not isTestApplicable(runner.testSettings.restrictions.sdlBuildOptions) then local message = "Test is incompatible with current build configuration of SDL:\n" .. commonFunctions:convertTableToString(Test.sdlBuildOptions, 1) .. "\n\nTest is possible to run with SDL that was built with next build options:\n" .. @@ -168,4 +175,8 @@ function runner.Step(testStepName, testStepImplFunction, paramsTable) idx = idx + 1 end +function runner.skipTest(message) + skipReason = message +end + return runner diff --git a/user_modules/utils.lua b/user_modules/utils.lua index 3184ab0b9e..6bb7f34dd7 100644 --- a/user_modules/utils.lua +++ b/user_modules/utils.lua @@ -203,4 +203,19 @@ function m.printTable(pTbl) m.cprintTable(39, pTbl) end +--[[ @isFileExist: check if file or directory exists +--! @parameters: +--! pFile - path to file or directory +--! @return: true - in case if file exists, otherwise - false +--]] +function m.isFileExist(pFile) + local file = io.open(pFile, "r") + if file == nil then + return false + else + file:close() + return true + end +end + return m From ced571eb3d58c9b5e443871fe581097b4a2536e2 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 19 Jun 2018 18:10:44 +0300 Subject: [PATCH 443/681] Update 083 policy script regarding data in messages section --- .../083_ATF_PTU_UTF8_Encoding_Check_HTTP.lua | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test_scripts/Policies/build_options/083_ATF_PTU_UTF8_Encoding_Check_HTTP.lua b/test_scripts/Policies/build_options/083_ATF_PTU_UTF8_Encoding_Check_HTTP.lua index fd60420e68..3031dce889 100644 --- a/test_scripts/Policies/build_options/083_ATF_PTU_UTF8_Encoding_Check_HTTP.lua +++ b/test_scripts/Policies/build_options/083_ATF_PTU_UTF8_Encoding_Check_HTTP.lua @@ -51,11 +51,16 @@ local function update_ptu() ptu.policy_table.app_policies["0000001"] = { keep_context = false, steal_focus = false, priority = "NONE", default_hmi = "NONE" } ptu.policy_table.app_policies["0000001"]["groups"] = { "Base-4", "Base-6" } ptu.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null - --TODO: Update part in case to check UTF-8 parameters. -- updating specific parameters ptu.policy_table.consumer_friendly_messages.messages = { ["AppPermissions"] = { ["languages"] = { ["en-us"] = { }}}, ["AppPermissionsHelp"] = { ["languages"] = { ["en-us"] = { }}}} + ptu.policy_table.consumer_friendly_messages.messages["AppPermissions"]["languages"]["en-us"].tts = "表示您åŒæ„_1" + ptu.policy_table.consumer_friendly_messages.messages["AppPermissions"]["languages"]["en-us"].label = "Метка" + ptu.policy_table.consumer_friendly_messages.messages["AppPermissions"]["languages"]["en-us"].line1 = "LINE1" + ptu.policy_table.consumer_friendly_messages.messages["AppPermissions"]["languages"]["en-us"].line2 = "LINE2" + ptu.policy_table.consumer_friendly_messages.messages["AppPermissions"]["languages"]["en-us"].textBody = "TEXTBODY" + ptu.policy_table.consumer_friendly_messages.messages["AppPermissionsHelp"]["languages"]["en-us"].tts = "授權請求_2" end local function timestamp() @@ -184,13 +189,13 @@ end function Test:ValidatePTS() if (ptu == nil) then - update_ptu() self:FailTestCase("ptu is empty. Preloaded file will be used") else if ptu.policy_table.consumer_friendly_messages.messages then self:FailTestCase("Expected absence of 'consumer_friendly_messages.messages' section in PTS") end end + update_ptu() end function Test:StorePTSInFile() @@ -223,8 +228,7 @@ for i = 1, 1 do end function Test:TestStep_ValidateResult() - --TODO: Update part in case to check UTF-8 parameters. - local r_expected = { "1||||||en-us|AppPermissions", "2||||||en-us|AppPermissionsHelp" } + local r_expected = { "1|表示您åŒæ„_1|Метка|LINE1|LINE2|TEXTBODY|en-us|AppPermissions", "2|授權請求_2|||||en-us|AppPermissionsHelp" } local query = "select id, tts, label, line1, line2, textBody, language_code, message_type_name from message" local r_actual = execute_sqlite_query(db_file, query) if not is_table_equal(r_expected, r_actual) then From 4e57be98dc6dc49720d9f90ca432ff49b411cd72 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 20 Jun 2018 07:55:56 +0300 Subject: [PATCH 444/681] Fix parameters in RaiseEvent() function --- user_modules/sequences/actions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_modules/sequences/actions.lua b/user_modules/sequences/actions.lua index 51c0c4cd15..df68d17476 100644 --- a/user_modules/sequences/actions.lua +++ b/user_modules/sequences/actions.lua @@ -269,7 +269,7 @@ function m.start(pHMIParams) :Do(function() utils.cprint(35, "Mobile connected") allowSDL(test) - m.getHMIConnection():RaiseEvent(event, event) + m.getHMIConnection():RaiseEvent(event, "Start event") end) end) end) From 2c3f87b8f5daccc9ca266f35127bc1d22cc3b8e2 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 20 Jun 2018 08:08:54 +0300 Subject: [PATCH 445/681] Add missing 'events' module --- test_scripts/API/VehicleData/commonVehicleData.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/API/VehicleData/commonVehicleData.lua b/test_scripts/API/VehicleData/commonVehicleData.lua index 7b82d0d301..72e1e4221c 100644 --- a/test_scripts/API/VehicleData/commonVehicleData.lua +++ b/test_scripts/API/VehicleData/commonVehicleData.lua @@ -8,7 +8,7 @@ config.defaultProtocolVersion = 2 --[[ Required Shared libraries ]] local mobile_session = require("mobile_session") local json = require("modules/json") - +local events = require("events") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") From fc429d65a49003761225d60c24810c994fff6336 Mon Sep 17 00:00:00 2001 From: ZhdanovP Date: Wed, 20 Jun 2018 15:45:31 +0300 Subject: [PATCH 446/681] Fix for 057 test script according to 1246 issue --- .../build_options/057_ATF_PTS_Define_URL_to_send_PTS_HTTP.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_scripts/Policies/build_options/057_ATF_PTS_Define_URL_to_send_PTS_HTTP.lua b/test_scripts/Policies/build_options/057_ATF_PTS_Define_URL_to_send_PTS_HTTP.lua index 29985658b5..0818c35f22 100644 --- a/test_scripts/Policies/build_options/057_ATF_PTS_Define_URL_to_send_PTS_HTTP.lua +++ b/test_scripts/Policies/build_options/057_ATF_PTS_Define_URL_to_send_PTS_HTTP.lua @@ -196,7 +196,7 @@ function Test:RegisterApp_2() print("SDL->MOB2: OnSystemRequest, requestType: " .. data.payload.requestType) if(data.payload.requestType == "HTTP") then if(data.payload.url ~= nil) then - r_actual_app = 1 + r_actual_app = 2 r_actual_url = data.payload.url end end @@ -207,7 +207,7 @@ function Test:RegisterApp_2() print("SDL->MOB1: OnSystemRequest, requestType: " .. data.payload.requestType) if(data.payload.requestType == "HTTP") then if(data.payload.url ~= nil) then - r_actual_app = 2 + r_actual_app = 1 r_actual_url = data.payload.url end end From c66a5f607d70381d00abea43723abb4185a836e5 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 20 Jun 2018 16:14:53 +0300 Subject: [PATCH 447/681] Fix removing of symlinks --- test_scripts/Security/SSLHandshakeFlow/common.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/Security/SSLHandshakeFlow/common.lua b/test_scripts/Security/SSLHandshakeFlow/common.lua index dd351d5819..8c18777eef 100644 --- a/test_scripts/Security/SSLHandshakeFlow/common.lua +++ b/test_scripts/Security/SSLHandshakeFlow/common.lua @@ -156,7 +156,7 @@ end function m.cleanUpCertificates() local sdlBin = commonPreconditions:GetPathToSDL() - os.execute("cd " .. sdlBin .. " && find . -type l -exec rm -f {} \\;") + os.execute("cd " .. sdlBin .. " && find . -type l -not -name 'lib*' -exec rm -f {} \\;") os.execute("cd " .. sdlBin .. " && rm -rf *.pem") end From 1d234b5f60adf0d88299ba8e885cd723328a3ca1 Mon Sep 17 00:00:00 2001 From: Conlain Kelly Date: Wed, 20 Jun 2018 16:17:36 -0400 Subject: [PATCH 448/681] Add electronic park brake status to atf testing --- .../GetVehicleData/001_Success_flow.lua | 6 ++++-- ..._RPC_parameter_DISALLOWED_by_policies_flow.lua | 8 +++++--- .../OnVehicleData/001_Success_flow.lua | 10 ++++++++-- ...cationForUnsubsribedParameter_Ignored_flow.lua | 13 ++++++++++--- ...ParameterDisallowedByPolicies_Ignored_flow.lua | 15 ++++++++------- .../SubscribeVehicleData/001_Success_flow.lua | 9 +++++++-- ..._RPC_parameter_DISALLOWED_by_policies_flow.lua | 9 +++++++-- ...ter_already_subscribed_Result_IGNORED_flow.lua | 11 ++++++++++- .../UnsubscribeVehicleData/001_Success_flow.lua | 10 ++++++++-- ..._parameter_not_yet_subscribed_IGNORED_flow.lua | 7 ++++++- ...r_already_unsubscribed_Result_IGNORED_flow.lua | 14 ++++++++++++-- ...allowed_by_policies_Result_DISALLOWED_flow.lua | 9 +++++++-- .../API/VehicleData/commonVehicleData.lua | 1 + ..._SubscribeVehicleData_PositiveCase_SUCCESS.lua | 1 + ...nsubscribeVehicleData_PositiveCase_SUCCESS.lua | 1 + .../026_GetVehicleData_PositiveCase_SUCCESS.lua | 1 + 16 files changed, 96 insertions(+), 29 deletions(-) diff --git a/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua index ee90d4c76f..ef9b1bf93d 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua @@ -25,7 +25,8 @@ local rpc = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + electronicParkBrakeStatus = true } } @@ -48,7 +49,8 @@ local vehicleDataValues = { tpms = "SYSTEM_ACTIVE", pressure = 35.00 } - } + }, + electronicParkBrakeStatus = "CLOSED" } --[[ Local Functions ]] diff --git a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index 694b41001b..8cf862a447 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -26,7 +26,8 @@ local rpc = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + electronicParkBrakeStatus = true } } @@ -49,7 +50,8 @@ local vehicleDataValues = { tpms = "SYSTEM_ACTIVE", pressure = 35.00 } - } + }, + electronicParkBrakeStatus = "CLOSED" } --[[ Local Functions ]] @@ -57,7 +59,7 @@ local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["GetVehicleData"].parameters local newParams = {} for index, value in pairs(params) do - if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value)) then table.insert(newParams, value) end + if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value) or ("electronicParkBrakeStatus" == value)) then table.insert(newParams, value) end end tbl.policy_table.functional_groupings["Emergency-1"].rpcs["GetVehicleData"].parameters = newParams end diff --git a/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua index fa577bd8d2..6dc8bcf5a8 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua @@ -25,7 +25,8 @@ local rpc1 = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + electronicParkBrakeStatus = true } } @@ -50,7 +51,8 @@ local rpc2 = { tpms = "SYSTEM_ACTIVE", pressure = 35.00 } - } + }, + electronicParkBrakeStatus = "CLOSED" } } @@ -66,6 +68,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "SUCCESS" + }, + electronicParkBrakeStatus = { + dataType = "VEHICLEDATA_ELECTRONICPARKBRAKESTATUS", + resultCode = "SUCCESS" } } diff --git a/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua index 198e447a03..15bc9a058c 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua @@ -27,7 +27,8 @@ local rpc1 = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + electronicParkBrakeStatus = true } } @@ -52,7 +53,8 @@ local rpc2 = { tpms = "SYSTEM_ACTIVE", pressure = 35.00 } - } + }, + electronicParkBrakeStatus = "CLOSED" } } @@ -61,7 +63,8 @@ local rpc3 = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + electronicParkBrakeStatus = true } } @@ -77,6 +80,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "SUCCESS" + }, + electronicParkBrakeStatus = { + dataType = "VEHICLEDATA_ELECTRONICPARKBRAKESTATUS", + resultCode = "SUCCESS" } } diff --git a/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua index 5017412636..83b23b4c74 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua @@ -27,7 +27,8 @@ local rpc1 = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + electronicParkBrakeStatus = true } } @@ -68,6 +69,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "SUCCESS" + }, + electronicParkBrakeStatus = { + dataType = "VEHICLEDATA_ELECTRONICPARKBRAKESTATUS", + resultCode = "SUCCESS" } } @@ -76,7 +81,7 @@ local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["OnVehicleData"].parameters local newParams = {} for index, value in pairs(params) do - if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value)) then table.insert(newParams, value) end + if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value) or ("electronicParkBrakeStatus" == value)) then table.insert(newParams, value) end end tbl.policy_table.functional_groupings["Emergency-1"].rpcs["OnVehicleData"].parameters = newParams end @@ -111,8 +116,4 @@ runner.Step("Activate App", common.activateApp) runner.Title("Test") runner.Step("RPC " .. rpc1.name, processRPCSubscribeSuccess) -runner.Step("RAI 2nd app with PTU", common.registerAppWithPTU, {2, ptu_update_func}) -runner.Step("RPC " .. rpc2.name, checkNotificationIgnored) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) +runner.Step("RAI 2nd app with PTU", common.registerAppWithPTU, \ No newline at end of file diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua index 519fc629b6..0c3d334629 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua @@ -24,7 +24,8 @@ local rpc = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + electronicParkBrakeStatus = true } } @@ -40,7 +41,11 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "SUCCESS" - } + }, + electronicParkBrakeStatus = { + dataType = "VEHICLEDATA_ELECTRONICPARKBRAKESTATUS", + resultCode = "SUCCESS" + } } --[[ Local Functions ]] diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index d111e36b24..5915487658 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -25,7 +25,8 @@ local rpc = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + electronicParkBrakeStatus = true } } @@ -41,6 +42,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "DISALLOWED" + }, + electronicParkBrakeStatus = { + dataType = "VEHICLEDATA_ELECTRONICPARKBRAKESTATUS", + resultCode = "DISALLOWED" } } @@ -49,7 +54,7 @@ local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["SubscribeVehicleData"].parameters local newParams = {} for index, value in pairs(params) do - if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value)) then table.insert(newParams, value) end + if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value) or ("electronicParkBrakeStatus" == value)) then table.insert(newParams, value) end end tbl.policy_table.functional_groupings["Emergency-1"].rpcs["SubscribeVehicleData"].parameters = newParams end diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua index 8a0991c33b..a8d60029fc 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua @@ -24,7 +24,8 @@ local rpc = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + electronicParkBrakeStatus = true } } @@ -40,6 +41,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "SUCCESS" + }, + electronicParkBrakeStatus = { + dataType = "VEHICLEDATA_ELECTRONICPARKBRAKESTATUS", + resultCode = "SUCCESS" } } @@ -56,6 +61,10 @@ local vehicleDataResults2 = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "DATA_ALREADY_SUBSCRIBED" } + electronicParkBrakeStatus = { + dataType = "VEHICLEDATA_TIREPRESSURE", + resultCode = "DATA_ALREADY_SUBSCRIBED" + } } --[[ Local Functions ]] diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua index 184745f351..1f9519097e 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua @@ -25,7 +25,8 @@ local rpc_subscribe = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + electronicParkBrakeStatus = true } } @@ -34,7 +35,8 @@ local rpc_unsubscribe = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + electronicParkBrakeStatus = true } } @@ -50,6 +52,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "SUCCESS" + }, + electronicParkBrakeStatus = { + dataType = "VEHICLEDATA_ELECTRONICPARKBRAKESTATUS", + resultCode = "SUCCESS" } } diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua index 368c604206..343c4b3349 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua @@ -26,7 +26,8 @@ local rpc = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + electronicParkBrakeStatus = true } } @@ -42,6 +43,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "DATA_NOT_SUBSCRIBED" + }, + electronicParkBrakeStatus = { + dataType = "VEHICLEDATA_ELECTRONICPARKBRAKESTATUS", + resultCode = "DATA_NOT_SUBSCRIBED" } } diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua index 4b550f319b..2639ed547c 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua @@ -27,7 +27,8 @@ local rpc_subscribe = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + electronicParkBrakeStatus = true } } @@ -36,7 +37,8 @@ local rpc_unsubscribe = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + electronicParkBrakeStatus = true } } @@ -52,6 +54,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "SUCCESS" + }, + electronicParkBrakeStatus = { + dataType = "VEHICLEDATA_ELECTRONICPARKBRAKESTATUS", + resultCode = "SUCCESS" } } @@ -67,6 +73,10 @@ local vehicleDataResults2 = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "DATA_NOT_SUBSCRIBED" + }, + electronicParkBrakeStatus = { + dataType = "VEHICLEDATA_ELECTRONICPARKBRAKESTATUS", + resultCode = "DATA_NOT_SUBSCRIBED" } } diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua index 3144254c7c..d4bbe924d9 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua @@ -25,7 +25,8 @@ local rpc = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + electronicParkBrakeStatus = true } } @@ -41,6 +42,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "DISALLOWED" + }, + electronicParkBrakeStatus = { + dataType = "VEHICLEDATA_ELECTRONICPARKBRAKESTATUS", + resultCode = "DISALLOWED" } } @@ -49,7 +54,7 @@ local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["UnsubscribeVehicleData"].parameters local newParams = {} for index, value in pairs(params) do - if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value)) then table.insert(newParams, value) end + if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value) or ("electronicParkBrakeStatus" == value)) then table.insert(newParams, value) end end tbl.policy_table.functional_groupings["Emergency-1"].rpcs["UnsubscribeVehicleData"].parameters = newParams end diff --git a/test_scripts/API/VehicleData/commonVehicleData.lua b/test_scripts/API/VehicleData/commonVehicleData.lua index 72e1e4221c..9f6f50a61d 100644 --- a/test_scripts/API/VehicleData/commonVehicleData.lua +++ b/test_scripts/API/VehicleData/commonVehicleData.lua @@ -92,6 +92,7 @@ local function ptu(self, app_id, ptu_update_func) addParamToRPC(tbl, "Emergency-1", rpc, "engineOilLife") addParamToRPC(tbl, "Emergency-1", rpc, "fuelRange") addParamToRPC(tbl, "Emergency-1", rpc, "tirePressure") + addParamToRPC(tbl, "Emergency-1", rpc, "electronicParkBrakeStatus") end tbl.policy_table.app_policies[commonVehicleData.getMobileAppId(app_id)] = commonVehicleData.getGetVehicleDataConfig() end diff --git a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua index a31911a983..a9b65a291c 100644 --- a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua @@ -46,6 +46,7 @@ local VDValues = { tirePressure = "VEHICLEDATA_TIREPRESSURE", odometer = "VEHICLEDATA_ODOMETER", beltStatus = "VEHICLEDATA_BELTSTATUS", + electronicParkBrakeStatus = "VEHICLEDATA_ELECTRONICPARKBRAKESTATUS", bodyInformation = "VEHICLEDATA_BODYINFO", deviceStatus = "VEHICLEDATA_DEVICESTATUS", driverBraking = "VEHICLEDATA_BRAKING", diff --git a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua index 96924ec0d3..3ae95052c9 100644 --- a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua @@ -46,6 +46,7 @@ local VDValues = { tirePressure = "VEHICLEDATA_TIREPRESSURE", odometer = "VEHICLEDATA_ODOMETER", beltStatus = "VEHICLEDATA_BELTSTATUS", + electronicParkBrakeStatus = "VEHICLEDATA_ELECTRONICPARKBRAKESTATUS", bodyInformation = "VEHICLEDATA_BODYINFO", deviceStatus = "VEHICLEDATA_DEVICESTATUS", driverBraking = "VEHICLEDATA_BRAKING", diff --git a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua index 085fd32155..c407e8b0f0 100644 --- a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua @@ -95,6 +95,7 @@ local vehicleDataValues = { middleRow1BeltDeployed = "YES", middleRow1BuckleBelted = "YES" }, + electronicParkBrakeStatus = "CLOSED", bodyInformation = { parkBrakeActive = true, ignitionStableStatus = "MISSING_FROM_TRANSMITTER", From 4a60c2b64e065739717fe60e5a16955e89581b30 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 21 Jun 2018 09:23:24 +0300 Subject: [PATCH 449/681] Add missing 'events' in common RC module --- test_scripts/RC/commonRC.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 10b48f159d..6eca7fd689 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -16,6 +16,7 @@ local commonPreconditions = require('user_modules/shared_testcases/commonPrecond local mobile_session = require("mobile_session") local json = require("modules/json") local hmi_values = require("user_modules/hmi_values") +local events = require("events") --[[ Local Variables ]] local ptu_table = {} From c3162b3a534de6c6fff8fe38bd6d4e218352bcee Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 21 Jun 2018 14:38:07 +0300 Subject: [PATCH 450/681] Initial scripts for checking happy path --- files/SampleVideo_5mb.mp4 | Bin 0 -> 5253880 bytes .../Phase1/001_Start_video_audio_service.lua | 48 +++++++ .../Phase1/002_Start_video_streaming.lua | 48 +++++++ .../Phase1/003_Start_audio_streaming.lua | 48 +++++++ .../004_OnTouchEvent_while_streamings.lua | 75 +++++++++++ ...art_video_service_streaming_in_LIMITED.lua | 57 ++++++++ ...art_audio_service_streaming_in_LIMITED.lua | 57 ++++++++ ..._Rejecting_audio_video_service_in_NONE.lua | 47 +++++++ ...ting_audio_video_service_in_BACKGROUND.lua | 56 ++++++++ ...audio_video_service_in_FULL_2_protocol.lua | 48 +++++++ ...io_video_service_in_LIMITED_2_protocol.lua | 55 ++++++++ ...AudioStream_during_audio_service_start.lua | 59 +++++++++ ...StartStream_during_video_service_start.lua | 59 +++++++++ ...AudioStream_during_audio_service_start.lua | 80 ++++++++++++ ...StartStream_during_video_service_start.lua | 80 ++++++++++++ .../015_Restore_video_streaming_from_NONE.lua | 94 +++++++++++++ .../016_Restore_audio_streaming_from_NONE.lua | 94 +++++++++++++ ...yPath_flow_with_audio_video_streamings.lua | 85 ++++++++++++ .../MobileProjection/Phase1/common.lua | 123 ++++++++++++++++++ test_sets/mobile_projection.txt | 17 +++ 20 files changed, 1230 insertions(+) create mode 100644 files/SampleVideo_5mb.mp4 create mode 100644 test_scripts/MobileProjection/Phase1/001_Start_video_audio_service.lua create mode 100644 test_scripts/MobileProjection/Phase1/002_Start_video_streaming.lua create mode 100644 test_scripts/MobileProjection/Phase1/003_Start_audio_streaming.lua create mode 100644 test_scripts/MobileProjection/Phase1/004_OnTouchEvent_while_streamings.lua create mode 100644 test_scripts/MobileProjection/Phase1/005_Start_video_service_streaming_in_LIMITED.lua create mode 100644 test_scripts/MobileProjection/Phase1/006_Start_audio_service_streaming_in_LIMITED.lua create mode 100644 test_scripts/MobileProjection/Phase1/007_Rejecting_audio_video_service_in_NONE.lua create mode 100644 test_scripts/MobileProjection/Phase1/008_Rejecting_audio_video_service_in_BACKGROUND.lua create mode 100644 test_scripts/MobileProjection/Phase1/009_Rejecting_audio_video_service_in_FULL_2_protocol.lua create mode 100644 test_scripts/MobileProjection/Phase1/010_Rejecting_audio_video_service_in_LIMITED_2_protocol.lua create mode 100644 test_scripts/MobileProjection/Phase1/011_Retry_sequence_of_StartAudioStream_during_audio_service_start.lua create mode 100644 test_scripts/MobileProjection/Phase1/012_Retry_sequence_of_StartStream_during_video_service_start.lua create mode 100644 test_scripts/MobileProjection/Phase1/013_Rejecting_StartAudioStream_during_audio_service_start.lua create mode 100644 test_scripts/MobileProjection/Phase1/014_Rejecting_StartStream_during_video_service_start.lua create mode 100644 test_scripts/MobileProjection/Phase1/015_Restore_video_streaming_from_NONE.lua create mode 100644 test_scripts/MobileProjection/Phase1/016_Restore_audio_streaming_from_NONE.lua create mode 100644 test_scripts/MobileProjection/Phase1/017_HappyPath_flow_with_audio_video_streamings.lua create mode 100644 test_scripts/MobileProjection/Phase1/common.lua create mode 100644 test_sets/mobile_projection.txt diff --git a/files/SampleVideo_5mb.mp4 b/files/SampleVideo_5mb.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..775a650bd506dc6cda16bdfec01e874db9d288e0 GIT binary patch literal 5253880 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

Aa@|$FDt-+LPp7ZlZYEj+U-s{? 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⁣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%0DXThCjUf28ZIq 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≫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

l{J&)}YQ*vBn(G1ylxHzv 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

^>&uqp0SB(s(nZAP%Ox2{`ej2 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

QHULVySZ}#~PuWJ^7tmFuh?r7A2=*(e)d45vEW8 zEPEUcCCcU=)~jdnN|8@*$U3?5ZP97f_+qg& z#v=8(o_Ut*F`m2(;W@_FOEu7yW1{C9@XHeHxF%&+(bJjM&$ej7r3H$REfm%8BzG4t z!@sE1rDfr0xtgs1E||jAH1$mOy=#xs>cHsqJv}A-`mdLBwu__NN69YZa1UKL)3z14 z7R<4)E8e$$w)^}$p+5*NaG zwA}2_K^+Mo!zkEeif`VFS4}~EG5-#GQmuO)SnZH=b>phP3^{p&VYL-6t`Y&!LWHDY zWc4#>02}P7)Mu3O;f0AM&C=vCR_lwXN^~)1hk5BnfUEiQKy+d%$?&8#ftLVnK$5>) ztL>5}!4WkLd0m7QrzuxZ41zI7j^HA#jb(d!t9Mn@;QB!QnB!X{bRIKW_bvm%?SK zXUZD8YDK~gH+H(~5k6c?AZ~CJEVKDcxDeo9h}q{VSD-17KTtfU;@$j7SQnSE6UWz- z)XBeem7wm}$Z@c4Ue^}X(f}rmy48Jy5?UFsaayuxK&Ystsdxx3ybfu%hSEgwpdJ{# zKrqo8E>0-q3nxbXB2@IfA^0zBI4yB1Uy7IBz`#_E7B_xDohTJh(O!C=z?nCKw@R_` zk{0`vzJ7a<`oJdI&%jeBQ5T`iugx9IJC2A34Xelv?Lxkkfhv>+_T_z9vOd`z1r`k# z<%t3*E3Kfo(lTM&4_*P#o+*QwRCnK8D`UJ{H{|HGF* zPm_QuzBZJM-Faztxg4F!n;20{NZOHqL$mJzWgs~2r<bd+`{suP~J}S7%*A z1N{7;XglM*K)C+&zHPwq2yu4;-vl*zXZ_wem;on9AhX-Wl&N*y-nZ$FseVNaIi;9# z;aiM@<7fLXJ@7`H%eTohsA*<@#zNbvQDeZLLL=7pynrVLhZrmcsoQAMPz*Wmyb)1e zm*09hb67JV|JR6jaxPZD!D2aHJqqm4bWRs}wYm3>M{WP2^zl=V2o6lP$6++3 z1`#o{T#!7SrS@8VO)l^?guYUkjy}GRsB-&y$>vM`biWeRDDC}?XlDY=h^8y+>yf%g zQSIWWRadBd1hajBiwT8ln8m5}F8MOk4)vq-abkv_i7a(FQ~gHBTGHUC#}kAUnGOml z3*r_*(Js~RaTjwuonqs)D${Hm8nBeC^~Y7Y|H9l<&aXf$s6K*#znT(lD|9T*S&)&3 zGPMucwLIMo*c_BOgxV7H5YORqRaRqe9#+wuP>N2NV<{>j6D_-)-8V3agB;5T{l{q< zqLjeAqraY`tAOq8KB7LZ3;2uT|VsqQqV|w)k|i)+p(HT1@uFL z`P`nFCE#BrWiqaSQH$u~Y%AdY=&<8f6dI{%nqxSe(#asN6zfFh1^V!fB6mWGVC4xz z#Y@d52Z01>If>I} z@qD(TNP=%GMS&oc8k2`Nz+36s^w4uRvfP!>V774gQ47(b{kqr=V-67q)U*d_co z-ibz2bSf`-Lpd>Cg-$96x}hJKD{eM>hG6(My%D^VyV)%|MHn(ULY8eqmw+~3uZ_z8D5l&V`lSPlr5zx> zDIMca`>9@yN1aC&PPi3=E}Z6sL#mqkckR#_RNLBsA?-eZTF|Q59xY@x;GsBeVPDB6 ztMmPK+4P2H8D2j05EMa=R5mWgbI0ekA_?+_26`ir0NvjA`%=?kDk%E?$qsf6tNEIx zExnJ2MwBh#Lhzoc#01@VB<|JNkUX$+<@U=8e-p={Tr%mh1(OlM<66K;w)X{tFAe&Kq$ct#G&$~HjHIYDRwA7Rmft$C z*IP6cU?QPIV>_y$(sLTo0-r!(Mu^LXqA=KAfdmaj1Uq9TsRb1E$l?gChQ-dy%JB7` z?|7}C(h_1fJ{lGGIrwJx!P);~vuZVaAG7eSly9Y-iuZW}=-htJK~F#BnFvAWWfVj| zWXVhSFp-~&C!9qL7peN_q_~O_MI^;Q)*g`;=zlB8iMUR^ovr z7)MU8;RSv_vpOvCLFd-sJHl{Dyg1PCc!Vd%%2^B9o>DwUTQQDzav zg8z_TwxtQC7N z!~4MPr`}{7I1^Hv$UjlC&Ea+;>!kdWt#mp~5gdv}cbuhmHOO<~vMAh`!YYvkTEz`_ zP>ESVeZucf#jGFRy^rTg9W11Z>NGPkP3k&51bsR|(Oqi0uuB#1IV6>`@F3V zFM~hlDHB*y!59mmi|;iTB*5rt14!i%b`Raf(iDusVI4FCcM@}8^7vrhA128))&P5V zxhkI^e{T=3v0G96ImS;bUErD{KPl=@pc*^b0K0iqt#HtSHP!r7? zDNqlKGIguG7N0^L&i_b1u0`9beB(5I{Wi58TkTNz%OKouRB+50Fj7z0qPN6;@o1B6 z3IM#<cM>!vj?MI3%qMX&)ELV1kE6y)g3gXgQ_9ijBB^1oM z_)h_OGX^{sG$h-k!$q1XwCpYAPW1O1!M8_?`i3NJ0U!{PIY3IByeRLJya=_CvJFIr z2bd6Ddm9>aEFOjn(~d;=D9kC0+8c)aU`X7GV7?!Jlxei*U!aZ&nUDHvBe!9<6V4E; zBzV7kEI)WhD0E};6wqe3bGFqNMom#LKIX-6CbOwNOBW=!MWNPC{39XIWs%ueK?*-)#BbuK&+{BQJq*P>z3!niGnf}Z+Fj=Bf^Q7LJ zyXZ>*$r7nDOsEvRAfJ4rS0hZnKv=(ciN?vPYBXE+*(GeE{tR215K6S}nn;S(&OC~8 zIV8#z1WSS$F<#FBZL`#eKb|MY)52+G-8me4&qG*X0@&j{OOKbLEU7w{Onifo>ah1- zCv~{iTr!2PI;pb9+_$Z5QLt;TO@+>*IAX6Bsvs!biLJOO@IR!>y3u~kmi$@q<@iT73KD|Ebq->M&-1^ z9-B2Mxt1zTW$N9gnw)ubbyJ+c8Um-m_y0p>YWk8u!9xqZbWHDE39^{lRb_6i@hTX9;?*=tt zku9Y{^cS+9@rB`__=i+Lh2wd|xo{MTBRlqu6x(4Q(s1KgHWNMZ`a$|SYpVFPXyH#W zyDG0ME#w4o-?{^<&_h5?+9s1IlbfY1T=0CpfEEYgKVnv^P6IGy>N@clztr`qoi ziP#HLD%UUdCZn9>M|Tuk7Jd3X0$hL|)^DT)-A2x@oXfHr!(C?L!miZ>v&!99H>D;R zdjQ}yv^x-l*8qAtiXy?dwF{({psWX>&VW7M&axx80muVea0|V46LE1u8b8fLR+FS7 zOxl7**CQQ(!C-Y8%pB)?-eq3);EQTTUs?k-%T-T1?8=8))75i_c(m& z=ce@Jn{2!ijeMznX}0=LY3sHXMXI;x4g3OngP+`m}5&4 zzWzWyE`69|IRrfb*a-p11%QwqpcVj)EBmKD*`sEh7ATW7j;~Z8?#C+z$DWoHvg+RI z7mcGH$XE*CLAhQDFEW6O` zG~SS}x%ag#4(%$Z@-c>DZDzLRid)4F>UBve3NIkfSiY2KDlA(DhnsKv5?fb8n^iS2 z=fbFH%c@;k)T$+bt$-pBDaVL+6X*3fCq`;$*&~uh>1ip|?JVQaYjk7(yPPHV~#WTiL zOtCS88i@!6P07_z}PX3Yq@QHZWQtQsYu@O||5B z`T1Be^n~N$ll>U^p#c2y#>YCt>nM2GLVr!_TK)LzJ;Y6YPf*!0q6m+83FA9%m-is6wmMf!rG$^o0TqB;%5_`ENHr7 z*n%H^+`j+w(Uy&oIsxnD^llXy+Mr;Ix7wI0$3?>zfy1Uw6Oh18r^4QcaVO1 zFqPGV{8ukg$wzcP#+;=f)lRJ$Kr{96Y+}%QLxuCc`dfyAU*imiY(@${5@)R0i2|+$ zS&IhOJq>Om$L)XwmbyOExCP`--&$fW9`~$6^83f5{35 zZqbY^JmpMaf}o5OeMU6f?{np^n*3Osr+zSx;(}4?6a3-PDq| ztc^~#xx+Pa2CC;8-*lzbT>vV03!+yg;Ue*882${e3SHwLk}zYvF;#G!YfBXK&|YQ(qKj?ITh!Y!_s;C^58VJ2XUFuaPdd>hks|vwL z0^~eNQjM-FVslaU@FqA|h|?h);T~|V5R}>x#ao6zY5@)YP=*fv=S|No&_c9VBGlRZ5{pCdXrFGUj47 zUmI9X!vRYJNU#hXp2s5?1Dedt>g8cBbk3OtR=wvfTQ#cDrL0ZXHI>F@#+j8L0b$h2 zrX&!7aGXQ~oZKj)7qZCcdxh(!?DUPjx2fHAWtm6?2c<%k1QSEp%A`SgF@;4@8`&+; zfHgsg6<}f!07UQxv#?POXjCL{1-OJpBywPT84TZS!KDp~5G%P$yB$LTTTReTzku6u zR;-tBcy`d0Lm2lIHeMIYlbu=Hc0SlITer{Xy=#wY0KkM-cesL8rJ${L2dE266UJ(Q^m;A( zOmu@w@L?5+KsXeA7cFGWml=^JqgrOmU^VrGUh}P zX~i8QT6!vf91)O^?jd2B+Kd6!mgyl0^n+1VCf zFwTwhnutWm)_}N~5hgi6(Y6jC9=J%OjNJ9hiR7qhNk|yLvj%gu$+VPFv<#rq`gk&J zfE%8cMAg-UC3X)d&UH4J%@`l9zUj;+u)ieO$+y zvMso>6szgZs1V6;SJOjx51*R*b|XUgy}*asnPto$r&(-~Z!_KK^x9UV#wR-fh20kT z$z>}f)-fp5q6bB$x{Y_Mgq6bnO-2L|wsGAoaK6h38nM|_a_xCaPRho(K2uajDUm}; zQW~+8Lr}T@ll$)98WM-)*__ROnPS9sRh_rXl*O&*bvQXl)&)8Q7Y08xyM>S8+dR>< zTv`YQbk(RQC%q0}jmv_M0@ZL{Snml|k<;4VMc-PT@1`1EW+tF9`t08|xY(vv3Tn!C@lj{90XADPykKADbH~ z$-3S%vY}}j^+CBuN+A2-hEe|S+`^lS?Jn(w7B5H^rC059iR|;#a*-f$oAMrbB@W}; zg42`e6Vd_+X~$1!u0O*x{EUu-Il=fxI}^S7upxv8F5dvVwLW<>M7_mN#Xk+V7DT50aGiB2cXZ82 zZ9i_fX)Cd!TBX{4?p~G|OOxogN!QBYUE|u~-fBW2zP3>0L7+VEE-Y9;C5(do*Mpr8 zpm(t6ZBxfC<`XJQm_4@_lUYOq(i{p?wrAw$Q8k<>+UBJ11jN`5Yb#2&D&vEAlE^O~ zlv6TgLk)>Cf}}jI_rZN}RzZgk0B7{DR0appSDlza#m)^CJ3h90YLILu1MfHsUMO}{ zKoR!_>k9}E`(OAIO$XanUcMj8v52!~dz5jcwIOC;ntIQv80My-zjtV1oca0s=|;R6 zYPFs!+YCzMB=qlsCAu3)uUn;B$$Pzv+NY|OL-q1OyRKG#CD=J4v0h(Y{*q4N_7M{p zcyL|^$6!rugf1Mdhcsh=<0QW5Rp8H&lyHB%aAA|{ONO02HF23l#<89(W^f5jhZIj59J9N3+uO3QZ@Caj$?G;iC^nE zr6$dO%=la_X$WpqhTE{xO;+vIa>m0F2mnkq(1QD-KKqVSJkw^<`n~yJoUe}^>@W4i z`Rm3NQJZ+7JYLkvTxeOQqCeC-m0#>F_PkE{5qcf?<%&Ne;?y}t9UFp%9V5~sOGr>u z$x=Y(Voo*e0(ZH#Q(89xoH+K_k~dKu#uzkA@h1hQ;nn^fj3?-a$zTM6LFBzF6mzTP zHWPgEeW3fh(~pb~mfbpk4RcRX66*%Zw9|3z{=9aZ?(>r8BM3cj=h&E?TM2_>ZVbIj zH-jToObKS}EQ$cq4=TX`fg ziCu@`>rd@rWEysnV5ak`9D<&N!XhZdI_He2yI|REz`lyHM+a)7;AT&9RH4sR@#A$=HJnmQ0gPG0? za)jf9L|_#isrO6L$yXZp-!*Pb8vTelQ7+Ou4kKRHyQHV(OzYh0t%B(cYOsZdLaWm?d|H2saF-9#P6ihS1%zJ-H#;F1+i(w zGT9^&4s9p13kyqqyVd796U5tvtO4N^)Q^1ZT6z@QyClUKKbL5{MAZW@P+huslR5ue zKOdyb{$rc{R5oWVayBFJ-35eg*(O=m$H@?pb1yNT8Hd&CZt=%vl!Xr?NUlT)BJ9C9 z7A^%BIU|_OytemL+#%k@R8Kc4ILE0X)%1+XS$De<$@ZbSg1F2s>fjAKq_m^ysnQSx z&+;m;(tJhcgxZ--!0|lOrgNFI)15k{#a~u>()I7O;9q2V2NHqNcDr&ojnb|JrzA#E z^1eltTeN7O{~((l?X<`c;H`U;voco4($SpyjduQMg`1fSFYslA=E}Y4cdOWqoFA7}qFFun@^F$BKJzmG$e#!)#fb^zItN zaX3=(;5KC!g=sMEb}f zaW%@PKTSHYG)>pLUTSaeP&Zo$H<#$2i2kfp;EY~8nyB^&wyB}mIG zps*f6-~d68(`O_4APy03ORUW6xJPv}n?7av8L53L@)5fpL{D6ne9}(P$lzA#nnw9P zov|~K&t)s3PxA-`O0pf~(IHQ%rv1A)J8c?nqTFNNvq=;jbMKkts09lEs)!we8(SCc zTCwIxbf7LaLkpSn4pX@Md8kig9N<3MdJ;-vmXFQ~D+F$TRM`tR3# zNr_2JIwmwj0S2}7eBdT+AEEnxrW1>}Gp94}AO4DjGxpMr5*$!$0A=HC- z199;tHx$%l19-Q%>+eW%kOe5q^l#=OhE5B>NZFuA(wx(-72;eK{83_XY4PFLKQ7&F z9Ynf!b!lsjOC0HuK#6+vbk;0e$o^X}-gwln#v~!kOSnnM_nLUDjARWC$R_*45RSAV zIb?Ra{f3u&P`=(Ir7D*?b>G~#lQQ`T+41)!R?eoax)qvpH>06lwd)HVNXZ6z%cqWr zpBhRJTg7V!T1(o%G6UKjOH&l7^9&Li0E8o7=x<9$d88mbFFV{73T!N7*_%2S0r78g zDdD?kD>ZlB!jq)_A2(DGxLsTf+a$ZcarQZRs2)#916T)rCE8pqISf9gx>NW+Vrfo- z7dy%MlxE52!Vy5agHB@MQ?42$@At>@@Y{N0s~w#qqZskt2HKK5E`QCbqlS08x9LDQ zkKd55CQL`^4trbGp$;V)h9lKlE!ouDS#{m3dYOWh#E`cWUl)5K)eMbxG@+vj{llr)~xq7AaI&ZMaU zO4s3`EJ{n)1|_Vdo1ZUFr9DLQ1NN2~+^rFqjPVt`zZKDXG7Cy*_Q!MNezp&BGq-WK z>{A@O0vOgWK#6r7A_7lw3u?_|zI!<=!9|z5) zMU%=&n78P6Uuh=gPi=ZD?9N=GN~whn2<1|)ltGn|1J~u3TnqxxjpQhAB;X0*BA&Ze z=|?vL^9LTadM!2l_Oa^-6r@Ou$$%Fp4d4wqZh7cXPgU!eVeom+HEOeEF62NSTf$yVY#U8wHOY>0lFVBA9Y{ca z%pwpLk8GCG&ZMI2s9|~zK|G+%G3=d)$4v#`dlN+an2^0t(U>N`LQ#UHBXC_?l8h7L z!i+>?#+4}mKxdBWP#JB%_rA9AA0h>+!U}XSmk?)GuTKIY9K;|iJrN{)8w<2hfPh4- z+b5VwQ4G%@&tGW7=<=EbXFUqLx8*IpZJI2fjef8V;bdWiwiOG|C%&S=-|T03JMvL3 z^m(s<1*_iFx9p?&5c0$RUJh5<7R;NOhnaHkz7;IsC3dwY5)-ePFgJpLWgd-g8EjK` zE7F#^$xG1xCw+p9L0>mbW+x6q7vI zc``nMZXYs=mFxfmzhcv9nYEKmK^J{jL{n!pYd0-fo>owUjlgM4^tKHb z`~k-UBUj<_1hwjDsyO8#7`Zq|3yDoWKZj*j?PEpJ5ill zx~S(ya#2TJ7h_jGFMW``)zbVbo;u{9Ct!!X)@!r-@JO!70}@mqjoUWDrbncfnKm7x z@qu@&`L?zX{I;girx*k|toXN~(`#X@TL3TKq6v<5Bxi!#h7cjsy&i)Ag9T1p z-F#Qo1A3y|fBzu8o_0LXP2a!YFt*7zxCh#Odx!PQW&i&|xt1P`yW;t3Fd;sy1DpZ( zi+eGNo96h+tioL9JvKC3BqAf z2@E0^cbBGLJaKd1%$a?7rF5jK&Nyv20eW|&xcG0|ewse_YrY>>wkxmA^ckM%@qO_N zyCy0nE!MO0#usdryO!>55#1xD;WVB7Eqs*|@-H*A{rr4=5A1mci0B|;0HO1({w@we zww18;Vr@sNtelze@gh>n}R3l)3Ng z`X=!hAVq-Bmi8BmhOA$;LCfEHmZqn(PZm!L;{1Uo@R~Wu`&OTAC<78>akA&O5+KH5!}s&J(D$qOa&^(~c_2?b+@S^|7g z_xC8l*7pc{90`j7V?bEw77_@ACjhH_YB%-i6ouksS{hnRfHyMdEq#|l)YL!X?)H5; z^?QHQ^3*PbR6Hr+KbNSj`VO0F$-FE-i{2k8sUvi-q>BLV=90TvV} zFggqgiveZGSSS_>3BrM3phzkb8HFV^*Ev!m*=UuTsFcq=>ZNc$n_m62c2m50=j$zJ zYt_5|dc8fKT^@USwRd?nXH}BlQFdSbq;3)F+!pm))U$B6Mpve~TsMBahTOf?gj8KJ zs*x+u;_cihAQ=k$QBTb;py#c5Yw=;Z-Om;v0f73BjO0gr4R}6!&BjroAYINv_cWpa zXAsB3G=6!P#;I_crp-*cKM#rHfRH5F66`U{R92_3!8EADFZn{UGup&8n0%S>K0Iv9 zmyOKS`@MwJtV~~LF9M!i)*Y{p%|A30aj^O+DRo+wTu1ixW8%0iXp=>XUEwveA5R?t zb$l}a&vx(#%M%6y!GO3}E*1<0gn^K-P%I=Yg@S`1sRV`*3*T9FdiMP_=D7QH=W~5+ znbpx;cdaWc;3eg*0&~^y@p?U<{w}5N|KzVp{_xdv7OhNr`?eeWQ>oAMU8{arCg-U` zqd;}&W3h14|D4}(-L==@e)}jN{#xRZv3dh|7sYCR$H&JCi?V${qRzIEdbaqg!4E9d z)+e?%V{nF!G-#QIr!z@@!Ia?5{@#$Z5qF$&_5IM!V5m9jYuUmRKmu9RfsWxAO6-;b zR-CN!ct*CIz912W20nX-|9%03L4dGeOc)~y0>ObWpe!gF5QZpx&0^~E?vr;E$!S+t zF5A>sLv7x*H{`ed_L1)k*4^b}ORWd|86FsqhsIUouY|rSO^NkmM2kG}#zGw)ohWl} zs!gM&l*;YTO+8N@8$XWt`fHN<{=Mp&46;ka8bQj{xZC1k0(6uX@@OU=BcishWva_; zyvLJ*2BZG=`Q#k#lqeUEZn75Wf_f+Vt%FuLBy{OyAC-}iH%FYr@om23~rvTH>k^u(-u)tU_79<6ng&>Mt?^5Petz^A-a;6JOS8@ut4dr&X z9EjZA=6gE<*75H0>dX7t;V0UOGv$^TXVstM3Uu?Fu-S%h!&k^J>RV)+cfVC=nk!AT zM*aTep~C`@^adQ3TQD3pRh=8B@-tyU_rFbT7uYfF?$3QI=iBDP|46(4ckFy`&Q220 zuhB2_o`oynp6>bpR{I9qrUyT}A9g6lybT`zu2db?wo#tY_trE<$&Fp}r_W+VTJJ$S z1I5__&;JQ-+=4y1{l_pyn2F+C`hpI*^QAFM>*ZU=>{*fSutb$1kOnf5OY!@WAWID6P^xBAu;$op4 zBRSlogD7{LS%{2R*hOT{Wg|4(A)sZ(u7HIRhj?JmUKwcA8_TJfv`&%mzU+Jcfl*QV z45vg{gUnycQx@j4xVY-vuJp4EYy)78Y~`a94oC|8J%7iFV>~Z)6F6{JGaK9_8Vcn3 z8dv-v$xw2aMQF=i|u4WeMp4hFe%Fq-Q3p+kE)k*;VuAp ze*&W6~$X|Kf@={c+e8OF%#Y>)6tba60Cwb+?-JGRDJPMU8)WkW7*?kon+A5>@ zibVu_)60Hrd$nzpX*la>{ADS1BUPL`g`mjDS@?_KS5`n@;H~3Y5QM;}jOYM6BN#copObP zzGd^%j&C#S8`LT|^evn0f{R82NC9sRA1E~omKQ6Kl5m;%hwH&l#3Vtl1smo*k;>hx zyi!OqP=)l62=UlWKM#Cj-fbv)?ABUPow8X8UweaX02DPb4J6fa)TJb93W-|jOfa6K zm9OQIRnf1%qPvOEG;iF+btSAebQFrahDr;OYh?3K=^X5Jp@Hkq=7}PgWPGrM@En|X z_E59uy5A|EIR0$&mFt~S2lW$_1aQ~NaxyXC7Agcg-|iz(qBmlpXaZ%ULtU`A13Y~i zAC^uw8q=ZL7ph9rsj1EY=$DctOb}le3ELOIy-^Ut+f<2b9_w%>9zau5DgO$ty+56A z_!tP1W)wV=yX0>vBa8IgU%Qekv)Slz!lcb9nYq?r9l#zTRLotj?!3a0^1z zQzhFEcK}GTj2hS%*lgxq!N`*fBY96lu|2>k0^5nK<%PmH!IH5nhQDq4T(PM6CWGRJ z@bv9ZzY!qsdoQO!zN+=4QCO##H_-U^?aWh(@9T#K)UJj7R>J%#YoMR%w7pocR0k$i zrwLOQ{JN|V3xtfJcZRW+H;OA=fu^ayZRdG=qItt^K{nP#0ROP7dFQgh(fHAM+b{D> zRzO(7gz(^0#`4@=>;v5#AXzNZPVV8$dRpzCQj;<~$gGWhphEFN6WDW=hgcoY-XYk@sBm;g5l6n?Q~mV9Z0Y%A6nK52eQ=bt_G?clUxRxruoKlYbDk_qlci`*Vynw3A~{e>+}Z*LP0 z@v5jRf13=cy_|2>yIteWdZc7OVjU^|N%mS`dx6|MDoAVUlW9qFaMc$hXCMp)UFYad z0j{%t4wRo;=y)Vm@F;9;xd7Z64ZkcwgIi+V>aaW*e<}{Y;xtB(bZIBBp*Zz$qpn8V z6dGUSzEirFV6dlDsZaJ2$$KS`U$1h|XZrQC&z+?R_7b%m-+c~(-&+zNtjnOqV`4sg z^QIK&jy5=&LhL!x$IsNxskCA#on%T!DC9gU-CBNab*d!AlYK_1=YOW%Ro7c4n{Aub zyx65zhMa-95gJ_n)?75K#OBAsd5Z)JeW`$QJ|E5Q#2qJDxy^5c8q0(G&B&@rQ^Zeg z|1@tv`w%OW^{Pk|9IYa$l&N~dH$y7%_w`p6;lpl>nw?~Q3YgvT!3)+K zevEM|`w{RFNCeP7uy01m%e$Z!Q|;9>`$%^mXW^PEdxF_Lrs8ZU;FE^$W^A zSX}cxui!mBtUx+k9SaU-jzPSK`4a6liTG`Cx;+3u0tY|UUxV3Gb+0ylS`-c4lLflv z%w`|V0q-W=WAi?2R+)`>ksAsTro|`Z{^;@0!17ued4Vu_-4Zxcn z1Jl>Y#z2O>Bj&&z|!?0A!GL&(m5)$_$R9V33#+Yz+_| zSFI3wa$m|K2!;b;>dI^F)06D6^+&wM0iXcj7%06F0MC6rJuMTcfo&Q7VcJGRPR+K z1_B}XJ%OPE0P>%X}bD7FCEc8sAT#n%JKPCm=_z)SJ(r|5>gDuLM~0?Sid#i|WE z!J@JmUn@7igNO2rPJ`&1C294&xfTQHFDXN1K-UzwLvn4;rO_R5FFp2C{SqLtAUVA>agZG+cfi*kDDPaZuV&3u<(&RZ?|oTuba z@KQ-q_i)T7wj!v9&Rmy63Pmv3$dx(8z{rpWtm2Lf=LV2TbGs{!hDdSt6>)4kf%S_< zJ(fPRKcmSr(?X)oin4%Hqr3PNdGxoHy4@?><9d%Mh{xr;c8V82$^dyVP2bofaJ{Qf zW?^WhKmVzt*DqF01V3fbX!3{pME-!3mb>wqVJ9XE_{Ty*o(QK~uSIG0>T+)oq>0i% z##@Mcp;@`J_37D7PZVtgcH`1kfi=1f@xea2p~NATT-cj<4KN0JMeUtY?J!us66Cet zo5T^=6fRBleiQ>Z!cqIU=R{I3gw}cb9fOSxOz+5wBs)yi^}!Y6hpeg8r76c=&jkcc zGki*p)lRzwM6C@BI)i0{I}Ap0k|wo9M!B9pRC~)HJ4lG^i+g+EI5bEku6bv1uj)E_ zhT0U3!pv&FaimT8pD<+OTgP&gQ+zVsrHA1#u zrR{h29RA$;w|@SX96&1f&mJ|<4KDM7;t&lY`N05Lv()?;Pi=YIDc!B)VDqT~T8vc! zy&)JB^2LMpKuBU1*~h!0!Rd7j6K&s8D|Mn$8)i|f=DczKykJPuMLN*0)~oc1 z;(_!r%M|ZWEZSD>LS}Flcf&eA>;n-oj<%1-rt9@5Uz|?^CJ;aZVRiVm-b^*k6TQQ!Sgue7wGtpD!89LX({ zwa)b?10TQ?qAv#rVyri`(__#!y8UHOa@JrJx_(A9SL0hmhB*Bqfw#Q`br$qQ^fBx732ba!)>^rL3Xie*5U>=*?XB%(sVCe+8c@zlY2E_}oc;4e6`hc8 zm3pEqrGNb3`+py8XTHr)YW?Ovo1aTsPx@flXE1W{cc?UKGun(*0xdn67b#gAVi$}J zxVtzF8z<{WRO?n<0rhxTf5~Q1@qQF8e;PY5ph5#hyoXTbBFu{ zBDzWI=L{Zl!__>(m%8df3yjwXsIVbNh#y*uRB%n%2oMZD5^`W9Md?5)k2Et+Y-)pP zM6bqLeEGg!M1KM-_c)@lM89flnT*BHXdf3kCYzCkSE20z#PZZTAr<@0vCnc&Wp8QT zO-^OT{!*)bww+1JR&xhPY@Ud{7}%Idxm&z7J!~rhA27hsRbNG044|hHcEQX!9RjR%SpSLEY2!bNIfT$`!Mq$ z_~Orp$ItHF|0=^tqmjdN*L{DDS0Mae7uT;o7e93U%=mog>JsY8R83F*fB%{v;vYQz zOYMDR&!^h9fg5jhrtE?6nw-0z-KNIY`e6{Hh<{aZn z3k)}gATV!zB|KtysZ~lMF5>>~s+1C5XXLCkt&My={QDlxxN%yjz0rj*?4Yi1(8)U+ zf27*{4wJGDPn6Yw5QPV;*ZuS6GDAUuu^>!43x$M(VIW{AA_;_ofl!c4A~gw#-L4-W zH|NH^{OYP*OwNd@zNI#TKgi`}bBWH-_LsBuar5El?)GfKKcw+H3ok#LId9hY@Otur z11$ZLI9S%Xm#$!cjC@1?50q2zHP<16f^zHMpzf)qcK_@5eg|7+0KAkuFxDc?r+ z%u`_=GR>hl`=uH8@IHeb53S5(|BdhH3hr<(=W|-zXrMPczwx0xKq1$^*3TX22PV|U zUN*X$PWB6@eDCg2b5s3QvdLbf;(x5q0E3}OXfPHG354O0z)&z23I#&JK(LTj777eP zp%9Qn#uxRxx7XY6?(@y>rN&F&JY8JN-xp2KV4Icn;r%i^+-;4wSIMt~(1JhzPT%hO zDA0-a|6l|!;vXRo&lT40mHxBZba2u2_Q7FLYf@U#@?hp5=-t!=$9!u4p5@@&Ypj+1f5C$UGd)jM3vW|nXvcr-=n&esC|BXZhCR!FZuxpr z6P$j&tN>J!v>9i$jNZnw*zd0eP5wv)JvY5M<9_q)lX$M@lxU$-lW zY>4Gb)z|*s6jRQ9er{W+)Y7*Yd$l!B`otUSqO?xvbw{+H(LvIJ&s+>8%XdR=%wztDSavt5I7QW(=dA4}Nzzj#|{r#(aM zBs9vSut3|6X%sX9ZE>G07NN49 zGXkjkrE&mzfY6|f7#kJ@$w3fMCJ{sUT)eJ3oMl?^c#7g~>xHvPmNwsKp`*xOnC-Q7 zS*Q5p|9WWYF1yJ7KJe`ZT$Lc-*FOKRlzr&Xg!BQ$NuX7dVTMS{ddSQ>MjTVoa zI%y3yX8sz9dVFxoT*jGOSLQ`|BT98wT%l$1jGS#1zS&CJ2Q4g_pzsm2+oJYYep}Jb zbQ?ZM9a=xfi)wDaO*t~Y&N+SQcF{@u99EvHcXLA(RuK2YJZn2rvNyn|71Uj)YC|4* zLk%v`1Ie#Y7%~7L2;c!26eutz6a|X`pum{O78C^vp)in4B4-!6)V^kM%T;KKx=L!M zaVb|r)h~M_$Jf>4U;GA>>F?F({=FafkC*;e;b+&aZdZY-A~OYQC`i4v6`c1xoh>>_X z*n>{F((C!~6_JW*cs>-oNn81Us{n*3J=eeg{cunk6Ac2vK*(S$ItzsY!$L?5-)n^SC^1F|NrJk^%r`7)B0_%`3g4tkJmFZhAIU29u;=<1PWV%`2z0o!pQQGsFsKMViJYB%KVS! z9j?M5J5>=!Ov%!z#^fccu2e8Ub<3Z2HUJT>7!?Kr!GO?MQWgvag8@LXP)r#Lg#w`= z7?36rF_mxM`uulZ+|Bz{N|8%lUiIG^GWrki&GGK-eML_n1H1UA^k<=UUHxP7AC=9G z`ta&O7=CU8dVj>XZ9f%_v^ETv-^G{BTpuWT9##Uk-4p2V#BQG;kNjP#aoyRx7%NP# z>2u9EXRGS-0rw+qd}D#pSs3Hw&Xv zzu*56`sq=0OudST-pVQG)3zbA92!Mz%K_`S1Ytq@-@o5~fS|x=Fd7U6g9T@xSSTV8 zo#K^x%gJojZtoIRT}i6E;4BU7ztA4?A5yX#d)Z=tn#ZyumC1VC*^yCi$1l&6-K*5! z%xUvCR(f=ApZJq(C$RfJS9V^#)b2bntG-?|z4m8d(m(B=ziqOgSd>&hJosGElS$xh zU2BZm-J=?;qN+m)>GM*N+<*_G@zZ;~em@C~)2JA05LY&nv19C8(ma+I5=@^=DJVo_ z#L^Lh&tB}ogYcUHPk}FL)~72AJ{H)Nl7fa>=Dyq_Yh|_|K+xb!S_}z;0cIeWBoRy1 z%J$y%&6&ckVy;%PEpZfZ1^iC?1-&dI&xxo1y}JCJ{@?cxFV$BdMR!6yb{@}uYd>#> z@0p;%ue+;V8F*^8$*R>a9)0C)UHB}U=C7*7>a>omI=8ga@r0{RT}Xv@`cl0i>F}y^ zGyW;LT1Co>9vR!oqIxj}#u*;#n$;fqGql@t-nnO`tqkA8u!5ljhAEK*8)D}pefsfr z+?|m8Z1pUQbZ5A|%utl?OFQlELfFSrH?q*GxotQQ_gD-W01yOl000$qL7HYi0{_1L zg%&Fk@(Dh)>sD&gVfrvm;n3;5s5544$v;o)1AXL%Ilc%$@&Kc6{xEl@yOD3Neq+`= zI{KT>iNh~DyY+lS7rhLcEKJbU2eKy!GMR;1OFPFEuj_r~J;!HflO7 ze4%Mt10-;1aO=lKemCM(O0EX1C#TNdd$Ob=%A5CMbX4^*(4;Aua54G}no4E`m541T z{9*gTytwqY&N6d3WWShKeC z0-ra_AH}0GDNU&8>l>}1xN0^xE*yqQXu8Xq*xp^Cu!Xb@@TvMFNZv6lZ|gcY&v`I( z-V%umm5jI*cJ*T8=*OIPkrZ0Sct&qM4$#gt>e5GoK}u`!b{_qC;)J57Y1bM^R(yq% z^y0M_G>LbQi~KozV!PZ8^0qlwsFjcI1;b#>zfWF|Pl$BW*wlw1Fh$L1;F#C0le9r`nJ7not@LS?<)wW)T# z*k1oVW;%$t+286s#vM_Ig=W>MSn+Xf4b}I%>i0yaP_$~(R~C&j6RHwX&7-8L0=m&P zA$gcPnTM{vcMtZh(&$)HG70|O@AaVx_JYw@RCEE}Mr)JF5f=oJ@n(S8-)sE8@ zV^t1Q>BUjhB^R!=3CR*{3x+?eZ;)1|RIl`CADpl=T$zg#%qqGZW^BB$hjh0*uV5OE=v;GqSy{!N-3CNN8Ho zaYrzq@6d1Davq-s#4?;TTf-kh@a!ud2RAuCv7;6=W^Aa44g7BR_Nw1zUH6$wzBBCi zLv?m!+}3*xb{|>TI}ckMJOLN~0^JVbeCo*OF-UL}$U*|egSTA=wLeQ#M!QZ`Gaax~g9&NpyfG>sr)qv*V$n?6IL9?-NZ{l~=h=N=ttybQ2E{Jo)w!4|6d`;LwhQkb z0Eu=$7Z5#T>}P;KGE3Lj&e;o!J`e365qeJh*Fr&L{UmZvWn*TiFYY~zna4FoAWf6Y!gIic3;L~17>PcRYL#21Wry(5EdOis&QZYE zq~iCP$$D?_K~(HiSznl!99|JlnOq=z4KqIG(xmRVK=@}cjeXnJafulE#}ZtZ$(8FO z@=w)Ypc|+R)SUo=`A0ju+6HY<(jf$@x<>U6qjy) zV-167-D|KX*~x!+R2$C9zM**|2Kq|VY1em)Nf3t~BO2VY`nU)73P4Dt_^Eul7#Db-(^rhU(x>{4Z zP(ku(RP@(3*&2AJe&>xNrypOGZNWmI_8Ec9ITSy=kiIl#jN4aAZ6ttiZgF(~wAD8N zW8XzLoaUvWFR4?A98rc(O#Q0;S>^_R2k;bm({OZhK0?#FkTm2i#&I0EoiiWJkc=m9t9_kkca|*6~r)+x^u+yTB>eZ9|@dr-)u&Yeu((gj$ z<_YjX&SFlcryif@4I)cNoG6AeI@0eg*IH~vC6ferj%-f~)o2Af3^f`6f?0M4%6;8% zjS`c?e#Gi*6*UGx%cqu_-S7U(qnE(I1G+cS%Qtb|GCr&1iI&MN09QXzsWPbSedWIh z+N+cgC2ua4X&MpvJ_#j7899joBp$6+xncL+w=?v_dIphfc-^vh&nlTp2+bc_8Y0@+ zJp`1$qf}8T#L{tq382==;P-VW7g2n)VKn|Wqd}RX25VnpEvyPN!5s_>{C21#PKFLP zAet8t9-A6RF;(WooQ>!`5rx|b`701M%h%zFhO*AAfJ{vz;EwXOLHDz`S+^g9&2-9F zKXG277BVBS<$~aHP8?kh!hpzTRMOV^p>0-Db2=VOiY>_q&y@ERkRtqX6Fn%3#rXYw z2v)!vw;9qN(NPe}@~$WeEdhfQ(G129noDQF0PCfs zgo3)-?(mjN&}siEko@-4Ec;0h4psDzvD14vdi7x`DdN&17AvM^?YO7gC z^ye0MP#0DW;3HWqUy`bz(Gep=yOIJo@$kGjxOv_{FZ-D(@$H?&*~P= zL(&jGW6kMIAYF>>U27+~W+FvC*=(yYKW;N&+9itGh72)~*v!366)Mq?`x1PUkg{QM zLpvx)e>~H64#^o6tAP>FhnfL7X9|LTqRK#D1ln~S&yMNid8-MMb2q`QT^cJ~x$;wP ziLULcmU0Mc%rf#zyCSc2&D$i?5RS{HP2x7cGPP0|S<&(%963{xewpZvXr00A-<^K%@c{{tO7U$Mn+3_b7h9&Cv!T)^G>hvFd(41R8c`3WC z3o*0jf5o@d+7arK@L6fgSK*gl3zydN2AjKVp5p+})aeGa?@Ae@8dmBrc{=qPkOo{T zU2e3F?QpL`azmzBvOB(7UpqsB2a#Efs1brOE8K9hE6xM*FxCgnD7>)QDI|&XJfHna z4(bQD-8c!tnhB+XSVOvL&@cU_dr2ju@UzF8JVo=^H1BG&s#{vbS!o$*fMM*-*On&n z0cL~7Ba?`GgO-v~X?!>x02pcd=i4@6BtB5f@ji}rOWg63oAya1uySJeGc-k35kC}q zc#?Bxv)=tXg6QQ<9{@oWk-GPi?)PRKQLGZi3+pQ+g@J{5=^ywxVp(LVsx0cKjZQuZl7M;vLi{+LH&nbomnKwBEg3LSWl4{k_vRZ1VsZ*5wtD&^cncq3 ziKoC0qfP+0U%sji#Bv#0UR!+o{P3r#;-5|7#aUDo3A&A(0=k;;im%tg8rLqD7pN4X zoHSCl4MAM-KJTut=pa8sll<0;$KLtx+Z0Ohw3Vv$#})hv@pe4p!bM>x4ay&+XYP6o z3%M+$nex)##m`9=5tBnB6IE+n#+TrJlOjbG0=}6!jdcq_WHLQm52ksWogVOv#0B`= zXK|NN>G?em0#9diy2l*}**V^t$AeRSud)zG4qeI33slc$*g9bbA#;4t=Nv4^XLG;k!Tm|Al-V8^?pCe! zhp`XdMQ%N+H+ETn{cui+m!vS2?U{M$3GT@EgHx9CZeI}=nTcDXAT{{%m&_*3gqo=i ze{w;~+1{ClvesmWPd9i4z+w=qfMAR)dFR@~x$*%@cuGO7Qj}!+EFSz)#N!~_=H#q5 zw4eaN zrD43}HVIK&mmt0E+!-s623aUL3?voB{D#Lc#1^gA&OUIvcF9|w3KFq6;tJk~fa&wZ zkXV87lXuZYv{|N6v>KB=`|~H-$^RbXajF5LuI>W1TiUozU%@E?(zCrsczz#HaeIzf zcVO|wG1{uLMw%hPQB=A_Y)t^5GzyH^no4kKy?6iJwBkEHD+kd&N=*V3T{GrQt@9Yb z91DV6Tm8xAeTj%X=0QP{9FbNTcwdiWr1-awwfMBGv5gqaZtffrAr+!!+k~(<52}Sx zURG=mn#<)unWJ%F#vKMZS`|*laun!ZQpVl_!4vz0-jAVan7XAqP$N}=d$5L~VfFIh z*w(QpC$+^Mt!2s-h5dXLn9X2dJ=_xm7*;3>hu*&Hgs{Rc^@0qf#D}KEb?Cn)dN|R))#!I{{Z~q21vb>s#=)@ zaFcyANQ-H7mXTyX^bfL8(AV44+AWADg_oe$F;n44!t5vdi=uraO2Lw)4g^|!8KhT8 zJ_}dL-W`tQC!iM|?jC&X=%N=xvt<~p#>TopPex`jbOfp0X>~d-qTNlJj{K?_t(nSx zxnnYBx%WvEtDD$P7!5I>s2&R42ZL3vCXVJ{nYziQwep;H6WWH6k7?8EPf#o!Ap9rJ zn7{cgb3mI?MMhrzUB;E`b7U%D~h>u|13rL4fu zV5A%$&7e37s@vsPUZ}8&X|8Yyas1=exg9UQXoz;W31wRflC{Y4rNpa+<(8K3om_>J zh)JaDm`+IK35#vE1(@|-RB#&YYPm+o#oUdXvq2mhh0d)HDnikCFpACE8FY@9HU)+s z_&hJJi)vrK2jkPUWMT{RIocJ6q~m~w#P#k3U0e)V+2`GFx}#WIaK(+;g6Dzopm`qjv+GqpXzk(KF~>-PH&h(UNEQ!a zJ9XBA5lWP=eghhSGI(^mGDI5BNPH2aPS}SXSIRToWm>#CfM`Lxnd1+^KG(ZOk0KX! zOV(}s7;N@*fiXo&_QvE;#$q7axerf2fFGEYlFYkC0EO`65X5@r)K;6Ab;!dsmzfHA z59F?N>GvzF?6k#6C%$QkHv1~a^xixKrGJBT>k%15|0KCzI8ls7{A|wd4ecD+^u_)O ziWlNS7*?1IdJ=BzNOd>%Dm>RGEA&01$3uUBcniL4>&9v2pwFKH8P8~-A1$8bs}3V& z^Qo#7h9#Bl%KU$6k84#^<!@t^R)cSWp3z-^|o`+pnx+_=s|1svdp;i`7_-*0`%^o zJru96`O%o8Z7 zmTuHhCzeS1ei6MHb)2sGWlagyylI~Jv2r6~z)~U*{X{D~pjRd=t+-bmA^9J~H zf3D6~X_AM|dgnPd!c+(~2~b&&?Ws1h?eK_n^+EQ5sHR-yE_chH4__(}f_E3oi*3+5 z&KCW<(*6cGRyTyN7$E&u$wcz#Jl+>g77SYLY8x=%fDn}he@_4VzB+{iV8B>#77Yc1 zL13U*NG1vj0>dFFTqqR?l)~0kq*iMVHM3bUBSmJlxvYS`=c(8|+y9mM+OF?$I!}L> zPmlNO&hjrnJy>DOL^R8*v%|$^vi@I{aI5m4NlDjN`%Cxmo{D}a|7Q`e_5Si%(Ve;< z-^>3<7xljE3*p;DE%xygBe`YRW934g#XGL3io9C1`U~O>h=p;n7Vb7A2t%Whewoe|?+qqesT}5AgYGQdEmH1Nm zl($-vTo^RkWIOG7-)^P8vbD`ua=ME9Y>>OE2g+5O+23;~tfqYgIiMx!>TkyV!=ah~ zr*McDQvC<`e#jgD`>Q#}OVz0lm9dPoxIz7mf+zsl(|>IJFZ%y#l7#O$Jf1$98SZ>Q zWW$5vj%A_$_L;gsBCEmKEv+^A{)cnO^XAZ*Ax`%ObWpez^*1_Hr>Fkmc%3lRb#Ac@s6!kN}G(%kDIB+0_kbEbn$)A!ha&!;Od zm*s8we=_OF`A_tt;a9*A=2pYsXZ#CXzGzC!dYswq?$nVqHE+&Bziq329;`i_8{<3C zhO^Zddoue|Jv;5YT1RbpA9te&!SMzJPuxs1~I_ z(?jE&{A`>KabvEvu#WrGm8{V@g$B$11T3RC-SXP>lXOTvnQB2w+~;8#sFpkFQADu* zw5ExwUMbr4d$z{WKL%hvP;4wH8yW)0K(J6O6d?ps{=8oPJKx{jyXNmLkqWk|*DZbqNs==oXIeq20h>+zcpwg;XCLCF1mYsW>M(Bt~Hy)%YbDtiu@ zGhnNF+r@7U)!`PXRkx$}AAi;>jkRzKf*okOSS{ zs&Lu$tAN{KnH)Zfvd#4R;fm;=q_{@5MruO7P%`37g_%G8jvHAvD3uIG?^G5a4<8(I z6sIC-MaU5WH8MbhZXR@HhP_sV?!GoyXVLw?_P^|RQxaxf z#9Z%T3@&0~Kb!c!bDn?e{|+9s&(k3GOh=wqo11HLdY9XG_~%V#wqJUy?ReS| zWF_AB*C*hG%8k_IEQl1kgxNBx8{gT|fF8gdAUl9S2>~EDfFVr&|NI@AP*~Aog^ILm zTh_Bu46xC~skvGv>yY_!n5ygu+9M!H{Me3&X9-*Lxei-4*%_@z_)h%NR?ZGY-#Bv~ z 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%0D6E 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

FJM_#;f6O5W>b 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 z ze+tn!w7%tI!JUt`JqZC|>$J3k)TK4QDX%TCzq5F1ax{g1~@MaZ$O<{{=aHc)!u1_N02cX zi*JSgn{eX82krr0Y2D+}^x1sD=e*AHR;?S|5No-ZzK$7=5n?{V8OA>`&qOyx9aTVd z$fV;Iju1hu7z55-MGY`%K}hjnvADAXiAdrxb#cw?)I&FaHP>jYjV`G zI@qeP0pX_8sTW2E2}lsfBKGg~W+FU8QFwc(82bOr7*N!^cmoQ4mlJ)AOhuAlFX@tX zjbw%KhJ3j`7?_%Ng+)ulBLU(VR}ER;S8Gtpv}qXNW6vHDKxE6wrECHv2!(gz0$mvl zeSgi&F_dXBOK=~?l6uOyQ&ZUC+4$)sFK+FhfJ)jEa}cFkFeE&F`-i`yLS1G~)Auw- z^Y5yU)GEUo`D92gYiyC3j3r=v(8pyO$!kCpiW?ioNcphwL9=`!+2}q<1m!+>CydGx zoRBC1jroxM36zCd`9;rKGV#_dy>>$KpsiTIFG?644d+1|z96neS?>f_TNNlem!7`$ ztND(hf5{+`nb@>xppG=#-T83O+MNerAU)zzSyJ1~@8Q+IYTodkB6grXiT^4HOieh0 zh?~$CyMd?sU1KQd)kwreWkIWI5p=E&b$h}?9@D&u+2UwUKuc>T<~1Q(@v+6K*1hS-BB7IyVPfG=yw9E4shf1QI+|Cxks5UK9|!lgnP|HN?$z z^rTNxcy76nZBF)X(aca-De3y_Fur`$MXZa22(h%d@S^LTI@;;3?zDh+g3O?8todEd zr@wrfi$m+#akS_epq5$mlrf_GD-Dp8jsH0t$gz=091Wwe7TrKwjb~ z_H(VO4+u}7JViVcsrXh)S-H?g=wgJovYrqb>bmyhY#sA|v7oK0UT1JWiwNf%3y^w% zEs;^c6NSYJ&il_gnENtl7wLRAtVxD0vJM0B_-7t`>$y7C^`%_8$bor+ji){L^{=k| zc447W{+_k=Xs*Y~MPx}F&{r>Zf?1&tlS=UK&;<+w`je#p12oar`^$wp_iO9)+<03t z!0Z-jD{Q4+S$A$E;@nj=y1u!DMkURRDpNoWG^6lLurpnboF01vi(h})C9=|t-$*Y_ZPcC9N zE1&36YgI@gx>)*Sm%6Ib2O=$xzFqWmzIcTOi0XfE$)8%t`NvME;jtpk-j*4AfcY zc3XChtn)w{ga@aIqtq;kz;W{~HRuE1LNa>(X~v;EHj%x}_| zRLQB&)CPrex3>@NKriBrUULD>9jAo@VmLYgRX8TY@V+wvfi#K@>FA8M7e<3elp=%~0RBr?o~huLS!E12=4sV~#*f@sblff>7U?p^?Z?k-f| zJALzzvdf3Z2Ce!R*6L6bPg%p8a>cbTUa1-gb=j>CAs5JV zAPmijaAMUUgu)Wichp&c=$4L=4eJ@&j{D*+V|(PvB&wmEOSv~;gNGI<&FW3HZ@3Ay za782RGiw1mY#MGiSeizDkd@-tdo3BWrISC;L9m=G(p)jsNuN0qI8LonDCVdw86Ll$ z|EeXjwUucTl&FPrYe)`(Pr8N@ST5OnoPc3Eca^}tQ>ZHa{Pk0NZmVZQDJ~Y)ql4%- zo-@oWJKHUxcY}+Ib4OknA3{81em}A($E@bOL(_JXUEl6fc~)psNeT-E=HwTE!-V1; z#4l?CZ4>mTCBfjsAZT)I#PS8E@ltz+SKAm$j$p&%5t5tj`LNhZayFP&Jq; zxfVeFZ1gc1+$9VLQQoK`k^zeC4FVG}#yftM<69kin-Z$C*{Aonp5Z zj(UuSN-ECi*F--xBE>F-xp1B9Tqk4nE+&7gv{B}RQ@YArI|xuRrYSyPZ$|%|Ix(pd zEjP{t>!&f`3kp@*+L;!Q&&^0q*R3j1@EyKu%^}JQvk*X}IE(tTCf#6wI ziBF2U(g%){{Eord&q#GC4x8a74GM(?Nk`BR*7ErsQpQA;O1=hT^H#I4_GQgUgoQq} z4WESQP94l(v(Bk*9P;S;KIyJ%D(b>4SnelXhg+wSS*B=ZANr^Mj6i*uEh!aT%gX-2bl5H?Kq|#G8?>84>R`??6g>LyL7Pl=>$pj4rQH^CWCaVBm-QwwXIJO7xmj1K zh*NQudUS&e6Yqa|#Za>eagtL_ZLju`$wLY}lFq>>f#eFga^3g9-HUM`aF-dp0TtKH z#y;l&+fTP0$kv3T*A)U4mos5JHxlZDjFYq70Op1&D73=O2T;yeio?V_ge9AixM!zkwbDbO0aePq7Xp zURWb5>L?13B~EE1aB*te zQ2yLs#NEyDoaZ%66|k0!1D{U9Xa1?br={H_v;J5nZg@oz9>m`2 zfpNyaFakWBb}&0)U5l5Jd^qalDjq`%_stLAMRW=8{@$vfjX~rJqAXUyj?u`q1@a5s zlwpdjo%rvDJehgX1oPMhZNbW5?5x)$;*yj>hDOBCm?^9Uq+z=J+v zbXI!Y(lcT7d_{b{(!~_Xp&g$4(_#=0{%GF?AG3GeqhwNJVB>)ZZ7E6 z0TP-1%{DMuDK?s~VsRcu-^=}#8Fg*9qt&>&o9{)uryKmVUyOB)C%N5i7>eF;WUSye z8$Q#{Am69C`Yb{9!vsfq_ci7j4-$!^liAr(IU_rfp&Mhd@a_DJ|BhJkgtngDnw&*c z1U+)Q^k3qmLthnXyi6m3DJwDMzULmRZYsxqjWTAvRr!lt%TvXG0QN~v4LTSc!}eK< zv}3{q=9~gu02zcMSl`#2_Qo-WF>{Q>*{y3V-PI^&T{PpiwE26}_o3r+e{Z$o^p0Fo ztk5@qZ7!9uEJ?40+FmSWG!pSfA>$7mVja;DKth@Q|G2v}Vj@&!O8Dba=2h6(Sx(dk zMd5F)ZMpZvV}`$9$(>NG@o#hV=KC)P&3h0aN>6 z@7sJ&>^~I#U>KJ4i~HXYU?!zqU^R3 zO%>nrql>?!)!!_Kv?t_TKXFRPwG|H76R#;k^4E@h&Ia7{b2Dch;0OWW1E2>09soE1 zkP+5s!(@d?ktSSqd^I`L_#Gb|YoZO3tFGg*%Fcd#W3)}A)*=#nqF5X=^l{WdOinHz6eJ*oC8;q=>aK*k%4JUH zu4a|8>ZT9fK5Sn@RX*mHPRbzYRX*ea&Q$_<3!DVU$C~_26z2P>O!ZEqz96^Cc*5@U z3+tx^++8{Kci!CHcP?*zO5$o%-Ge_JlC zD=w4IuHPeXxlJ7pj#IW|XvdJbJK}DMxhV^cZrg8VDhz8$ow%QG8eKJ&b2n#UQcM4a z7vmuz`v#CE8$*_q`^W=pQ-RS?qK-~O!Riy1RgafmmYZ+RPcN!oYOIC9e*^!i)H|rr zhbhJ52qm)N;zyr>@zXQ*IVajns?-)0gv_LYLSP_3ow@+f@o<89($q-CjKsk%k^mq` zKp7GhN|`yvNG6x^p({3O7=Ks@pP`C|4$YO<$Lel?(^-p zl<0rqc+lmqJ2io|K7j(M<})wkdx|{n@DR=7iv~m=;70)xnf}!#icpDCn$L)9Phr)L z{tqGg6o=>$yeAXv>nrp!+>0N{KUr~jgQHoEPbuS}Tan(Lt)>n=%r&Wwq-lIRz1ZC4 z%CQZ6+b@$cDUF`fQ*E$=q}=fK{jIA+-lTeigKE((j`lvolupkHOC5`Q-hb>*z4NzS z>Cc}_b?d1{dFYy4ak9#+ibSqMXSS)D!&Dr>J<=Fr;E3%KK$l@CZh;Dgcg1QG8LN)1 zW|th6?}*xL?)IN6>&@#k>RcwRpzh_$Ih$lv3|X1iBw1;q>Q$Q&;Dp*+ZsVaqJpecW z0I(SWfE|DcQ$Mc%A7&dgN=&J1+luO5LtUHqnZ~c5(im?}L~!jAyB(%4j z#(q#OuG&-)7sAdblj|F=)8hUIhi_?J{)y5K(KX1Ew6nw}2y1H1-6McJbTq7_0^udXE2=Tq=KYQv5p@&>Qx?YE?(zc6X*C;mbOJKNrY zjNacn@O6rP?$>I6w9S}|Ml)gJW57mCzqLh|mP zzX|BoRbwDzyAwLrp89BRa>=`^3Wunk@nD`+g9oKuG96nicNP>LMT$!ikj>6ZslE_30(G}e$M1A^OD`xC7KVG>6-8f?y`bTka7nhQ6l}h z`y)BdAC}THl`WFh*-_q0g%2o!tO1^BUEj+W*6~;A_Lj}Y)aiK|4E`-W+znQ;r~^(- z+EqfwUvWp7sUf~J1nvs5q(-pmN?>}rtOZm^ru_TYNl|$L7ZOEdSC2L_SJLn5gGze_ zp4sftxaON1XuG9%FHgrY^+9Z+8ugIAyp*U2VnCB}O?ivWwlNXdzv><{=$@|s=ny%7 zimQy5f2~4nAF4?SW)oB{rmZH0BcRbkhRY&m?M*Wc`$CDk6n9ZUcGp|*%Ffz({iBmg zPCWc^Va3Ivg1by?YJ_g*7X^V-Am%3Xf$%k9~zDSP^Yemc(% z{P;u6wZlofS88RR+<3&1#SA+~sji^xDG`{$i#z3-O{ExGB=WGaLB3K!)gun&ct}eu zAc;r~*H<+h&&tlg2tn(UR_a|-A(NNZv4bKH@FRc#00Rs`n`STn03Zr_dgY~01z512 zd2{1el)Dc-z$5T-rOyU=rW&WcDbpUdwT*a!TIyoUPciJiM&PhZ?U)N zIf}!wc6lNhCn%6iG6X`q_x{V!9!}{2Qyj%2meERrJ^(AVmsMN7;*n*62#}Os8t9D= zif=ifpjh;v4hFdix=so*5WBxH6Mgoyrith%2Wc)?2MMKManej+xVLp9>#^w+HgI7s z2y(kj)T6YKYMw(_^SnOVL~AwBog)5Z_!M3)4gGIv$+amaUm4Vqsj)32 z#Q1DmJW-)QwkxMtd`b=6qG6ntX+y7>v_#VDO@f%Fdk8&&VQHSmQ@?)6=f*2VS)-O@g-pO{Tn^8#IFCzK_O zD0NhJ(9+AXyH0Iwpdu4}Xr*Z&c69%~o(G)R{ze42N-+0Tk8a@Zc^HIYAO^II?hS2L zvq#68Y4Or{jqV^4L7B1 z9=6Hio>~R$FwG)=B-p#Pesrt^zSv1)0GSJAH!pnfpdoJFv^!QHqJ5_c1nG5w1D@!B z|5+q#wr%FN*NI~a@l^i#*o3Z!{5_hx?^ONaiqC~O$y^YA^WcKp7%r8du=3J}Imh&B zekGg^_nX>j@q!E9mb6Bfh>d`6sFqF_6%68*4HSGq}XSoOg5Y#9(8WaVC17Sdza25;+ zf}uhvP(~36ghXKyzfX^TJp0$1=X1?fOrF<}#M1MN$yZ@N@q6h(`-ji!UwRLR%U;dS zm%pp$w;%GZw)(~TeV4g3G}G$6vM;4K-}5KMWWJnMj@i&hWv;9hkUP_We@nHn&o4#s zmiwQR{j!Qi41N4N>;LC9K3`%8yXH)iJac`@)NT~(Tiz$rC`x#PGPk2!;$TBo9Fg^n z`@%Uwe#?eCbPfDg6=*$jXqQ6BDSQ_ZeyIx-v0Lt_2wH>qpa0)~CqjWxU{n?i1%m-# zpqPjj3KW8&5tu|K5i_1MRkxhudebW$Yg@S2I=tiOj+rWkpTY3C$9v)YmfjP+T_60a zHNQ8TOgVeIwS7FO!o{2S`q%0I3HZr7CQGIIaPa##f?=t8{{9L7m)mOfurwKOKXMta z^_X>ACJ5{Gm)}jH7*AOZm8*#js@T0%evV1LounQ-8K(h(wPkKOHgsXq00UJTEz}Qeq36X$~xJTuMHwE{`z?lF~uDsh9@KD?20Y;*LM=Y%pA{L0A2uv5Xz(&)T@x#9V@DLgl z355ZWz^E)33kHP&WFVL*5*V59tmBVSTFbuUHENM`vxKQoH@??lV7pPa`nf!xZ>!1s z$Nm3VzODUc_VG15`Lw?cTy`GfKmGjqe4n_|619yVIy}8*>!X!jFTV`?Y_sY5t}A{U z!fY<*A4bu;@$hV9w$6L(Ies+Pw}Gfh#zvXz&gbxWduXkQ8z1&pnqI2z8Y$P>AOqVWQMrc5Kcl>6WZntfv z=~ZTDe)$#Uaw;_Xwp9+HyR*!HUg4`xIW=G7;nJ&oo@uGi{4ZC3J+#sNm6*TNz7zch z67Dm}-%wENXB*e2eaB@}-AuxR###KW1&3+<62npnxyUmati-D48wDKKuhPB8|1s7c zHPAV2U`rt{j4_@RG{0ueEd|M=27Dy(B9tZOMA=1=ifc`1-V=tA3n3H{ow>}s6T1dR z1OXfY6cj8p7z+*p;bB0iEN2S^LV-}ASSUeL^X=c)ITb3kb(-Asr7EvDwrV7(5cuEm z<2(yr`|kO7eeTw_`_F%W*CWkKwzMiwryuOA2+OlOqE445qq<9cDe?E!hd-_VjbCoZ zA3^DLSUYZm2Jm=SIhy><`@iScp|2U8Qf}zS-KY zC_*4-T|t%>NC4Rk=z>lIL9oFXt`-Z0hJ#?Bh$s>Y1V&*Hm_*KZ_0DyjckRsc&bKXc zrxdG{=Z+Ox=x_gDQuNNP&^*g+D)$SAzthq4pR-1~1KH2XE7|wwqZW@!QAl?9PJ;`g zRkw(7|I_|&P2b;i79s`Cq@5!^bKzs5=V4HH{nb`}WK-9M6PwZX(O*G9ik-D+H{h(H zxyylKm-3+-f}j70`f6Ej>bfCF0^}DdETB{ribkMvxDka0o&A6R{qBndV8EC#77P`N zh9L-yA`%FR`*Gi1edS)cwR?TE(qt;_Yn6F*VBaa?DQbQdqowp~AzvrN)nDcRS@?Y$ z(L~X1YJ)g_vE&a5{P+I!_2@Pf_&=LjQyz5`b%|kzi${~jQG)G7I(Uya;iP2InqR%9 z>fU-~d0&;A=qq&q6q{NowydW5{=4`OLHWcKPhBXbSW{&){)P@T%~537xdqh z9ke|(+svgRdN{vxyQcB<4nL+5Q2Li}gG7FahEcX-vp&kfrB6d0FD3v6rn+z zhA;o@_-T?+ki-m4O8DhvDNQb5;ZgBmWGK0p{atZp;D+F#8jWmp){{8C2by}NSJ&9? zb!?@lkoR(@c!)fGG_Uaqa&d;6>}?|80RtKs^)YYkd%JjBOIYkl&-NG>X!ucqk(7VT zc}uEL7L#4Qd}f)toZVR0{uPg+b_p}Y6O8Dq5z_0u8=#ck$ zldEJQE&rkv609VSYLe+Nz}^g-z=*TpVd!xJ=7Mb9)frjb3I>|J8escO`uT5}5J;lA zEB2O`@1i+4l4m_=9@I_UiU6dX{9V@qJO3RKHTIgd3CvA$8R+n@v7k5g_Q z%A95+3;~x=gS|ma?sMTq7~;&`sa!eiHzdhvL;i-X&8A5us44GwGb77=iXJcVbee8L zha`~yV){S|9)wHbu{2Bbb`xhgDLGZ=MxjG5lbDM-^~i3Zww^a<)~d($VNRw6A3PCZ z|5%WwKaBEPTuft^IKPeNXfkDlmK`3V8?sAb*;&=>;AG!%(>58mt5X6JxRpUUnv@|+ zs5Kj6a%RQUYJAvYt=fh8uI7lAWd5An>>sfmjq4ih z3T3*xS8s2TPK^4UdS_4qRrK<@OlyC)tt3rPS6|nxl~=%#H`O)N>VvGcsbcPFH|K?> zzd+Y5Z1NE9&%qEl66bhg3GV>^ZIG*K*5bKmRbByucmlLvf9s^~Js7%S20Bh!ImsfR z7h8PktzFOdi{acBuBXE|;V$fDRGPi}dxfPMw8!GrcyA`TcM51KL9*Z?ssT=n(Dq?G zD{pbnl0(g&o<$%>|J*lg;#t?WK+T`M3oJUcTCHjC^qi?T!&w{B7p`ZzJ+e*vEfy3y5F-3q{+U|*>kSZYe1TDRmZx4XryxsR4ybZBzc2Ywe8ii?@`|mD zOH2hX2VgP(F~DNr-(n}j^nas&!?d*$^4%X_K>Oe#EP3}N8o#U*Ee@+oJn+y;Qs@U= zW`+{*MfbsMJ-5M;FlYpHJLVw*RD#7Ttp$eloNAfD3ppx2nM*pRFn|YXX{=tn*Xu=M z_H%C?VPE8BQb6-ecYb+pZW$X}0N8Mp(N+nYB{fq1`2z*oR}*(zTeOF)SO#CX%~McH zdd%Bz73}o2lzP-+Yxu>GPQP0;L_DXpe;><$xh`c485vNb=ekYSYTDh!orSCNBA5W< zu2}hOOx(a$SwLU?igu`czvi5J=eIqU5Q|{-NHhE@K5R8{+&L|=d3t}y3$z9LLpt#_l z3Q&77l^j5^$w>`T8jRH_uMr%2f#2A!7@HVWo47nyJ5wb4_Lv)NJ|&k$Q_eHR=JOOU zsWWBKX-zsB)@vh2??=mgsWeP@91R9tZ04Iu?wF;@3}3k#maExZYBGZ)#cUPcj~$X5 zb$?nD*DoW8&@jB+ zisZ&M*AF%3?@Jb`jxY(E^sjcq2GtUn0R9^^+V3BEbc%IB!Gx!ZYsm`3u&<(M&95vs zF+CA9;7^XMyxHq0$eYn*nw{bcZfgn(G3r-HXJ3*DC{8$f4$mc5hHv$n$z2(vl?rOo z#-jQ<ngIza9wO|N4lqMv4|J4y)mHvsJgo{x zh~FwH^FAVtixIJoorJ2R#rQWunabTuBsv9zxn3s|`tRS|?n+DvhVXll&{WFI#WwJ& z`%qSa8|@^$EyBpaeo2&{tH`m@GVex46^~+7AydsDcbyx0=YxPzHs+wL`(RM@z#`1l z3^=tyStwQg_oFC@2%SKRmWy{5+pYL!T(k#YU9@28m_F_icVn1eD2fr=?>8&KeQ2rQ zT69*4w|^-P)z@y;dxbIxl=z7*qh6+(uBIYfV*jcKyXs7X`}3X^%9P~r!Mp>q!io23 z3@R7YU|jY1hNCKJ!NXa+@*Ny0F`mDn(bKk@iSKkH5u4*VTZClIo(mGC5W&`s8TT3- zEoe9gsx<6iFaS{6r0l^M2%{#5vvmJ}q}i@WXr-%ev|0G%E<-)$>yZ1`n(Kh4QF^*~ znv-yN-JMA@oJ_L^{ z(6p|q;WX*BKXagl6+3DAOh$7Kp)cDO*yKr}o{9LN@e@}a_62~)4F57}_8+2ioM#H* z>s|1d{sy?hC%hd_AnyOm4CxY8^9la#(=XW3135!T9dIz66!%1n+oIPB7^!$eZ8?pl zp(E`n15ojPZ%lMmTIGge_8-o3zYD5b)d~OVn}rY_E*^da?}pA{%~EgYdHC!T!H*v) zc{A0~Mrc%&8n+C?$9;cmNXc3VE$<|OzbbXJkxJ5mZ%Y_^_bI*rg~j4 zpteCvB7a`}lH<rWAIO3|4LrMZ`=#qv@+do%$D&?@h(TN%Qc^vN&hcjyw!rxelEN z2+brqaPbgRCSJPSTRS?1c^KbXKc1Lkh>4PJCdl_zg>53$oSqZWRxm zrW}Wu3dTq+x(aG%o~NHDi1AP-AFZLl1!#Fd1Y@wMwL_SR+e&!$7edL0a)xzmaY1g_ z?kky|IKl#KQx@CDN)EZeJ+|&G?W<_SuirV9U?H=Mqs5 zdvWU({t}^MN?oL{T;_U2-ODk9Gd8`7#?otDTC(k5s-W@vF97u@+k>(EPkM@+J`s9L zyZ>eI2Hp;pRz>YhpzDdB$~CrAx@oz03oRg1(xnw63Vlt`za>-&T^{Q|;%OYf0S(16 z0bdIPD%DBwzFsf~qPS4P-0S?j27wcY1yTuUL%^zC%wRWBV8Pe zI_G1$ni_14d&HP`?hl@O3P-dYF!FkSR9hxZaBAiu1i*aDhFx}#5BSte86;?MzwCs% zTEPJse>Whi-ghG(e(D2&LqW*+e5JD7T>x}dlU3tVq*t-*#~3#@Ap>sRR zkqU@bZdeXB^C8p7z#|WRQa%+vqk2PTh&F_=lF^_Jha$TQ-^7Z_N7BnP=~jmQ3X5$N za;pfHYfHL3T&NUX@P6rcO7O1Qj^dT%=Yt%17gakr?G9R~>;=R;)u2p3gk>soj;Irq z@p+AqD0a_6Ukh&^+y&UK1T993NZv*-rZ7IQnB<>;Y1XH&{=8bar1S1$b9KodQUe;&%ENO?d0Lp`^pR&Gll`$9#^pTUlv-l&b#LJ==5Bp~Kdmr2 z&?^ai6Rt2LSox4_L^)UeOu=S_op*!k&0D8cUYg^pfmQQ0lwLaMMj+z#xTwW+dj z=J^zj65l+rx4PdSdcx-S0HlVuz4IXBDko?X(R5*D1RaKLbsV@-B?}yaFsPYry&?pG*b z4=Vhrd~1WiD}X+&rW4o{({CB}223FTABx(;+Pgj4{H{%MZ*I0<7+ssq+T5P4Pb-b^E(;qtZ|71CM2eOEo%k$v=w#SOdc-AdD;wbGF{$^4OrB?v4qrXrM0Z-B2kh%%Nx^LFHJMcD!*+%9#>MEFJ%^s*nIU z@s@WU`uGbs2c)mzet@7tns{%w;SN2#$=@V4PceKVMP$wxE|JlDN)Z>`aTzvZ${Ppy7f3s_R}+F)5prCZba-tx3Rb)kXRb1MTP2Z^aQSiW^y8@K-mQ)R+=?UX|v z#gs~si^UyA9_U!o)?yjH3&o-&o5R_w!xnOC&Yr6JKPTrKqPyQJ8{^iX@lmEQ-K}fZ zHMX~Y=a4dwkCqZ4gy3DZFVKev7n_nIff)e;t8%(;A}J}V{Pp)U!?Ad}XcqfwtY={{ zhXbmIM5r;w9-=fUISG_Qg24_g8xWXPV$3E%ct_5WC}u{YQ$seBbhmvolOxJ{d_UA6 z_(iq~zM0a0>WITNYK#j-yO?9Gzlc9 zx?TyOQdUa%@a=8j#%og)^mG3sp{0t+RK6u*8d5Y29EUHdbcs{xn&4uV;9nHlC>)Ta zSO_vmDtL*2L4LHO=G^z{!ba8*UTR za{CmCLw$CXenG)0e{_FQ_dLseqi*dYZrW*3r-QiS30)tfd}d!hIXY``(Lw81&}L`0SrUDfCB49fEDIIyKZR4?2-VdI_f-$O z;y+fS;NKFy`Tsac|E2~1J=JMBv_KYV z(iOOCy>IC{@Wt&q{kKb)38=Qbaul(4en;-El%3ew<~FsX76tziu?by83z%tychvgb6?q9qbytvbL%-55h`& ztcddJ5Lj$2kuI0XeXnACI(T@&Vm;!P2j6K7n;ux>Zfx$Z* z(3e!YGQBddDd<`sL>;S!JnCiw?Kee}Z=N}bYWg$W^NS~Bm*jis4iG*X#9ziVx>w~(_Tsl;%g2gC z>}g6&5(#vh;l|uK>*qUlx&!V!vL!UBKUxRyGb)QA0U#7CG#Ctpg8^W`oGcg(1_FU$ z&{!yS3I#$XFo_)Mq`mdc^E%dUXBu2pMw2*Lfbac(HCp|AAAEl}Y!LWYe`T{H@6Yr6 z@ZYDY?q|Ea81i#e57zZJoMVq%Y}rq}>&x6!cBe2iRq?AsRjNE)hp*hp{bUcJc|2dJ zLC3ZowRpGj5bw1yo%CKu_&`jxP$DL(H-zFk!fxVNoY zZm6NLio|Uqp6Vpj8^{KxWdn>++Yk_i1$Y1Z>;7WJ0btNr&=m_20>MDAP(&0F1j0cP z7)1_lF5Pp+`qehO)TyoNmzB?5RK^26Pt4bPQGULCOfUXjw`aTJ+_-DwaEHwa)sNiG z&_uLI(D{k?troKt$XsamV6%bq?Wlh`}=Po>80yDbL`=40G1lq~Sk^5NI5 z*YUj`N8=1$gYPK(JwLtt_rO1Y@JZghQ;|cxmUNQ+=`u!tUeOtH?rrxP#5q^(zch6} z77f^b=WbDRjY-sIpnr+xw2@iG{0R)2!R)zDiRDZE+k%e~rRAflU0D{*_){wL)cA^+ zf{>{ofhHX-K)jH!DJVd2ObEh*|J(on{`|p!(3n&h6AFUDps;8xC<_h(#6Yl6BohdP zf+c&*;k`KRr!wl&lIUD$l#qQN$<4O%?DIA9et-4byNtgUyAS4(_Z^>pYSf(sTy!1`v-gVD;q&Ei zL!KP~KK5JWzwN4R9iASaXNQozU4)cbwj;y5?W6T9x)YJ;r(fUAquGuewn*QU{RjCt z_M{9E{*MwKOVakB;9a_+>AgN2@wz?VNS>$*5MkYqFt!r-7SJC%U1P)MIKp}b7f@WG;_X%@M2ttB&Z~yc6H({W_+$>iM5d^|Qs7OLn z2$<^?#eI9~y4O72I=-r2UR~|KXqh$yox%Mq++Mct4*);f{GVq2%z1F{TWjd=OX54I z*ppp;*+%ZG|7Gw$>UvA^lsepZPvO|9dRDiorNEU>vm0E*C&af>_vl7UcQG#CvA z0>PlL&@L4V6#~IPs8D1h2#CTZ0G;{gS)Ft7w^akGm8z2yUcM=Nv8wF<|NK3|H$k%D zN%P>{1OM=U6mA50-b}ChZ{fYI{{K+W&l#!eKFR$oj$9_?Vld;<>TuBt2cIxw=9hSn zqdtK_A}`8xEt0dlqOW{OD;*ArN~Hy*>vJJ<*1>6WPKj|-8&THg@Q3S(-ubcx_LSb= zSzj9myDmUYG?Ia2CXoFu3U0iBjzC5f7w_=@|M*%I7J|WoFks9$3kd|mK#+vM6-cIa zk!<7AONd2X$)#Nc-r>S>YxaL>S6Yi5ezP4$?|1&##%DpDPf0&~wCRsauMfAn$l9jq zR_J~oEz|kCzQLbkJr6>6E{jn(6s+2}F0Oatep_ac`CV44sG59FEl-fJrJ%e?cZT|^ zvt=Akq^|!>H6^Dl)g<~3g^RoRM@{`{ICyWsHF}Cqq!o#yxXY{##S|!N#n6LZHasD5 zl7-$x+HpE@?n2^>4oM=6B8e{8;#LonB1Y&%^Lav$Id@I!i2-83m{2xC1%iVim_%S9 z3;NA#INc(lQmuAhYGNMG-aqwj-2`-wjif_?1ZI`(Mw6LA=?r2mpj(odZB_8$;aNB|5*_Vp85xPZ^F(T;>L z`CO=ft}CJUvNV2s*gD=wV*k`U?*i#X>qYbffObx@THsovOcWnwTVz1G-eq>35dnCZA~47HF8A@_}fXGfyu2lzy-`G5NO zRec5D`}vn)69ME8s`wr$5F|&*25}!b6_J&MOqW>Z+SG@^mNq-pk%|63pXvLmrb|Ak z*0L6P4(Sin#Xh`{hoL3sy3fJ8yMoqPYk@z~bm}E7`#0>pS@chr;wQEF27nSTYBaa2 z!t1!?2gc1fX9~@k2${jxA~*Ki(p-9i#&MVqVOMhEq6tZyIzVg0)Xi{w8|!IyDR-{S)SiPI4@AJOPZ2k?!2c5-#;41qQ~TVP8WeDJnXk{2I++LM_{bn& zNY6W=ySFQHk2bCzHx(rB-53%|DP=*`pxa{bpNWUZd|=Ius})H^x8j~2!SMEcXCSAo zU9X$}-^Qxhq2XGAhZm(s+W|?1yoGN%d)kT9 zfsR=rTNbRS_U#ptG3u#t{zB4Zr#A3)f~+Hg!*(($$6P)oL52Mq z`@3eYe`BJbI6R-_p<=5!C_D~r^-$Di+x}TFz;BlHX~R@hzbfak;x^5P$cZ+?AjXlx z&m3fgP5O-D+?FkOa{=e3$2ky}k`Hy4z0eFU1wIo7dqaW|Ctq^L^S5O5eRLXGPRRCB zH&1xL1nknOydpghme>)=lqJypqpZb!fkC)^FWJALDK=6HvL$$B6qVM(zi80|ng~x0 zK5!uHlXTgNcV0yqgZippT~v+3s29ooSzJS%l8SNm!0m^6NUANR#T@p8R4 z8QuMtF`!!K`?Gh!bOW^`JIHS@#rW=SrA?f$eKsn>WAMJsJckS%aW@?p9?L@~lKvh5 zF(T81)cw%_kzM{2Aa@HFVXVVckrSr`*;B$(Q-nxzx^a+%^qVA&$849~X*LiSXwu3z zZA19`k4q=%-1C^iVv%l+>#fKae8bF>cQ8^SS*h@!= zhc$99=p7<+U$)oQhNTUrYX?sg=>$n+$7~*gRm12E)AV|s9|U5V4VaHkPcd!pf+!Gw!Ab)2OIR9Z za{F1zWrbC>+#B(m+Uoilm8*#wXh)Q!bdyL$ikhbQqSvMooNg}of?#SZstGVQ#{gviBVx;dXg{Q9a4L-O7PRYr^ z06cKG3Y^VVO5?yQ(9Wd;O0Ki_#yN>sotz+mwb%#!;_M@Kv3apfq0GroQ?c z8Pq7vFPm7CyN}Erb=B+6@u0Y*X}~`y4FQI@V2ZWT6+mnxd7Vv0HWBzTT)z?-ZAYa= ze%JO6(51tBU-?7IGw89D9aI-fqLrmDt&ecq*G?ymWvBtF>q+qTxFT$63+>eJ%_pIi z2-j<5BKmc}JF}>UPuA7!N?ak<8(=BI#q7%zO=gea@1*rLu%QODq@X6|JH-!vAQFn40KBZdSU=uaSS z_BK`gnk)v&MRq$*Ye5YjsC*XBu)u2dj4SzUPPZ}TL*U;GwD-0H0PT0iQQEOS@B3^L_uUVYc3XY7Qt|Jb9G4O|(G-)=NWa7<^du1@+0x6e81d&5AdJGgKJ+?eroW6;R5A-@x?oPeJx!AY)zqKO>Fk z|InP}vx!L9*gEku)o(y~ zeBR9H4^!MH$RKB-xZy+lCCA?mdT<*C-b4-qKpby7N_T-5U-A@WE*NPFD{w)@x`gke z`>oB%cUj}V1JRf5#mJ5;*^njvC<+pJ7eyE;f(z|~)!3t4-mMX3!)2-{VYcN&E= z>iUQV)pqx#kbomh8pi@9u|#}et6g^CSNdL}8jcx7D0f{S`vcj_BG!zgdzGB{;E$BNps620K1KKn^YelMSB z22jM&;)lDVw$rg8B&G@_*u;~IFA zdtFZ?@5_z04YDC^J|rf<2=8RU)D-Xyt56DyHBt#|<1I*u7~JKuXh26N`76T2_1k9W zWv&PZSjDyS=tEZtusZwdX8W46>3DcgUs&@f@Fa_4wfEM9v( zE@%)<}Geqq5R$;fa zJ*>e$=5aA~!?P;+C%o}5Tp3oc$~{;s5)%`m4Y=V}fg-*HVPf#M_hfd@6?by@5klYz zrjaG9Znxu2MAPelcIWhqoCb}c;MNxr8|SqiNO#ZAOm(jkZaapy^h9A?j{(hZsBJfs zcLQ+3nRuX&Ki_TP z?pSiB41($<9#5dDc72?K)+L6AbYc=zarp{GXZZVS=q+JV_JiK4Mmhu9{lnztTk3w} zaETcbWiQwGpri~BmgAao{J-TmoXLAY+rIBZRVz%2|HtiY#>#Ocqplf??@ zMJ(z`iVq%8xkULxZ>%FYhdI{$Q34lMgnZg=gPn&)(@JUnk)RzceVj*vuw(0)l>m}Z zKxJwUZ-suN3%kIT87VOq(MYnPuwoBsKpas)N`#tJn6q0Rdtkx*VNYe6=c!X@laK$)VJg2UJ-) z^g8ukuS_cEU_+o$<8f%q2Xv6Z&>v&}3#6*>r63K0Ww@5{%ackff0 z1*)0uyr4?&hSXi&u=+WGEM(zM?`3}+#Rt_B1gc$-DnYb{$|^c68kMP!Pc!dyu8N47w>rd_s%cXo8QORqfuq#)vaUkWd5B}j ztB87em)#e4Xet}lI1B)*q<1N{^PkoWKO<_3pX1hiD06G)6CG0WxA64K#Oano4NJD4 z-}b$tjm>m$@?6s!dh=>Cb-zwX%6uc8M!L~e8Z3l; zP%c9om;UU{D`6e;8qap%=l@pU!wAkbk1=rib=*6Q;1R6qH=BOYK}Nq6HBZ_kH#;YX zQ#MtwO>saJ7(#(+6K=0t3WsrKp@IQxn!M<*W?ypRf{kND0zW2f)`=3()D9;4h=@yNC}DWEyDc&BE6f zCpd;n?ZtVaH%K7j1!u}O_C@OGys(FOR1AtiXPSsVBBlCwd9MOi5pQ{rFkgc(Czx)& zrCG@ED*4@MxXFKt^)@}EPFRf0UR&1rd0c>|VuPbcSoMh$$Ek30Lk7!}E0R&8#d_+- zG;M!G1u}CWBoQahS4sjaq`6w_!>pymq@aKovq*YUwcDozA(3}2dv#rit%AYEFwMcL z-pScLw%GL}Th5yi#vIq|w&)0nt{H|b@`dbM#$PY$2h!+UF~)0eQE_AmIA5O64h~N7 zt?2&vU=*TIs0G%Vv(^5y?9?{Y#5@enZ3B1YSl56H#7se!rRO2Z8$7INGzH}E!4dlw z-$Sh*Bc)4pFS7KajN84fTp_s$4hE4&+c_*HGH1M$2)0^cB@Xv_Y9y4rn;E#(Y4_;kfR}^|_P65ev!oUx%l^%H zU^~Y*r>M1nWFr=orOagIh@x%~+5JmuWYCwNmo5lmjgjQy#!M9-ip2tO`YgWW%3OlM zAPbUvY@8$Ps;n-cHlZhtKFkkM^u{huf^AAtOegLSqGDHI*8kT1{+tC#Gx!Q*Z&6Kq z{_{kTBR@5)q(Z7r%?3?pp-lr3EpEr3Mxmy5*;Y_4L{>R;x6H@Je7hi`mx!k=oP%wQy^ko z$J2}j7jiJGlF4gppXKwJg5$N5=@vangSgh?0zcgcIp9iX<_T8@Ff(+YWwTVcHN50Z zSYiC|vuOhVO3Q7Vn)6n(k`8dAOL5aM#KmbIc{S71^;?Nat6O;kgpTMwO07{@PF$uP z;5(V|R_tG!H4SA>qFOPV3arL zn|gdy-Rzu}v9|J59nSt7M7&b+2ThW%SHy3twh|43GB5g!7?~&W5y>SrG9bI?YL%VK zgcS$G^pp@Xax-E2z@ZsEI2Cpu3r_31yLMg^aZZEX9!L-u8q9C<`>YP$R<#kse8BBm zJW#r^(O3G*e%nyuh?+5eVt_j9ks|Dcwt(wMZ@8U{f9KNP-jd56KkOq%t;AspusOlY4fuH9DC&}={M$0D5@i|0pcrTk)$aoDkR{<2uMoM|$F}s)3creA4;){@t=&s{gU~@A;i> z-;MQhyY+pT`5%16xP%fmz#VY`u%YtgA zZ3JiuTcb?hD%g+6|y=Bt%s=OA7@$*0zZ zIYN2#*J7F*Q&~T0&AE$hQrs$sx;^- z-PTN+x~@60EiNkRL0|n{&6E3YBFSqeK7_yTXdY|Bs^n4JL}o!eD|vWzkj|5bHNT&S zkLT_8vgS8?tH}3Xk8PHocJ^0~Z!sj<5@~4l{k{#SrvABZuRHY6k~3MEQ=DR4ciBpJ zsjmn&P9vfP2Aa7HXD-vPI61Dy4X zXzGPaB-2ZFjf&92+~29~6Jyx5V6rCSeailPe6#$0!uN6b`XyW43y^5>i_Au; zF3zo=H1X-@?)2H$_>=n987y&f9BEo@`SbfHUoP~Mwfyqhw*SG|&v6}j{|O(T+Q#SREEfmYJVGqPP?68GqOOaqP>{^r#&2Zm&2faFDJDd*CnMg zEdu7Y5=wq6eTPYBQb#q@n5eO`b+oLk`R{`BYK-W0{+*A-2#RRYUKNm@D)NXhWB@=B zzyTZ-EHoJm1%lyXz?je!3k42A6+P} zI?c<=lytQkjw@h519SD_7YSH zUwioq=sNBRU;2yWIa$i}M;#y6ASFMErP%0D| z48kl|w5{Bi$1|#UlZ9qu=<{UbFZ2k|>rRwrFngRdgc3#*CZ`#r2 zN9KPyKLkxD#5oT$)7l71)J?2_e437uxS$w7@5j*^1Ls9b8C~0ce;GQ>f-u_+wiofQ z8pgaY>y+GvkJSZNCf0~0AC;*wmKVGUf_5yGR=L;^SP=x5rM|#N(BL!{3<-k)WFkmH zBM6)V{M@gvm->Gn9qU%y<5hj@UB<3geQK$|RqZ~jZRxLHus&Wkt^c&%S`~loUl(OJ z)!*T4n&=*=gFXx|VIk795hXT+pHsjwBD*ufDrv7wTH z5rqZc;d}mm3IjobFkmbg4F!b;V8B@@G9Zw`-`CBV8mh{?<1Xc9gp%ehD?t6kKhyjA zud3(e`)hmO&!1oJ^L2f{Y&CuVU$1Fc#QnKFrFVC0t+(y{s;(-Ymmifou$fPf{I}(! zQk^=aD*Ai2-A=CkmCKBJL%wv07gx$S;`E=WB94*$Z9Cjkgw9%S9 z(qO90HXoudTauyP2HVyCdEa+7|K=lt0Vu}UE)FGH>BlS=sfjg1NI&pMw^vyU*A_%? zI&4&kp_3S7jtCumIX3o_GN@WZpP#yRwrM@Lje?;KVWCK1EGiQU0>OZ=;4E|#2?9bB zfI^pA$Xy8pA#rk{0v|U0bLIz%`P}>0U-QxB{@^~=_+$F~b@+Wef}v5R+2#*o(&) zAJGK1XPJh-iR^drjcH0M+-n}JnD&1KREhjX!6FFbZ2`EiK{X5Sf>95UGx*gN6Cxzp zcFftGevTAjd1?yTS<6P{cxUh@)U|gq`ipE&jDWQPx7+KfD?~~`*5(O6tIPAaX>a2A z2b@6)e$qxK7D*1^PZVpSQvU$`d`m^&mh$vd(0x{Z0w}_!4>NRPbZ8tKQr6{Qm4P#KxAu+3Z|%{C^cP!l3CC&D zjse2&CrnVcA5|QzN@7@a$M=Jm-Q*sK4XD>tVxuR?l5D)Gf+$MR`2^r*%Ks77`v>!e z$Vx1v+=^p;+RT$v8>bLN5FoA2ki(_lw)$Mx=-KHZ9JHA+Tjav=SMz!;tbtMGpbxLz z;1Je~m!rf=HK^5U(^ut?*L$jxSKU%Uqa)&>9w+~*k+UASB~%2W-cOn2e~ zN2$*gDHr=jmme0TgB~jkxLR~5-SCtSJ2UFaXDqeL!L07 zEtX5l^MYoSR62F!=)_$-xpiM2g=K-FFW!()uQEHFL*Lh6;JoQp+$kiO9oO+k$u+sAz8G3P zzmpRN)?Vuw6I!?L3@V3{&VX6@xnmz{1D+5=T7>PcYXwPIQqAwEeWc{e#?Y;q( z#-tb~8~%y-6j$#GGQz&3Qq**43l}PCT}GnhiTy~p5YC|tvIe3d?GJ!zxTAz@{Ei

e!P52lx>iXaw_U;Hi$7d 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

  • Gccs6sqo9#&%zN^|9bZ`~lILl?=>eil<-jfa! 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μ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 $2j8wY`y?XtWc2?Fb>6 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%0ADAtutUJjrL?5* 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%0Ag=qj|86S+BG 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 LBjYa*Wd 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 z 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%0A9{BZ7?7+I$oSkk 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

    TDVeV{+u1{a4 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℞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 z ^Ov{;zoIl$}N=${|Jf9JJ(_J+?!JdC5qu&6Ifwy7LkkPiGD6)m9r2+9>$1AfTZ zi+%4j&PFs4w^e+yFBtY{f2^Whznq(l`P-kAq>B1nJ%tsMTS>J8tGTIV!#>*bfmvDY zTwRw#n8W|&^ZmfR4k832!l!^ z`&mJ$^h?vKWv%8-lbnXINN^)K^95P?T0R-Gkkg}kt?osbO5~*EGPO7EZjh=}iR89H z0eVp^#kPJI11jqe@f#3YzcVc$_g)>cbw{S_?!LQ8MST}S0_)ldT-yM*uam$ZI2c%O z@!#!$V9;McJEJqa%aW^SFHf}HmYO-LQ%y%v84R_&%ZK{?z2ENi555gzg~_+wQvl68 zf45n6nzWuL^5*9Gr%l>ZEBM#NA@i>32Cs`qoSW5+{`R$af+rvC*E4108kt3`eO~WH zGhUBW$NKRNS~*1$4ZmF#^675N8eq7etL1zrw+!MVfuz=XSu9c4jR?@P?Z_i0H`@p= zV_XljF=$%s>FEGB3t7`V@@F-lcM?@DB5P!WYBUnV%t56)ip%qf}eaE9Mc{!xDE$)GIQy$~1)GP0+r9J;8QD!DKzE|P z**`zIK(*2ZmEJt};4zs-Q*i1|vxcCrO-n_ZhteT!$yUmQTexDZ#ssbn4abE3M;L%I z5zd7A|H43J{7+OIcD$FLR|O#isj0=U0 z^WK2b$zUG@06c`k5FZ=;V=ZcnST$STc&NDoQB%wJWV87hN2H8ALM7=G(dvhaf77pA z5w1$w6OuHP6&82v{E!IgRMvH`H&u4Rx0P!-%vPT$qUzj4wz-NI~;mO{qhYR^Or?iLwjZF|h5f15NdaEuvB2xT|O zbtl_HC0_*Le_R*-2+|TJFDqJmm7tPlowdl(+_aDS)b=f<{v>tMwxL6DX*j`G_Wi)H z2`v|8w`kQsO7#|*6B0^pG~6|}wxlpe^T!a4Q-3GhSzw^1h2+i^uX$tK7fGvV)Xp?2 z_|GrS-4+ureOFQuMiYe;tskksBuC|;!nnD6tK0s>C|iPu4%ig)m zdb+)8!oO_DDV*xzK!3B@{(Nj__grVaW~BkOcG7^a!k^F1_LQk@86a5mkN>By((TBL zK!`i7mI1C&(|psmjsyGICRM3c0RJ$`yvTF(y-CMy%U-?KC{k%c-XZaV92uD3X-jqT zkx^&VnCM`rO7P)c$M`!LqF00yhVk3o0O~1CLprAfWZyi@Gw6>DJdKx#P&LNPJ&`Rva zcOml(qaa$sP(F{Z2kDIU&r;l(^bsn10{G(fwy)Q1ilEry)S0hAjg5ut1%AFbcj#BB zIDv*RsdU$Drbt+be zWx_!xac*XEx?`f-blSLzs(-VH1ZmP}oX2;wIBvp)^2?VG^ zg;s**v>seFT9L13wrn()YnfhgJuEBxnV_gpJm}bpO8$Mfsz8_*Gdj^7lT8K2Rn_78 zhJ6yDzOG0=NYXY^n{w#!dZ@_W7k=289B^RyKT*-=(W+@N9XS*s1jDMyxv%25$+dPU z0qB_Tb`;LBjcr*eNM}GBTS?XXt~?R$b)Wm&D`EA*5d5pJvwQbJ($_jUi1SB8zTEW5 z?jVbDAjoTjKw&7a&4YM{+vD4tNZG?Le-n-r4Q^;&C4N{iN0z~?-gDV%H1pct7yHe# zJlAC7At~0`2g5^r$&q>T^RzTd#3Xv_URKUwXCzkzrTq# zMdxj^XsZQ&fh3m53ax9^%CZiR6I9inhQz}

    &rXhBrEV0Unux56VTiZXq2AerGeK$5q_ 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�kLD)=Rebh7QpZRfPU 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�VWCk%39<$SOIyb$0Ulb`;iUBfbOH7hr7{ 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 u#_`waKtR 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

    L3`( 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 z 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 z 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 b+%&$F3gEHio;e}x(&=K+v!62v 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�_D* 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�^+iG2ZxdS;09dTa*IL@3LU)T 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�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 cb1m1*;uDkXw-(j*$8i~~Mh8KRLbBqM+3 zvK5}^=iLlWpZt>Fv;~sS*WLAX$fv^9PQlIDYqUXg-E}tDNR*-JWpEERZ_`~m>YzFf z^VS)RN->sFHv)0F?~SHJWOQ436_NVS736}eEgDcVoQcEzI1g9AvVKb`BV!utUK>)g zC#(xBaT~R-X1+Q3<+eO)WLAuNv$}3j33FA*Tu+6YW57)<%($z_U;<*XuNu+0nKb zwNzZ>m08IacY^HbC9g}hPy!2vNIjv|9(oR>+xYSxzE@O>jhpQ#x?($xHIk`eA77i3 zT*h}#r%}${@MDjG#k?1%9~`9?l_KCF$X48;d2Gj8c0s6a7oD+z-oJPh{_uun+#cnU z%pF@~Olr=28hyZ(Th9jp*8+~V{TMo~(+NUHQ|stvorP=|p3fR2cIt zVd6>_(kbfoPkj7m5aKjO9yWqFCPTx41->g}5`$$CBDIi9C>q$C8d(Q`c3>cowwCvc zWHw%fy#$ucEv=3HY2;7EjUpH)Q7 zE0JyD+1ori8|L8}oGy2RQKeLH2{nMTUbE(^O690tUeDK<`WY3B{Kx}`1{OFg^SfRg zOH7Q-3maEGz^^w&Y-IV}8*YmXYbXrV69D|CqE7ipOnLU!SLH;Lls4*g9CdFR}F^04jl0+PH`LCI>sUnjQNFw5J^N zTmt_N0>|#2mMnTK8qSx>Do4qmteD7!i%VVdP^^>`Hf1cI`}+n>t=9G9 z#ntb86kkmZXq)aqMbF58Fd=sDu51LNYW+uluo6}++P+*mTVH{S3mIIM28P--egYX} zi;jcJv2YwzK**K+S+x5K{{nAMhEMO3a(r=)6QR9wABw51CeCRq{;z`pA^gsm+lb;^ zI`I*xc}O5eAuuhX_r6=2ax?&zQI6z{iRduG-XL*Avf)kas+Ag>wR3&Rqm>?eQ9cbp zgO$68_10O1k^RHBkO1M2ehMtRZ5{H4QHZUtlY}zSDdjy%kuMgc$o6{Yam-Mj+Jz+n zn<{2}314O*b51{#vj^?#2d%97jpBMHb(`ck#_7AaaE@I~BOPraEPN{MT!06i3+J`5 zA%`%V3>V5kddw(+Xv%=C^J7DA`tO@EN&&)mE*9p}76&t@NQ4zEp;;KRLn9Wz?If~^ zM`blKSauEGuVfM4+QE?_+esME1D^(ncZz&GZ@5b^JMX!;eg%Uyms)vAK!f-Dc-<2o z^O<1}@Qr_&Y>{*Cwj+nh40fy`z}C@bj}-HG^8-Sc^OMaonwrtP0>jU~YWVqT0+)d^ zfz@eca+Q>&zn*xwQN{^u9`nWSr_z?T(8hsAhA+4E949TpfT=`YOvrHy2jwo5Uz5zJ z3{nEA^jrni@tYt{#0m`?Jn-@{s{xwPm-YuV${p7*xkJ4^(W?m+Y+T(hNFK>S*vnvc z911FiWPLxFRpYy#>b#aCS0M?(SA)iVMcfqE_Fq<;2A@f z49-9~kyL%tTRI;kg$y0FOJE6Me=)4$8%x&uWYEAC*q;9|Q?X_|ZJ$}b9M$o*6Rwj% z3zro+HpDnMRjmDsR{@`Q1H}UK%7qLVKYP4{;agniyceN(%ALoJk_<|jeW(4`irq|n zr&>)85#J&+=8zKZ5DGsZA1(RQs#xGqKTRe|5~4!WE6L_hV2wr2lHs`!TsQo(MOxW? zT3RGq50RXh%^tKKuz1=6SX=y~6aREct(D4Z5g#LahJ9GcyT)4D`?SM!i=(HNPmuhW zg1U0xnmXE7*;2HZf=ofO#Yomz+3mM@x^t#vTgc z{FaF`Fb!KgCU#StdR%`4`QlkwHhErhW40|uV$*02=(>@D(RT1 z8rUsBh^vy5!`>e8rZy^v^VX-`zS^Dd^Hk%q##Pt|!b%%@O&~a4wYOAv8vBarzanPh z2Ku|^Lcm@;n$iJa_lXS)drGUm zbxpiZ13FKD0jBfxBkW75*{Z{n6&o<3`QFe_O;YPAu!+v|R~AuxTZzED4J8P>S8kAa z7T<-LhDaD%+}&g8q5PIvB3OkV8{NlS?W{eYB$ z8qs&rnvlIA!od2TiKvoXq>iuj=~rsch(BOp{rprQGo&o|F;I;INDyPeh(d(KJAqk?Al%{MX#NAlyKG z6J^3p2$eYawMR96iMc}SpC zU0lfTeqXNwn;r%*7sTZG+rF@j4A1ai`7r64dWcZ+Iw3h2iaiv(gzJ%Wlt;rd3heN$ z_W~wY@roNBhwh)eDXGu6?@r?n8*U&E=UWtoLJ79apx; zeEAg127- z(2!^{`T9<7C1&@Ay#@N1%U@5YAn7Y20lPzkm8LS5=clsE}4?^VR&0NhDz^(jhG@fi10u%#Eh)f&QB3+ z;C*!Tmo;ex)V0r^#`9A%pa!rt7#Wn^;{XRv7-su8{Xb*J$P`E^X06L4jqyYr-viDD z+q053P<;u5eWckpoD7(u0!G!q=zq;UFVTW8h+`ErM%dDFq3d-dT%zmyLZj2;eT@#z zG^HMui|Zf3Fzbpa(ix_yKO|22n!WJ+J`PazR4Ohno(qV63$YULA4XC=5`~al1-j74 zuP@VHh7N+D7sC|IY#c^2^Tfzu*+P?L;)Gg{fV9!K7Sm1vsTJrAdC&6K0Tr=6m^J$T z62H#fVRSxSXUQ-){qJqm^dFzZ+!w*yE?J!s!~FYv&J$aI*-^b&f$H%JT1qhSo=S2#GyO~QyW%++?t|!%x2G>$S1a0IVq#>5rOU!`- z`#ck6>Yb_{2lXx!DHhI2RglE-l3p^j=4J{2YyTBEDCZlU*^Fl~!F9fBumCf6&VMT} zW4pd+Ld!OJcGVPzPS4#w0bOk{No8H6MIxJkZvf;Fg3B0aGLp_{C>G-hR?+mCu7Uig z7^a-%=-1!hqz$cC-O)90@p6GnAJ@q6h_BvrIj;9%NrYqcmZ-L|h=KCXm!(`l(l`_D ztsn6D@aeHX1r8g+Zi)my_!TMXJ@q2-?skc0GoPX8r z6G37UNZp3WZtsp<$zz~9A|+Xey>?SsTOiBb5!GY@qfcc^C!)Y=nuAVGuiWNwQv`VR$(ZLlo9*n=k}K>x=3$#TOe^1 z0xF(rdocaCwBXfY-LBpD^gWtdDQUX=L88kvAsgC&yH$9wJqi}Moouy zFK6znVVa6|H$B`k@5F1oRu>STZBAp$*51*=2ePdhfO`1H=g@Y|(W4hU! z7iUcbOYn*KxnX3pIbYTzfF@K4}-we=9%jd$Dsk*;IzF$~Xw=tER z4v=S0uxMK^T3IQ;%{a__@a}dl{=}kz1E7KwPqfA1;szi$#`ggTP+f1|_uyjaP#PNs z0^)$NU?>&}1%!cMpvWi{34}snAqiil*WdK|=6Uzwzi#uaopW}XcST~Py$TN#?>wLD zY26B$(Dj~)KW`+brM~W^{>c*f{EYlD!2Gs(_^5bc{mno9O3GVfJ3Wx;!QgOzCk$RHpmlQpon4;2!z5VZn(tibH1D6`RbE3E{RFLtyfkM z{&@at)GPXevwPReZK#3gvU{jGPn0~kXOjMv}yCx2?nSKmY!<&0_yp zV`hx|AI!Mdll>5|nA5t~PyMco?mBTxQVJ|CNivB69{0KNmSVQ*KKlN|waPRq{SC7Z zoxVfOVN{y~f+H}AU!8T%e!nc>>z#9|m&(y1?o8j6 zSipX-k!d#e6!~{DSp45<|0b9;m+iM8%yt&p)*rigd~TMwf>x*Co(^%)*6Y(I{8eX0 zwA~o;aV#Ztqb~$equL4sEi&D5$j?ThyRPabvzD>< z!{v57Yo7XsCooX_>K$u#jM{mQqtv!9^|aNLniFM|1Su4?rGwCsS%Wp=9;6EVZa}@m zGktg7VFN;d(4cH83lajvK(Np(Boc)JK@)&qp0cCcnyon523=g4a$K1sLfzPWAJXhU zO-#Xh&L83Xax}O6`#)doE3HX)KAuM9(!baLO0n&x-d!a<46^I?)?OX6U#kF_@(A*F zrJPHR|J$No*>YLhs`*YBb1pBHw#x+c0c$_r{eU^6-wMMQOF_l#EKZ+CQZqU*_<3i( zjAYj1xcQw}XAbE&i;i(1_QvOCRxBN(qDn0*Xrv5|2|`SlBW`3@!m^vm+O=n##}@%+ z41fp%H~|~L=64pD;5(3_y4l9Sxw#tpD)(+{> z&5F{$5!<5(tdK_qx}Ae(x(+SAIIJGTO~PtOW z>}Ga+n};pnKdHSP)BSJ@*~;zsZW!+Lh<8WBMGNcuZi2Dzs${|^pO7N&xf(HfRvzDK zvT~8^N$GB~*E`T}BK@ZkUp3}E5r{-ZQ_nXoJ9IUl=mLma$0=tKOQ(l2Y>PIB}PdE5rUBCw8Oz zquKkr_Ybi%{>q>1I}4{@R)^!aYlHA8Vf^u4mYe@HdSdFn3!Mq3t_(;zK}-T@z4CYZ zqvat!WLnt&Knbwy!L!XUC;k?RqQAOK0T`?DO^iQ{N&drzJ*`hs4EPv>sP&V?8$YWc@rw`q~Ud!2oLRh&)2ZkXFt@`*YmnF^sU?X z2dnPCv$m!9_MSa`vEOe!9JEp8RGcuwuKneD%3r8;JrghE@~vep*Y&maul5`{_Adwe^gu0oCD~ zE+D*+=IFHZwXrVRM}{$-sxF80t}%4sdC~-0??@+NI?HDq>Z8PNXddL|XDrz&(XXs6*;Q93)jrm1NySyo{fWK- zHaA%S*K>>ds#;v7J6%)!bv}$9W0lR!^u{>$+2I<~%Oz&6=KIX?pBn^9l~g8ITY@FkuOKjF06-DI000!KL7GM*|MSzdY?Q%u zT4VQ>+J@2<+IbU_EO6&JG#`%oNKj)2urDj52nC`&OV?Lq+Mttkv;)j;!;p-{EZLy2 zMpQ|x@ek3z)+F66uY2{u0;MYFt4a!+TmdJOy|NiT9R^#F;XfQHUq}Lc$V(nP|1eLY%J(m+TKv3_5uyJmdOVgJ z&ekUrb4LMHlTvQUID7!2KwZCzpUz8aW?z>?CoPrP5RhEd;&xr&?^~qf%pQ9%-CGa= z3u3h=Rv+>$xO%&O}Uc-M%V?Ne&pdV3llluX7o zjJ5Gt;b2x0XJPIU!w=i)QXHrOaDZj&O3^{zpofb7Bj^GbN^W-;C*-p!#pEd7-bNJnC8U1P?$2*v}&QA@b&CoYa-M`;7YSQ{5=D>Bz`&= z=%MoShpZ5FeDzd1ew^ObyR;IhE7WCZm&3{80O=Zy3 zUbsKsLJX_#HfQ#Xe2g{aEx>wO$ST*hgeoU1tG&ZD*Sj-)Xh8SYU23t~%z&{!9X^C4 zKRVA+seeL>BF^FiTwX%&awB01YUZDPs8-u@Wf*~<=+avB2vO+C#tw|ZqQ>X@IVs%; z@G=M_=`ie7oj5V@;kMHU@38OP=@B&976OQZG#um%b=t~a#Q}AS(~L{B6r&ISL^wJ$ zJ)g>yHN8ON8|(c2ornUn98qk!WK%W(W)`bi;jRhACZ?Rie*a=P%ST@@E|j&8*}(RN zi$fBs-po9Z1xaUpc!%3|-Cp%P_%Pr@OoN_n%i!M!rJRw2>^v5vR(MGO^H$HhM(bHHgD7imELsWt zq94JSdo!-``Y_PaIe1RQtV@IU%l1Y3PP*F5=8mPS5g1Xx@w%Xcc59K!0BzMvWV9JLuFx>KX#3jD0 zD$q+h7_%o=TGZfZwmV7ECZo6}j~&`eJqzx0`9=roTi{e~&_)}KE`U#lERUlO=n>%> zs9_37(x_PWr6iAkJ~l&~y+zlovT%U92utRS9t15jp22&OTsNX}iHNhgpMN|cBW|WJ ztRoP!t`yAeUHsYCl}0_-HYJ9}>uV{)w#joQ4`Wi(eh?Ca+tBVs8&^~%vuu}k--zPR zB#lm~SmEmGXmpa-A5%9=p=3gU112aZ^`qT(V%Z@$T9PS<7sWQOAcN)y z@kJlC=V#;&!#CfQ&nu`~p3+uNo|ewoNxeH2q*P_7VpHYaI5rO*QWiLEU8J>4jMehg z&p<9$IskTtj@5X{2RsuS34e~)_~2tB@a;3O zo=Tv3RN@*|`cG-&YepB&>)zD&9p3syJ#x-vPt8hAi^e+q`*a4#dTxH*R-urz%T!Jp zL+hB$z24BK5aKEc&nUgxfxZNd?Eb%YHS%_c=20uy(auk2-wyy=+aPWkewz~$87_cJ zw-i_{w`(LC2@vO(1~uGp5XcSF22~*-3Bi9+R+51D#z)tV$KpXCN0n}6VAUeA^rL1O z5HJqRRp4>$yAYcqxU}(0t2iI#xIPA+5)4`nN~sF{ELBpJ7|gzeCXP76b>qsw#3mrk zu!FFLQw9*ZFZuyb84SdVFIBGN8O_K|@F(7An;+%Z+2wITXFu&?OO&jVaP}fLJv9%e z@iZAJ`_(f2Ek3fa+adr6^41*!2y*>>(a(m`|BMR!xikO%a)KzOtXNKqlozK=`V(}u z5HbQ!^RHg@ZIe23nq&ZYYEGwYb`Kj9275j@cSRM!qcj$EV#B070Uk`a^BHzt{@;#$m+TwgIm$IbJ*@i&((m_EAw_(kLAmn%;-$DL?t~>I zddKBC3d@}E0wJck08DLnspDvLOYiv%%Kz1~$P`-GM2tDr!nQS#sc|7YG3mC4H<^6j znv&3m7W_sRhy?nJ`mN#5=ud^G^5Vq@XfOaNB1QM2u$FtP&d_j!YTk8LP7Ta^Vw~O% z@~WAwyA7ksva083y=mZW@&50y?#-SLR5K3rD6?CNR>}j&$c$|y6c2(vA_wASH?sxD=nwP=cV3+3%?>`!4+cl)$Fu4YLm2ulkflKD>d0<#XFfCGTe@+8wCsXJS4 zJ3u4gtB+E&3@A&+c(at|&(N&?>M*oAFQ1-A$Wq$kZC(zTk6MLLwDN(_^uLZkWu5Xa z3QBpC+7cwV8_j_0Ot-1!T|UI20mZaA5(mV69NRYy94Nh~*@KR8fRxi}%Bl9d)Ct%& z4iHm;i-Uv_gmF!^SS9SpGuc?l%lHiDQ0NR&u=F-tQ1YzQi8&xGNT*kJkUdYv~J~ zNwjn3Oh$?MFCvp0GM-DD9~NUHxtv8EvMi!u zR1l6!^WIxFYU)QEBCt!Xty%-JlrINzB2|Z%w@YIj07RiYhK~Tq2ePZyBj0@*#z-v; zRwSFK+)Li%vzl(AQQQEufJ)?uc-n0$sm_#0YKXn-nPsq6^G9)x>b=vFHH{UjYB{zW zo0o{y)rSD(k*+I4=T7#6v&5~E_B&F`=fTPT$gidG$tHR&z#pNRx^D940;uSQ@ie%+ zJ(FCvh!nw5hAK6w&6!@8jW|Xc4YNtGN3JPqA>vew!@1HWp(=`uByzwO2CRI+Ei(G* z`Rg!$UpYYx=kt%prtJPObVGAut7TsKTO4m3-k?C1xi2n(&tq$)S=|5?=;iHVg6;s-Bn;)x)GEpp7@5ulT?0_0(0X@C@G z5}{BS`dcg?hSp68W^Z?#yt-u%;j}cAgh8eWSnB;Yy^yBTwP3M~>O%tnux1jx$%pDe za?GoJ2sX^l)CdEn`j7!`4DherqoVsyp2xXL0FUi<7sEdI!g{8+XD=WmT+3&d1Qr(BU>{Ej=pgpi)jgz6(&) z*9u50$V&j1x+u9PPOS`k3@c@Mo?bGq1|1icsQvzg324|gzyPjY8l>pH&Q(66<^9UJi0 zXDN~301T5Txki2i*r@0G{Bj=(xZxBoWk>_%A3+chp|hWJGp_V*MX2Tm5eH%D<$HNS z{Jd;HZlpWcT!01udoVo6hHzd-d@TUP7p3QOxCKEM8qsaOb~*Djd*mQ1;xR`N&X>35 zEVjeYDcSK$z1f?UWp~pkgxZp*9sN-x(B8WJb9&(AJwB7m9LfQI{}XVHB_uML7@25F ztz5UQVlZ?dqFUyoHYej`w>i*s%_jUXMGP0r_Sk*e&P2%*=#Nnr6T&IRN#x(l{ab&uq0 z`xbgQK^Xe4y?e-i=VNk~9lS)c5Mz5FaBsi$f zt_gefmA$1$u>HXFNIXUCpO~P6NAaWLH3mD1>w;ArzRmmBW4}-}AQ@va%vM1^>Y%uu zp4xWa8vi`Vm9(t5t2cCJRy=O`^%VwofiawMCz)R|EZ3eVD9k2cGtpsrHft%?VBpW= zYpj_}6D^X7qAuPILjMpGlm1Za8sr~SDkX$1Hljfve?2Br8k#PG$>R!{v%+AIpTM~|F@rMgt7>GWDj$Z{%P_w}oRlqt z+h2Zp=>Qaja?up)d4m#GI_NbPc`x(E;5yRrTKj~f{oKH+Q@W$?IuN zIMY4STM2Rby{C&17mrO(=x zqO6oouyn7>sVmRIEZex}cFG?P<)woN$JlkVmq}E5#UUqP8or@4GMb;3OyIw9r*8t# zm{EVrTe(`AE*1n4JINOBQCv5CMernI*2foVD}>knfJd3eX=)P$W(^&h?I|ma(pUmm zkVh<}KX29kEoq@Jm^Js|=iR|e{&v$_F4FCz*xB8}$h=gIab|sEo$LHlKldVLC9Y*V zJpFx9=3?PaW$^8yND6l#k!$VV3G1INMHOC7DfT_0 zhZ3HU8ih%lPM4Vh2-b)xi>;&PbO`HEXF0z83n91b&L}jv@T98QPWxA7F6%?W>`av@ zW(s`{GF@;=`=X%QEW3}q)3!7Zg)INc&!mh=F8xcuill7RXK zlk=o>x6>zG3I>t9XxcRXtSd?b;9Y}_20`#DPeUox)Ih-yMQtR(pE{}V7@zAN!f1b8 z_;E@yU<<8zoa1B`aOuz{9Yd26R{#DVp?$>YVMCR^{3V4}4)t@Do{E+)k*{qBoCMLPD7<)9H%pojWfOvWe&Ht^w}bTRwUgxM zFRqEH=AEE2!*dtKIs{G<73jiqLj_x2h>CDYVFteu8a`yui1EJ`E1uB!+()y-?&H(^ z7`Cc~snKS6v(XxA`+*1Q2AsfVY(*m_aYR96eTbYj)P<)?LQWZvqAaU&&s%p1NE+zH zMa65t7v#e!u^EX)tzt0t55egj0toZY#0{`uF3eTV+wJu)o$<*FBU@Xln#7+SF#TlA zQdODA7nq_#;zq`*A%A7g?UnRf19rc(i7X`r4?cv)qVvbFlm8;HOGT5>4= ziltn%J`+(^05FcqfNh#mGd~`rA-EDMBNs4uUB++#0OBQ0sW#4 z8PFGf!s(HEzZeO0CzYgn6nD}E1=DL@>Aj!x^JtZcY^`)sp?E~T758RCw5Ja=l8#8| zJd3DGqw+WZ4Z$o;WPA)=^HQf{t4N&-=>_gzU5F2DQRRIYmACrJ5c#1Zp;LIW*KW{T z-(=z5bl2mSpBNW}O4GxabS1$MI??>9z^bG&Ht9!uPIZ2SL;?-Ev^Mvw{N3}H%&bhi zqrbh8?#Z?L4Ce6Z#~Q1GDJ2D6f0Y_xOg8(3Tc7=}{>LC4kn&IAR@8}T8eZ8RSoo2l zMZ`T_69I?wyjY^B**`ft>2AH73#hvxZ&(mjFz8gn-8a*5H!|z9#^dL`$D}S3s%T3f zsuuwiPsMEr zP=XQ&rSEz5_Vd2E&XuZOU0hnoTvf|~-*NMLqsN~7B9Hs=XTBD(A!pwH`pVOoBcj== zbBRzkF$@bAXHS)%PsSbLv%Y9FW*Po>Q$t(%U?(yi|Nd3}`uVlrpfMB1bZ;>FM#+zh z@fR*6B9_X1O&(F6KWp>15)mAaQK>H;*t>CNQ}0N{(+|^iRoR-^;h_uYXbc>qFM5cUjlcT6=0w zmcAWT-`SV$#vk@ry+4nC_fG#%mK!#n)?c!x|IQ+&8a?fGy+S~yBb@Of)@(C$yyr4> z{X9*C4t@Q9YqR+O*Tq9bp2KlQ)?DpU-LRH0Stpm1;Dq|{Kk#AfR&`VVilEO9#3#Uu zuCby0|2YmBt#vM>F`MkP97j@rP1q{Var)@cb3H#m5=+5;`MoUTa^7ia2%A0z+9s;0>vH%fz}u)u zVo$1C{QwDi0VT_sGzh`a9REO0c7**>-~uwB>)rqV|H43MFe(fQg+gXPP%IP~1p+}7 zJzt-GD^C5YDrJ|nO1T=9d36G#>Ct>PUeE5Y&FvO@kHXV$ue#;CK6@W#p!CO1)AKhT zUQ?4@m3;PphPr3N2{c!Xtw8tDzBD#;OFsp?xr5Ms-+rw1U8DL*&dZ)N^89lS7H_B0 zzbOA!jFUPVp8#6fOOpS0K!u0JLxUR!DD#X|6QlY`OUOI^`FqRqLwf6$8Lq5iN>Krr znGp8zZNpkk%4+(V6BSOl6B3qf=s7JCm!)ZQ)u(_VtWX*Z1%!cNKv@VD5(R{WAqoI5 zQsr?ns^)4{)TLOGOS19=XUD(wntVUsrZK_7_I>v3|Bc_*9;tXldvaf@BdvGL@aWbDiY-X*uWi%VTdjPqS5mrzPi&8O7u< zLiVa_w8fBP_rGz%jS2WCzn~2TfZgL4flrOOmn(@$YiLd^ik4Dd{Rl!^OxHrXE~i(C zwOX=jLd0bYi>MnL5zeJ9vKT2Z!3Y{t00594pd7$Z3jrVqQ$M}|8D@-Dj#|A`mz6z- z^VgoSt$OP@YTV(;9N)yS>z`WHJe}1*=MdY17^@HPsldr7HHLk|s9$%ZGZkG7oZN`> z`OhZSEqa_gRHD5g`y*`&Vhr$!3WXfB`0h%+LWiF@(;qJ2ITo_?%&Z3u5oW zScxRSI%X1%OD~)MQq+a{|Gq1#9A3a0TG~^v1dS> zO(;%u#uISx^Z$^t1f(cHz=&o5C`>^)zDnr|GN{j{VyDmg{PVU^vlJBoU;qGk08k(R zQ6vGdn4_ntx`kQ8cU8bA3HvEp?RbeuCz2TR&%_ zVhZkNl)k^uU!$_RI)489HqAzl#UUw5Hu(xv0_N&96PIh)8Dyc zd@;0V8j0Uip0}-ovJBn%_a>n&i?rjf?3VNHozm8%LY1tuY3AM$ohRPW=rY?+n4Pt7 zT*q734d5ULv;YHe0006s&+q@gS)&z_5Gq%tCbc>hR1d9Y&7G)Zj5q4OFW6kgwV}2R zdDB9%8o0Rhs7?k?*6W!?n`#3S8^fUb757yW7?Gp5yY#LsYG!u1+?r5t*2@kE?Zm$; z!NtA_71{bPQ+c89*~2NDRmd zkJDpA-yIdrCAHYyv|VeIhlqU zQnUqAMv+Jr$1^ci!%AX$8bFj<7?Fh@tXuZ*)vb~0xL^fFf;x1{rM&$pu8wTU2t_$W>kI?%=}PI&RFC#ZO*5N();T3-Jm-E>hCrlgemGh&BRGn6VP!ptxlF!*K4QW$=K@j1t zn2Dd3nH`7pmv2TjiQ^cZm@**$0yqEw5HLZSW+VUe)92Xs$$wavYXH&8 z2P7v%#P1)3q|hMRM{&j8xMxPeCd|JRCsvIEMja#?m3rQk{lA~ zHg`SOHNkaV8+Og!%PQ^s3Dq~HS3K>hqDkcR6Yyd{$4Ek5Pdmb2Rb8^ZC1*ijM|~3n zLO3A!RUNX2VkeYtR?Rz7bn&Dj!jpJWzlVaSh<1%I6;sz!R+wQGb3mE`loeCR0IOi_ zl;A0_Rgaf%3KMHVDme!keRyK{bC)c1CGC^D7P<8crirNRLEDM8CJ4O;9_Wp+ ztrG5|62v)Or|ZZ%T`Q9^lXMMISLqdk%F=clbB5N^6BvlK6MPnm|#)a#b&L=5Z9hiv!;n6I~ zlHQ|lj53HO@&(p0d&HA4mOr;T5j(tTbmO81SD;~CqBBt~hj%x*DmN9cGvq8R9`41M zJoX)ihPL1S)yyW}62*dh-1QzwwV|5)x%oQeOY1aPxm!Ypb79R#J#Hwv`ej=y>OgZJ z;iK0N2I&3jL5Lk}7lXH{S%frSBojwMedn>EVYz zX;$UXSbtPhU5oRxXAWl2|t*WUJ1x#(N4K z{vTeOJZK$)q#1p1kJpcfz;UH@@WLHjuVp)c>xBu9J_mVbRrp-Q%Q{GwyE^*@{-npg zf$2^IPtU`onJ3nE0JFpK)4<}r;eOUgj`BP+8)FfcE}9&oLoE6?;wW@uq_8pqn7CYZ zLlQ3J4~ZYlF?mK1QIzlDm+nW$Ss4#LA9}hu4NEX7U#9t`PBkBE0M4mUK+<%tiW~j% zR2a>`{(L*R)chULYI1>ruHKc)V5VH#O()mGCgrl}97cyvSWk{ygj$!=k z`-9suj(GR9qTvZ4BKFr)f$JN)p+(ME29k0(Zb19KnpZlo`>$xO*1zBrG!MIYMUpra zgCj{oa$K~kMVdgpIbk{!^v@{|EP)YvRx>$8fd=LOG${qmvl+l2J&Cf|%~hJ0Q`&mr zK3i;fi|)g@ZzUx!CjtnVHe#_5&RA0rqH;83e$Qa3DL2e}P=|qFT$jNO=WeuZ%^aC1M0)n+@EWRDUse@xn=m)%#${+@<$C{ zc*LA#*^xEoEw@3@G7i--#aQC8#s!_m+A>(}eJEyLOyj<0yf zf#OI!m=kSSv@Lp2u>d}S__f1Zn#xaH`@O#h4FmHz&xJsv_IZvX)y{0^_J)`a6ou+b zEt*1c0InUX>5WSuvaA*1s%SfblF}C09nL6zKS1W!6Zu( z^WxR&kzt^rzItX88Yng$AUizj(wOCrf#rQo`(gqFc6S!3yNe#2Fl!({8818pKbKjJ{W}EMl+(3NlHCsHH{w(mhMnW%${c4eJGJdQN z!R7$QACBP$Q#TG6-@LhXT_<+Et(?WP`6MjNcY7Xr-Plfv458aBSf=w@rqWv-SlLTKkn@3*yIqPm+rk1wF%{frCSHkAazNQ^mD2tTC2HTXa{=XMZ z3CX|aHN7>!(AG+Oe&>?J)u`YZFzQ@PW_YpMJJ{$aK~uba>J46nGZPma?4nX0p#dGd z@t+R|+8@Q)y%s#xKKh1|U|oSM$jQ0o+G*8aki`QB^ArZBW7cO=d!j)2&Ts3z1%fwS zVkfW~Tw!K@uw!51<~i?WUZa}>%K}r|QUL8VeuZh-KASr3f;S1^1C%;4a#SA_7!aXJ zlYwI4=Tqb(C46-`idZ-a6`DRV!p8b}^(ukjM(01bz6yHCrX{i-`(NXA#Xp2 zS+s|s?(Eiy9IhSWbmVS}W2GiF{C?UsL3ape75*CHxvL_q0Zd8*DN7iM)i(;)rM{@I zz=AyIwa|JRaA79Un{K*Qa+v^A_lLT~9La+KS%Vo2){ol~UGzB0x?OV|h z^E&$~12+nM;PK$r?^XP2F?7Qg>~m^K+%CcEHJgk4#i^NnEB)5!^=z>u({ME`ZrRL6 zxe&3BVh;{!M1`qAj7~k6e{t1vQtLu7Q|k9pfb!{58N~Jb^tZi<=1x-17ZlkXHcNua0AE?C@V#&I0<5wk0!^*dVx9|qbpX20)2 zD}Vw^!m>ke?pXt(ZS8y!{hB7$qLF61i?0Ey%SA3n1 z%kLRV!Igl!{e}h1hECmYc3wA#a*x-Z6QzV+y`X6CqpMc*jeaj_kGvUl4SY&7gMOfh}~(GD>Ep zuuIJ1LD}9}LfhNC3bLm%vb3ic-Nn4@Z*bKurXk?s+qqOe^Ps!Xr)a`zoQhGFbGr?* z@r)s_9RU3s!>BXKpn0>LQ!#Rim)#3j{qA-JUn70Z32EoUR+RI$upl*eJl zyTPwKpn3g_T-^;&dLrFXmAkzM@r+g%B9&ttN*6sy)JPw+rX!Kv&1HmfdaHxd3rL56 z(c0~fn#n-RLA=+PLK%_a^}@4bju6B?5KOv=9I>H0H<`AE=6t9Kha?mD1nwPWvl#J3eHF%fmy;A|MHFfhFboZPhNK)7+Bj++yNDSzC=i z6{T}c`RNlfHN=d7Hb4RP?>Kyf=t}di9b-=gOCsXy7IFz-u8Y^X&e1j&<|ze@yovt- z=M6MFcr}&gZ!3`O9vrdJO0v=`U{=pWmo8=z8s9iwzPb4P5YsV<(1TqMLmI;Y;Z!i- zwpS6i<4c9!jDu@)AYy_1iv_0MeXCU7%iu|~s5cV|=er&g8pyw1Q_~CpSL_dBIUoC^ifA zw5y=kqAweAU7gbz%Y4rsjd@suGmSDaE6{ewP_MBh!;zk-rJW5XRF`^szr^w8EL>X# z<3C4CxxtU+LKaJqQ*y;jEbG%<{m&m47G(^++$A9L-$@y%h)?*ar-OgC?g$~!eM#`! ztr$`Q81GTRA|jI4ssP$Mzn4yHia67tN|Mu~gAJ8)QVP-zT)3#0dBQt^#`xf;BZ#7q z4WbWQRoqeA#2Eo$XJ!sf9kQn*6c2$LR4jwYdy5{PiG)uQ zY3xthPT%o;7We`!#-Bg5b$W)JvlSq{)SGrlprI+I{y&MWm~!PeWK@BtD!wGsf*H96 zI8uPohS8~Dnb?Gl-vjK0DaZ%|*PlW`F0p4B&>=3O-&hdI`QS#zXSmhcG>&-GhO-sqg@tXqxCz3GT)c zk=+v>957~gB8p7cXA5mL$OB?7= ztSzWV4?JA8O?{JV%ZEb)#Lv?zM3XZwt#BcKS*G)Z-?vD6L#w9?P4Pxh>2{t&0})x! ztF3TSXw}VB454N0p$rG7_f-RdfkdI1p4&!7u9Y)i8XR%c^{qs6QWydG=5#sCDrr&f z2-t6&3e0BdiJ=rkm-chkV^_oUif1^7=d^t>+%eQU(Qu5>mVj|ic_fEQhIRvW91ksy z>ggu!d&h$#DnWxPWq#BN+#vxP)F4zQ3777PW7f?%PDLZ^HEeP*0%?d?>& z;ha=!B&#k|YM@?jmnw_*KZjG}{0r^(c{Q;gv(7Td&m+0npe9c4st=~XmBZcBZQKv# zi$%pxJZzf|#B%-gAM!u<=n}i>l%!(n`KSA&0{KrnBKdeCW%~;02Z3m;&t3k`A{4*1 zj5Qu5Av2}UJ73;B`a$i&SNLwaNLRG1H9F0vB3;lwL}WJGWDeg_gY-vSp@sohN(LJm2ezUOw3Q2RG0&;4T*2vJ{)EiY#HOEZN)==?H z7aj$1lL;^P-uZJ2TX4)VB}UKSNf#LGVcBC2Qm5Q%2&qKEw)XS1!yyklAGG{e7^>k` zX2IKrSA1StVOr~b%B6cIXirz^P=H5J*f1Is1_r{Qu%Ijy6A1#rL6A@?6bXnzVG_Hq zZ145&DZ{@l@IlOG{SSWcvs1MM@ETsdE-UNTeuDo(V zyZ4V+9bF6bSJGJUOE(X7$+_W#_SXk(*Eu9K#MUo?cE-}mnv9+s)8V39V(93#6zUQ5 z;s(kK&|t~TiO%rA3v->J|+IqFx^HbqnI#Rj1y8b-Fvs=mgT`ILT-*1-GA7$QrZCw>h zJhLiWz)DseXF}=!h*ZC?lItWKLrQV1xxOc;)79Xh6=`#Qh}TMj&}$&yOt*!159&|P zPfX{lorMy?LDoL03*o0UxJVS;+hJ(crqakQ?riG(B?1~lL4hz}Oc)gg2El-^kSr7n z1p>i9u#jXCKn3FUl5x(wd{tHD*0FV0DqUTO2l73~&h~pw%srOWoxbcfLlhThy3SiuiDU5Zwf?`BoLFCz{PXnzuYVy;ywdlZpY&mg zs>6Q;PJ2GS_I-0k5n<;gF`DBUrX!9B0FoX3qMzS1eyAJc>9!<_=o1C9bx=*n-+Wrr zDA|=cHq)h>Z(DS=#vTo`rd2MI2~M*WUhL@`9s^B9q`{Ga07n5B6c|(}4GD)~VL(_= z78(tLgdqx!TJQP!)pNwovo7LI>YAn1l1k8T`}YQWT1sF-6dl8jy`UKC3=+h_fUsaJS_=jO#89A^C=v<;!hs-| zNGK8tgo0sm_I&<3&ptY5p7X8n&LvY>y=F?fy!Z%rkL5CN`TWf7d#S&Zc`;9~x(*k& z{JQ0ApqB3$EbGwc@juVnsL|w?h-{F7oxN+UZ3It5&>`h}QuFLql&1-_-&uRs1c^0D zymtFtqQ9J0+WJs9fqanj)V)385YwS5E{TP9^7B|xS(*#5Y zg<*j)ASf0L1%iQapjaq!8iZ8+xAgJxebnP$J!_vl>V&$NIpcg%OyCbpr^EYSRlwLM z{=cqL_;@v4OZ-UdB3J7l`omx02i16VJzZZ8|M}@QqxN6@!71EvWqOyEY7KS7xZOaX z;{TUg^~ry&&5hro{M*O(d2M^7_JyLyO!suj_vo#vJkW1ArwTglqyF`E?Yg1S$MxKc!Wn<}W*AS}CQ&VX>@b_xMm@U1 zyJ=0l`1I2qwPILPyMCa7BbH1i90QD#*I{!ll~A5q=rOb`RlNQi&wsH?cBd_KdPc+{ zR(M|Pj)3;qc73C|VS?Q^>b5Qrtmt#B;(UpZ2SeeO>>;L2kegjn#mcyOm#2CDJY_J2 zaM);2HWUVe#elJ(C?*OJPyu+CciyD$Qfo6+bxX;0B$p}>KC@$eWiEIdlAZu)G(j1xxwYtuifns?>4lAFIJQnhzYB-qV}YT|dv zu--JS_k~FkCY)_Y7Q@wZzv#arJBW=Ycv^%!_p58U7c@8g=dgIuVr3a^ zW^K!E_ia^TYRc{YwV@bSGBRnMbEyljE7oh(8CvOFQ5{p4_Zdm_oPsPF01yOl000aX zL7Ijm|MYk`dYQ}+;*UXvffdMldh!^k>J5WU%3kxfHqX%1ro+HQqt6?C?kvo51G)u( z6sjLMc{w(G6z(;)i~|7R2wsl8gzvj`epB}X&&t=Sj<$UJ&C|E8+K2p?ar@hk5_TX7 z(pmrt{#1MwXhkVno3j6v}D3oN`H|hZpMrBnw zxwdpL^0+{NdT!qswSf^d_3K-4tX=PerQhZha5V?1na+Z|*M?bs?Z1z;P?>R#gzz>C zjxzBhNa0kM4ENtGhA1f>DjrZ+e&90EH_@IK1daNR(H6Tm(R8O)Vb24Eg?k-1IVkS? zWxyYplx^(}G+0aN>kHIaZ5a$Vq!TCb)!Z8LY6{r#!B(}^-O@p1Orr0=he4o%VQVLO zEWInM3r}(>IE+x6ry_P&G0P^nAJvs}flwlQR68{+bx(&$ZD-cm{x6&ZzF#?_W1`gy zIZk<4mNynvd|Sk3NJjwfj2ZAoLrfwST=D$JSdbS)ho)&3?Z;g^^B$z(c1O4Nad9Xe zc6IX~^V0hp4=S%aoS8G`xIVOB<}wK-L`JT?d=7V>$pcwQa{io+ zw_O}xyE$d9xh%V2+(fS#AWU2ovlZ+%AxwN5T_-7|bY!2XF~wY%yP|Zb^3aO%D>5ty zswKX)hjrmN$0dkaMFLgRXhzMj3HWM+?q&d zNh3f!e`4Ofww%c)tp(B>q(0Vxg-r!ZL#N&DYvihUKGi?ogVy8P%O>*)DU+#~Wy0x06-WVr( zi_*DKuFHta?nR7?E?F=)aV1^bxxXKWVrT&?uNqdI4}F;AR5kEx6DzpY%WbQ{B<)pP zr?D4>y?zBttQf(#QwhwY*jdcr?>nLbci|gAzNG{gMC$9kSY2ODs;PDHiO%~FlK0l# z${tErb?+61AWA&5X7#MYA|X;ZPT_M;R3jMxl3td1jZ~g~OfFYi`N?uLAq_`Lx3mj& z6)J*X(rWd6Xmf>^npp-RRRW%JB0~*Ony~g03TZMzIm6tC62^Fbk4mT5i;Y#)xvje| zKfY8xQbS~6UqwtFJA=O!id6fYMy>mQjIRf?ujb{)qheR+6G*$uN4yr+fyp^T{)YfmrjR6!9G{z~?flXBrVfXq2 z{j=Q@`;$=n^c8}$hf5rsvQbay_PHN&nAe2Q zV5aHc0ubwGxh2S_9o2rm%qoeI703!d47y;M7gZ4`An=>8xpeRjA(xMNfH&Xx)A)D+ zv(1~L;jEKnYC6}$Sr?y(F24`H(P#BVZ{wGx&^pF|T_xre4n*(s0+V$n1Cb-4IN2lP z_gEPLFET@|u=CW=#?JH?uyUZL^Ye<|=OPr}?s@-UNJ71D2k{d+h}#9z2j{99^H_b7X4)0`ugDgMMX}x0WJ&I_$snbk7eQ;Dmuo3_1 zAU(j~Hs;H;5w3(x~wRSbuuzzQZfQC}y^W4t83 ztA^YqGma4rz+*fjP6fr_5BAxS#b%Nw(H3PO>OhH)2F#rawdk3y&brbq8gq#{{{uiA=00X#|97q zd?k-9sb2mboGmh-cLE^Y#y1d~$>F*x>#^c;;%5B=mP#tuEIvb08~kr+2q5tJ#vgul z$^gO%?!nDNg09wq<@}Aqr5QzZD-Fbx7&=LUp(0cBB>+$2q6GUOb?3NKYS}ZE<2Vp% zfGMGfG-8Og)Ah$)6Gm`!)-TH}`~n6<46k7W)R|1sc|%PFeqla;mt}4L1gw?bAouo) zG*EwuU-e7+=>OcU7KZ>^IdJ?@LcbDvUD{OrU5o($uAth$Tb-Bhp~F{vBe1!r-Chcs z0~AND`m{0)RQ3Z^-h4jS&7lgakDPPq1suKyA%zX_Wr>Hlu{z_96O;tc9JM-cn_>3f z5MN=xvI8y(KQka}mPGl?9dxb1pR%E7&QV-|=*-yS8|hx=*-L~cxCYyW(>KA@j7|NO zXYE!xZXQ0Iz}W(@!Bbt#hA5gX=#u)K0+=a0+%i*yAyJMq8nlWQzjj)CJFJ>jyJ5ay z?e;hk7Jv4uqnP0n|FlZGnXwB1FeI@nd%K5a?w_KK4o~V`y@cZ+_z@cirb{_m1X3L> zk(rVQxqEq|N9Ng<7U%vegZyuV>Vsk7y&g4ti9$`_zMgoZB<7KvrDiLpVYA1j8_plT z&xEgM_NoB*FJrFJ83zwm&rG0|6~0O8EfN)b>sa&Q1gB-0*ry3omw4+_2!_B#5Z2Cn z@i2OqT#ZIby$VECBh4&Jk-t14DXP6(Fo)eyeO`EThi#g{#ug`8%~_kpGnmU1Eg8dm z37JOP0frodWXLv2bdg2LZr=+KnN$J~Bnp;zt>RPROzurKtF>e-Lv_}8ea3fD5e%)^ z&E==A2BVu}**q__nbQ?cMNriM8)#oSf)O2f!`+j7`ld#T%odW-tKzythg3Fvz@_+N zK`!D%4>J1JPis|YFXI25kT&N1_Tm%PWg5j`!GYpF_wy{}dl(pFHxW!!D@Mg6kdFY8 z1~PyiS5ojEGW;CG!`ru;mAn#FG`Qef9mS<>5AaiIggAjfY3%I%Ag~QQprsvFZaq#2 zY}sIfT%!MrN!~RS(IkeVjl6I_G!{K%-N)N!VhDmd2g@VT--{QfnCf&#Amdr+{^hvkI}ZGfCzQn=dU0>lsF{ z-zI-aYjS*2t;L5&`5XJVvP#YFFJ68*FLjZk1g1?D}4|Fbnt5ut5lhU25mTC<( zw*ln&Ey3S1l8LL!??=9qCP%%R`kZqFD-z&+_}FB7P%|oiPw^G+7HuQz)U(qJnG&}Y znJ*E!Pa!dirPESPssrmR2VQD69xpsps|oFBnt%s!9tKl zPJ8xv{(Mz$<8{Sn5|Ze)TwGMTgU8$A*gHK7m*W5UyuGIBg!=Y%=cHlzL#C(ie>!^I zylUlIN!8x1C%f=tt9a+>X$sPADIN&+e8K@8D++qKtS;$nigLvJ+bD4+2g z!OBK3eRQCja)&7WWp=tZIbOK~hl!(fC~Dlxpns17#}(qjmNZD7_^KgfVKN5`4YOEE zYDB+i40!+{Dh{W&|F8^w4hF%2u;45h3k3rKVL(_&QVIz|fe?_;CKl)4*7bYyqV?`QsxAYqi+KSG^GvQ~S2 zfudjue1Ds3=wH=+=ThdlY&pqpn(2!ZhH#?M02hh=`GuzgY9^F?1soUb2Qp9cKY#cM z`P>jo5l!?fJ!A-JyXepN!~w5|^%$jr-?Dt&d%ZQJ;Q?RxVQExINfu1!u^Lq!?{-4- zC6cYk%k0_m`3FOd$y-e`p9nDMzLiwzIo)8os=2Fn6n$K-|D5#Vsa$4m`N<(4{S(UP4b>?adtHG?%!d zO0pQNbS}9$fo%C}<^YVSKY#!K{_zwz4F&?jf-+!CG${l|K`{tSDx7zvURMZJaIYOz z-CZ>#RJ`B^>2+>G=eT5SYCR+WZS?)SJYm??>EvQf*wiPY7gipc_&*)8Z7%PPGRxbJ z^zT30N7VgN*3|O@<%QX6PX6q_d2v0qA=P^ld$f){^rO29jisu}(^yby_siwh%1=3u zo~4pnxqSf|GxoK}>4IMD8p%i==lS)%_gHtESne8rQ&oD}%+AB+r6CBlko3j>(kpQ3 zrY`%2T}(pA5i)Y+Et|T#jP=<>>3sQR^05R=28RP-z*sOA6NQF>Vj+kkmp>jaJ+ZG| zYAWUPbP`D~Rg(974X1l_|6YZ%^zrTXRUZd4AJHbB-&)qp{_lLjy8)<-8UNW=M}&j- zb&D>$<6P2sN&}gVUjM#*tNN;gXRWdyF2w_Cwxt!(LBcMP-$l~}&$n^C(^YQz>dv?S z?0^HbwsPnnyED%abH6h>3i+5^X!Cr4rSaEM1!!~v$lRm78)Y?WBN)Qb+SLtHlHm00co8AR!I=;b-uemP;ny`(k$H7xGva|j*5SdL`S1}ahw)`d{ zQ}h3kmh;Te9`GPPeS<5#CFAziptjC?XjD6WAY5nxXnrqy6^7ghpOt*V4s_N4y=!## zP}tf)2MDIfINE%s9>0PevA|m}zT%LQXVzdbTw_fetfKPF?w8-6%Sj#x>Z&>PI?oP2 z^j%V)#UR>;W$8Vt_hrxc_QF_Z7hf0RPXF9~u~YWL-~3VRl8veB?d4TkWXt0ie}{Gk z{h=K#scfybji%u#<)6Qn8j#b>sB@K$0~w${N9?2=az?n*kpA~OQ1v&0=;ZRln4IvE zw`GpZ8&;(2t@`JUMS(-k`^Y%?D_)Z%w|TlW0xo);^}#4xjj3vn@AO|I3(?qsdlFux zLzZai-ro>$*-EPf?TEj-8>25z^Bcn<$zavM3&ko!K44vnjPTHew2{pyv;qK@1ukX( zPG=c@8DbxuG;omj9$-O=%N*O+y?z%wHAr+F~9B}4#OEx zdev-&=tK}@2oROlUUD2Q*DYE=u6}^6pSrclUfSeT4SKC3tBE9 z81*r-?Q~k7-B)0xy5%?F-!|B&Z<56bID#5f-x_RwV>6)Bud`#>PyCdtY~9~!0@vHY z_xLQ2%`8S;)Tr9wRYMF`7P>BC!I8JvdN$RqYQuZ5+xmMJT9uR(BaYlgJW9x5bTK;@j7&8Z(%G-TP46zLW z8X)8{Rb8}BUML;Ulp&B;N59Q+Cx@MAg-g^I)>rd6dK0Zcn@>KxO=_d7IA8s^os)#c z5OV^Z6k8MQHbSKXQ`Ev3oXL=reYupW6N)B^BJ4{0c8$&dhNBfD3Gl&km%QbXU)z^%V8=v9+wKC%VZ4pAnbJg_M15H5P zwF?M*=t$L0M~DmBMEa`ZW3$e3N=zQKUUO2ILDt&LD(; zqn;U!*ry}jCESGKE?+*qOm6iabWcQ>lwi9Uw1Zc*{Wj}6fwTC<`B{A52`}u)YWqXb z(v|e%Tk(*VO{vyjofr6F%>%N5%<$;~=Txf8-y$AstwbcffU*%)=1YRo3)Z6u8ro&KrzcKElsK|)p6PAk(ZIGPulNbk{ z0<$fTaD>CsMg-GF(F`ScZ2LFs>f^h9ZiN&0v}#fbgm$9-lVhvz^}g^&rW-m7W!KVb zkXhTUf6`m+6G8)L*l*uT{tJB4={}mk8;u`yMb;rhT#o z(7{?LUbZHt>O0~Dxs*h-+Oui6!^gSE&39hju4XqI8Tu6DNX54=8S1URwf8SEADa*Z zFJ?Dg?Gkt8gdoFxf*ajl>)ygMUeVL05M$J() z((1>)$l0bM1kUvSK-MQDO?pqXQ(^+OBeRMxh~h|-7dmHsMNaqFva4ES^JRw2NmBl*1A_R$bSx3X z&WY}o?F-XcYv1L@jqUWTBEx{PkDpWrs2Aj=6FC-g8&&AVzjH$ftZaLj_(6|@n0V3|QI7HTJ=07CV~zDD zVWRZCM#KSxy;CYE(^FCl*z@dL?<^uH2(91^<-EjMd(H?T6l@io8$kN`r5#cm%tL~j z8z{Y+k16#ph_rZ$N~ai6zM{cBDv=@U=nd+2k6aDcW?AMC6n!gS2 zGD^o0(qVaVfP*w6@+44P$2E}Rc+S?gr^=T@im9;t#=(K>+obS!Qb1 z`6hRDC>IyNc`Wp+D_bwtqUOFGU&cfQa_4YJvDWt8^7?wa*^P5rdr4qJR}bY7Lu@$4 zeIpg&#?iNJnmBsfFk0K1HTeOj<8VqI*P$#x4u}nqisO!w=uN|;{x?^W(c2)K@nmA( zS9g=3C~&C|WyJ#8rXd9lBhVK+Opw;YXpe#_%tk|#xwz+hLYr?D2!w14SJQ8YwD`(b zt^-HfD=h5TFyOKC0fE2Zv~!e^7+oI|X6y4kh(b4vsFzr_&uz)5NwZYf{P5#c0qsqc z@P7{%3M5dp9{%j)z4vt|6Cieg$_>(NY`!3zv*iEqi>&Y`U4s7~mv(`wP4!K+68=2J zK5ryaScNqJ+D$SMnYgP-YALIfNC0EZf3TCJ*B!HD8b_v{U$|&9nS$OJQuA4cu40i# zco&^DHS0U{Od7($kJLhgyJ0E*=B3f9Gv3rxl z$6LZmf5bDK#uJ|z4~~{JA^m~5lvvHR3c|O}ipUU;)aUb< zS69)Wuqhx06CpeC^C5*(^P2+>mouuVs_HhG-S}NP4pbdq1%a!iKZ_nDp8$gXd>L67 zwnJ?#0{ysxJBLBH0yX*&63xhLx=S|+_e^#lvSw4b+WUyps_Vx8Qy8=x5ia*LP*BZTZY(AG>b-i`?;-)-~H6!PL?G^M>RG=+iIAiQ`mrPF+!NI8mK`O)H&wO*W;j7Yr{vOqF5XiWQ+OO_ZU414}# zq9*laKO}XaN!cTI4AZj+(SnvFmi3C<7}jEa$u6Ri+1ea3ZrMb)*ehG&c{q|t+}-}Y z`2fx();BH{%pE6N!A>NXv&G%jI*1S?DCw;jj0z_Du3YAu952)j^1N-W8&H)?-UG!o zv9^cWf3VTU&R?mFN;IzU>9-iI!j^eLt%FHARm_dBUn@za_y&@`T+wTARQ8!<^u#ZS z8{ta52G{xrmETewwur4KU62^vCrcX!ps zhS%OLl!3n@5zwttI|mOm3DyFcsf6t4c<2dStoXVWHdbr;9GCf%i=jC8popjcu<)yE z5$~l+`Rm}vB7>JwzqO5d?R;&fhr_@3y^T|Pjdp1 z%FD-Wo3$X23F#Z%8xoy8NIO6Ei8~?Y6mItxp75Ry;xHc_akO`o>cj*#YE9IAJX9uA ziwkfZvpMG}y|)JfQsne?%vYyL?AlB7mF22~Iy}GPz_oJO7*Y?!^pm8~O~8>`@tf@o zkbp1<;Qo+(>3D`NOffl3Tudf3-wC@m$_G!yiSVA2FWUV~B1v42{kuj824Bw+O2IA#9pEDK5IGI%!cWt}nBk|2&=w^hS~SZSTzV`w0#(2{}A8rA({? zGm7r$|?<4RUBdXjJ z5Bf88<&rd?73U2*Dd<_)6o+|KV(<7O!(MlLM|oTwuZTC#vDYC`9`T`9PCX)RbcVO3Mf_~I3+}q%tuxN26c>Ys3=m^g);aUa+Ab({&?M!A^jQ+ zr$_L>`Iwx9QFMsZz_NCu6p($I*Gw@bD8QBBu+_GDzIk+Td_BR0U=a}*M~W~4G{5iu zf3rp%CMr=lj9#^L5I-{;{?!a464f+NbU(*Zq0cu8N(64^N(MVpUPA}N4Y}g= zg0n=`C(bols_}KTZ7gJerD}TbMX%vgF|K*tUeQ~gop!=}c-0?&Ot$-R7DFMb7p*W5 z(lZzAj?X3P2Xk}%;wK(i4QLxd=w!qn=5t0xlSFI}U^gkr6=MEZ- zFy1n3dqVCjKckht`udTzesJ9tVP7TqvY{dL(tn<`O{_u;pG zVhJafBwD>R+S;e0$s%Kl+tXDQqYO$Te7q1w3Q>601bEYKmi&gY#+FafmeCXcxKx`F zW=rMzWa%PG74~L68Usg<)K8TYygb_!lopLNT!a)qS*ch^8V!W^xY3Uq!wlivf zj%PsxrMblg${@1E#qReq5jrX)-7PWl^NoR05s(5^B2~E>()E1)<$%x*pb!JR1OR{@ zAP7@Gzk4HQj3zKxqEbamj<}iZs?Q-@#c1}}cgzt9oC`CsTy|=)$0gEB#U%%mRFe7t zIOp9}Z<^JahAR`}K@Cb2UFXfw(xj3Tus&n1-U5^Fv3{yDvtBY6E>z(nY^11;UI}SH zl=jGnIcncCpf5DeluLw!;?KZUsF#58j-VL<%mje276O2KKt|c41*()LRJG>ia8>*XxzM2Z9I;>K{+xAk-IG`kiPY## zW>H25uTO`o=87&$Y!yt^cQqKSKOGsRl^z7@ceK}dc4LG$T|4ic_O}tQdcqKT>14On<&$V*X>w0OW5|fxpP&}n4pzR$6xSXv`S8_2#c13ix zg{vW)){R!0VPFHA1#RVx)w}yO)w-qEzXddorA!*M-5Uxa0quSvIxN=vz<8smyKJHIO|k zI-HjUKQg>=Nve4{cd1X^EHGn?!5qV$D=sm{5-I6iZzUn@z4Ypl8OZNrdwU!UhC{mc z!CZ3FpU-=k>{B<@)s*kDBMG_Aa^>z?&}Tk)TqH*y9_&!DjgLLC&wO5R7HL9ggbH27 z%|Z5|DTeR1w>^mm)Hctr!t>SdDgl=NsCPFXa{sV0s1Tu#yRNR~@GI&IO~80}7mBa& zm}<7oIYPFiG7H3i$;WSbyB>>((rpP<@e=Yxk^OwBSryP3s3+5MU1*7@z27dvAgpsz(5wD35r19uoTfuX9zaj5F z-H)n6LYg#Co4x`=U9Sn~v5!YfBNY56K&eVwQdh+?UbFsnT?omECZI84y@d=CIiy&p z(-8lq^SAfdgzx3R{iTV_(K6UW&6p zx}}F2I44u0MulTsu_H5pDP%e;)P%CwG~{Y>Gc=v^U+k55Q`7beBop6Fi}qT38^i-Cu?eIFRwS&9p5l`UR%hI~RsaI+Wxvbmgy zKIS(1Nq+ zC^x=aUh8$8YG-@bt2S8?>H(YnySjk&6x1~68uH=j1FkTm6d}7-O6a*dCZ__iN$Lx(znj|GIK->mbtYta0nB^A4tapHy1fnto)HBp% zuikjlqe5#;w67Y@4l~@1{Gi^)Gi#EpryjF)O-6SwlXP}ad{|fedRNTM zSX8zbZ-rV)|wM?MO`j6fjdutHv4P_J4#hQPt%gVU_;tN4}6^AzyCFLpW7C ztc0ljicXMTOoQCR#Ls)wiQ(ehMvI85NX_Jd>Mj8+d}U4AcuuUaoSMfhwzXkmpCC$C zQNSXeixrT~&;_W%7zduD&)AGS@F8gNvT^W%UcV|h_d|LDIm-4=pQ-4iphn7^vC>OPGn>ffb;sbu|%IxP3%t}<0 z&XsS8!vfYHj8qMUu`|qML)TexNo@Q+qij+nCnHNl$il7rSbE zwqM$4w#|rxp9lol7@Td;-oDE^=Sbd@kv31@;RPgg#%)H&-Pt}-TTSAvrNRxdra4{1 z$8_2el`OAN?BP1j2lTJ%_I1PPe6t^Ij+DO}32t;l z(+La+%+t8isjiP1zap|jQx-myB>jn2e5JN`9iE}3BY$B_kDl%&7-{YIGr8wVUpk0U zxe){%;b^WumcOG+(xdN^x&12G!3O?Xds6epY1LApF+2ImQJ+2KKi$N#wf5w22lN)bz`#DY>@fs; ziYnltHKK8D(mZdEs5h68&qT4kEJ&mmcto)I!^eC{yqqM(8p(z(>-%RW{a!gK0dxW6 z5*gXtk=6uvWj;9G0UKdfH(JA=Vf!5_Zf}ctZvEo%pZD@@AvaOtp;hp{ZOAL9tegjw zGi5X7kL`3qbS%UT9L~eFW$R2oQCl<`e=E9lDDUBL{t2oY-L?md!R~)mFH(is+G8GJ z3$v4b+qs>J@f_2H^Yx*e@}}azhXdxo$kFX@9my}le;Zt|cO`Z=Ej2V*6nSbH|17 zw1~ds-`JUpXOAs*|3Qw(F2d~eKxJdCgw9@5aTU5TcA;7Z9AZg*=_TVbJYG-X*aGil zCbPl@_vZOnT>((t5l1!mG$JIoB{xUQ`h}{~+r$9js-7I(z4v~bv}nzlyb8`1=EULQ zgnS;S5Ry7>l^60FO`X!x0$H`vy!yU77`Ye)AzX-dNzu-U7-?SkkQ@*RM@H{P2#|5` zkB3;$rF{%_czW|$t~GTSv5_e-A?aD%`4uy7{#=F&zkf4mgqpS~g&j)k2TdHU|H5(= z005PxDj3F8r*v3=MBGm<(5tp&?~JpHYlIwz!fT84R~=iy8?+4XzcaXn3r&_;^Q~$B zkPzMa2`8`M=T+?ntGfhOAH*nuZHMQ9`Xl1~Bs#%k6?3ScBKkYvxA@IB9lxvQKqFI^ zU>@XlsxHT4h5@DV{|u)&1+@|yK`8xOkEEZBe+Rc*X}gFWeBuNsX>aS%hm}mWTu&ir z%B&qZvwaUcQi&m@Q)W^&s1i3i5>KNf-ISwMvEjT@Yy2+gnxoPd3}g`uclklzOe0tR z!T&@Y{JhpVH4-9TbfF+xtl2TWp6SoYQzR@c}_B>F547Y1BT19V{IzU zM!(Mtl~ik2VIgro;R=M#!e_*wpS^VtkWZs>2E$`_7wk6e?%Ripj85b~hW7pWliw=0 z9cYI62#&67a(d@dorXLFDFapXg_b<5$wNo%XNm)Q!r8J8Z2L-a?d!Oh$YgrveM^hsSKA!s3{a$*VXjf&X8xePmQAZ9s@I;d{iw`vFGk)sCi~UWY{?F>|5_hGd&=$U6A?m^EMo4v%WQjgn+`f>0bOXK&+Y?|lQ}=I>lr$aJix#8Jq1gQ)CLv^e8UZ$`@KkRSm?A3uFh%C$n;(G zS@%9`2Ep?wR1tD=ZAQO?V~`p_jS&D@ZMc;1g1r+5t+uXZng=XC%)K*XVVc-1YtuKc zcK-TcoVe4}CExZ(rR||1gBCVmwaXS`qXpn#_4}0gJNkh;!2&M=YwJ79_ zqh71LouG)7ng+}auywAnxJ#)EtW><)p@{IOS;5%E0wg0k{FjdJTzxJ=$9Zf+5%A zHY%blo0Q1W)#t+~t`Ken@;xQLNo17^WWplV@pOF9&%S13zLV?qR8{OD8K@_iw(=rk z14k#0)WUn^kb}9DSvtAFS-?7(&;tv-kUqadd)SP-?*JX|XW%F&fteiCi8gh&vDocH zmG_8^NOW7#UtHDoQrWiIdd0IbxLnL-X1uwNvwj&}UbOQ8snKPiJ1TZ1R=tCDbI2{^ zw>f3tF$u@gn(GDh4Bb3$vdNt2n?_6OWUH9f2Q418r|lys{Z}3!`|#s1fp4l< zqkZ9`^owWk|1E?&myIgFOK&3iBlt;_SEzO@X~hou)id-YfC&7SkKVcf;EjPn-b??3 ztD2nRT`Pz~3UT;qpb!HG$hDp08#gnMjytA~=U`!p=Pmuonceju5a+m^XsuW@fHznI z;&x^*{@~f6d-aWs9kjXYaL0CQJRncU%L-r+MbEaVn;R=wVAw9+20zX?x9gL^;OVDy zMZ@p1!=Ppj{y9-}TQceE)yOskzhtlGUAEeh|DKhoR#}BFPn=~sri@c4_qu_q%J^Lh z)dCjMBaW})`6PW-B|Jn*FokUT+zvit<*x{!;`@wCOQvbA0yp4pIm!9Y-r~Qqdfdbr zG7zjKEX2{XN^>#23E^=dY(HYb80BFYU9LjTPI97Omn;-zv@Mqi0Kt5=OTI`>x+de| z_MO$R?ZnEW&;wj~1xtYp6Y**vuyH)j)?#bN^*ujH`KE-G#WL<{u}4N=T!zE$gvVKM zB|hXI%O)ulh&&CYm!YK3!sCCSb!1vvHP~STyJ;Sg%zrs)DIoOaeSB&(K!(nNM(P>Z z&xJI%$TomxuMhy;w%VT=kFSolDq1vZ#mcZmDgfHo+uU7{U}^^mvGl?}%O5=eX({lU zA&fP?kte{z{gvl8wX>K&Ip{msAi|Fy!ypMwy(|~_)aU>Z|{48<&I z^q%0h9O=>IWKn{Q{3Bd{X9E?tgiZ9BxH7qngpmTt>+Qu8Kj~yZ)%$i?+36xd^vC|m zIwN1Tg%#8MU6Qhx6XLwp(#*g1wy8c{kommG!QF$ta~&X$0r@!YT$QPu{V|EAZ;NQ% zUt5S%>)(Kym)TAI4f>4(w6et%4TyNc>hhWGLbX~`AcAdb7l4A=}QdZ4t+ z*)U`gCf#I*iuA?nA6-&Ned~b4)b-+-S^xA`>#s;VaO_t@TOq#!?uq*s0%Kl1*?fY^ zNz-r_$WQx=e#s7J;g7pc-42gnA^{lEB)1h}5~`m44CC7d;7f23+ad-COVmHQ72lq3 z(DG>wCiulUYV58>cFgx}VuO0%zk^LGLN>MVn^W5)jDm8*=F}uQZ1%wqOLRCZ{!%Wd z$KLltUU4t|eTzk-*j83>f&6A|-S{#B&@JjmD-xv8nulszdK4q@jk1^PT~9wjK1q}Q z6Vm)Vj*|ZlEq!%9t$sipW>DvgwU^Z1Pa6H+CRl&+e<9~;M45%uf`i3Qd0lSFB2B$< zqAZjy*b|8>W_{@<9Qbsd!RG(SF4k;)ZaFJ~6A8RgT#p<5nE2A{J>WkY1NJPw{~_>f z$=nI*(PxBO{($hvZ3@JN**Bww&HnXba@JR!AKS45p$ojYy$SQZI()2cPMPVaH@#G8 zzItr+r!FE5nrcNadid~h^!9KN`xwvwq+}_4C{^Q0lMEK?Jk6ZE^EUu#pX>e$Jbxs% zyQB+*?s!I|tJ}6ANig?n6neh5dih9bx19Ml1_Ki`DFXSHec?a2Wo_hI5&na6Uga^s zJw|Cma?pPhr&*l=LPZAgZrV+%i9?`z1gBlik?0qS4c|C;Rm+So+I^*JxCX9x@Q#6E z)YpdS=ihzX^W}{{B}AfCP8Fy~4(%f=HQJG^6Gc@;eHP08%nY4zFYKe~X}lCTD2I7r zevEVpU+Ya~z&!S}l+R4XdlL2@MA{Q%@|wL14SpGaaiT^B1&hvCA$I59miR*q&7{_0 z`?-*^K{r=Q`kRW6D>gFtjqj_6m_gnEtU8{#;E%v$sC~U`9w?`ILH~;hfF!{`&_TER z%TZLQ3XY;V6@y48NtS34tQ{$0^eis?ZV(T+;s+KOKP` z)hQ&k3?^<;D5Z3)E8eT^o`HQ@i~$mv{?tZDl`q;FkzPk-IN&+MT57%}OE#{3LG0c( z*y0^$Wx9VfYnA=A4|GFjLyvfCJrf&UhPtcqMj}p!OG4g^dZ%Jki;BrT=3Vqt zU9bu>gpEW405HYHJ!m*^1-7vm3j%>=xRO5}-k_JXA3@=V+U&TR*y;;4){KuaitDL4 ze)2M@%bcY7A6|{aC&Jyb=|xq1+g5lWNh={c1YX9bpalSs9DsBHfF2+_KoF*Xf6iXa zCNNl`QiO?>FFttG)^~NG*~g<+nP5%6e`=MF2kwI_5Vj^YY6X3#vZ8;{&7Oq+6B1?+ z-*^#Sj%m#`Mk5dw9ar$KH)EE|Zm-{vDP_Y5X2x)scx%y)-%&v+yXi~kAslv8vQCoq z87Fm%NW3|Z@$g0Vy+yH>^I!UZU!}Jmm?mjk(Y`{XtE#%Hu^oO`#P-^0Sw&;@6VrQk z*6sE2-8z^Xzx{kCwg*ze5VAy{ubu(QWe|!A6DJm>QbPHu=^Ak9&;o#R0muhH41n=-6`sFd+oN{Vpe=f^1(dD+0j=BTpss_ zC*QT!fD{5iaski+0C<4p0F5X6{(iGYB^FIU)`rEKV?7Q0il4fEZT(yEyzRN2oqBkE zgv^{^c_;Q2qP$iml~Y2-$l$@5<UhXJ{stK90k;}j?5wrV@jID9rf8RcKD!&oh*9arl)$A_Opt&MzS@b>rX~cY zCy*M!DM{(ET!B%<0s_=VYq=9vKKAT!Fmp?Lx|L~-F+PHCpMkx#V`BY#bfS~F(HX4e z6mn7wjKjs*B9}f_z79S)nf9&ssza0Vr(IiBzGV6Oxxeb>Aw4OT={9_=oXaP(sByFLP$%SnJ2_u$DXg94`n0G`OVN%0FJpf4V+`|R;;y2 zsPY`4dnB!IGm#;HlTJEOn+H@?F zy*{!R@NK)4gAc&jgbfxADM?D)18UUULBI}@Bj2LJCja}c6R zgdK1z-y5@27Qc4UH=oLI9a5RDs2yC$dahETrYeY zef|E-Ixv{21f{FKZeLsqj0=3dp}NzcV(f00M*)wl;kJA#FVC@;fBMvRUWYBHIDeJK zsoZW^A(DCb8IQwiZ7+n~9P4(&#=&#%+uAo-KBg|z4dCugO#2(N2`jPA%R=Q6rlm(7 zD2Rgcq7hi%R_X0CXIkZVr+k;8Es~};E>xHxp!i1k<^~tuE|AL%6Hli_QMV{C zzEraQ^QKGBJgR#%vIO^!pDj-YoGN0o8#9ddE9q;NnaXPNwaxBonE{|406PGDfItlZ zpb!>l#AKuz?^!NzGI++;hralG<;Q`(aM`z(s;Y74i_|{a8B70)F(mmXar=^MC2+cU zk?!rM;Oxh=&cwSa#udt3Xk?LNSv#IaRkeBLP_oO{H&d4yk$O3DkV56RiIH!Hwe$@z zp75fvZ6mFIidIoXL|GaU_O%-7nC{g@6IH|LR?IYyJy~zQH$j@_BmeV? z<^g}KqMl(5a^-}dpwy4l+_^M2{E)Lk8WhRbyDpA(o0ASne6fUhh44NOJN*tq2e=38 zCLWS9EH-ioF^Kcci+QCvzBz=#NBQe@_fA%uxYp3h@j^a-6f>t8%7}%i3BU0BC|ToO zTjtaRZUdvC5k$O?3GC@3PIAQdWuve{#41HOkkY6!Bo5Z}1yG6wDvZBWsgju5-sWEqa@zW zUO%!PMzi1Se*fm5G^Z~CY)SjP0SBsfr@Pvn0RzQjSoN7it$cFdbd~G8)|iJ3h`Yie zy5_Dvj#$NP;^^YLou0e2f(`0*umj=k=@VNdyS&yfH(KFtebzB5lHj+H*}f%s`~J+X zA`a&JIqL1+W!$OkJeFa5>QsD>JNLcCLcfk*1wkO-5H6af7eb{<5~nBR5CJX`bLoat zH1+Jo)WR9k%;;~&$#j#SiS%Jb)AGK_IVb!IL@ItKfGwT#6Ul?T$5-e!roFN{5fx+; zNPGc@Wk%n1XmUV@r;o`ttnSrO)bifY(vac~!b&j;v#|sSk338bi z(mAL1XRX~@va^rqbmjget#Uu@o}Zp|$8}?oNQ?@C@tWuYoOLcZZyEqJc3x=eb5BTf zSo7bay}v&AwnJQGEqLy+(11+9`~Obxmv=mE=YeK3h$8^$P3x7tNhzm6`Pd|f`OM+O zK>;c*fuE1V30xf)qmrIAUS*{Vn{=)ZE2t+omockw;m=6|Vf(e*VR*`UsevZQ2SOj7 zP9=_R>JGNj_bwKil@q+gN`cqbcUXo}YdZ2t;T;u~fVQfc9JHVXTcJ4Fr-j5a3dlg_ z7%f(mw9m!iN>?el7!6YciUi#%n1{&PcPkL@-HhWGC~q6=UbQ@-lfR(7;xx{42JP}s zld~32cpYqL=Ws4UH0vMcxU9#_)Bh#k{_S$5HV8Jq=r~`rpA6z)zq%}NlA%E`OQlOi zZDQ;_YNUXQuEs;`xKj_w6aqOGI#vlp{=w23kR;gx=O5QsT#j<8O_T3wH-#0}N1mG7 z8lb||N{l_b*zZ3_mK!MKJX{9!&-10(I56$kbW(_t<+T~^{)@_Lt*DHZ8y}En19tyu6)(4l^Q+`xy z;i?PfNnc4Qm@??%ie1U?d0PWBaczr0y~}9X{W5G)tfT>V9%8b*Q3X1tj4}Hoh{I3!*udKhkf7F=B zJ<6vLalr>Ramg)*beS-8XZe8QfY=so?i3)}3pmmm>0@WlHVbRm${Lb+`HrSo6?}2a z1?t~M9LSu9^)>-0GgZtF^1C>UMe(mCeJxn^Mtk2i4zPsl+@rO#%y4j4ZjM7h@xFP0 z?mXfG^MaKTn#kHfX)I3dtM@y}teEq+#8sl&(nqb#mS>E&S% zF8gxKj+`y^>-jf4Ke+R^3V)gX1hCIR|A{5K_m~^R-_M@x=ukL0F7TYm9h)6s$JfPm zQcM`!En^L#d%9^z?rA5~k5f$oY1vd@AA>K+dh14Eg0`*A2>=PL!pDO%6FmoJcIOJt-Rt zD-E6dk8$b%UqGP00nBjyu4+@7iPxI?)`wJAd2N6cB21C6L4=!HlS>O;>fIUj|K^w( zaFK@iYH|siAe}2ct(*P6eeV7)e1RF2nkR0hP=%vc#Ny7QP!&7z-LyC3)?Fi!dus`^ zm^FXxY9Hm35kD8Bvj@J1Qg1Ww1wcldD7xO8yT?Dcyy5T5@2&HdFG6suL$Ra^4Q5w7 zH*w=Ae9Op6@eJlD{mR8dGrOfySE0qzK;A&-SHqAd>M%graPDcG6_n*g}ldl z^WHVIH$U3Rw+e~ie zoL&Y2@ffgx+Nszv zozxFCBp1Ywprt+FC;$Kh0Jo>r;J=LXKH{~m(s-M#FZe*``)^Sr?B_qh6mH0p;foe| zmG9EMVB+DJ%CE9DT3X$LeYTr?N*n{9w8fEzLvTrXkx{%&vH0@~c*3xCSI;ZT{^Ah7 zCq2IgOke?@5&_GQ`V-x@M-|@*Qy)>wLI`|u;%eZd z!srP(!^km+RI9PLLNkJeRhSvtetx;fmXAkds1Eq)aMHkl)*Wz#{~kY1EjXpJ8r5?1?|TwruWzVf5#Dr^!-NJM@ha8$om#i+f! z6%)aStkQ*#v>}S9JbF9@tNNqUnmV%9sZ4N;{xC#6DUEN@U3$l zFCNp#d!R9zkgW*7CdIMrbMLma@YO&DP}xjQhQqE<){ux7*x9#NKYOS+@QQyeenHsH zpef6aq7nll1p6C}r%}bJ#Y&&dRd zIMfJzA@Hqg!?Uo!^lo!fy*(psXDvG>zoPW~qv6$88pbG^Z{HRHJRAE@o<>8HkLO!PW(8ta6d}ov>iZMQOBwxSfc{*D& zY&Khq-k=ldGKa^3N46=K8Zj1g1TL=S0!%}K&yz>S@g`N$tt|DQLJ#BOJ~^6t+1IyNz|Nte~&mR4(jdx8YLKMNP4~9s@%PC>D`UW>m*AZFnG{ zb%O2+hJGTK;^ER2I`E=yBfwEJLEyC1}8_a?n@wuNDNC$ zqVlC5a2r21igMerSND7*5)2MEg&(v_=~g>>I(Fz6iT@n1D~|3zQ@TrJ^wqAl$yM;XWJHB>46W_kk_T#>u&?_7 z-W37dOk(2zl~?I7bZ{-jvPh&5A@S`-&Fk=KG&W??I@2r7S`EdXia;ccIi6K!-7LZ2 zzqt4m3lPdvTtJ;dpHJ`Fj~SQTc|qtB#-C`xuyH(14I~B$4-b_(-wifPnZA*rfb2O1 zw9@y!?uGPelat-3iheYwI0dF28Q*6zle)WnzmQ6z=3mT!nV~4aOQd=Y16em(UMf%E zbA@$}zvCmz9=Txr{jrkg52{)w+Vo2wZ(`y890cCH5FlTjTG5x|?WPS+HnMI8#fFbb zC6qi`sULZ47g4Zra_nwEH(+4*O`m*35eEl`!#w4N|U8_hnOpf6^LuTn~5p)@y zJJ$$s7v$+*kN&;Wo4nzM1(t1YyVV5GVXpfV&M3$BK6WyD*HFvY2uZBtZ?^O| z&^qM0b9FzN7_Pkj;}19j7$(c*SpLeOR(7o1is(X}2RfB=hSyL)IE+_rUN@DR_yHWa^rXg}=EL zziqF#SQueOm&Jum5?Zba$p|jlU7UZd71USz0? z^4h*|TOE*Z)b1H6hP}+-;^IK$cT2ywQl6yP1K%BEXC?Lbs@iupq>)Vra@Wh4tR*hn zyA9JPTN=R3gD7Ci=O7chpduZp!#J3CitJhV)dsZG&TpOazT5*@EL=Qrd080JCQ{A` zi&t%2zwO7RWD|;w-kZ5E(_xixj?j0+T_90*kVlqP%xnzE1Q>{{IX+5EA<0w)MoFGG z;ei9p_k^KoXHadh>d-qw58(HT+B>`r+0?0Knw#AcCPqFE9e4y3BU49~8}DGc(PtHFQO;7=X5R zreFgiqoEqV|L%M#a=cPrjf|&PC2RFErPCw?^zLr{vPl%V{bilx+zqdey&9!sspT~b z)459x1^)5Pin2w`bmCP}ISv4~Md$XcX>(I9oN*@er{Lei?tjQvhdJGb92Zf4gF4Oz z_n(z;iy7qT)D*h!jz3qJ)r^8>Fo7FWeW_}qOE!Y}jRE8rd?iaC0w>2_h-6W=k~F&| zHSV82F}$Jc7DsqU!i*C5W4w*~to8#BKn^K#(Y7G!oODtAQWWR0W3;RH3f22I!tvHt z=&tUIdcAwRDMjp=6d`4f(<8Vs<;QyVK7!+Dm59Aejj=nDx>VxuN)&=$P_2MF4`14f z=ehxSt5HH6>hY1n-4XXSYk9HLbdoGo#L6NwtDVRLZ?84bo0!};8p3^}86CEF7K%AG zOP?aug)a7$Vt26*m|w7r;x=}t1(??y(}`7}!P&6+M)u^yGBm{7`+Xd2&R{dOl5HWn z20@jErP1ligdQkVV^zcvh5EIHClU(gd1Mz5>2sFg-Sle>qIWO&Jh5Y=W2WJrHxJwQ z`7>UnE{o+Sl0-%Gw34@oQE33UoOx7ZsVC08_|PD=rz*P9q3tw#*iFg_Qx1?uyt>Z2 z`V#uUGbBAGIjoi0d}LDi9Q)G1mP?bLp98f}M;TjN`b~KQ&cmtiiS*l~qo$T7AmA`o+b^YN#sQQvjYpE zV2poJfe49f*Bs0pYr&(IAg0jO!+S|2Frq75?!mVcf>&G}CMoUHr{?|HlcR=*!o<^3kA$;Z zlPm#`5{HssNV;!s_w(G(8$5@@!(o`&*n!Vl-2*?53|7FcnqBc5=_p|LC*kCp3G0+$ zodm?n=dbLS45|P+`HoSrI)G&;u5VP!$uUGii|4nO`#=Yi4ha^WZ0jW?g@eS>?Of6*QJ}q&E?=B>kQBZN46yQv;!q$sBNuuTpYSj z%*sw6cE-G?xN;Ip#nGQ^mKogw;Q=btC{Q{J4g*1Bpjb#15(I*RAc#mRArXi~VRwCR zJ+GQy4t_h~mv_6U&2FZ+=A-~UQ>ybf0Yy_h}0#KCjImwCnuIw)ON&mh6YW*T<^9AvV_jTtc9I z>TmQaHrQ_42gGMJuyj*lmuT6@G zFQ`7_07BFjyB~l3dK(l4g8^fpTqtG=41$3mh>Ri=2!z5UFsM=d{+9OdJm*}`tjns^ zS#?*HoNrz6u0oWg4-A9&HoxD0ZofZy!AOEDANa zd=FZ0O@i{R1sx0xG030NLaFo0+7gmUg^~Jzp7;cK<#336Ha*b3D22OCVvyvsQ?7s3I{=8z?d)=8U>1kAgD+x z5(?cMs(;OqM-$DMR9<_rH#;kqMDz;~#jhJ*G;oI-l2l z5tLpdp>mTv3>3pPOfA12 zv(0JDyp*e$nJqO}CD57>doo_amzIA1kHr`D{a2{o@%7iHPxj~2;VRSlx_sM}5sza2 zA8YQTw(GjG%CzH~zrO{~3;)nyI))uDI3aW=Jz;VY9@aPnoc+_qU(R7?Le zGq&nf;)&IlY_0~@KeLbs{yxntna{rGnRAM%?J==36SSDNn$YxN%apfkT3wM{s_8|Y zM5x<+i6b~7B^#qFMQi~odj!=@22>r7g18lG$O1e z{Pz0~I+vY4Zasb1Y?ll1i`(P#(;FMgnEm0ZXTQSRim)}|XPmG!@dhqQX zfz_Q?J=^5+cXC>4dJ7M`dYWkO(Y3R78%?K+eILcW;#knv21FNa-uMu zl;Ic;K8lg1Qxk&o`mPubJg!S z_U|R?PC06=brDjp$D3|k0PkLSu5M2;dNk5!x%Bm0w}byHLw2cZ|H1yx{U*}Ms{RM~ z4e#O_%X#Elod%ZZ!*xc39YK1hOXG9dm=k;hN>0sRT#THuhp=_AxFbUd#M{x3>ON0WKOh0%52vAUNRxg`xUGcqD%mDvO)_O0ZSNIVA z@@ih|yIr{IR?2PE+Pc5(;Xid!`B)&V?&Exc<6{!Dk1<+?PCWaTd%%O6ss4z`rrpblYeMS2)EvN zJ!*m_sVNK0?*)8js7CQvR8pFMdx`*{u+UgAMjQo%;$WayDijih0-+$FNJb$EghHVc zE_-;*e!r&`Ul`#zzAKI0OiaIBaa+6i3O@(=8uw@a(M8YvPjB!|+7!BKy}WsS zETVVcK-cVkgF$ZJh0rvDP_Gxe9p?SHf0xNgd?lxx=3IyNtKSfYa*tklXVp^}rHgB} zSlW-@8c%RreWZPYXliIc@$*rut3XptkM*Ai28A_vO=iFXb884(QpoNJM*_kEUhx=! zMidlpK7Ie#YYhep!f?QtNERdsjDld0gyt77k6O!|Y|goh%F`{Ea@PX9f%x<2FFmK) z=XJMQvwmMrzq7Ne;`B7AOVswI!GP)fe7pGXUx0lh4~2Ph@TU%~(dm-9D*ucdYKmfu zUPs)1QCCgPUrH{b`Pz$jS%$Woigj99%jEEq`~6*QYh4vrT3`G85KwTe#;>#ep0}O8 z752Vs$~!k=k9pqrw*%TmQZ%EifQEoJ-#I(Ow3Se(z^;0g`iXmZlWesxUrh@}T~=MD zg;3>LQsS6BaG^>&vcL#<6$%8wfUu}67!x%HK@_uodHAkxUcI?pOPQKgveweoFMJFh zb$|MS{EuSId%b3hDE?4$ws>jIlpj5r>glS(Y~tfoY8xIj=zos)p|g`kwLf)PPZj0Qjv+nrLeMEK8qh7-?@^+%Yl}^v)coCMZu@4DaM~xA* zprIbQK*5j!07n1-6_7!j1|$FTO1yf3ETx4P6frFo_liU+t>1~ki}v0)2Qm$p`mut# z4%FF0p!E1yBd=J@cUf}2oK7{+0k{%u=zfm)q_9Cb(EdDu8}gDt@##xec-~C#qTwMY$Ec863TTs#J#2ehECZJ~k$bqq9?Sin3MgNHjC8&wIkQ#9{tr{&e+YP-gsjiA_2S>5F^+_c5P}E>5 zhFl%@KGcTL%$Npk<5S$9^_Qx$E{MY6>vczBHk2%CSxQqeFrG;;-+dhAl1ULC24r(E z&$zJ4oUVp{PF=S34ceh|UsyBUi`d; zXW$!GX+zrXv3KBqL-ET*Ru%*?cv#T{?(N8832b4rI+cM<`5?>JdZE6=^$7bAbkjaP`*$oZ(F;J4pF zECt@Nt{!K<@$*g<#5}?tyqY4AXK=EqE5;2f06NZ(X`NP}&mCXL9WQw46Uz&f5ypUKJS$mixFDKUd>)Fk*h?0yL%kt7>Hp)3JA*yN}4It9=)^gdx$T9z(CGnOgGF!S_uz0gq+aDg$@jZond0 ztH=+D#4q!a>sUh08hYrMU9M7LDY{IQ1hTr(f3-`!?{{Ev9~s|liqY6Jrz2Qf%)Vn)soL@SbY6>{yTot zeuEt0<>+vSa9LZ=VfLv^o~603K|hN2nMH~V&pTL%j|axmIb7_YUEM3xZ33&YO#Q5# z8osw`lSezppbpyoUjq6SCrDNz-g!DVdsenWgB)$rGgt1I)h5UTVc`4126!fmED-^w(E0k_ z{REp5Csa`LDy(V);Zb59I*J4@7nZC0upt z(3omjiO;|?7QfAC+n|fw1Z$QNkJZxnV1_jYj7#?!D~ElPbi$vIBA-GBiv;=v$@)x? zkTm!5@uu=fnur9esuu^5IKB#zd9j1d*#$y#S3ng4v*T#}TUs>AZ&d~x-%+Y6JjAHc zRm&~sQo&T8zYIgRPp(CEIQ-m&1&bS@{6t4@YV+%hMcv9v%=~fkGMc@7u4R zFWe-Wt%q;gyz}0l?;k0jG154EyypoI`{hj5$bb?!3LQfUaKCLmajZpl^+@Zkkw_|7 z>UrU?e~QRrke+Peyfy*1S;^7yy6AY?2L&Mw==33P3zM*gE4~M8ah-D-hhS;lj|cem zoL(|O4f|8;FxA$P>Pav77=2JbtrKQ6CA;P!tl5H-{m((V8?Kjxkma5_V)IRIJ!?e;X|qDx}SD9>*XdcGRUJ7zJG zXqI91w!FK5W8uQcdOY0 zGH1e0mFR15=QD1ZT?T=h-Lc_Hk>+>B8gpci{^Rstiz*N=eaZ+h_nwb;X|P?VMW%_f z7BRk<#8$Cx=pMn}hVo+xLJY_SmUIp^H6`3sl`dCyS0zQ*gdmTGSZXO=jV3rD#SKi~ zNfFK*KpxU+@qDth|Lp%6Qn!nvu9wcZMeiFe_dAbbi;!`;P84OxHFfEc)h1uo zJq$z5mR_5gnh$k$w|{hg_jreVp<$oGZEf%SJ>H}#2tJSF z^Ys_0?YLr!LmON6@Nolw#nCFoQ@t^4(cZWGTw?OB)Xg3%dqBRU{M;DI4q$x3g%0k} za9*=O_3?KX%6u@|ql6iM?fkw-J#)vUFXCEwr>6Y6#zm9ktOK<4XBZuepZ4Bt(stH9 zQm!{|FM4XfNZD^08Vygp8di5pC;Mo*dKm4)_N>ovZ@7ljHK}s~A$#1#ZV$&%+#PW$ z2i4F=7%J~E_epWk(q8G#tb3%F+2Zl)8F-K7dCi>?fVf-&t`^uB|AlfM0Pq-LWfEQt z^aVqPabC6Xyo@3x?p&&%U`0u=d5%qV4QYY65a})#as>&rlBe|F*byRp?iu0QY%RImMHLW?dhv$58n>O-%$z z;L4|~6aU+EX%#I~%2^-*tk+{D>Lh}vJro5Lv5HQDc=X^7YTN!=8QUKjSbR8@0)*ZT zWL0}@08}Ty$h4X`(C|iNFQlu&_bCb789Ymu{>)TihfS%Ts7t6_BdDUOs=+suASMaF zO|p}WbrKzav8w`vC>-_UN2+mtr!UCvd9+4Lz6Ch61XB8!uZ%p2z<#j~Hj>98n=uqx~wK_^8S}xga@xOroz& zLA&?BY}W6iPF>v-C_=>K)k5`P_NyLf(cSWRjKob6`{50C?*p(*d=@9-Zm*j&rzcoE zK{{yj7HO+%Jb>l$bKrOAQCpM3#<&$V^k7N2GcrPEzh4Q(aT5lABx%pDeW3u$_uGED zJX#RZOh1O@%=v|@?jz6R?0%n6xRqpJ@T+izR~a6RMaXm&}6DeZ-2m~ z%PMzg=PNAJTJB5=$R&x;N6t^r!`vt9&rat=OSVyovqInS2=JC^*-qoYsYQ=;i}D|d zZzFr^(GP5#I~qQ~8!V+{#T{6(G?|QJG>Wu|1@2#qNT(8(ytyQ2j#jSPyG4&S6#=M(kQ7SlSGHoM(=3Nxhcg2pAMMdwk2p&GbwJ) zjsNN3@*EXahd*LVu1Rh&EKY%1+pZVw3$T9fbho@6)%-VsPpE3Tm>S;>B0W^LEMTB9 zZu?~y+kb!u)T*}6YPhEpd(VJ1XP(AG&-ylD9Ub#*K1?;l7E{i74)xy|R|3NeSHzq* z)c39lu+RA6;Oh31tm^aK`G&@q5_Qx2VuJ1e52g5t<=BwglJ=BU_o;jG(k}ly2eC6H z!2nm0y3l{is9yWXvLmb0=y38H*yk9If80(-6Wd0eomgU(n2=+2Y(3Iljl?CVqm0?_&9lv9g*Gnk~%P4-#dFUK;Ho!>9gH9dSDrZ^`|dFmN$amTLxbzE<*oMp8ca5s8TQgu*{x$?aok#X9%t~|TOXd>(L zBAkTnUT{pD!5U7&(cGxPE$3758X`WJMX5HnudU-QzLM7;JTcHX`OoAlda$EmI5?nx z>D)hHPB~4?Fmj3=aqiI-hwmBa#ClU>L_lBiRLljESQQd3gfJCq5X;?E;8T55uRV!8 zr>(O(XN8sn8T@vNpUa=Rh6!2!x_O~#>zyErxeL;7baLY)Y{C0$CeI$3s1R;<)sq`C9<=2 z!bsC5?>#}vqzC2EHm@#Ol068-J`O_xdQpn>T*;QX{Z$-e{6V$bB_Y}Mm<+0 z;w5|ipjtQP%-EfWguA<~?)u{qHr9k>FijGKbd}qMZ^h#W$C$?+=ey(=w2OhY?KQ90 zCYxa~y!?~s#*TSkrlq}&dAerK@P;5(EG6Id3NBr38;Yom75Yb4 z6)5jy-l7@&4^da_K@&>mFHC$_q`vU=lN6Nt9iB}BEO9y@1uX$W-?Y}$ST+tEvFZv% z7K7_-oLVXW$%GSzUM?pEy%B-0o`VFR`?tVM_^YnIXB1R1nZ2LB|4M4p_@+4H(O|}q zn-2i!Oq4yVF&w|}=Ejy??!l~1n0>_<8y9SP?Yfugt@(v4$p(}rr2tK`2trNxk=q}m zgN!75R*g{rqL2i(?|nQEa*xm>oZR9nCX+&N6d{#vIO$V86j`aX$VGVNvtiYyc^?WX zez!eBAmjDU=ea{BEqQto>f}3%78q5;lOpI?2Mio`feclqnmtixb25f~8U^IGjGV9B zIzx0z>4rGGwJ(VB_W=37fOrQ;pT9i{2p2t}SdpwvJ|7IRiHPE0y;YawvA0U<{I~|c zG~Fp|596Bp_n88Vnk!_mK1K~pYlh=f5H<}?ADQitOS>6-uy6NX%-1zOx8!mu>u5@P zLy1rG80qLA=J1;vapQ4>7M06hk}R?mT?5xHmC>PubgB&pWa!D z;EbhM;`nWu8w-QZlHagK$;}7JCt$art@sKT=CGRsPz1|{td?RDl!dkZj`}W*@&05A4GlqDM{G&EF62D@;d)L;f8M)R;eIwBV>R`Np^^Ecd5c1S@Kdy zL+Pq=v~XdSPfK-^2Hjhsqc$R#@vs3d6ew&c3lapxP_R%c77B#|p+JyOCKU;ULShma zL{A?Rd-lu8T}+YHUTKnKnb$X^R<;4&KV7VL$2b0U_WqYR`o0f02K@>iP|zn}6f3_H z?qS|LN{n=e;fFDL!p=Lt@P{7A_+IiUenkZV=V&MmFGK|~VKYQwBh2W^xR45h-1ww-$phzYWA&5+x*M8O2D}R1`eP!NUn(tGd zD|gRXa+?Tzr}n$g;ox~c_n7y&InVXFh5O<=$bj0^HeHIQng<1XK-(7nydr*|=t7)n zE5N~jPx)?U1-zBMHMP$U!y2ts2M zJN^CYXXDjzzN);=bhfg%b0$seRhMu_`Tmc^>v`7VAOGNwqldz$vv#N6o*j{!tN&Y| z_au7!)0`j9!uk@Fcm#xa{X74Z>awG0od4IA>;GpszfWGLA1S0f$fjRUk!91g`FX0G z3_83a&&SpqZYQiIcho;@Q7gNQV60n}XP~%$;PsOBidKAorD-ZC8`~Eq;Y6dd;EjCh z8FIiS>i~=>FYoyO{qHmz4GDz-WUvjs!4Yx*j;{kfYGoLLZ0Y6RR zygb%f{E*(|QQ}YIsF%p$%|$%_ps&}{LE(6bxY>-xWz za02!8{|d|T@9WpMsR?{QZv|)gfEqQ-WrBo~6n0nyV?si`Mi)6eDq%oVUOn+y!br0@xIZ+awLTdE& z#^S~ZFLfu{k(%(P$%*;$p$%z{v!)U4c95hMsU(yUyj>(U8i91=6k~(|JwkynV5~F? z4Z?y@pp+yO5`=;xF^QLHO>VsJ+piZl!E)()x~DvGRIY~s<~}A*$trI@zuO~Pmp@ri zuuwNW{_TNptNMKmTy;*j6feKh)s5GPsXCsooam18zurF^`J$^xxe1OFP;q*e+~)mr zN|)jAli&iMbj#7v%EV?^q6vW9cM&DNlZzqVaeuxPW~y))jel$GGg!2x<&j=Ys7Xoy zrW`9Fs03fD$DSa^00_#1um9iw{}%zF!5B~$R0)QJAc@Q(6*ZFYEh42=?&`Xviezj`P94Jisyd!)Y6| z3A`paLg5c#puw0_7z+jh%0RG?gb_FeizAHQuN+qGOQ}~<;^4Rn>F<ymv?inZmqofB{WTikA|(1X}<;` z^6}q1o4;x4xjIlY2E7b0M)H}Bf2}pL!z)S4s9u@t`w4ffe zhjz%0nz>RQ*I~Jz8YV{zaq)MIpu$V@%E#3%Hc3pQ_PYDks&;}0Zq%}CLbG3N*~mn} zkbwY4000)4L7OHcf8=1=b{lbqAJef5wj$Uo8v4v%GfTiv_M+~ObaV2`Gi;$!{YWP- zz5^?YQx~erdXIBvP+_)ECDlP-Tassp53HXEpXc8b6YJ_e3lpG}AX>F6=3I>HygwCA zK9UghEAjK^F~f$RHrSP!-vO~@2P^e&`K?^cQvJvZtMCFD!75ZQl5IyKZhR*0{RoM? zsw?e{+`3YK9n`eQxpT`&A$;6lllS8;ljG(%yhY64!~_J;O3joq zPnYmSzz`?OoL@rzO~fYji*I)4nZY4Hnt#G3Cv1%dOwc_WBJM8F`t5V>H2lEaWC%*; z>HaWA+0XZ<%0`%|@VIgeo>R2CsVdp^0;kb(8ri(;C1&)=ZFs>sJ@ivCeh!s3uiRo2 zRJfQ))zz`H7}?W>r#p|{84U~n9!)rm4}Ig^5l7KB!1ZNA!euM|7CJEq>W zD&=c9;IyqfR{8LjH^JJrBm+WroJi)_uTov4A{z8SDbst-N$&GBJ|vLj+doXEn5EeC#M3l2h;;Yi@J2doq}R!`~h zci-b;QyyRykAgxnydAK)h^qA?r%pn2o{wLWfqr6Y74>N~L(j9qcy9ydlY)61a&<|h zRR-pUPan37u?0}4^CH}22Ws`Tg}v{8U&We-JlAH121J0aH+S2SXriwS@;N#Rfav!EO|tyE$*=A6)^74Ofq=xzjEoG^a=Hdsc+MD zP`;y7qwi*{{^mpqiPu(sb^m8Y>52}e`|O2a5akOEUGRoT9D)tM|5e2k15s9j1@19P zeuxfOilD+X0RE!xTIBhUyy%iu<}uy}yPyV=ua6tp%|zR!a`@~0wj?Im#=y|XZ!+Hy z5us)it+*UqO%wVAW3b$o12#277@3I2uSH{TB6rYOCRj}D(aT5w$0L0>8nbmrku_5Z z4uq{s%``tezE)MywAS@BJPNSFi*HcWw^Ox6uc9e$$C1B7&U94nw3wJuy{Ukd`KgOt z{kVlft6eCL+^WFpjY%F?PS=sRP$8TT_*8P7Qdqpga)R+03po|ou7fZ>^Wm5(YsV!Y zoOra|U0MpR&iU5T15R2nJgnSb2jxgnn%GwCF4&;ke!Kt&-PC`MhobJW?ZFI2f)&-I zfbM*N^vZ}iQO9f|8hKTqWrF$~N#m`^{5OCnT)RvR;uaNZ7vWpeZlxIn?345@{aRAW zgF5o$R(aap0-FcXN);ZxloY6^U!d-KVY=JbnOO zn~(mXOREJ-(0_GKNl$IUh}(SNeee++?i|6ScYS94r0$!pE;d<`rciyRrsIc1pIEfT zF2j24jdCIHDTYUFV2}6P+>-^7QvGdQSQBb>L)PGFgPm19n#@^!Lgq0hG<5D`B;GoUp>zM z*FsaPQ$|Ch&YMO=^7Bx#5T%`sCW;y)c;1l4yxC3R?XjhO zT$H_=fWk3pZ%mfzdWm~V=9UyRN_%4KM4KgrCT=tryAagLFK(~XQ~4h13~ToTOSptl zsW%(I!&}7G`vcq1J)7hXY>#<<+y~Cv(iZk!&eBnRzn1ySF$1^K)}#p@SRoe^;P^jV z2op+_7smTS#oJ2?F}pJ>mTohwxt^={^^KOahC}7`Js&BJ9GGt6IeBa)DdXVM{|b&Ws=gBNQsj}@3Gy$Gsi|}(nv~$ zR<=djL5{Asj9LO}KhRa(DPljhSNFwc>JwOSemX>=q;4NzbKio=M%964;|=pE-mv=B zK)1kL!qxnVpPmF1DZ66e;^X6D*PSFe1zu-^*AdHs6Cb*(-d;JqQOLe7lpy zGtm|>eVI>ewhyUKu2}N9&P2x=sU*E1Wj3B5nIP3lgdQ$(Shtc|$?{}k3BU#6&t$!z z`u|pFO&oQ-z{GP^MU0}vsd)4XlW;ap=+6@~`6rK;1DBm!r&fexhWJnJBQZFIwd&$C z>kdvRy3_Bv2}jIcPs70cL+B}KzU7N~&R^D5_C(?FyXbIGNcJeZ;KjD8me^8{xG)pR zJZpuwHke{CjTknVu@WfT*6dZp`Yf$oe%h>20f->r?fzU2?l8V_ClTgSZc+wU9-Gv# zubnCA3Oc4|Wl4@Tu%a(fFC@d|fD_=BcKH#=UWdzF#33AK{5#4kW;*VyK7XyS>c?NvW2og&L&n>o&aDGbysW`I@R0MY3YMiPB|9gMF0B-`d+h<_L zXxMmc>^5tTx&ZpQ9`tU?diL?b#e*J}RZxIlL=eTvk2;TgydLp ziD^7(^ygZ#y_V*@4@v$>^r=a&(gsg9j@cx!V}f)M^%2!?R(`^RQ<%qi&<$o(GM56~ zqN!Zn4{a8BrfLurYXgL=oVF)Gh_A%P>%T#*|iqdWn7 z)q1?k@X^QK^xs+ys<*BdOVTUafBBbUSoM5ARMJwY{c+oFer~hQMY{WZ#^-W zP_vzOyC&W3>THk@ANB0$gRv_jx( zs280_={B{vzOHFTy8=L{(AOzD z$8HdZ4K?IN2biCAg{0+T%i4NFbu*i~4TKoA04>Q&R~3D%3XF0$FRRJ%I&@ZH;LiUwP%l)JP_qDp5$W6K9XUM?%jNoici|;ES9f*k|D(6? zPe?rEDKeN((Wl+?`$KkT=`F_KYwCPjagtHQb|D?>r|J3b!(3)R48?NWk7IqPBd&kA zB}?B)gikPX4<8n$+t_fkHl-;thzrBYuUryY@?cFTd#Qs(34Q-zz<6-^UUKU$rcH^0eqm(SqyMTdb$P7xH{T3 zKkCPdE(L`<3Gy44ZzatFAg-0PdW5O&)JZjbRD7MlQ!Qo%(dNw=K~TSfSfY_)RWrX$ zE%d>XUiJX_2*qz?oat3t5f&947IC$`gWFNWt)a!y69O;w!8C`a1EIyq`$I!Z^eoyH z$PCTQ&Wpk6qbuq*icJ?shDEGK0d3YjOky4buG3j&2o;>ghR5VFfQQW%c zVsQC&OrN{`?Rt`DlcH?`W^Ea@1?k=3>zI5ZwjD=#mzX(emlW}jT%ZcQ8s8_cL!m-g zZ5E1IW`)R+I_rd`dbbj!<|c^c7=Px4^`y$U-7tTf+uz|H!CY>oHU_rt;XwsQ%p~^E zo2bF7G6Yql5=4^Ol8#lzWKOP6wtbct2a7)d{*FSYJJK)+)nx*&M)n}sK@$I*K=@D- zN)>v3$7l5bi$HY0PZP~Op>?rIv{Y~DqRzeQAzF7} zu9h=a$6tXAYMhr~Q_8yQpYAk6Up}_az`IgK{0UtiZ^`U2fXj=S5(`dHW~B(^lQuJE zFEMA7bAEx#aOf;~f^dpa%3fN|3I;m|<1vE>{PhsJDmhseBy;k$%~5B370K`T8|%%W2zyH?7CbTp?<1f3ga*1+6|b z@FD4gV&LMw2b^s2HbLRZ{IJ#mX9%*cfg?Q<&2eE27S-BbW+Hj1pj$2p&mPkNm4p~$g05dy5JmgSbdLy-}q zi9GH|@zp7rD1JxF!zzb3V-PA-`y6jYU7mNdmH`l6XTb}w!@A*(v^Mk9Pc2IlT(8k< zlzHyS=nTSTRD)>eDDfF9VKHO%n9E;?!;kp^J-NzZr42evqLU~;)WQx%;%f5a^L%>u z%HI62LN?i@!c+TFWxN7Z7}fm&eD5ee9lRIW?oJ-)Gg2|mWh#ObQMsU(FmQb zT5`x7__{p|ymnNgsi=Hp(<0sy58N^35snb$K><3y0T35y+1l63hX(4l`4*5!8dnM>sej z{(>42^@$j&!s!oRvPuqOtw^t7Nk{R3$w1}cZQbbyc|sqE!^A+GZ6DgsL<~n5 z2l_K^`jCqp^LB|nJ*KDv2zggh*c>Q45oR5mk98{$e(fFj@_y^#MC6k9iC0TDQ(NQ8 z%H$K7eqc@EwQ2VHhf9$c^IttvyGrA7(z{dY~!?~MeT_Ec{IWo-o2VBy9 zeBvVSsfc(4rR^x^q%VG;^-M20(dZ+B--{X+8-K$BN!BT(=kE|-4sW-O5q5%QSDV|g z$k=OiQEKIYJA#}7`uqUMVA(AJK9)-t5}AgP>Ni7Yr88nBcIgNp%Dbt!WPcl?V4o8p0N3F8B>&1E08ngQdt$o*=?7#apU7(In=L<@)Xy#M#TFjB55 z!I%1B;Lk0Xf!#ZOE41gIJH}B!c{Dj@!ETWw4d%F31o=K1aTv$?R3Usl&$sM!N*n2v z8W8rUKL6CRJ`@B~ZOt8|$F?RHu9eO98O?9qrEuj%RAF&D57+YO8l8(UR-W!RW|ru9 zk%$jCuU@+4mcVrJMzs{E`#MHjOd4GUKyA_WN^@0XSA*YMoiRlyj|AC-G?c0ExycvN z$YY~qEc!0TC$PiG6uTcnlVCTm&almjr^DE$x$n^!90?M^Oa!qN zjqBpR=f^rKyF9!iZWb!hN#-{S&1%=;4w0(?hFpw~x)M){dA!NP`E7p0T`xn@vQ-<+&N}`7s_o%dj~Q! zp7-Z-&D2S9D5-)9>zU`s!{N~I(Fx^~A+WJVpbToU&i9o!@2c4XL;ojn1_?ur zKX`)eEZAA$D>8L=G;;MjV@Sikw{5BpIlw}byI~uCHH^Zz4am;0h-9sD!#ibOwv=iZ zp`0)Xl4L>I7q9uQWGj0H~Dcdn%n$YbDX%v9xC)#n!Jw%Tspr<7!Jc+^4WhzH6ZlH*Ay|q z_n?Aa{`OK8Y9*e<>aq|4Ljb*pV+Q4>OnV6jA`N|zerS0?pdN3uG)y~mcM zIdsqaSU0p8|J${8(u*c#i>k&m=gnX#6ti7g)?X^0>=@Mr2$fSCn$*mfuAuR{O4UNe z3TrdfCijI8S8Sd`dU;7HW|$P_!~+3BBQ@s9B;>YrtP$d@QRWhAV#Z3L&RJ&x&6ehz z08#i#4LM7;>A{)t>S(9<`#&UEvikAbtMt3D>Ps#BlHcl)*g88zV|VRioL_{j;EJYF zMcjx=l7e=NJ4iJ`i_%~0ijhnIO@}uH@Bjb;z<2<#9v~nA3TOBJWbDCekxQK3O%o`z8GrV!+l3@ zqODlaKb$)<*nWBFn#v^B({RrTy=!1!?-WY|IWjeFEi|{m>Ft_cm6*uFZ<4Y}umG-w zRlYB!gpu|r#!y;Q?G+4ao{4=2CRkZ~>3xJoG(XL43z^XRatk`2dmEVN_NwI`?W7~J zCD(WZ^R(Nn#b)UPRybY#;Y=>(bgaDeCL+ZJU;!HHd#qo4`#=BySPuXe1JnWlN?C%+ z3nVH{yx*C`o0az;^j$KY(#>-L@h7}&DL)jZ z-B~*=u*y|cC6pd^YZl=_$a+X(N!_vhV$(0R&-12J?_jEo zYf847^{i(`x|3U(LvMQL2E3^EbdaD~HMVSRUvRg>l8&C{T=_5Ez8(?jr_T{|2%!NW za(JPDh=N#1@u!ORSi^f{(Z{|PlLl2ts74iEx3kBp-JTv7?fiZoyi8~-mTHK)o3;+NCfB+sK03a;UgvJvjAey*MXesvO3ib9wYH_mK zhq|>VnQu>s#^#l)fLWTtGUa!z`mndcyL;fj?W;b58rmR^%$02RI(}ZB8ILb97fAAj z9%^}q(@niUkCxvLEK8nC0YAuEx9 zsnbvyi69ur)FI=GvSH6V+$8UV3G3C+e4CV4Xmx#Y$7&8pdL`=8otCU^MT-9kH4+`d7!@jfNlo;dI&Krh*PvCxe& z8)jO#_3o2QfzWjKc5tg)#ph7Y*IIr?stD#Zb1z9a1*FNs*8zX~=w;?BZ|bbUIF>-7 zw4pRN0$d_l_@PP|^uP#OgZRCDcn3XUpukvA78`~H!*H;WP8A9agrOjaOd=8pohFX5 zv3k{46>~3Jy46;>$}-x47m|NZF5Kzu@_xR8(O28}F89A&Z0;O!_5#sP@Fmemy?>tn zCOf8p3(@K0%lH5)e_`sp%Znz5N8ixvcA3gA>}9DKp5FdB$S@juRt#n5x&-MHV&h7_(&+y5DCr76enmmL-U!;Hc~|^10HSGw zDcmVkg&^XmHB%MR0yd!ke*gdX!BC)VC<_Jz&Ooq`CKL#z`M$SWshWvPqM3Da+F3WF zLv{9l*5%$V&F`;tANviV2nH|9rntwi-V_!??714WsN_4@18CXGbEF`qniej-;~@MJ{ybh01k{ z_}sZv#srL3LUXolAc>*D7<3jK1&V=TpjaqE5TVcC#yGr{H0N5}m3z8esd5!-&1zUp)NZ9tHnG1Z}`IsXacHv)cO2#e${>^dKF^0PFvQf z?y~d=6pGCg$Sd^IIEjzuI7U7~v!81M+Eg~iYUDhPjp1L>fQ(DyisN&zdSSqu6vCCb z7&0&*2;cw!70E%HMk9aZVA^%^PNXoe;*;g3NYBOc2@WQocZ&kpV*`@-{$7-`CR8TL z3j+AF;K50-A5qumK^3w^Y&nM$TxWugNaZ2Hw*#3T;W~Pp6}7A(jUKMSW1$lsE9kB{ z;uUd$F5^Yg+i6>$pn*CbCaiNOKV6mFl=C3xA1H1O$pS&B(p!3nQcm-5Jskl8UvXpS z{Dq;HrqIz#nu;>3t*%dh7b->td?Rz;^yf;kLvN`wIsy^&9gQ!zrGAohn52Iuep?hsqV?JK0Wa@e<3C7n)G;qYjJh~Fe}F{|Do zmA+~w3{)nqI_02VD6G}WmJtLIyFwAWX&y_kN6*fowf@eP-UVM-alwwQzCQ!B5D4<5 zFq48G6}_ITXkj|BwVhq0WhKNlRaY;iqZ8xSGGjIt)>nPW2tY`B{OxKkcl zuFLBz5h};iN1_%rU)1s!#OQ_tFv*BHZVqHmhxp~7En!Ab_vC8n;tFcd5?}${2 zKPy&Hu@w&)FV#p56uiV!RRYT=YVaSAIufmNK8c8GEq@*F>$FMPik$zy3_;BekpOT837-;W z!H;mUv}0Hl#N$qCFwXyDNqxeb+s|ZB0*;5{i=m#O7>xvegJ=!F&4hTInwOlxf9~4Y zhvP0NS`fk}6D$I;I_2-Rq%gr6z&hovo*t0mG{DByQT14`sbh;&s5|Q^(U6j+m{DCw zp+IT0?0+Mvzl_r^8cAxhk~5KFu>BhN)8wUKe2WUke^<%$k>u22l;Rp*q519^nxZ* zCO&pS#6_f3H2XX2nzuN(Pwdi^@kBaG6m()Efe1NG%=5s+Us6jF4@pc zxLf>r>D(t7_E@@pZb*~C8coqhxyziMDl0K#c-BQr1H~^??yvi;nCFJVdAWhnk zr~2R>lQ)i zasw0_sFP)UfM8S0gpwx{bZJ>!ftqPh7V7Pc5j{lJW?>sjTP!UdDE*|x1(ZcTv`4Sl zi&>yiaxoUhZmvocK^cp@}{V8n zw7zEjY*(wjwt~{Nv`h1gCP#u%WkAY(qW&IBmh(&~A!lBMGK2(KYgTZrNK#XV zC5<;qoN6$hptLfJbYM6m6b3kIbGf4@9I^xS^l$anmswzA`}X~U9UZzuhAB3s72r9D zmbB?}_#m4R3%uMkhA z<%Qd%fyHbVkEGV5$xbs-(w+57-+1DAtMM!qQ-ZIP4^Bdgrg{Pvt~0gl3QQKv<>wJD z^fvhJXoQaFq~U{j_gI{ikKb3E%sdZm{hSjM%EU~?(Iwn@2xV$CGqk8l%_zs`sp;ew z=uIMgIoKf$azVl^(PRc0diBk!qKor>4{+{uMb>m-U|p~`r&e7!5eQU2iXpPz=WE0B zm^MQ~$S0b1=(+~yJ$zl)`G}NxwA9wXzt=D_0TOGr1MME=)Y#X4*P}pxgKE#RI z6|H`&(&;e?YiYYk{0>duGAKX$313e0BaUh>2KtB&>*Y330oB)LHU}{1?LLKx<0Mh% ze0Q2S9c31f3pRRWu1UU4R@`6d;`nDzI8PM$iYtQk9=~bS3V-)27jxmS3&FGuc&2Bn zmI6e4W6y%sb9}i2zC^B0zAu`yv{#EddbUYpBQ9%x4i{6CCf%vjA6kjEWWaq`=EgVP zclPO6H?L3=)hv|^aJ<+$)Z*@JB!cL{7tr_MO_gHzPNIsJ8(lW8(0%#Nf zBR^+weSKz2cUmmBE|MHVnO^5k0Uvj$V}LTs%~acNed-65aU#Knhk4l(b z>Ceq`mB$D+aUn^vqD#gcg7m5 zy_j&x|B!^wr2prT@f%MhnIC`L34Y9`VVy|%D*~UCBnyKQ5TpI?ZwA^7gtyr^LI(9VtO6=|_OlI(F3N;V;v4v>(%^NHlCS%991n{t2 zavDy`a4bIsAw2_TiQl7T9&W0lIHW~I#%5Vf-hMGP7&I*&o5GupkTN|nPb5oSR+yL&dj20cZmiU63IPc&$-DM#KEWbowHIj1s<=K<3YekVXeT134s{reMT z{3O7r83Y|+G(SONUQBP@38@gESF;Oht2IzhBOydFk>{9&T_8fFR$) z&8NDgVg54G*+O6XJO5;XCX>)EH(h68)@eerlhZ_sqB&l_|&jC zk>w)!cX1*kV0fXH_1~49*)hRyn()NcEYRPuT2Tf4D-5366a1U-M3)XgEP5WK3>ed+ zBK9N*5;&T(Yci4rda=7b=5rJThi$8u&(ubo<_pMbLuDa6Wec61uQaD<@K8IU!RU^2 zqShy-A2NG*K8?81it<}-6>&s=)%+pix2`g;O6<7GI9apiki~=n@p}8_xf=s z!Mcx!50D=PB&3$bFrjN}i~tz30Jxkg$;jR4P@4;=94R}vZKK7caFAZT1R4jdlR0%PR>>>{D)Ymq&D}g-m92p12a)V4N)K#f`vOMizuZd6wi^M${I(o6H)Q*c1 zfd5mDx)aeXZ0Aqajx@}1+{*Hh>#c4C2ThICWP&O=sm(V&u8X{YCIzbbcH-3&gO+=?|jTSw3 zir7WiF7s;Pf304Qx7QpLw{31ckA`yhux6rWJBC3G#D=zdsQSi>|AFVia@vgSW=W7z zHfZs(G)eP|kqf+nZ35%f6PPv9A-I~e%*`<_p|FibkS6znF>w$U;8Wxk4R-TsE1!@W z1-Bybf}A+rnZz-Ltb>rNMbZ{wmGn)wf1%U5CM0Z$Oc7CrUgL%~Pp9kgxTgzd*D`Uc zv=2MM@45(fk>xXRulcOG$2s8AmfC~4;}*?>K`SN>@n5*Ml86Vy>t}fD=VSaru%zW0 zm5?8-A;U0t@>mYVms^HeVUpJk6z`v}Dd)hy&UL zR_7Se@1HxbJu-{7&S7t zbB%rl8S`}!>>fszVo`?NnJL5H=0oZADyD2oz}9CxSj;9N>wlE2PJKkG{8s9tDz5bG z_RIYOKWF*&&8A}OCKFKsw8np&p=~Z60NXVGE>Nqa$Zo#@0jJ?!w^RNUPvQr;uib2_&iQBo?kq6InFQB}DCvA9wsOzXn z{C{a;w+H$oC5h`IXcORR%m^n5I;O|^WMVsR4?QU;rLDYCVN*iG)otax3?WCpy9T()xJVF-}^utKS6pPk9o+`GpU9W!Gq!~a|V1YN%;xAfN^c{F;#!q-w5Xy5rk~q&&pF>OZyWD z=)bqe;xOMkT8|yjLVTu^kLv8n-OwHNwmqt&%c-g1u(lpgwA-}GMH_a<{FnqL>cK}@pQGnf-T)|i zLpaz3{$p6}Z3C6uzOGd$-?j5XsIap)xQOZg?Za z8p1RS&UQ#X*E!s)oY5ke~x?Oqla(~yLHXl&iO^45i$cu=8ZzlNptJr}Ukvtw;t_$^Vp-`GSH=RF`R z5+3P!s3!orzpv=S@sjT+4@ew8!15o?Ri}+I1%7#J z(x1+mVXHg)?_Enqht&QLi}^2=(m#N9T%Df`W{=O@+<`i}G+XS$Q74>lt|A_PHfHM( zB9-LuYhepX;FS7$1{-glf(#*&hq}cCQF}+OPaJ{5FKN%iJtMcaOG*<3MZHgu4Jl$pq`0V(TGjhXfQS$1&D!Auuv=%6NL()Ac)K&69}2#nN@E?)1kJV+yz^>VQD|uhRH%OgPEWodIzr0sVefadr za8sq@5dv=sOCtO&``N)kW2qyA%TyC1MsqK47K}iQC_ktF|M&4USQ8Ec%7C!YEEEw8 zLO~NL_4d7W-f>rZO1f3$O;xT+w5rfMq^ufvEqs8h(H4{JT&2nwNev`lw&)lSo10 zOgWZ5N_{d-AJNVg&kn0E3jIf>zy9j&mQLhVcPuJN$3qlL(t~=8pIp+i0Z})DG9-Ia z=sFrJlT4x7pbv%<+0>{3+m`jdg&E~osgT+e%6u-Ksqp z8A=o;|DrDn3f{NK`iAP2RRaIiH;`|-Wk09RL%ETbquIJjslR)qN zJj1K>Yu}+C(l+fy{{6G~#eGm8@e@Dz4o&PI!nRB9A5RzVcXAy+brQ6*dHxkhy2yqR zXm=rAI<#p&BQ`&i6AGoj&-5PRZtPdB{4q?9hn1LPnvy;NF0IOMiRTm+u?ID<8Ipw` zc%kdTap0Z~F_=&xMc(PZYRw<*8O`x;l_aC?y62!f>!qE*J_0 z!h&$1lq3@g2|^?=iI-a5xBr*?eNSIi@At~M*6M0ialLxt_a%7@ysMF8zCQ-bGvx%G z06FKItLg}RB>f##KV==ag&z*u3jXb5Bo**5XtT1>Y!~|1q463WoR;WRLN!jm5=1)@ zFFCGkJMz<{wzSQE&S*GSUhENpknB7bQWtWEIL8CZIQna-P?j~XiqSf~fEp7CMhh73 zNj9KfD^x&(EhR7!g$H=^`Ro1?g#n>JSWqStg@XcPz*s0I3I&2;P>Bp8BMZ~(=3cj) zH9NSgl~m%P#atyc3*q%G??1Rz>fZi7PQL%|(bJbG{@3F#?f$3mqm5o>o*IKX5-Jh@ zgp{9w^}_v{{-?uLVamZ#=IzHy9kJ*Da+D)YZQWcX3WBBR&a<%Gl83rd_2z zQi3uYv);-tWcO0ns4MAfi;Q^EA(6d?#w?t6H7-y4p( zz4_f~yWR0sD@`U`Xd(H(q2%gap5Ms%LDlp-x9R>peERq^fBibVB<|T(>?*rniql4} zL*XBt{Z_3_Q&=O}eR2jJt6={)Yhn3M9pU)zZW$Q@7Ww;qtK$4VxHd(m+o(X-Hq>-( zalt|>@d_B&R2on%4l2DaM}YHocmJQ|xqs&Z-UU6V^+p)-c}!6yrt^{la}cGTxdM=> zWW_eg15(p)R$#%90RTq;02oX`n`R>ahYL&3{Jz9H#nCm>;=G#WRZav1`0r0sP0sVRA|HYVFJ#xvxqxr@p?NU-n$&=dE`GQxVcCMfZ*}n%Ypu9Cy#UB z`xA^eKvC<=GUj_~uodq0{AM5{jNd=sGMm|6Bf0eU`&HiMfERr@hFdfs9a^}g9>a^> zd=S}BB3<<04iv=_AS5YyFWoI8v5##HO0H=@07>*Kuzu^F4!%0z(c>#YSdG6EE@cJs zyq4i`)VaYKL_7`FAgb&qS}6t&kiv&vOMP#-*8}hSr+h@z*L*rJ06)=2Kmj{kUG0T$ zb4P1}Mp&D&ft6OCvD?_~dJQ(JJrYca!AvN&)xbedSBI=>ZeAbq3Z`EyazR{S9{tKx zmMBXj)-df=gG0A0Z3p}a5DQmaQu?1(3hjt!;HVbKv)Maw@S-%BwBx7q(ll_yE(g9$ zwifs*v`MRe^)ZVMTd@`Pm(V*!&83lTcJ)VIGDc}jY1OlmKUnv&0E6cTu_WaDv{4W# zTHNLc`a5&NAVHeNHgk4a{gZfpJ{gtJUsuv~-mBUSkb4vI%;*3^=?`gio9I6p`4^ z^-3QFQLH&bKu*Ecg5ZDB4{1S4?l3@o!$L@{sHK~|(7}nsvsdgx8npX$nS$~G z5^F7wiSYz4l6>g9cX_@}tg}|5q+%+>^m}R8g~#`{9;i0~xBObdx?tOo85>>)RohTQ z&@t6YJg<^3m7L9W3JY8RFVv)U~ z0Qzgw0nt;J6JUK-hGlIs`$^ra^8b@Q=T4?(H0-Qqw+XN{If+${@SqU&(_7Bjdi|kn zWT_=%5|6~y!a3KX^`WCy1)a#xWWM10T!ASr5FFC)|F$Ky&_?2XTg+K6=N%u4E*L)C*sQ21IIA;l_5*g$2Y*un^qL78E8C>5h$s})`pVZMP%wWJ@ zB}w8j>Y%|zGzfQylG1WOG6w|kIdpI1l{bwj->wnjS{WAZ6w&-pIhSVzTu-`m&u!L< zc!LiOZKGd@$z~OYKv~TTiR#rOpO13}#SiZLGW8-S%9FtjeX`!ooZg9ue_GW54@ky&tVkQ_32aWS&5AY z%vQuEp{K$e9~)dnK3w z3mQW{8A?7EiZowpMu65ZNu8&}xSjMOHlMC(Z%p-Kkukr3UgPaz;=W#&NM;q`ysd!7 zK@raG<%|)>aFGx1aXwJ0goakH&2JpXYKkExt1H#r#vgQ`ISB{^YoV#o8eZYHMLUrw zA2Svs)wPXGK3?xD-W}XHcI>SmdfGiE|9~7hdi3-SPuRR0cG)^C3b7M=+0N6gR&Nqc zdzys7eH}7ni|=skq4FrrX8f;a)Nb6^bEftq;O_Qu$gn|j_lp``Q*~Nx)W`8+5}?j` zXpi9o>L0vw;Us$7F6xkRPk165`A~R1DQ;FG1IbQ56?b|3nFfdcIuU^u5n4wzO2ofg zN<5)>gWjq4QW#S1adsTfAJgALeHX>CcNmYsw_b6ktX_GF03p@EIvb$+oV?JwJo?2+qIExdMxiCyn>K8spB&G1rRU ze(ItlGFTs-FY1mL5{o=GK@Uj|*AGJ`(EMLF3ZAV?SO3Drnl+q6BJ*|&5=o;DZdca( zCK&HFANKDTO1jIC$YOK)9+XWW9$ojn#rUOraks56rPM#?xXE_<(SpL#=n}U4%|yc& z9TAAJtbry2tGIEIW*k^1IT=WQq_KJMm3H12y8F~pfR4WNUrk=;p=SE!+w6L8kN(6V zFE>(n6V@as-|569T|&{JaO)Y^=+ny$jh%+PEt7aGG6Fs78*q@3goJOy8u8XHJ^$Hi z#e}PLxqL2EM4mF*#3ddg#_+S|hejwKW5&8(mD`s%ruoKiZ3I|Nn{k%D-X-R|(afE6 zu{Sab8vPjUljh?#Ue4$$yo0={5=oKo&b4b3thEFxPqU$97>)?FDZIH#cqD;@?*Dz* zI06Ac{|=k_sKwZRk5c@F0gdRz;`F}5xQ~$g#iNNL0?h3Bt<%N>zlf!_W9+f9EQld(>aiA53wYv^(%&91Rhih{okzmcWyZ3W&a$A{ zh02RoSG$Gog0E?pjw8omAyZgd=^4@~#We^eh`$F5LZ|O4LEey2@__G(nRU(-fW^13AWFh`pK-N1@eo@YC(|yZtr9Mgh)3)Hv z8&_SH!49A@xnNDPZ!Ba43dH|xI<@4ScMbhx;|4424sKefg96V?l;@AhA{AGR} z7oZtQi4E5h(d_G~OvUnH5AAe#+ka~-FWSbF$aA-yKfW-QQg*dt2X312617ANvRna^ zsYy{i$+0M)u4;Pobna?qA?iG+0k4Yc&qRPcktvjhxD2b9Kw8|6l(?2sGjiL)o&QTSMf<8%<)%^PZh!oQ=i zHCLc5ue+px5E@{tFG>qjbv=pef{F=5FP;n5E~|>Y%k(=tr-_fH1iAR?oLXIvt8{H~ zEpuR4=16Rix!PMjDN1P#KuepHg#HpA2?U`-{Uji=7Ja7Fm?j-fUj#4s#p^%s!U1hM z{V#o)@6^E0I^M1MY?c!As>Jj~HUJ`2SsqJ6CW{pmgPYaT4{Vm8xo=27JL(E%@f0V( z32ObfiF@t*3#N+(+!t@G_niO-4^&gN0YrtsfKS$Ybg) z;Fjw}`y|-(VMV2p;O2>^{~2^fCkUd{p7;s1yj7i3cB$Rj8%A>VWNW<*A~L#R22@Py zps~CC9HUOFI7LzD336%T$NA7J_@6p{K0d9iQzfp`$4VE#WBvZ|5=&YK>8=lE4ggSL zg?Nx2jibvZ1`bUsIv-0qmpXM&wT%dMQ!^KyQS`jzRsK-cxkY|(EFgyaG{QDs0<9hI z0v7eyLJind{y!%y1U#xTGaJ7zjw+>7zM4paEG(1laG;Z%1~i#)x@0Wt4WaW|L9eGS2koA>TWa2(6yZmTI1^8m{I;jCS*S`$gAd((c zAShcUPm)W+%piYlwU;OvK#^apycqM$Czm!Bvas%Lkotb@zrd1ul&GjuH~i|hH6~@% zX$~};y$_>Pjk>AAbISyG;`ZxZ@HmU@fYJakiNB`CV0 zz0Gu;yYAw#^FKcWS-K{<;@R-t{ORcX5riP<+~_MN&u>-qCTX zUgM%%q1weqL0TXht#JAA`N&up7t?C>mWWU|`gLI?HqCk|h;stXMWWzuA_Ts44l^Ac za5vM6_1J;mQlG-eHhy|wN97J^0=J8!OE0OyYlpa*1R4EKK>XPk6O7I7h%8x@L)@#q z;NlLq3_gYfKfz)f>CL9RtTc$9Zz^tw2Ynf#_(gOlehssfyB1+4-y@5)Agl`&dqm0u z_n|nN|3D|eX>pE!W4Yr%Mz#QP>T2~UAtlTDSeG2VzoTT2pvAp=>CdSd0=wlncE>$ZafH0f$F0gzthGL`n+VuC2cr5(X~uJ`c7J&zegLeXH04 zq(iAFD$=Te_j}t5gAXNjAU8CIWc9S|kMhH*+$bpNU+? z9?7z}p&kc(mTkH@|6YE#nj>J^VIP(y7|Xh{9K};`x_kM7Ev9@)dznRm*-)-^^iEC; zfJ4#dJ>PfOH!&BcgLnGxE(-JEasxhWmiNLds2?e$;zO26XHtpLg6w9El-#9!CSQ2$p& zA}*K-Ht0~u^bXFrjGr_+F&p5*;2brbodo=>-*YpT%h8xZ@KwS7`@LrbE>~l>xwqd) znbN3is_PH0upf(jp~c#<>}T}mpM#-{hwz^t#+9N3bQ$xL&|*?!-`@0kc!#NT=4y>& z=JJuOE$UW6G1X(mXdMs6iAjISv#}O4FT=oC0Lg}YhYs8{M2sY1g+~dNY!U%fY6_0$R}A`M*4cnhGc;l1SVbQ0gTrkDZLAdB`3qX|4n^X zO`Bcba*MsASrn8gpQ)x!fDy3>RF7@(QuQwe5>m?F8oFJ@bE1|o(j9$q{6Spw&&Dpu z^@?iY`B@)8H)SIXp-mV))%_zNd}yXl{^UHdX%HzX?Z@nS4)Zw3=tz3^SjM!@up6LZ z-)qu&ZlaNZ<5uN^u$P<3}!tb+Vz& z-1L!0sCF4rlPwd>l}U2HY`7QfF^&<+VT`+Hu-amlwV~uJKN0DAiB>_f8e@4~6P0!_ z=U2mM1nMDRRb~0k(h)9L?|`o$L>{MhAd+5GCm)7&*jQl9XE7X9g(=pWcArTBZ7>1o z6j^JC3DMy#z|Dtd%K2IPE3iRoho>Z|gXVdT;MCmb<4|0WgSoM77e04fM*Gitt;D$I%_lCsvk=4()I{o=;32E`kEco6H{l795)7UpXL66 zi<9Ay59%W^ro z{XaUi(@&li-gW`nj9Y{7Ol=hB%6Eql&&bX}rA7=;eAKs!W;|&|-}V1cBeSJk#O*zG>4y-ihR0r22c&E z1`oMFEvfh4gd2L1k>8#4h8?w7!&bLCU${rawNm7v@S;@gbk()$@g>2|^5MN*3ov{q z=IEmVeoVFG`~>c;ifXQ)pC8btAB)?RL6dbjGy4!L-u;I1VNT;tqzcy2l$>$Y?hFpIc&@kc*F9(GPGC!lp!N;(p3Jwx7m-oNKxx5t3tO3WNqSm zzh&?(sa@x++~Es*Z>mcdAgJ3K-ZCl;dC&EIo+4U3toHo_^sd9Lme=d2tA=CspM>0B zi?a{GD9|z;D7K{R>29VwmMc^$P^IBWBQEV876xw-5OtcLKfb%PZD0k-|C=w2=T9c{ z2wC$68MR(tJ7c|ni-y%jZ;AZ34JHJ`rv2|_B7&3nbO*F;e#6k8&HWDs^Cu>9AW3I; z@sU~KZJdxztg35a1vIiW`X zJ;0TiiSh7ExGrFfG}EVfp|35z*j~86Zl1#&a?pR)VDOVoz#I5Npz><{N=2#SOhpkn zSu^T=q-V~15&&Viq2Sv0x)|~;x6wvca{Uih=gSrMR;Wu$+zn8_XZlSd$zyf(h_oEN zCO#>^0Vot8G$s@che2Z?lqgaP1cYG}vc4;CJn_fR!@sWU&PjEasj73pk_lgL-QG-n z_O0G&`m&_?n%d9Sg7mE&Dnt$8%S+zv=`q$%+3TH`Y1>2qr@!ILynVNdf8f8w%v+w; z`k-|B$aeCuf8*sMPMq>Qe3(UsP#@|3j+1>NvaTCl0DJk|>&Zx+_9UEtqM2pvU+{!# ziytrJ0k|F4PHD+0w9AkKb8^~l3i5~uLV}@Nf47G*LV&PfEF=qsg5i*`oG=y=1w!FL zs7NRh2!w(vdiZb7bbH8fMA_eVpXYpWe(x_m zr|)eiD0`U7RqnGe0ejHgkWTFZf!ZJ7>dHG>QYdl-{O9hqg&rjxURjjv!guYPdp@Zp z=Y({Z>3wK2v!PfeSlO_PIMfM2g0}Y;&W$Og^+jdKl-S5Tk-1zmw5x{93W&Ro38xWV zF$DF7g28~$U`!(mh62HHpj;>x3WWrrK$u8I5nGMxcRoAz-#*vd^x~rEteyT-@33?QfDxuyz!05#tPwZld#g%davF9!a4>lv_JULU;;Jt5o7P zyV0pCW=_qZUzI3?CsOY`pb-=s3@?DfP1jnX3Ir}7QmiKGz^g-5G5u*7UO?O{r-iwAoca1IK(7SU_VAM zaKl$7=L>>6_SAZuvv7dvYlv|jFC3Q;jS1@^JB?e+jD;Obc!rLb> zV8{S~BY*)K6ew^uA_hX?K(LT3Bnt%$K^8wV@96rhbMWuZS4`Cqxs!UWDrjH+tL|@W zJ~pFK=9-V;xA?P}dhPZ9P5<8XewH3IU+Y|91pldHp?*I=q5=8(3eX!;m)dh?|VnLwsUSkZDQ(w zVr`#ceFMoU@OfX@yWRD7`nC@*ZK zXOx0M{;*0=;4T&o3If4^$WSa73kkx(K)6sWBoPHdK@k{4<`=)#^0WMXyw^V!3rq_-qVa-|oGi!GFumD_@`+)(CT*jQtBAs&}X5LsWeJygRPl zQ9YX8Utm$82R>b|NqSP3`zjsDq32nfn3$<+ksQk!9H6@r-Z7pWv(|cUu=mp$5HQ(m zJD^E;^uV7%o^j5Il%5_t+uXXPQi_pGov1ISD}?ziRq1Pp%C-l2KqCqd$NT^P`~?aG z!Jw#F=oShEf}ueWg)icKcb?bHak~vt_e#+v>J`OSh4*0No!cYx`8nQSnvdjvU#4An zYS%>lG||)k&3}4*Fx#C!IJ&9(E1NT~+IsJ`rniqLxD(f<8t!q731$sE*65#u{|`^~ zahl{b-Bx$}EA(9#wCKaG9+DwrnrMCB&$F8g-Dlc=*BFo>rih3A7a0T}yXz?hYmG19 z^LGox`d!nawYi3*RQ*-EDK^!nqSaq$ltU$$;W9*Cxr99m13`i?s4O@O83e>Zs7xdg zJDJsUsZ%eF%84kIbs}jOQnV6$kJah)pSyTjshjZSU+Z#Mm-?UnXwm2ZXYKxF{${H5 z`1bB#G&H^5Y8rhM-z}3p#T(pg81SGB*b{P*|2|NrB68UygUa>`5Ap=q0m z=RIK5kl8tDcDxQR8s-fZonkP-YyU>KO~oSPAh)x)Xh&E_xuYg#g(-Eo^AVo{dFr$Y2!y45AHsQ-SzB|Ix@ZdhK}z`>9K07n1-7>Plfh9dum2jKbYT*Cs9 z$GhJ(TS?UyYIuueLxQJ>P?LW`_-Frs9u}l_*|sUibqHqjJWXP-9jES3?JlRlMivQg znl^>A8Cc)ebOiTzXYI>T@ZHaz*m-eGG1+v-!a^T@qV}QZhhZ^IuKZeSm)$egue7%J z@gYcS@3`W7p=UtUSmxC$r@KPQ?wDSa6=PU0=4~d0>-_C6L$?3M<6of?)>c@!Y=v88 zuyrNBNpAD5eIT@c3e5UsAT1kx0RV=@ShGeH}sS(^sB(yq~FU%b*SbV z;>F!!FwVbrV1ddA^{lC$3m;6^Q5h-Df~ah4!ChPQPyPA6u_2=ka!b&;;AcR-!ZbW1 z+ezYSR;8Z?Ai6ATs)wVJW;V;1l;2a1M^X5%E1NR7UP!1@c4pSy7({vOb`GwVZ?{nC zkYTuIF0I&J?#&5EJ|4M#h0s~+8LAA6%U2R@as(RhaLv<#a3GATPeSFg(6*SzxOKw! zX~}buv~?v4At6PIOZ-HZ@+87(-e!@>`n^%^7g2SN2P5FkdSvE_RU5$Pha4udx|l!d znwD7=AnOzAF0<=3_#k8Ke(1DJBya7El7;knrCW5IrnoagQ@*Nct&S9a=3R5WSbBGx z*r1VBoDeDy1OWqV8IPl|w(z_#bb{%b_vbqgKF(DWMI4LMNA<^|P+??8M3o~m&GE44 z8bdl`XwFa!&QY1I`qcYfvPwl>tj{1chm{i+;Ib37lY{;lVKr3YW^0AfU1HE_{N7ml^VL;5!ZS;(m&$N_bLaD+V)9*97ND86mK01zx70xlE~ z#agtCAlA1_6dc-^4&0*6x#H>mx4~N)93~!cA>AYWu;7)!5`&!r>)lW7J**#i1RpLJ zOKg6I<+kmtLFd%;SH~IK(SFScWk+(gaINiZzdEvA=eQK5@19s8o)lo#39#5v{D$C7 z2QMpUM-$G^x?hp_e7f_Yx@+nh zCK%U}1Taz766x83-^8hU`e;=`3KtPWR{-)lsN1$MR(2+bfAJdy5>=T*-;GRUCO2XS zvd_OzsJ{cd3O2A-xOo6>d7gUG)KS~;q|zuP>zu?>MQzb**4r;!QDny-6$$3Ws9&pt zXsYl+3exvUALVz=QzcW)Xu{nnEZ6@eDuB#Wj4pCm-4 zd-IsxNGy05n3*Y@^%NflvKRTF2LAOH;L(tmcmJ@HYzv$u3n~VAiN=|w#KFSD6{$g` z#E5be@qK~MhPg7Qr|}qK3(Kt}m_R=}F4iEeC)PBbcqERMhIkr;R&nSRjTj{S53e}Y z4G8_I#PArr0|mV2-EI585mRs=jA|&;)m<&kayBNwLv=$9nB_m1GA9k=u}OpTcvRw)!eYV}Q|DO2Qrd7LzIGRbFV_VH zNWyp1E2nJ>B0y%a_6wDX0hqIS21Lzje-rq2^d6=I?V*w+lI4A$G6hX+Qh^}#wN1K1 zj&gVFM;dQX7o>w(l9PRE4fde?tGP78GZvq)P}Af%@yBj@In0e5_G9cDWPfZd1FKk>QhH>3bhXu8UGqLbnUZ=;AKRF|T2H2N&5OCFh;U4pN6(4^ zO*|wfJGJ%5Ue%ZV*UF-tM$oCD9t#vBS*3eOd7f|F+V>Y_56Re`;U23`r~&E`Ab4xb z$E#cRLHIgDp<9u0I1ZA3U$)kcosizC1bWk^?d7*^ltMCDJ%6TQ(h&F94x-cpAI9|lcx0-K8ECgorCkYLec?Z$FlRsNA67_!?9#Xa$=kz)A#J^TS}KHpx^1~ zW=1Y&n<6mRwIbuoAI^DTR!`MZxOv&ftnRSDXZ74Pz2Pj+?q|A~tYfp#(PaG*NGHjB zHUA=}&A2rqsTBiQgQg3^FhewOiYSWDG_WcD8V}0L!X;J>>2hz;-Y@v&-8f@I$5snF ziP0}bv_VuOz4oFkQ1#Oq-vQqXD17);Mwo<1dJ*C4gzfFEk=4Wg_~deuw{TL6lAOxH zwMuGRa#PrA=NF*i&974#WqL@~I&z{%YiR%8OERO!c`zU#++qE3%cI=H#dC{PDvJZV z9}DHZwIS8LHdG8zIe#K$wGpxkTfbCIbr#+05^71R{&*Njig^1nRAo}OTCa4rg8p*4 zGJE-bnj=Fe&A8g-e;*FYm}p~;Q*b8~&O7+CK)(5Ua!HV)9r(CCrE*1t zL6Qr$3EDGE#S&SWCB*A=vlD$P8{5$gI!66q5TGExvbaK8;MgfBS$2ZQPirSR zs2YhF3R6hWbJ}w(4EIy2pODO*UIPTY96gEGu$OND1IET3EiM(iY1E%xVz$dq(fbY$p(h=3#Y)YlpCP zol7;;t6WTretB)WdojQ4y0XaJhIq_~iH5g0eicwunL-amj6d|u$uC|! zwFDyEEV|CSf7c?1Z;PoRn;uk=Rcn=O)Ea~`@}=UU4{Lk3-G$EPyo2OQrmq81k#`Yw z#Q&1W3a*y>(CA&&)GfY_Y-h;WFCj;0Nfol;lWdGrp(5Iy22EYynGYfmdsl#LaAhGf zJFssN<99iUP3<Ah4FCV2K1~ z^emeY%z`_8&LQrMtRr7~@A!BrwGgH=2SoctHKMC5VV(scKQyrm4G{AoFhqs1$IT^u zD_VL^*%LAh- zsZ488Oiz#E1JQ}F_%orLs%zG=AmY1;p2YE+% zp0uc6xFj8bvgw#Xs^$;2uD{l~?>7o_o{GA2-}p@gG?1UjABW;I;Ve})dkE3Lf@JCP z6a<5}g+#9D!#HxH*%~nxrDPo=5}O-DXCT{ATKeg^5=sfq_EiuXJH&0Z{X>T$^kV)B z2#JT7Vq4L-w!EZ9n8%zNE7(pfECUsc+BN(x^S3dBA*G&qz|D>&UE8TT^Iz|4U1VIvw$_?+A^lTh1pSVnqTpt3e$bvk`mk7-~ZEJ$##F3)X;JKEq ze%X_d+B5HeT^Xg}9yLso5>C;iK4V{Vex)MgI@u;~D(e_SP%H8sPQ~ViBf`muq&D3G zo&u*3LDSH__b|IM5fQ^niV@PnN?=m$eTCA=8>=>3 z(S_x9`1|xPBZ<}eHK1B|4g7DQPs7*JI>NE-&0|w=Ez^^yBw|SgC04S5p!KTIe`kf$ z7BYsYE7DnAX@e}k_01JnQ3CI2iM~;^rpwSiC_1s1KWdZ-U=ZJAxCm-B*<2)_Ibq%- zeK*J12c46_GqT9-jyrvZK%~c#kL**pV~@Swwv@81z8Y`UXV8B%GY`}N;n2koG_;k@ z^oiT@*OJyTA`0c!ow)%k0g1Pyk)z{COjEz*73W_!4?*wg?#Kn?^8XKUs?zl_j=w@w z>L5>iRB2FKAdSNELUWY2j~r8gD|)?7uaS-aZ;4u|O0+fQvg4=Tn5+XrO;AtcV4pm#rCUN048vLc%#1j!SLBZGc+-EdrHdbLhK$k5#S5!AsFX%mGrbnNai z>po`^SP&SP=67i14}nus;{RjyHvN9bx8sWtV2pAidcWQN1DV*FtlB z5|){JRwtLOK$bNz8pOIa2(!mL`O%bztDCh=@d4Pgo9*Z?@mac_?)?hMuF+;?(oT1` z#wua%OB^vogZ$JEF{;9%Q}28p9}t}%5oNSf{XLik)g2lZip@32)#E=a7&_K}yXWuE zo2~N*qka$hW>X|FGx$+f^xyS3I{q}hI0r|b-|mw{H^b(g4E8PK^q%5|qc=y+@(QJa z(Fe^lGw#I{T+Px&(4)41(hg00WYl&`W`Hv^`~E@)0-Y*jfQ;Jb;}h#^*Gh}GWC95e z5PVxcbjAJo&4pWh^`#3(_{Sel&z`RVvNm=ay8oSt|;BD?VdhamA}RL~Z8r_W#QAq~7iRS2XKF!l1yj z0N#X`(a#Y}{SdTjV%!Cu-Q4M6HW~r?rCTJ^Z=S zpWNVW$xWtEa{QQoZ|4~dMmgbn&;V2ncDV2EU8nyxNI$?eHT_zw%*Abb?-Iv~{2~Z6 zC+cm`2X(1^veqJJX)b$kZb0{{CRZi_0MEqJ0pSs zWHA@g)55^qx>tKp+ln@+KcWQsR+Ut$$A)~`aSW9so~*_(b{dt?rjUuiSAc!}910k5 z+xg=Nwu8ip13(;hSlIw*qtg)n#1%A(n=?B?eP0q56-`=pB|+N~PBy}ydi|goliJv` zykB%ysLfnj>M%N-uD2-5$eRFhQn@!abq=k-oMJ)#Gv4HRF*om=(Nt1&(|2>;gb@5& zF9?%rPLT)%3)x37$uGe^8}ByqaMzn3L7JMI&b2*d(gwJjAFj&IcbCoqP0e z&`qi}=W!J)wZOJ~&GuVU|Kk8a1;1uNX>1ODm-dxXOnhYW-kOEiV2gkQp@%#W$pO}M zZ2nZ(P<8N)R9pTP$vvA_bvSZn#;|xBl!7>1u5uUJNEeIH%hVVe^6I>qP!MQf`wz{g zo&3`#6tcye71FY5YWyuO`FH>Sxd!|U&XoLv{|}qvBU-?pxL6jgKNxHA8N#CO)nii} zX!b{t<6z4a$@yOwZO-QDUtC6nzrJBLPg=m?;!P^jLN=qV zmUNz~MX`y{l+@dLK7z>C$S~O@tt^3WNuZk@qzeV3X*k|L@_*sk(CynjnAf8w3}`sG zw5#I*VR16+HKycV2TT64t-kR?wZ{X4cSDEWta4e`SP6Q94g^Xdc~Xt=98S$LEt~xm zES4?fe9j;#xFT5*%n7W((PM@*81lC+3{nN%5^o#YJL@;NaOz>8#dky2D+!4dknQ|# zST-5wq6kFvELOj17Jy^MIbY?*Bc@2hLcIchV9Ih>E2AqtxMqcOZEKoL_RKRJ}*E;fd}Ew00b(ZGkU^M=cqlKtbU zqn0(CB!ld3pbDOO+kmZPN7$B><}s^5R_BCCybIgc_t&P)#-tZhI~n{x<@iqmT^YyUr zNjmmio6wBy*V0EH5W_B|p}~SX)=^P8nI6&a8{H4jDu`k=@&-Q z7DdbU>)K_I+NM9;e$7$Mab$^8DRv}RkXp70-K=`>ePYw@-x-B#R6Bv>D}l^<0^GJH zLzLS=9~ix-vLU~;0e*3^eR6Djciz*5y*SPy>C)uhEp91%znT)@!FfDh2bZGbHV)LG za^r2d6oDxZ^xo5txI&CFv4DZhNy1~7Hv=5f|Bl4}zw!$vy3urzqFB4mgRLwlw~`WI z-o&1ws7?^6Oeo92w-MZ8S4lwghxJj#0gp%KnShu2lLZQ0%JW8LkAw8$ol+Jsn}@qqcb zm4?rCMSYN}*C@!S5o4P;nlob9G04(@_7UO4{8s!x)Vzk{x%PE+Y9zuWr{gL#deYO9 za+H*n(LEYLqdARFLDyxA4$lJ~=f+oA4lR!>VSh>2UipG$B@*Apcg+?z*Gu~EhJ;An zq>dd=tV^~K8F=9X5;2MTZw4@kO6j7{*jBruMg^Idai-PJUq~?UU~vi z`U5-unte)i(8A>5`VU1eJBa(*M}O=>~Km5lWf_&7?4jB-2RHSkG}Rm1!D6>82u^6D{p-*{fpk?ocNWYmH} z4j%@8_J4u#Y#ymF-B#Iy`Q2*Wm#W=Q3T4{-gJu&LA7iZ(=ZY7u?EcT;(%FTHC!9T@ z44prS2NkAn#a$t2T*rydHT*5uOaaTjO2@GuplY43N4VZBwf6F}@Cg(Lv&aq{yO2U9 z^wMx^o{MTrDvmF?>z4Z8^Fqk70+j4R{B8b^iLeMyXiB=nttI(C4$&M49LkQE6@a`* za^%3FD0PA_>>9))%Wqu#v(BhjDUSMPh8XPuBorvH84C^rL13U*vFF@x!R!1T7;ByiwJukw^By>UdYEH(PeCy_Rd8jf*Ss7O{!)&H zrPI1y&;0 zltDCGiXly9p$1-7iu_sZl#H6J3N7Pt{6v^Z3IV53j7$PmfLu~;DFNIBVL?Cd@Bi&Cto-2X3)a<87cPI+xO`_XS@c$ro4ZZ~-#?x$e0b_C6q>fjEW zq~3Z@>7OD0zhp-@{LhW=NA)5jUw^Oj&*JgP?^fX2)`@3CRTwSq!Ul(9Bo}bA;baF0>XhHSZKl- zgiZl|+Ut*AYI7V{8B$balBK4q8o;*yv&tGTY31Fz?L=F*f5Z3EzGo%>QCNEv^r!W! z3)(twahrkBs(&fIX^+V8ANAYc@~%8@>{~yx=ThmgP%lSu<-DZU8(+HBq9hmYJD;QMB- zULr@N{}Gd52_r%%I>eu2Q#pzZ$n8ID!F3jfb|*jp_G$XRxngfENaQcEz6AK=+Jd|V;(WI=Xs!dG>r!htsQSy1w?!p5~!KNRhQdc4#KNL*P-c~XkIMh`~<gwT`L4OzN*Q@C6 zdT^Fp%yv$B(jrA)FHmzcb%^q~cV&Bx|2trr^k}!~AS(=uP>Dn4=n^9Gje*U^NmY#1mnrb;&4H^&c8)M{CY83_-|2u> z{M;F70u~=Ir%be&a{#tTk>u%-U#GU6xGx8?<=X5cGgZ(afCn#5HsIQR@3O!)d8b_)Cl`@ zr;*9|P4u5Jf&}F9zN=(b0}~JjuQx=Ygf#zq@%*3bKaA83DKO0Yuq?WQZpM`w0)A3M+l&^oHPRtI`Vtzne4k6qo0x0zt?{R8_H=2TO&{Fo*|-#8I+0o&X9f(f_T%|}4eS<0YvC+**oZGa z`elz>VCxUf&$jsBy|A~fd3F~W?lylY_DXo9@}qiJ%3p}IKBmDSG{o>0<3t)YP8Ih0 z`b8Swxd#w*>*dB$Ja6&lPNW@UZv7+sLWTrT&$~uAH)PevNa*$9c!I3ZOmwV3G@ZyG zx}9X#N85;?RnvF~X7;`iD7C1O*a@R4>10--p4-f$dQS4BR0}V(-R{iCP>^Alf?jaw z6tl=Ea6eoia5}0y(w$!b)}Oz57=0nZDSirC&y2(abghbqo`o(3|845lRyhCD{eied z-3bT^SrU{BvI^mb3)jy-khyj^R&+2${v&BHzZBL8sGfxyzU(}5ALk7Ild(sm31km` z#_Be%^#4i~r8%?Hq85Hz@#E^TEa^9sfR>kw%h?C<92AN1mno?jlr1ETBU9$;^mX_N zJ6jNxkQF%4I5Yn)RwMqk^ct}L{7RezoM%}z^H7~oU~^IG)%N5@E-tGMs!A&$VN0S` z^l+|DD|G&Un!ZMclrNgQj%^O8`l<`VE`}FI;hoitAZaUpg&ASY&FV#y4W>LTE0y=BOMQa*?A=o&w5$D8+r>7C_MfMNB*MD)gfgJ$@R*cQ+-jyq^ZHbf!P_dHY z^8!642I6ZfG_)IJvC?LVL2Y&ecI>TXlKFi=9F0R4>vTFw*^vlze}oiMLp495qg`7|{OxC~6;EbBq_DTH>*gUmZvBLL0gjaCZ@@O_bvsgx~$m z7ly=})l8bf&po5a#e-^_pr2_ptZ;{Hz9qP42&kNPb`pk;x^koZuXQ8H(F@&1aa+32 zyPyQ7w{8D|aNp-UtzeH5OWk0A<@@g822#G_F_vMZpNU4MqKaYTsD{mb7O3vb_zpVR z1(}H2tov?6x<*)y>t>47zuhh?C0x;kXEUhcs-^idso+OYOR^dQ*z%skG;~C9?P>I6 zik+iXAG(1{@F9<7h)+%k^@Xobq^S}iyfQxOz0ikbaX!!Ovx{!Y<%4{S^*A6<71p`d zLzn%LFki>71oy|EiVXv^)aZYL$8n3(F8s{a^_Y$FPMFx*v&MPo{8uPoPLerko^A{z z(`PAHtT^Y*skAk2h9D%eA6NDBGv!#5KUpIiL)F7<)NUVF-BsqI_cl*a8o109TjBf$ zYsntm2BK6Fk?xKNnm=Ps3eobHW88efqq>rzGh(`Bb)0p`V(R@+^}|!Jj@6qNvQ7{o zdr9$lA%>ALL$O9J#4Nhr?HOeG>W#hD&GtBvU|W$jNj#?{Mo`Z;dB~UxnZ1mC7^Kgg z2Wj?55{PDwTw1!5`r#)RKF z2*N$ZSIfK~fxrAhedq(*L#>g!GTpRUke3x2lDQZ?|I-sie3L^pW)8KZo7(wI=He#x z2S_iTdmKV*DOWpT$(~8w#V_x)hwo0Fc<|TNgR=d_OU0f500vt%Gn?G>ZlOU^O+~va z-t`saW1f!y0S`Gw50y>b3(xKbQa($EyIqW`N{ROQ(LVNgq4I zk^J^ExIOgw~=`IpM}rxmLcDa)L!EY ze5zv<{}b%<#UY=|ZN2wr_2T7{y+kmcepc7w;)qO`a-tUF*^QH|D$_?GS^365z^(*Bu*nOddS42|Smd`&4A% z&f_gQIg--D`|UQ`mhzFs_1c$!w+wf`s}jKqd2*HL63vi|O-XR!vI%t6opHzWM-84p z<5z#$TnUMSJv;PFh(U5%U4TZZ><94YEHfrhU!yS>XsJcRW!~O=(4yyok)Mk+ztI;} zS~~lC5h4}x_b4{v++7eiLFpg0C!$+y%^#htm74=>0b_^Lko3loU>n@v8;&TBlQ4nz%dz$DVy7tb`p9}6yBKZXyi_5-h9$m zw>dRWK}JZ}YTO{?7=__GRd5s;pXp$yNpR)!->Lk~s|G=03WD6>y?4iAG?*sPDArjO z9T1N3<@TczP*CjOuj7tIQsKo>f%hnvo=vIx>p}Q~v!l`IAy*T2Lc@zHO@dwS;~=4j zkJPe(k8jIuMYC&wL!CGW5VuO3T=3L_eB|Xhip~Oo&NRaye28 z|5$~p(uTTMwSO6<1J+M6Y?7e(ml*Oj@6Lm6ee&6wy!Xvd+g8)`Ty`f_b2$V zG7Sg~hAMz{02WC9u2WPUTC^OjGswsiM%)-xfof0aIMN+g9`q&+_KQ840Jp{uuyOZu zI?43`$z`pT)MS758dRKcLw8BHJTAr3Zw%FhU+Pf+xjK1W*4%VQ_)4!}*?n7X`nTj& zBnX76kidweVwweohd@Q-J~}y!c69550JXaZUDLzFK(+Jo$D>>GJkGTtSIbU7%buR{ zxHb1F%Jnx`_>YW{4@~5|8qKyAkb!I$ss?9REUP+U%MQcAkoD26s|dVy~AH&|Kb|H7~5mXktXIq@YGdu>z6EWBH&t}XSOl1XygSA8K4E=EP(i@G(o@rYh;+g+@*Ke+su`5e;zQ+^n$m z3( z0obE-u631fKj1S`;i>vEh;`~A&!=YV;ExKt5I=9yrYe{jNPr&J?Qn3xHZZ*ytp(;=g>+FE*0)VX9# zG0Q$771C`UbrZ|~?aPo3>+^yYMegp4Rp63kt=6}DmLUa3CdJmAUeBYF0)0ntgA9&+ zfsa+|-@?92ZdkUZ!9vy*+ow@8ekD{nq-70tN9xG|JT!ZqVOSR;XPC!YnU0cM{7Jpn(tm=47~p(d?9qw$Y{)I5Qc52wX+`J4eMR~95(^nvchnEz^u8* z?z-I(G)})IwgbP802Xyx5jfJ1TfoG|jlDsI+ZRd}Ki}4TKhi=?Sc_n=Govcm4mq0= zumVQ20>+4byo(NgPjHdEF!`g@!xF03hh^~DoC-J1C+>37E#9FIbpWHz5_U3~!3>}Y z0y9GNl$L8PH%-P}vQ%cF8Gr{)lP@a!=aO*oEtacmoU%!#Eg`|CbW#BZ;R;w5o?t*D z)Gwa{Yd*+|yFLX_G=((oRQf=J^<0pwiCec(a8-H;Ils9o zvn$*LNSJ=%zGpmk!aPvd#~Ji`bQlK+S;q+1)gk?3A2fs(e)faiMKCv?<&{Cu>s_X1 zN4jcz$G*8~c#q6_jgzNEBn!tjkI|bh`Q0Jd-!39TSAIeym^hXoacg-Zwp~i!YyhA# zaLmNK?z*F4rz?Wo)5kFh+<6Dh1VpcG^WRYOd9KCiGb?CB6KOL(zcv!6Ki@L_MdW#llZhP^DIM>bEqrxY?0gxmtGF=tg6c_u)a%%23=(( zW|{Ms^Lr+6ZeF>7N&kW%J8Z(?ISt=ax4E4|*@vt0Ai~|ERh)ar?yHTBnOx1B>}n6C z&&H`G2A~{TPEyPF#fC|RdP zoRN`*_&(X#FqU>Z+|0rT^AAGt)%_alwOxNS=o%smzi5)N$X@}u+5UCk9cv`6BdanM z5cO-}8IO#M@F*2vG|$-g5tU}|@@Rx+jY1W$7WfQw8G4jChzTZ>T~{M##}^isir1Lv96$;+apY2S$d3(SGm4Ze3y)?A&+#Fp8_(bC<%)oZVZ#Gp!W}< z>skPe(*(wH*09-9mUb9owW{=n`8CnbgImEa2chs2q4B3m^Sy>GaA-vBY>XxC(gZBAXF^3y?j7J>h?T4#Eb3!z`iW(He+UXrLY3 zOB7iph_{O=xYDhIDD?o7ujbU4h=Q2r`dl36MAi>}eUp`#jXUr@1?#p+n~QG`$sP9bN1cs|BeZN@ z_^*)DT!FNUhk7Wg{!}F--@C@$<1%e>+0MhJ$%01%-+7T;c1gYTm z0_oc)(*$AiUAl_@h6fs%HYA0{kU8RM{DpbYMcNO$>i#v+aKMH`iaBtW3qET7B zl z>-S?i+o^wF&dmK?yUYwx`TTffSl;QT-$Uj8lCVbo;x)=8lko3XxK(xsj~JCz=Gm>Y z?~>CIka|sPazqxz78dWzzWaqZY)NRJw`Gb0(wxAQm`!%y>-{be(uK2srK{0$wk;;B zc8H5wS|PGXOOFSe6bmH>zO>NtnN|LO0J=a$zqv<>%(bqdbx6n$)#U`&Kc95@Qi>XQ z{KbPdgBIjOEJ>f6&JMP*CnE6@#aj=iX}#9=N_WtE!I9K^&&K`Zz+n6;xU7@8ep+~e zxA85Rf>fK)!g;2&&VmJ^qfDXKy+_qPvFZK{oL-p4pqH6ZfEy6@3%LMh*>UMwhP;yW z_=kV~0jmzs6U)jitar^m_D2PmT(F29dt4g3k<4{~Qp~WT21L80n0CR%@oxHjYJTtILry!aa9A2;V%WK!ynn5b%eN zwa)p5Y{vKgryqyyyjvy;mRt>E%s)9ZASN`}F=mg%7CXqjIV64MHIU@pZMIE2gcVlO zQ!}sbrCmetA>$CntE9jT6oXdyVXcq!1%5aE@!NACY6&1?f5Y$ow*U&?#PmaR?nxs-8N_ceGjGG(+aCO zfr)Gf*XV!BA!m%gvWq$b!|s>!l@Ceyz3PLc9DVV&~9}*{J<-m%*|8J-85?UyDOdfjrO!R_7(GUU#4!^9Zj{%GYkwN$I z^%DKZ`;QRBq)YtMA3hoKV~GKS?Ml`dZL*9cLN*wEXLrnWn&%bJVO9IPL*=eJSu4&+ zoiU@7(hu7iD>+YbF_H?}l~c56J;%+m18NKWo7>7c1NxLve+W*VO@PfKJCj;UGL6O_ zHOgG9x+&la0isiXLF@TWF(}e6_=t+9J(rRZbM&=3vIvd~b};Ujj9{iGGlkp&M)u`= z_lxr0G@ghb#DP1`QgPf?m?zx&3#P@M-F0$ z#VB!c4>gsG00L7W!i~Mx=jg-=j~6lk)=Mv7^u=C`o2{`0UT&wbju~? zvUqdFI!R~Y(Ds=6S6hb|h6ES0k5+deLy0{Db44+f#Ut=gfB{5ymT`fD-Fde}HBXg~ z>ah<(6;E{(Ln9v>n&KrKo;8$JL`>wX{M^&-05TMQeZfht;?yHuDEGGv$(^3;w4fTu zkrpcz)AV`n$rP@V@iVl&aMl^~3Q^(Y^+BP0c0c4&8c# z_!2!+A6q$>6ft5+|AVKH7}Ea8@F8C{E|z^qIe+&ZcXizJh&nTxPyE^8BEoewu2S98 z4$1*LjQkDDPczMpN9`6gu$jr~Ae|7m^{S)Tw2%#}Fb3o^@MT*rMYhe*9N!sSqypD< zNVn{BWn>Lr12~3{Cb67%O!{(+ebG=z$Q@4?d}p#HkU4pbN;>yfQf-4DzR`DZ*B#kU zDWnjiZ@+m;m)9O(;ns(!ocLJjFd-)f7w%$g21PnxD0FWyPW;*KiBh8^?g3fiLIn9QEB|Sgf}t=(kn6h=YI=Hf3k1>h9*b={@Pi)M zuoE`%mQ`)%O5wARA7tvxfF<4*-rDZ;JsCri@7hIZ1esS>BxrZVSd&Qjt(OEE2my z2#xJ#Erb*eF2?VET$q|`@GMErP(&dKgiv8^?d#6`)XdUU&0b5Z zytkC(08c7>e(7<8Zf_0P6|*Z;NFr{1CaFuT_!wY!<^`Xz`>7JEyo zcIWN2>t5S;%`wuSK>wqqnh%08X6ApK=UoqoTeE=1_80^vkMtV#maS5S>-+}cc0tO{ z>-;gJ=XyNj>!zPw6(QZpy(-|GV?fy8g&BlpvzjCF61I+!A@jg2sR|}z@`-yM00=^Z z<7$8Y|1U#qh6ovwUVYpCi6bT7JB`}E$FC9$Nu6M?JPoMGYIBx9=gPt#PP6I9z z`1PL17I8VzcJ!~)?SBPN{tfLL=lFK;32`l!Xo|<|I}|r{J}1=e$iVuUv>b|E*Ao}3 zh6beL9p72%=vyf-?8ylJ)S?7}6OuM5t=lsaL5a4#k}K0v?e8U-l!@Htczds7l+sZ+ zo(f?64WrgfjJ&Wf`vfjU)J=3m3Um_n_yC=-uwX104GD<>V<4O;B?<*Xf>4M|A|nWy zesh_>-`|Vp?(wbXw!C?&jw=Qj zvM*BFG|8)ER~?!Rk{CZ0-fZQGQfZe6-|oiLaq7%N_bUp-Y%jxLn;IJnCPh;J$1{A31$0bsybh!zY5g8^f}P;3+#2vXl1RdGwqg<+0zy0I*^1GweAPC?ABorVtC=CV#!Emss zEGQBN0>Xf>(25iZ1VUjGxpm&F+i|}<)t5y}l-5mNVRNB}wB4;A3MTiJMW}KjqwdwK z*1A0T`x{~IJ?z@wFMYle^_2wPPca%{{Y&TWO(06wuw&1)Y?SWVev1mgw)tMXJK#ff z`I{!{_MEoMn$D7u)&~D>2fO?IS#n#^zYp#DF;_cHL8lbb4eDaOO4VXe`2R;NC9!AB zW}u|}*WQ19bxmRQ`q57D?=fA9O? z&C9|~9Od90Jjp-(XpibjePR6Wj%Ods(|9C*%;^7>(>fpr<68xvqbeIssD*dwn%ntK z>C{ZEAv(|I9{uDzf`I;N%^KtHZ&Yjb=?TBu?viE%d*@G5DfFI$NCRkNw{=2@?eCs} zJ@FQ_a4gQMT_CeCT6{}M63lhR8J;!4KVhK2*fbam4Z^~3z)&(43I)Q1Q5Z#!JJ&pS z`}_5L{d(WT_xrch-x(K5%?q#G8TGH>@~5{yjNdKq*8#de?yc>SJ!dDWEAtGO>jy=j9&%!~t4tq%NM@vG-GFF8HDA`(@9!`LU%@GB6>m6x`iU+i!L8c6w*cR9|e_qRdQnTdjoAFPkyMoc}S2W!N`Hz!mHm{X`K$C%4@_p8&q9oGN9Ra_!Dk4pv zch&BdknxD?j{t5wzd-$G)?h~jI7L4bm6*fD$JdoW8YaK`@tSQ@(~KB6q_BPVl+DNY zRcOe;BRsN7q_+{|8I2Pty6OT)0GUX!iUtgT2m&|&03T98o5mx5ju5jOps8zm^ z?I-kBHgDFp+nV^E1)klYn1_*Wut`TR&`bC68B&?nZcpDJNy;fgY#i_+WTq(-nXmhr zIeI-Wsdl)$(gVpbY;Z^C^s_-NN;S)9t0#%vFhbtc7cYspT6d-3fi1W@chW+gGgLIR zC`OWYrAY&fPI--i$ekE|z!B5$&Wp86oK>(P!#xm@51GzP{+C?y5Kk|+I#?vn3`BbP z-z^Z312&zA%qaeYn{Kb$XTrCkQ(5eTV)If4LhU8`JI4lXXLt1NOqZ2 zEtQwhNe*h;pqr(#3OB;2nwr9mcWsX6Xk}-n$)!Y~V1_-_CMt%T$6?BaRf`8o{sFsm!Kp`4QpJWVmM2|6( zs}NG%2WdJHLCNbl-I=gu(o0auD*7XCBXPGH@6Tux*&aGvS@lHkkErR$PK-P&2V-j| z0D5NuD_A3;Ju!{}S@IX_an3kYx0ub&YDTI#;UUjvm~YXnUnQ0kPb)q2ScAj9K2?{- zHg%Ycr>oqWAGM(Aa}h%db~8HJ$LWSZF+@`yV}jD84;X<#Lr3%7EUDA~+@YD4{`Stn zGH>{0J|LD6Q8N@2v8OxWnreH)Az|$|*ibL*Mfco^z)48#18*-1m<1Yb zV=B{qSfe&;=0etP34DT1BJbCi*=Y!^^?kXzDB`zw1S`zEn0NPMUrR!zETD_UGZEM7 zbH_+}N7^SET9+LADAh5JV5M#HMm;_Z^d#hJ%vGBueEociJ9oLs!O3_co;i@@a5lAs z!X<_kseXZg1X_x)C%Xl0%CX`1TooXMG(RK{TX+(6RA|N=d|#;SVO1J z7xui;7U-5z!v2TbEL0~6p915-u*H+4u$i^&0=9ER2No~`u#yxlkiD+9v;yUg)p>o& z$bzkgrsc)xOjPsBr=UpzG@rER;O6_}A6ZcA4Hjo}%GJczEMpyTE$Og88woL_#mm*#a>?c6nlNzv>ebIu=GZYPB(%_2f zwWCDkW`U-fZs+~k|GN}gKqGLCU0gp=q#Uk?!)c@^$(w$tG1Yw_F*`o96EhP44tAto zfrc@_SoYQ_Q4WSKGj>2FYGZ}mMF*TU;=p*t#kn&sIPx}&EAg@hmF9s+V2yD8Pc=x} z@WZBQyXgp~|GeQX`%BKEO*~a_UugOoG9&Z^jUUrQ^lB;rVjt?iS%1D?3K6>R`Rs!M zk%4$?jBC%SuNODWjkD1Sq;CJr@_3sRIQ4|8^OZ!bXC?wm5oQo7MHjM((iH{$x0E_1 z2D7+@&K1;-(=G*Tey<8Rq4mI3^cmV$Ob;R4^p^F}mhs0#Us)Gltk};nv+S=2Bc!0c zp9*XUpfk9$=`vuptSBHOPi?P)z+gn6MMq7k@2}Pm(W7@FIrB(xDUkEvDkvSN`uE=7 zmkARN?rt<{j>uu}q`85>WeY!_nr*qWncvy*LqGq zqAzfFC_^eD-z$92*P>YnvY8`u{U*?fIJMRU&?Wo#07_> z>9PVmz-#7yNdS`#lJg3;lA@vK?magSBhj8_&^n~nIrgp<=MLN~;dUIV6~MqInaq8Gdt{g#Iot60>#mF!wc zmRP*(T@P?X{a!mpg2D!tm20^DnU`Xw1?XxA(yp~X$_fL6Y?Wo1$`=-df-I5|4WlF0 ztQ39i%%f12W_uNjN6rOns0>dS-$iu2y6xR&PKDx<{71i1F!2k3cAy>y(}G+6XfZg4y9gdqOgouQ}tV< z2SjRsT~7(qNj$lKgxL@DKv09;$e6i0$}l+UY>2-K+lenAX*@f}nfsP)8`>}U?@%-u zCRFOY(opiGBH4$n&BLtZYSQ8E5Lh@i?0@)}QfrkgbaDyst9I;UT&*P;*J|;0yP~{+ ztlLo>!=9$|%Zm0WjH)EvBD3eEOdYKr${Sm5$D|Kbj!>NcOq~^*TCAep;;=V=(gM)< zAyYonv*)UsOT(qBkat354Q~e3q@*@)vJ&PUD^}6#zo8buWH#lAMu7|sya?Er>9Jpj zd~|64EME|N1a8xUY!{gMFwY$=)`-^{?_o?fbR%Ty#yM+^4r{tD3)2vF4w}zwhr45i^Vv{(-Ft4WIng0PtuPspA)MQEO8FC!G800JgYO-qj-4;^~ z1A#wHIl}z7R!nRs7p%#E+oG1YMcvGUnx{i_g#b*0x}59b`a!@z8B8-ysjL~N5jG!c zNe$293k<}l&WV~JcaFBt+xfO>=Q{FB!r?GC<9mt&Ejtn?FKmT~*j*9K8%qA#=rQhk ziK~(uDP-R0(S)Wp+#6_aQuP0PUwIy*+Csl>YjvIlJ=o4lJyb3KW;vV33z<~@W|DGg zR*-VJ@cITP%_ObQ>&IAkK?zT%CS<`RY*n~3%zyqQkJx1E7MU2M(3HybhChM^1LOuA zD3{3ig>rxK4?_9ZKWI0Q3|Bq(;uPN8M;Ro+{dF-ZF|Z>aa86)Sfz;XH_tJ2qVE4o_ z#pf%P##i9{Iczv`;e+EqG+`uk4o@GP!%VD2Dz!O$Wz-iKly=ozW zV@V{xF(*|+^OpuT0nutmp%idM1pf22U2-n`>$WpDc}^KkiN=M2+K)UzmaS9j9bvq} z>-2VTX;>H)~-Rav`^puJOT<8Xu2D&J#m{gFS18!p6*{tO9P+O z%I|wE0sB;#A{&W8a`N1~6hHz-)Ow0A9<}M9MqYtXu9x5yulOfk(`wH6@SM=d!?bSa zU0MnqCR{FlEXTWUcD7UQPhMdR^{r^tr$N>~XSDG=I)B^JUPH<4(+*A7@AYU_P&)#_?v$?BTa_=?`HOmT`@bQ67Z`_eC z7*upKB}4sQAQ)exlwdt9OPlv3nf%lgdE2ef70~=Y*Gb^OathyLZzdge7H-)fg|`I3Oq7zVxT~xn zo8M(i*P`C25?>xS>i@NgjC+w^WqvhwGRRVqk?+tg*8rKZ*{=crBg)*{tOK-AsK|=c z@BvU5NoMG{SmC9%nHfr~QO9D;{GYBLwA~6N6t>GGz0MtY>m}ORs|TSYQtdbKM)K*2 zub~C`Lt5&Kb^d=}om`B&4GIy8l;5U8f$c`<*D6sr$f`i8%iL6sBT`i)RPgu5%S87< zkrrR{%>b7l0x)GOqtJ-Ggti=TaExQUD{-AA3N8HaWxS}mM2h42?eEK)Bei%jbe&W_ zjcl_x{-y;dohb2)MfnZ?PAoIA74*X5Br{r9eSXGOBfF5!0XUQhiXc{+#3p+Nw-A#0 zRBTFTn*zNRnzZ>bLRabW8{^z)l6p@`BsYo z;d{v}~&ghXwM5SlR-y1-TrG>L?PVtp-gbslF?5SH^hd}$hvC?X8ux4-V zee_aT1UN$I#)8Hc`CbCsts-COIA!%Cf_No5j5Nf9>aKRdTcx8?POYu3!VvnhB9ZE@ z1BY39&i;}FxW;&pfje1!l^CB3dhwgIRxTN2P=+;XKSrX0>x8^X)(@%4tqZI**y;Yg z2*{b}?WyRthZ8S|*&#O!?g9hh!K;cAd?bDb=7IVSF_*HOYE-Qzji6f>%I=zG#4Mu3 z$Ux3!?^Ab-sy~zR`{Gr>)WZ~I68NfCgTTYGu;IPlwX7WX{G=6Az`Ki8C5X2=HSH86#LT`*Ti-s!-(cp|g*il7Msq&6$2{|b{3{U+?V*)z>s0M%B9~YrNO>f9h zIHL5QO8FMNBbsD%#`qPArgh)RI39?B?Q(_*HycJTmorWZzIp5eutB`7u3m^o$|`s) zffrhAz)#b9TUA&$p83qx;s?%V*vdJ{M{_p9GMlz0i{!>07sP~7&9e|&CrDSPJMGxj zY`E7RHQ0Nae~-Rv8N8MRn@f7C0S#K4GE$b|$tVw;y zR`RFRQAaS?>CFGY$ycBUAjx^UjQ@_&g5ojat*X*iZPXV?OPvKeW?VkPXBa^{>neLa zstk^W96Y2mxnm7J6(!b$s=8o8%d>DGnbU}5>e|oc8p@I#N}#O`TfeKFW@y1e{2-bf zVnBZWcrK#f=B6IemAI!eEK}hxx6J9A|Hb!yTC#9mOnMBCUb->NDK}i72}RGVle`Blq)D&ogVoh ziwXLOkZFkgD_vnwy^zv(2%?6e;A6XUapUqSbri}y{VkZMy!$-WziCHhU8me2hUIx=kv5P5z4c}ZqimCG}r^XjZ~(K?~@K{#1YSLzKL zG0Q&@=*12#y7^{%S7pmuM89uL;aAG;L{qwxc>h9N7-pbE#wHAJvG5N5z_(;rAH3YG znW3tK=}M);vfr1bzj8O(dMYjQ1@os@_5tI3323_*phtz_p43`s(yknptfVd)g=7exjd#&Fz~RrOIwyfN3}YnPnyJNnZp96b z6p?yT=v?A(oGc)e&<+0K+8@-;r(`5(&HvglnE(d*-d6c({KCL}(=N&muBlw(+=Snk z-M_ZuqtopxfAek5H+qqOce~xKybeuix{;1dtd(nBuPlF{6(vIRcFFk06>G zG9SoT99N#L+2naRgUq1S2P0njQ;h- zVdQe1R;z?Uz$ce5`dQeVuN!zU)VI&aX`uXDSAu~0ih_%3Eo$32$?~eVrt%G~51>OI z{Ew)y2b&C_TdcDbHhC!3J>mD}MpuzlNL(N4)WpC88C5apUkJSPL9VK7?QuQ?;r`$C zQ(4pF(9t6MS}WP>2OqAa9ldx{C3B*|NO_OxYZl;cI>p6J8d^Q*!>(|-0H$KCdFAu@_{gw+ zuY&K!T6h!ulq8aLQS&}zRf`D$iF#|?3&#}T@O$Xnr> zh-o>x_3{-31$lx;6tBc_(xAQ)L~b-}41gy5!`tIrSz6P7RdoK;ZWe%1K$dU6%Yuw` z_s|st8?O)|OI9$>!r7EdGo~mcz8Vy;^&!N^0>=pBJzu4g9^|gchHj(2z=_p5a$%8frtz`m+$Tqh>~9rW);!wmj5HNcIwL#O5vA}&=E z@xB72b&BqS5qq=vMi5?mn`5S}cWrp)sLMcsh22YmqS;X;3_jIL*N)cODEF5-C2MOV zUHf?B0ZtUv0?9D6O1?XAxGOFfgP}Q-#c%-?Ce~BR5YkW`#SXBE@w;89QiOW(^tx>^ zJ%Y#`2jJiz3{^`OwYtHn?~NKL#Htz&gjvi{5uF+fH>76-ZQ$=iX8(xxs8k;k93qFl zwj2oJRd@4;*siS%)au1-D(Fkh4MkuaklM-lFZbPtJQPe7K1`SfYM9h9WH2$(%M{DX zc|zT}yR9q;mnYL&&`{9UgmCJ@z_#U)ivsd8wB7vxwH9wFCeA-;%e7smD$hiCspd=f z(p(RtVlU^9`+g@1dUcf}|1J-V{s=g+PM5l};Pa>L+=SicPBqyfGtn8!qQMV1NNO|_ z9-T$&i?^+W6Z2OFA0NN5o0R((LcR5$1tcE7?(BqcpmvX;a zP<(^g%2NcJu_2TUeoarXKW{|sNREU*O2U;4skts~+Nh_^Op;L04w^{J1NUq5<`{!x z=>S()U}$!*R)lP$f_XPIS|>0aj_1Kt_b@5<0OJra`UJXC+BWuA@kDz(?L(M@VQEM& zSA!BDpl`F9_I*8!|GRZ$V|71H8!Tisoj2{Zi=b2WTU!f%5!$6p(D#$tXoj8Mx9-LC zzTL_>h)<9Z3+V|>qWesj`0k$=!kV=!f&V5l?fNzP5S12-3*ij-kEg}EE5E_0o44xA zwf39!_=Fz_DTC&EmR}i3hb3SSvc#b$-Z?4;+zhgRKn;=5))MNFl!@uR=>SGgNQ+tl zEN#4S>G?Xe=E3HtBO0~?fE2`Hh#&2rqAq2Ww&+kux+fQsfGm zRYFtSDk`qX*4*wb9a2^pPsgn2S9%~yVllpERUlAH$b|BD2gmNH^fN_cJJN}c0KdXnG-)VtH#~WQCkwTAFdm%x8sL)!BCSW zB=GA(Xk9m%5NO$%D+4TRd`R_%CEmmIMBOINta2p<56AilMpgEIIZ=Hp4fcAVv9LZF!#!G=Px{^XyzzI`C*2OpGdtvoYj^4eQcFU+Ihlk_ zp$Y0-l9P{y3Z`n0a$nI^(UUT^Y!4_ciV#i5iDr&g6u9V1^F<)#4sVc&rYa%1)7(SL zp+V8E{NqbY*X4k=Wu#RtW<&g~dJFskz|i~unc0o|AI?exg-CoTRF-56UtD@!Sh<%8L~XA+CuboDV||>Bdu3N?q0ajLMAN9p zl(x~J9GH5}5het1Hs5|l+OVMee|W)xe$JgC8Wdv7rf+gb=#Ls*gNxZFoZVJ-MW8i} zC|QmgMp}5kn(+4}qQ4unFY8MkoniGt*=g3a5AJ}XLw`_0 zm0a|zGTrfMss!sABD3Q~GpXTaknSyq~6SnuOtfMX9D@M5PXyRJNUG!g$ z;Rzq}32MO9&j*5y%b3e%Elfz!dF-l;$y!;=d%e2oXHu_Kgp}>OabQENNPs>;f;bkp zU^wzK@feqD)^s$(`}cOP2aoJuBUku3dqk;vr?W>_~DW2SZ1OXNl95f~k z1_ME0xL7b53kCxrfUsaJWE%+rK`@X+Bor8g!uQXQo-Rq(aHzTeDj&foEpLrQ_u!v7@6a@1CR@1GIr}iq_u98_uyRl0me66JF8pT?()_dHywX|f z>VTD2%+=BtOxHltL1}=T=E{A;sO?vi9F~(o?H4cneb%PgRO!GGlj@ZELrd!DujkGf zXR#ViF^|kKam4J^4`D6p^Wfw0AmPW3VwLbM5FrW<&Aq?({N09w17bK>Fcuqygo1#u zP~;&wghH#+S*~l(Jt}LyDvHunmz-0bI0GkOe}d;nU7)vPz3!IJmoI0sS9o36DZ|;D zRDob_<6;iqe|*a85#wNMdN_UbA6@vImqT~aTFfG$!uM|e$u&RS{2o3b@l3j2=*3|2 z!q%HrV@FPETZ&)k+aYj)Ec6y=u)PGOgybV` zUpPcY^tYiBMjvnzZL~sKgCU^6=qyMJ3Pgc$pqMBo3JpRmZ!gb#{dui(^}g?~9V>~K z7gDlb^;dqumx%p-{e|yw-tcAF=5zc|{(cHxdad-h!{C>aj+wgElYX1(dES4{HG^yW z_>pcOA^o4@qt^DA)A5f@4}?TO7rO9-`cy#-(`CLT;$RcjbMAZ=~=c$+b z(JN;^Rrq0?bVqUWaUA10qrd%_CMid&s|NHy+c?|{y zLSVp{R2DP^g#uu}SZFc`go0rb7+alqpB}Y0Et6D~-M7V@O3g*o74QBgmZS1{HC_0K zZwv4A;G?Ev*@yby`eGq@(0_iqasD|~bkp|#5A`3@Y8Fyi2_Vy{j^R; zP{!Lm;J+x70i3#xEK|c}Sefz8*y#%8oeL?19esHDt>6c=svl1uJcoQi%IjQT;Yb|` zJb)lK$kD-`;9`soSx-Xc(Hdp8Q>!}D?o4YH;GZo0#MQ%hb#H-&Z=6a-V@2b9F+URu zS%sRYuXwwt`_TY}u|SwGCL4u9C@f`ed?#UK~$)wh0qT)rzas$Ed4iKvw- z;A8b}?REEc-J-Mgm;Usx<-_Mx{V|`wPX8M|h4dMAVltfHX&%o2mVJo7rSS*@p52;9 z{XsftS+$X2V!Fk}Eg5x@Z=6c{up69xpr zfY4Y}7z+jj!+^0+Y7_{C2thEpua6q5$$RT`h%#MBslur$XcztWwjH*o{^~1vzrB=y zLiC=`u0ACb+Op_QM+r>2z1MblYbfEo)OTGA(Z4SR#UZBm9D*=VEeYrQ`Bwjxm=#%P z^yls+;bla3uQWc<>PNbiqyG9dpIj99<@9W{ z>-P8v^_H3EXqQt9T3IUR-={$ByU^V|OAP*-qwfGh6c&No|Nr^R426XOV8B!^7zzdg z!ho<)EHo1d2tyQ;Q_qe&e0S%(^HVjGcPd(@qiI|~RO}D`2>Sni-|(FeuLv|hYuA8i z|2OhAA6PYK@GgD~HLsKF*V0aZ_+Tz4t~SbcL8NQgC-hCo-`>83LzL$NES(3sl56b( zD)fcUcK#q60nF%IkJ^FZ_Xw{1`p^ycDFc#L)tGd5C!a~-2`7UrMijS67rYjNcN0Y| zB6}{Vyz%{B{Xp!m#M~2kN%qrVOu*aa|0^vb0RAeC$gizyjzW>wb zjIWBXA74Mudy#H1tH>pPB2TB=YjHo%o4tPFNYIJiz3TI$@V}`p_FBXBqyIi?%Z8$g zYxMjw4Sp&w9I*ZecZDoa2k^d0PWEn;Tbu-NBJ`22tt2B|K!~1ci&bO2t81V{dHbd_ zjh2h=xl>*;te?dJ>0vLzoVLc0hQd;}nGrK;l*o}ulziZrI>uBSVUWJW1e>N+c}xN@ zpxSSL-T%VSpi~$O1_Z%?&{!}Q3S1z|j+4Es6t`oI>&nf)5bj!^EJU7?mna@fOm3h59t4|Lv&TcPM z>&M-dx95OqdV(P*M+_c%y8Q3D^CAq--dRy__GhK?%5Hzq+e#S%%nZWYZO9=qe7JAQ z;hF%jp}4fy$^!&Bl;<2Me-;{VSpEjLgacwKbe}-2p$fV3T8!{``VfrW!9kG@QI#Q8 z+=#$jt6GupK{?;)V)TI3Me_r3R&d(S+-=7}~@!Ka3%-(yT)!29)yuLHfBK-Qfrtkh= zKK?K4{`0SP7CCWhCwV7Hxg4WKv=ugSe=PVFrkAPADJ`_=0ojpjF(r<^TlDN~cb> zev84E08utRqjQ{{MxW z2k6WdNS4XL8p@rtvD%i(u;E9K!#3r{g54yBLcTMfxce*7mZ@mP$iolpAHRie8Mv}2 zBt*5u8&Tu5RK>SOf;1QgtZMdi9XYrTjlmU0#4|CbG}o6@5YYF5xd?ZO|3>=Bio_3# zJpP3<*Jw4#BF6b-vgV3WsiniHJU+2Q%61{7Ej#8ju`&pn9Q?V!p-7q4Ye=%di=J0| zQ=@?0YDhS)Ed!!=d9{6%b@Qcwn=qzqiVGShF(@#KqVQa(^^ao>tuXm5ApF$q zmG$paCK{Yht)9YSQ&@Jd@uze@ucs{}n^u{Ki9Q(Imbd}<#}5;FX5CuWuTy+dtDZF} zNm`+!uQ30o<~>vEQsrxVM*rVH=^b%>Rq#@>!U8)Jb8?3hEfHJ0p%ZiyM<^Yf1m+Z2 z3tNvl90N6|OP(tK%lBh^S&k0AH2Q49IgAujY{2c=N2of{$IU-69@j$taV(OwYYKah zWmI`Si&&Egu~gHp9BhUFp{1lYwrQIem?30bK5Y9q0*uN>=;I*b@U$5fD7<*ot9+J$ z2qwP2@4+SSEJ3$X`LN!1mrM6-#8Itph!SVp~D&nG=r#$4DpwyW(}Oag5`6VJQl(jGQ_ZXBO#W~W3d%7{(VIn)yP z^bpRRoF*OWYrNkoX7-oeK2LjrsS4JQzFn@m+fb*k+8gI;8@w>dOX5NJ09*n`97Jt8 z(!^n2+?Such@z|3;Fv)zWJQ)4;YFSU8c&53xiQ{@zInrwLBlW_9}Y4?0eG%;mLqUP zgDQSad2?l&Zt^$gc|$TJ&B8kq+*HoUl22uN1!vCc2;$Fp4I5^3XgckUXxd&iUL#vH zjFQK&dhMJwh4ORRLKnaw^+F2>2;XtIqY6fXZ6_&i0i9qg^VcIuo%BrMPF+x<-8Ch; z(v*U+SXgZ_pGZx|y36^iT8`O`R3H3HMR^AMEMNz``t^pX_xVIr9rsRLOV@<)Ucd82 z)TG0P-ox4sql4mo{jrEj?j$F&x$YUZ>GpudnX?^+>EZzftSg*Yy$iZBV_&DB(2(8=qg}oTTPtM41*OsUAO_FCT3=t#4j=S*1+&3|M%T9yEY6qwMm1iCj z!-T!HYhi?m%~kqQzc$l*opgBwtDa!NcP0^h`FL#htfiXn9@mgt;%aXeA7#Ng5nVhW zTsxe)&0aZ7vfd(HoThvsgfOAiIhkcDu>+jkS-g3XCRxCiqjR==811RbD)=r}_jeG~g+t37rA!-Y{033lBrl{K^fv>&|5QQuHii;G-Ckc4+Q&B?lD5iq0 z6#ITDWUIOV;ITd@{I$R+C>c4147MGe@c83bGi_(@DMog5)t?xlQeymp2jVDzc1__T z|4*;{+;h-4gflPY{kf6nI1EQ4+1}I{xe-BegzsC{pb>h45#3o$D0?=6dF_B7h_0K!Iylw?Hl3Yl5b4ygnB9ujzg`* z>?yy|g?NV^3&v|Zo|UgwdrP>2i${s>Y+T{B=H`mZ{~O-8y9G7O3OGvYg^<8{$L$vV zefbOWuz{mC_n8kUjEljXD#nJDrkhp@P7^1FJV+XimFJPBoCE-QZ=ut20S*c_bQ|3c zSnidiyY3OilPI19eqx=iv1)SM6FbAG<14;w71Q|=Aa{TRwl~3WAXkaScxj{J5`5(F zMzR7fKu>;A2@)C>Jk#rnioZCzOWpQ*Re7uq21WkbkLu_lw=Fa80W0plDrYOpnTu51cOe<0VlSlmys*xJmoPv~Z;zZjpsxxCt z?V%*Mb%mRyJw)!TMVfRV9Ef{;*UT;A;F(Rk)4gdamn?BzLDVMh!2sw9q~G?CZe;#> zqhwvvKm)#w(_kuHqH6iRt=>vpEEtXX&x)fd=ez-2^MvQ^w93!22}nsi1(5QVU-{u& zlzuy4(JHoiqX}$xojr7MLJbj&{;bir5t7*24RMw`hr9-u<%oid#sSp9pn|y93&f$v zIqm@-pce%E^vc`~gb-YXi%-%3!MI_9C2>`DBV%QG(*>-=h>e+>{42y&I?VdNbL2J znt5|~$X%wr$C+0nc?qd0Y~01`nPsSJ&%#tXuoB1PyfG-AtArTtKsf3mU{sjRR5yTj z?aDvIA!Jyhky?17Q5;PfX%EBdZ~{dm{t3K)qf)x=^YBOUmw}VMW&;H_dl;)Cj~E@~ zl@wZ3eM+Y(@!{Cn!18LviTYPaXL~5^$Y_zT-}Yp&`1BGBk7fQ;@?>b}@b>6iUwA@} znr;P=Hk8>ExR|Y~+ybM%lqQ0t5FCHs*C%IFj+v>M#n?xznTU9@^5#|sRHO`@&ZXw_ z*@|RZ;;#4&gM%jC5gB%-tcohul;wi6+bkV9I4kUG4*aW^J8W$<*85b&!LVS|w2xZBHvqk{x8A$LR)?%)7IeH9+_5UV+18Jh|H9Dw;g_!2?-WJB~ z3TAYzRQ;hJeWgcG=$bDu`r)x|IOAB?h_vcR!x#(B>RXg4FPmT{M+}1+J^^p;TaxV? zf#9wyc$fsbY{) zgh_H2C(056lex`iMuxR-m)C9R$c{GMF%H~Hsuyn*TU8j5L_S!5khJX$w^&D@iv)Un zP@+Bhz~9+AK5DSohTaA!+NYW(ekU^D^nC?DE&u9?!>``Gb0x@DD|oaCaIDdvqnh`} z@Nx#+02b)@L-h`%T9yWox~`6HUm1&g(2LQXOWB6vBU>Y2MAy=SOY*J(Ci4f2pN7xm z2BXL$ zB4yMbGx@UupSucy@=?}=htXpQ`(hr&tMZkS&tD)Y=Eb1_MP#~e>;X~)L{=ZrTFzQHmsT*G{$8t%u2_aHIe+D#em$UeV#X~V za}97D0oNh?PHSFhcgW}D=-ey7DfW@fFelb`3NbK5r~Su_u2-4lKVg`tkTq_d4o9c1bhefp)hT|k)9F+z3 z>C|Pb9$R=|?e;==uU*4%3Q&G<`**#ea&g zXk0x~qqQsWyTNZ$$xDJe!d?d_-k<`YXX_xWDT+>n&WVF-zy4`qDz6Bc16Z{6W^w~5 zt2cW;eTI>Do;KGpwGcb)RRqRwr;$LL!Gw)c$Zw=kgk+r>lfEiM$0A^C=}_#Lp1}IW z!SYNiPePNT7B&f!8Aw*zUj8aSI6<6_&+d#&#ka#OzDKQyQe(4OVmjWP7P?-3E|gtS z3$P&H&&v)L3JNVpFZej0;2FSB;ARc_unI!rj8Ok)JnKRR;(>kjq*uBN6bUIhn%k?P z**QH!0u66p9OK|#c-0h^P`QXcwlDIx6bmM;TsDl7Y%QPr*N| z4M)G$xC{57u)(o9h^QetKOF2eV3kU)H>pPy2dguK9il5#9VerUY|A0VUuQYQoSEA0 z742%Un5IA`*&hCiS+y(4P(G+3lKx-g?MamZ@f?LNGg;}mnk2t+|L^X*Gk++b5e6AB zgAhEntUb1%!~Ag7P+(LQu=d)1>16Yjwh&NK?Q@P+=FMbqj2ak4SUWQ(=MQqu0>>nPi;?EYR56GUUH7mcTxpNbsTc0y9g(7Nos%$76SR|8WH}cxzKUpSo?&p|j z&G|6(zxz6vT$*tbVrDKm5mk?HV{}4BEpAE1pFT3|PEx8U zQn?6T!Sb#X0_BtYx%YjAx}XS<|c{Jn8F(z)*E8Le3!L3JpJ*J=N;xeU_f&j zx9LQckipCLGsj}Q>CE>K;9Q#%0W@(yYBa1JYFmYG-+ajDX9&>Ci3R>`FPQo+v^ zG%4R~Z6?Ye*tC#M^erDWFC&%Q=h)2&)}adDkO$|UjUQFccvHjpb7hKjY34hZz2MYG z2o4Jb5Bl}**UP?T&_Bz=1G=cGohm#hfln22NEA+c9+>oP1V7uJ$v57!yz4Rfu-;Z? zu@rPd8|W~H0DHC+L9y+ds;ol5QjZdDQyYnLGbA1%FHX?yIt%B=%76P``zY?X4BqF^ z3~6PSP2}OsNvcI}qrfPEW}%TzzO^kLP9#?|kFX?(+aXyB ziqV!S4QKGU@wBGTqgZY@(yxcqV|sH+nOB)oU}u+CN4<|X(Y=WRhj@xnK9hn-@ri*m{{Y_vsS9jwTsNL955g2;nVpK%d?n5@8bx!W$F<&b5X=~HlZ*iQ*xU*s#nJgvn0Icu<))Z&DUIw0{j?)`N| zpRGvf;W5CX(Qt6ee$MRa8(11UHK6ShX1$#2>3MF2YluqrV)%H&6`G|8HlEbQTyk^K zNx5?wBM7p#gZ2vK`K2V(A_S4-j-dZF<^DI*q-((`+;S>{-azgJ9V!FuQn>#Z>WKTm zreb@jXtqRO9Uz#nQcte0vE>6Qr-V{sUv}Gbm(OOqUJ`J;uwRs9>6i(lxzpy~9)jR# zZKd=vgad?Q^+dXl>?xnxXn;U^Y?ksJmvj#)3?3@?C(&#b@_AH?f`sA9@?rF_CI)Dh zLV@RT7201=*X~ngB+R8U8O7H|A}RgZycfyk2c!-|&si6f-~#I0qROd9AK)#IK0p~c z+-Zd;I;R5J4puz7pcKb!2VK|7`Og7`!)gt3LUZL8SpS(I!E1@al2bZD^9F+nRkn5Ch$Pl(#>RF5nCmZnPfUtlZNtp{R zjoFBO%o zl@bXk^kryIB|U+bwcr-NNKku>}`Q>W`;qQKz4um&>h5YbJSMxGr~lv5=y$GAPh z#H#+k{)6UYZHoy9mzBq5~=tgp}_FrJ(`(P)%D2 zji2-~yV95qKDjij+9F5yrQ~8c^c$Pot2}{*okbu7q%;$=v(6oI1DO`PK5J7Kke2n! zH8pqnYP|bOP!I7nV-C$$?|5VTS&g^+ycEl|nf(8lwn#mE9_A?O8Ob44zY?Uv#c_vK z%uygCypdc_W7Vz}7^K;{zI7SI1Shu%mHGWvo(Iz96HOm-1|u%V8$c6Uxjnt&t#*~) zS0u?@12>?G@4=GZVwd4pkX5zsj*kj830s$hoI=r1CVX1hRO^Bdg2IL)tCdN*MI1rv zTl5J*H%FH?L~t@xMbAR_YUa=XMt*En8I#+H99MwTm@*&io=UT4c{iHG3X1tluv<9O zmC?nVUE|wq)W5v#PuziEqN&4zcEqJAP%-R_>&39#6Iy6GQyYkRgVl3K=d;){tbp|` z&iGg@oyu}h5DGe@!cqgQ`q%&i9pa&d$K(`p+z5$wLF24UN? zh-<$EsYbx>6H5BHoTx2)p9#FYb$d;WIwCw?v{JUF`gR^80Htn*M^hNnEt%90qip$@ zs^b)YGd^pj_~K&;k^U`OYlCMka2vQl9s6oQj+Mp}lfcW8L9$NwtM)VxL^RlWVC`*c zkxtjjYMca)XDKUZoZ~;-!T07W#|zcV1rO^3fW&eAKd~dMEGs7D2!fkl-%a~E@q2$x zR|{UzuKqWCLo)@+>}%dgHZ;~Y-<4#mXk!rQu2;!aR;Qi{s4}5u(jvN!NQ|<J+EzviQ_kKW%F(}CR53MYU#MH?14UXjAyopH$GN-jCNd!&R3G}@aDdRbkty7JGW zb9R7P>t)>WC%9#b){?=q?BFrhwL53d3TA4rBG9SaiMh9n;zK%HM%Amq>AlfvHu}G*a+wc zPg4pq{g+dLUyQQpMp-ro+jpZ4uPosQs_jBOTNC9x%#pAt0=gfDuYwBT7*q@^F=f4L zcMP&QfWISQWK-H(jTMXE^XAL7rUFmSmDQHS>`!dO1sa$izg*HKBkbcCF!evaQI!ah zS4D=o|B+eP#NzKsE+yZD3J~|~?6SGX62Z#La96yo6cmxYA){Q)Sac8Sy9sn6Fe}_Er)kJr+Xc#Mtd*Eu@1pjolWn!Dg17K2O|skbh~=;ZdhV;h z4MYDOhV*o+9!zk=m3NT2HmROOK1Wt;DoZ%9JV70%=A+*ebeG_F;@Y;e# z+5jB!=Kp+MerW$|=ic3Zli;x6TBe=BugdO0f4X3b1t7{ZuBAu$@JQKV`-NH9~`J8j1}Oi&P)Oj*Vj;&saq#w<~Y$1R#xH)<_3>UtTzKnNPaC#Cq% z7X|7ln20Lio~Bp3FAtp$_)y%@}#1L)4o-<-O+9u@y2Ir@saR;!0SQ2@V&TU zt4-qvY6ZWuY0tP2(2<19G&S?(KVP}~&*_k)yZYZq`Xb+cS_Uc>ykbQZ+WSRqojjuqj>B%6%f1S(%WUn)o%Z?jl! zk7<#M3~X>_KK!u3uVq;l*eX-@XN!465(Pvm9+WpG;*XNNr~1}evMMnp;Lk@Yg&rT` z2MeV?BgYAIPB@3^TR zK6WJ;!ctri4pfLHp4M2v8JojvbA*bmwg*nZ_{EopB62c7kT~o>FRqjIgi%tc^^Nt^ zCvO6)!y-Byf2ZGpQCa5K{5sye+aTSD-zY$uIjltRKUns`;OCK2$qnEz9%S{*go*Qb zT)GOqK*Q~Wi_5ToRW_y30}z5d7zDXWCzvlps$<%O67a-qfRg^B{DAyn%isf2e4-g* zKb!cikYbwq?IvRnBbJ`rqy8qND7av#Lx$EpItBMnatdJc%xXYg&ar=={VEQv%S9W% zzXUJ6OC|-Km>(PB`}@)VPlXr`cjHdMvY!PBke}tBocJ({wa9U#vh($I(D$uaa+U;tK@&R1h^p95PIUar+?sUT-JQYfU=b~cOoKaBxOPOj>jS6k$Yh4OL~HEuBzajm>-2e>PjFQ z%7ylNN6dlKPho$@#nYZ^W|a^qx(^+56wj(E_k^l!!Mfq**qXnH(U^Xot8~T!;NXyc zc3{}|za&=p#}B8f^3nqXu@A(=#|T&DGmu}99bvE~=n+)ah3}ifm@Dv)r9a$cT5ES< z@~pU0Gy&@nHz7Ss9LM6<|As3Qi8VtV(rZpTcF}1Ik>m1qAC|tZj=WCags5$$B-%W7 zW+pu1CFYB=q5$6$woZs>Hq+lP`4$8+@SAQ7qd|^gsQn-)r~8DFJFlmqa79)eI%Vc| zPIbX@z@+b^fjeNPV@Y-mLQZ$SzGsNG;-LXG(){PETu2)`A~CDXGZU}qb3aXX4A40H zrfF5y9KhV7=Elelv~AuK=6u!*L*~RYGyv#!sylWjk$t<1`;5x}NoWfww4~_cMEVYf%@hR+;$2 ztC2^?Dd$iFx7D9-^>Fx)4AwgYC=5%1t;Ijqu=`f5g5Ru@4kBmy_ST2THA>SWgrv-I zDdrlQZs)U2%Y|f*=GJ21swy=pXYxs4iX%0K8Pf<;n?3edUo86_03ht5o0!MsTv4X% z{6eSWyfA(~ASv>t=mT5b|x z7|Y41UDq_EnU;r!dZV!p;L&%QKUpl+s@xBltgae!r16{~J~JQ#!pl*nAJ5kocR%}n zZ^L`p-G2MXf~Y*n>C*>{2Va?;PN8#9CNVhL!L6@4>!aV4-6m2NhAF_c)>Put?{GVfk;+<0s*m0sR*IcY=x2+7!9bH-_ zEk#xc&wBCxbNT;r1m>&k4okAA`xcBV`& z2&=QQBZ`SR6fU&*w01r6)sa32!VZu!*}<@B0U#70R2UNmg2RB&U{od)35NnmWI;3%d#YWYj!%k*>b!_r9iMs+b8aVH(!`l(mpq0tt4M3S3BB3ElX7 zpBMGspL({=;uxyQQ-*&0Za13w>e8OP6hAL&lmZZ-y59T$|I1L|EGP>K0>OZwSTY(5 z1_H=Huuw`7OTHrWiq5(7yz`rrER`ZnD=JCAC!ulQEc5M1y#Hs{_0%+vQYqQzgUoli?flT5Q8Vd#l!+@YzFc%92 z!h>L-)J75rr~>o9KChqo{imNE)vveX-|D?|tyQH3TC5@e?`bJ|{Cn~9@oWC|U*GTT zw$Co@fwFZQW=~h}J_xPCDurL)(5$(*wE_j1oaB+|>_=<2JgeC8eYpNE=R z{b#l*;pjxGxjXxUW3pn;uiMM2Zboh~r5v?WY)PVC%x=^C&xqA8^LFUfh88;hmdh_u z%N{zan;y3~mxSqEvmjGRwKKXUOSlNcYNe)E0B|m4Lp9mMzuMWWnq;gP8}PqA#Aodl zPsdTTWx77Q9cfsmYi>9p7q0Jy&?2BV7z+jj#DOr-OcV+tjWj;rNuAh4+(XBc{W<6uz_8WffsLUDJi6+oBbiRmwGLXA;mSLKaqym1SQiHT0 zmEsTt{;*bh5EwE5APC?A5)>FT7!3vl#DLgXQWy&c0>Xf>U@TN22?#+jzd7;U=brBQ z>owhqsaC11yO~6J9>Lim|KH~BiGOp=^Ss~h-*?xa*CXt3kScDJF0PH+ryexl625Pq zOLtg5!zih;CwP4Er>D{ncZ8JstfIEiwEkSM_-WCG{rQ@Ch!EKyeVXU#^TedjvP@)J zAB{+s&6g^&UU%msWns50wQQdsjJtH(m!GwFQCVR|&H2g9d|&sqTKeIhC;r`ImF-8k zhhxJ|Aq}0Dk|Bk)AZ;zhV<8~P<)dt0!s`bq-@+%Ln-5LTzsKsen0rAbI|a9#Y%VN(Zc|lLRXCZIb#@J|LFec#c0JwgTYA3aM?A1hV<4iEO^r8fcAS)u^@uc^j$ z52ATN+jnC!X`MKa9MfB>hD@%yO#+V>OTJYY9as0isjUYg+i~~x6*S`y_<$%zrcnD4 zr}8NB-HYA6ZMm;ot>$skj{I?YsS&YHpi7!EMciAOFn~q*UqTV8cENUvk6ic#>jq{c z+F01db;4dlL4r`6EGP;Eg91RvU??^U4MIW{v2!{9O6QLs4fyezlsGP~H z|3Ljq#5`$s*8K1ES|92U@Vfrd=V`wCdK;e8lE?B##OD%={d6IPFPHw}E-Rn%ZEAHy z)2#YvfZzQO{-5lKSEhQ|V4#rqb^2xVUN2@d>s@J%Q8U4KuD6JON~gga`Y4KnJ$T;dhdho^ufGc{hMFb z#6JwazxS@bDa_firZe_$oPWvVFW3Ly{#iE}>*wJ#i!BrJ4DSA=+y2u~02q?U(Ug#= zGir9*!@rE+63}rfV)_K=A(RDv zK+Nf(?#KCwv)h=(&x6`I;v44%29dGfm*BE3 z?{J2pFkn;|3kd@QW}wt05fOw;`Rk5z>A73ftK++?%9U{=Qt6jC27MR&e3t*`FdHX@ z&wL9Fw0w*D{E+F^HT<{Q(F}C=HFLIG-@_rahf1Z7<@FtN^1y2ADVETjbscedw&cTo zp8uu6P_&X*7G%LE9At6|oeyP#M-3G>3*XJ+a1rGlI@h&mYO(hE@3JLm6?e}xY7mMQ zfP_afS4 z80tH156VFktYNIjzZ(ERIFNp{Sa;az1f2Z1>c{mK?)nofhbM7ciHQHSpE~e{HW_8ekK<8-QNHa-0O9#(Y)2V6f=kIkJ3vJ8v zPF?s3vfcA|0Tx=2_L6vOtosf>5D?j;8xu*|82*D(pN=Ny5s@+AzL5!s4BgrjTo~#_9Ms^14%wW!du#3#LS<|aHAwsH5vN<5STCajyp|A zi1xHSvcL(`4cL-GiCEp19wQ(}8~2R5vNXN(pzz)oMhq#o42dk4IgnaVYWcr&e*_tj zt*5em@7G7%X2>qcrNGMbS)c#~SlfYgJ_IgIlgY6m3@O)H@CDjvS=ndG3kxeR3$xm_=kK9MBW^!+CG%cjWv9wl(^59EiuC|KXsH)7h`K1s?NtaM zJY#GSV5JY9B^^|E#rV~slMnZI=CTz*Z(NP8J3QGiNO=h*$ za`DRU_JvH+E|bhjXY{ivMMNq5ie~FaNOd}$Lg7zKtrtzq0PE-IfC1D429P2BiP+g2 zV9;?sHAHLhd)iLTJfA@EEcS3T$CB`lRz6CfbY{?5fK9Wv9RZq;5Q>1?%pMfQ3#_B% z;3fM(M#mA)YacG$B%KxOHSWXWqI0$Bw%nC(?0=7iDNxJ7{42S)cOl_Awy5eMiBTWT zO7;Rz{)}uvGqB9HV}>ZK{9j&=Yt+4=H)B&7aRfxv0cIXNGK8t%m}~`T_S1P_?O(i* zz*iT<8pAv*ue_xRdOYLS7At-oz{Qfxh}b050(3AViZ8kd%=z}YO^`OX?hH2U9SYuKo^a&o; zZ9nh~h&2X?ST62C9x|i*19VQ>$h)+YnM1!V>=~}le{e%L83M4d9$8^nNbXA~6cPo% zLumqGMlW*#l=2;s3_L_{nIkJ*>NGo49 z)2tH7u!rX~=I_%;1d6B8;Z#}>)Jn!b#Tg^TD~KJ?YKsM+?lz9bE;)X)wKTH8HHHtW zrmSTBquB0lXxaM3!RS(cST4%CvKWurqih$C+)}o;3+qK36yEr#8h1sKHDBv0g$fBI zYs$66DX*fPvE*&MDo;KYVpqx)(cph&0o~e{W^3rTuT)@am?$lO@uG7Cv)ZnJLcn#p zb~k?MuhCn;|3BQW^l~4K*&m$0Y>lIu+JQ8EwqyB!WZyINK+su9C1%G6^_k6|V> z`RM`1DBWWF84wkTJ1Ul_-!+K(ikN~XVGXDB*qLF<8ce#cejz7??S-XW60@UAIc((l z=_cRw=KL5N-Ex(e(HAgLQIUoBgIvDjieiwfD`W;0H+Ick|*MnN7-TfgXQttl$hi*{MCPUyk=FAF} zFAHXZap$@Y>iMaV@mL~FD8oSNys2q~QK;V5Z{MajyN0iEm$b0#TOn2yftp(QZuxmx zJwSm0=)i*>mN{ebXZDIb6n2VJ^`l+cUnhsZo7V329S$(d|4Qyt8OU2ihzR~T+d#!y zNn&Jo1$cKG2+>-N3N{J#8CrWh z>4^fSam+w)y!?kXe(^Wop1XdlHC(oJiI4+bxDaY=R8GJ6%+}RpHf1=E~Dl? zR*&VZZPjJ-y^FOVEUw;T%UYI+$Vg%z{Ro!Gz>e4bDH-V0nn03iE`u0Cu@3MOUlfOh z#6*ivLO^H(L7V;)`^skZ@*Rb~+7uXs#+cX9bTU#Oyc~+e*^w-=MNbTn5aa_p9>q~i zAlZVZ$NaC;94Wxk$_ARvI1QION!J%@z`GMWk~g>)DX4Heu`-sQy}H>+B$v8%a<36N z#4;*xQ~na7HKD<-ewj;-yMf09F%(KwF0V7yG-WcxP}GYZ-$s2nO~MO_vO1?}8!jK) zN^b<+0}jdh+n{foO)RGfVFVOC-06_p;eFyz%Iykef2>wtrLm9tDRH00iPo%*sqfTVIhY5~Bl$BJd7}&yTxVv^IQr9pnJ0 z*>JVf55+fc)9Vmrc3zsTp*PUzU9)oat!Ib3`VA1@&`p4I89ocN~ zL>T%C1P7=r({a}CAevK#Su$Rj0mjZ-{ue>^PP9NJtpF0<=J>*s)w{IXl-Yy4w2{nj zR8qB*3)tfenMHxM`3gQf`-lz<*(gzV{}1V0vIuI1dZ1;QUPUHDUoMQ{^!UIc!5p+;Mc3)xY}mI;GhE~ZFjB^1&5 zpSYwAC!UW5RgEcU!(l~Gt_kWA1rGS49W3#cAttyz0Q4*T&01r z?%x@fzv*qNgsex!p--$uB{`Lx25)|rpXVb@SrjBFpOnHfTM9M}$1f8W-bC0+ay|s(4#|Bu1eRzbI%-bQ9r+$?8*gA+-p{ACQ^IF*}Ka zG``DqenO6oWInR$stgPg%}gXZE&$KKXA+aPyon?ZI5?zq8K}$wtZc>0yloE-CW^0oguonqkR>-Df>jbL4F$#!4|Nu@>)UbZ&=O zw*Dxed>F!UmxPQgd@tO>l*YPUzY|fUV38^F7xLPioTedZq z%)R^;So;^=$j%)ieA4+xrvJ3?2(}@CL1666Q0r~!pw2UYLm~d<3(6&PvMP7Px|Zh$ zPVzmb(PVBWv3KhJf2a~~y-+qE7*8^2Rxsa8sD=?lUsXJ$yUKG!#(QaHi8`$AJDQbLGU=o ztwq>%>X~_*snSQji}CS%zJ(_b0-bcxOi_7WJxkFcx|JK>H<}~wXqrm(T~ahSj)D-4 zD5&1at8f1od>bg*JVG`%yBi{A{r9jjgQGVm{Qt7k(kda_uek2drwEL5YFG0!aOL0| zPmS+-oIKC#0ewWo+vp{*)i`3CW=H5Xgji)`VEO{A?8N%=#B%a~x?3Q$cVe$A9UrE0Au)sWU zt@?0};9A5Bna#EL~+XkQFE>8BDgaP&yi?!-cbpbwpZ4yDkaT#40K}XRM zZXJXT@)JD|KtuWeO$T zbHOCtTeA?Q9pUp%wa}}eqT7=JJ~%+hylYwN_x$kQ+h%8_3-txW&l*?XcJioRJs8LZj- z2)Gi!*QO?!#gy&6O@=iia2|c80vYo{pIiP9k?P_7YgfS^z~ui`MSxT;4-_|5KIF*q zRaToRUG`DEz1JzlQ$m>jL4dYFMm1tTYOQa3qM zR!zMJ(q3#LDo6HAbqn;8BlsjC)VqH>I?o~1Gv%p=qBj?!I$b4t4kL?qFfcnEVE11` z;{d5d46J2{kJZ(g*Tzik8vqtKcN8=1(m`><{gSbh*h9C5YB5(Wd4pL6>Jl< zs>0Q{I**VOg;r~yQ{=EkQ#U7vy+)+YW)M%FaR6Y#|0CL%bcEFoCDl2cnZrQB$1I_= zbHxd;@rmlx;iyOe6-#^Ayud`dDi7Zb92^3~lJ$cT;oXHmbVZ=c!c}ol(45Qq1zU9o zp$IJMtg?dR*_;cV4KWnI&FwKds=lF5Z|fyqeMpY-S}5K^x2kOIbokN z6#}Iik06g$mo;?L!~w{x-{s(biB5HGz1jbj)(7#`TV-dzxbR5*~kU;W=+fX;M zP4bZJdTzOk+2(1>Z-v;@`O=+g7HZ6TbfvIl;g>^f5Xpc6G2)Gn~ zrrTXx2CHpms{afyo>nhEKq1A0KW{ouLN*i+es%^P1YpX2iqa;l<_x5ZFZ)8(bNuH> zfW=8Z(JS5>l;H#6srUfxwngB zueaOE<7_;Oq|S7SB)=KLsKa&E!DWtiyeb^o@9QXB-Q!)VTp0S3RUwrQea}&amZley zm7QYG?ys6pEE(mnxlW)&_x?l7VQ`F0xNgiFM?obwT~Epnd0Q)!in^qE0GE)3uS!Q6 zzSai0Mcgn_CEZydCim}v0}OyK>T~j+NV5UMt!FkE?6+QEIz4#n6`U~Wc|@=LL(xDn}Q2VW0XRJ=%UNDEw+%p(+KaP*agx&;6P{`RnqVeG?s-eT$20kOo-M+BposHDWO(_Nsd~-2N4sbM;|xqT~Vhor~ZEY5yj_&V~(*B4vm%I zKK&8=;B&v|%xevynT%~h%9`p7=jt6Wg~YY~Z})E)Re@FUwGQ`<2F?=JED6de(F6Xh zGt`Js4M}dDWEYmjRo8>Bft--9cxB3>$F9CvM$UA0LB^TG(}a!0q z2^>wN4Z@hF#)2G119eK1 z8*H*3C*x(bZ9>tg!MVzBKM}q9kVb7Y7Ls}ylvpfWChUJ0$rL0$u$jBiKfpCUuwDhTg}`OWZut~xbnbu#x_W(-LEOuN1dfIPb&&*h1OUkIu5#Js zr_ey{u(EZv6Hwl)kT!f^{COU7TQ+P~DeE>*QREl$VWflxZ0<)#z{QdA~WttZ&i00i3 z?}R1Wg|CbqWJY)m_ayR>9bii)=^W53LQDXEB$Iw+{tYF^|Fx}NH?m_8RTYgs^pxl_ z(^)SE$gO`n@gOVFclcLUXq zQxewn#WfVMS4%qQ_aNRv{O(H7qGkmkmHHolI&+!1#W*vjjVUZ13$w10-MrBJ(dfPq zvO5fDSHJcci#m$_qHD5-7y4 zGVyg4p7Iyjhs<2A-F`|WUbkA(SwM%)t)LLEJNB|Pu4T&3sW*zPBnq0wtpy)Z5Iiq^ ziCS6GaHeoz-ec(owc?3iJYt&Gq^rzDwV2O8;p?nH&+{rPKdm0rE$9@%%?s@M^&&~R zZh@)N_L>Nle#z=vR`At{P4}Hzx!Ufngiy{*1&`-_WTQa#iQVp^FG$B=L&qpcY zX#hiB7XXKLe2zsh!G3v#ME|=E7H*Pu;eKR?A>mpB9J#I!E6|^-h5uz;5J-L z?fkm?18u_AehZuU&16gFl6DPt>^xCP$@A&$a;h3y!8I3^lO zCMeAH{w9A<#Rjn~Gv*DBHee|){m_Fi3SSOdTazN9VSrTD47tlS`7Z@f@NW9|ksnh0 zT||?9DSSt!p@JE416?Gs1nT8ku_`Oi<*_9?4ZyEE!;$gf*S$xb1X0(P^9QfLx$wiq z>n!P0G9&fF`Afw86QLmK#A;P?+~I5_QuI1e8b~^SUXmDZp#yb;un_IFMvHJPyNl1; zy1of=+BQ9Jj{u*oksyzk#_o#s&iw+ptrQ@S)kMEoMU9$*#_lRrvTx!kilam{E!qmPJW~t?VjN-0uB5M?84xf5>K^X@`;m!j%N;EM4e^3{IcV=dxP> zQWM5)*I{7|OE)c)OJ#s?Q{W|6JI^ z9|0e|y~vP|11wLyh`VCL>_Vg#yz`8SUKRkdzIk^pbQ$j==qeT1hqV~f`I`OG z?Y3W*OSfW*sQYCvQ(X;wYY9UF*UcoLeFm(~8KpwIYr#Mv;vG-iL0=?Ni$p$^U6B6* z#zq7=ThDc4D4L$ynkU#-m?`oWZhPx4$pfMuDaR==(QEm@1lYcupLHNM%iLeGu!3Bd zbk$|Ba|8{1ZIo}S@!I!g)pl3PQ9f~XV}$_4@;G6?X7}%mC<6vcDGrYRjiW#OB68~bw&iRW*C8+J)Vf8A z+jYY5l9|KJ+d`knCcIzeE7XCoxE}`{qkn(BJ1c<#iYvr@qcxWRUw~2nO|Ye$N9ixZ zBwld2=ZjGJH;|B=gTsJB^EnF`d>DRax3AC{pbFT7VPLabp;ohEMaCo?hYd!_V*sbr z?n9VNpBM|aNS5{ruUe@64>3oKLYcFLnnVH?FTRGEo4v5?&8v$OYOU0TLLImwuIK5T zlgMb6g~MOUx>Xkat|{(pUgYJmL=z?suOyAogIvh|yaGKH8V{JHvqhk3t`P($IMqcw z?fYzs%%_|)o>`<$K#Bh|!BAl(P<3PU7Lf9^;?-bs zUy3A(r!@ENeb-I_l&wJ()mjck*;pJ{SKHZ#-o$lO9b8Sjvrl6s2nH23-)^Qy_WCgx zC0SKA+n1QYNOTgWd}|XfBeKh8F}x#9ufj@Ap3SX%n!1`U;qfF?(^eVC4667t;1K%* z6Q_{DJ3d#tTUCo~ZLA9a5C>^)>8Q*JXLHz_FmmfLtfR~A4M_mXiNTKZxyZiG>QCJI zCR?)`MH*LH4;qB#gHfo{_A^}-I`Bxzr#TjdI6q&PtTfT=RoeY(5?CvNEYmcA0o4AN zKYzrwG@UTwCJaI#(u1zKKj^5n4Az9QWnmD>L`We=%zjd413ZBdB%Zb%>b;0H%d)Tl zh(LG02iPw9g2-BgWY(R(M*6FeymS!a^oQp}` z;9Zac;9pgSGeHZPE~rGJ1MpaHW{#acKU!!)=CRajOMi^J#zb&&vUjZHD_fPO)Hl<} ze%?e?;NGLefm)W(z+ASDrj^*=j%*@;PsEjAsG_Ka3*nGJUjI5?>Ie{?4*28FuhH0| z+Q?gYP*kSjPKv?P49wB=b9>JcUz%3OqN2UbxN^=eVXrz>yuw7&rq365EboG57u#T8 zTPd(gKrMm;geQTKLb6b-CcJ=hcU(n@$mm=kG?<8R%K!)9 zWFjWsaDl+pun?uy?z-Dq-lu|aI8HMbZNqlWZT?g{QrNCHBLsG}(y*=XWd_?NZnc?z zR1zjPKO5w!9{l{|%$fZukZpODU((W)@#SoAw5=E8oX>7;;E%koIpOS{e@0jshlTfV zs?#mA?geWM40ZRVbSow5)J6Y)U}g8I*JN*_tzVqwREa!Ict@aGLJpcI8_nBJAg`)^ zdxqFk(rO>gn%~O=TPKH_3{|K*arsP76X=7DDtxen%y%~fu*EuL`j#`zl)+#$#WqQzt)tokp|v?8RoYQhe00^ zIoz0WDuT)prHn5Qv)HZl!Ah3j1v}#>i575uaVd+)Ld;-v)CY7@ zv4WLrZfk~HK2>hjTj6(Cdo_vif*1{LcOcqt9}tVyr4>#sM6|_t^Pr755^n=@gb9)A zI;}4~-b>*l9k$h%iVom_cFNbQPxyZ@@?0@Cem?Uto+(wH9Wb1`iLe!6V&6NlQx+M5 zXo#4>mx0Im$8((gD$M6zow{xZ+qeT{8KzSOLT&O2XGtcrx&T`O@zaB6ik^6WN0LQu zPd~$t$ITEq^wDSKtqCbrA1w1tC1^{Ef3)+#fPs% z8!^v}B#-7`q2*TfH8roAFl1e}ZOfWykytHGq)W_Jh;i<{*+7^fnS+i^O@|mtQZ#`4 z!;ri%cta^i#uck(VC9%bn7$$>}z{}MYo-wk9CwW_C9mPkFz{09pt7_^S!^m&o0bt)kuF@ zva|o%L+|<5%1;T!il1MOBlL^M(efet+pb2FjFO$ba!(8mO}5Qn|I@O8j&)d8W!3VY zU)RtLxl=1q(I(G#)jO|e^RLNUZ2kB}(lgMmYzmn)aOfT~ZkP6!y0xg0k)?dvP;4C- zNc$!GT;fW(6EK;XfwaK}MbcEDzVE4Uda@Pq)t*+@U?Tn%5#s$aOb9}Qx%vP9zcXTh zxL_<83lai?fXGlX77_)7f>5A{C>02$m%_8_*PVE|$LHIhHC0unTwhJ?alkjvc>c?S z$d30t{(i9bpKf7?yz@!?_VFemQRrTZjm5B=8w2T^v&RL>|9?4EHW&Ow*FROaE9pNWcBti()=9o)B zXfPTJ1_NSY$XF;C3xxvVVK`7q6bgj|K@zA$u5;S6pWeIk*`1km~eig<dG@_e&0v)CZ~J;+LVu6@D?2In>m#G#{Un}Z zu7^xh-S8y0ZRgG0{oi@JW=ZGyNnaTB?aXvqDx`_~_N*7W_%rYmpnP8cP63#)8)oT{ z^jUn$YB$z5I-%Cpno}EC&@ie{`O`%WLlX3eAYQg#jRI-_j3^=R|Ns5)Fd7sQg#lo| zSa23J4T6DSphzeYA%sR@eD##Os7bv_nH}j`OTATVcPm5S{hlA3ckFJL8@r{E(!Z_# zsnzyY%h|)}gvfi<=j8HS{d+FbzJKFhK`eh2R$Hl9;k-xnjucPdImw)uH3jmMcXf@a zYE)`+ye)3tuRU`~x(iMLr_imUJro53MBR^Z+G?kHj zE5tjap(BomDE(;V-oJ-n4brbAV)j+|Id?g|nY>axuzt<-w6=)&_2ky2(~BaNMksHB z^pgY;zHgPFLr`om77PW40bszGsuUXq4q+gQ058uTd_AYXn$1YMBXX>{c8atNKg->* z_hv_aokUH)#U1)8{aU}F4(B{@de2*aJ$@BQbVmJ@qV17*uNQ|8lR-8AU_ZsXZe^|b z+@6I{lvD8B`=0&0?!OVPJ^%;^gT3LkUsBL^(0ZVHdT-00l5}5wE9m)gvbJNEe$R@W zWc#P$q?187V@B(x6rj5qF|T}WX3(Dtg^-A@&@gex0|r0@0UQAo6d+V63kHJ0fUu}6 zC=CUJLSaByFcvBWf`K6+OfQ~)e|zW3ufH`p*D_L?$t7xQb%{KQUQgE(U*9`3TI~iO zkav&Im^!=ujq2RTIrLh3y>-=fTYM-_rKj-86urfV?F8f!Tkj6QVV@W)F8ohjpO0nN zMCc-IcCFx-$L^m$CRSIcTo~iO6*+3cy|Q3I<6*SSQ)T^kQ+6Fy100*~-A*0xvrQpm z%yd?Ct+w;XNS-f{$Z#Y5jXkNm?_l+@3y`T4Em~YTnf216*s|+Ilfq(CZ}c5!rp-8s z2v&8!EedRV-61E4B-En>}3NiB<03fxo6z`tMTB zVNhf&C<_?^!9oZ~LKO&vf+B5xd_KKr>+k2EkK5aDqU!5aEXs+%57B;}SJSe7XKT4? z4?QpYqu2b-eSVIzJ8AE1W6$4(!rueTkX#@knQcl9!t-IMs=w%2ZgT>GAZmjB$sDp>1(4vmNF z3R7IiTz{TWIudqAUbbTv5kh+Yv5|?XRQ};RO>R-^{^YbMP`I98s`RtxiGXSN+6{GS zPAO=cOc|&pqRT!f^bP{&JHc@L1t7o5t3g%D#?=iF0T@tQ=KlNt;OKBB90h|xfU+Dc zC<_q;p%lH|aqZ7Nb9YIt!)ns=QrC5ss}En5^c8+phxu*u80`3K$IW)OKOdUn^#=5p z>mu8+>34Tjtyh2X>#N3_aOuCzLF&p5sXJ4~p1%v>yFFyPF9?l%<@ryR^sN7Sdw0CQ z79=gvK^Qxls`+xw4d&q`smP8%FteOUW~fnsb2)D*P`1cW0S&O5-TGVmf^z31O^TCH zw>XD#k8CWmUFPy}ycCSAoS5KRo0FoEyjO*yFJvQH+*EhRT)n&iiJ;h6FeWtxh=G8x zlq^&k2vYA~f3%-o^~XNmE?sJ-*}|Gjm%B#*o?p}TZ|CKn*7k?5`G|ua9QfK8aBh$q8Fz|;=f<3(HHK1qf-EL0R8Zv!aG735oF;JYqV zV92aF;F_c+ah(@osDzUzdQ2Yaua#(uMgYN(0RTq;04mEtnkFOv^B_(Bt|>{*UC$96 zCZ{Z-Xzc4DUjS0VH{Giqmm1|nwGKIJaBQ`kd=ZL}gl_U=J!5xawlZLyoMmF@jh`L# zZPEEz3U2;P2YucQ8jSHmR-Piu+8;KRqPkdKE{xWmO()C2RsOBd$q26Hiecqzm>L8( zl*R_feH|wDsDWQW`LyWh&}|;mzvq+E!wKwGGM9S8&}fSSPKmE}NrGcsK%}OvsI2<$ z^+eVKJuno3Lo#URGm4QkiO&A8!vUWQB@~K#T%afUlTsv%7;wRejp1ICW@kJ-)_&0? zO*1Q`HTYwoQ7&v)Ljhj>upF=vT}j7)KA?_yT1-CJ*8FuZZ$sTiq8*+_bc9+t9#68A z{MM!IZZ^HMG|BmV!kVNH7`Qkojf)V0KJrlzDTIeD=eB}{Ma7Eva5Q}vb_5xNx8@-4 zIolT}9B@`OdeWUv(p(s+DALxm);2ZZ!)&@ zA005`ftoHnJENw=G(STzp<#0^(Ej8jz^C-}@dVtfniV0Mywb-Hl76kUoB8A?Ej$?U zw%R0GI~1YbZNn%q#zy0@Fg_rA=NkvR$cUd>Nd+ua)*aXM(z6_dlgAu zw_1WlS*lxAJy`=+F9cK~vxOZak%+?-Hg+0T5dR8N0+$^h!wpGHimq+>SXXblO+#P; zLrVu#ahe~&l2^UqK<$i5GuV8e0O!kpb621QX5Y(dQyI{SiHmOfjF_7aPg#KxIi$B>Pu7MaWI{gGUN{w z-vJc!EeMn7tcg(Ib8u7Y?ag8FD13|Sv4=GK}^Qsl-p3nH!Fb$xbwE?YaxZNf1>N&o7z(y)E z%fEO%Gd$WZkU)=oMi z#HL`HDSLsVqJ%xq_CrT7-};s~$?qpoT)XdRG&QBX>QwV&Ahqy3izDr{>{;6kLaXMZ z;WD6*gzonX3HL%|u)o*hTmFJ2C+{pzF<$VNOp=dl1oBCILB?awKe&9^2AVu?dE%BF~k$iHG`z!W+(C@ z<8|IlL+aF8nE#G(H_J%(KICdQtc!pr()8f2E~WI34V70h$*wiwM=r4!xNqS*Q^cU6 zlbo7<@|Hs>j|c>g%!TDO)OcNI5A%H-pJYHwC6~yIB#A_yAzN8da3Qq8xRg($A0Syl zEwW(SRNZEXqtF$$SoKdp03cNQn9Eh>l-&>qcGUTp;Xm+VFCBf;^G|I>b>O=co_!6j)D?p2>% zTKIzqI|;8Jq(ujTe9KJ_;+vPA5{C-erZ&WFkVW7DJ6$EN%~1efEWt#mqYzW2{0uJPB1U9@iCG}HiSa1c(E;``X!b(*l-L?O z`2#X_$MfMql?m0Ag0zxLUes*O zJoK^g1_Tf(Wt?MP*nZ~S(_&psk?U~6|Iw>cpvVD!1dmL(DSR zGTmkoyV=Dn!a)CfP3CHxSsc=fAMc7UhAk`grVD<+8AELF$v@ft1%EqQ>oqFT$vb)? z($M33B+g1iJInf@x%GB9{}g$zxqR`&b+ z+pHDfC0I2Q>e{*&N!z#<8Tte8k^r|Cdbn|>F@r3;T-NO@kf$ur?V36Di1ZlPq^05L zyAnD`a2ML*Ha0}Ger=y(ZK)RCec}BtHY^#FGTrlWRK)`AICI!ui;8mj^fG?hZ~Vju zYT}pS`5~1A_t70iT2t(hdj?lprRHLGsJ>n9{3DY)#7Bz_#Qgse9?@fz0wSs7f+D=) zFv&krqbp=7W+S%GD3xYoCaqF2jioT*4QZw-q@UJEXQx_zYpSf9o|M7gPNx6?T_+wy z3hawyZTd6U$sn!!g~9UL1g~v3nm2k6{4`D^2{ju#prfwY!`i`wb{;^WN;m8&UFa{t z#hj1PQKNjVmIzu1;>!SHiDwnNHQ6K`TqmlHxWc*hD3Obbuou zMwuhLb-zELiS;q7kk_v=`y>ija?rz)Vg<4|z<;@X2nJukdAt4lV=gUJnHuaZli>+d z#RzkJ7lXhf@g7WtqXCFZjm~0h`!|qd>rZU$3C1hf5okY>PnF-vAUsai%a; z+w~FdOyD;{&o`$C)=Rw;Te=y-KZkfSA1TA7BhHCLPXL%-W;Xef9sVMoTS9%0ajyc` zC^Mo=6HC=GLeQq;bT|zm%|h>kctQBpaE48xEVv#2RcI>A=q zOpbj{jxWdecE~MMu)=?G9tIa7(lvpiE>^zdu=van-E9pH?7s|)BaU0J` z7NI&7gpY$v<8UumV<_~&;oa+R1;u)lwrOmqp=ce?#2(5+>>`k6gNY;#Le|l(ZpDVH z-&2AUn9|AuU>HkGWN#MP1>kJbIIv3R4r|=<7K9FMq^2#YzugIsluI>u;;guJ zP%qUs6RIa}9!@nLhUgIs~qBjvF1O`qwsd5!pu zu{$t5H(Jq7yi+r>h%kcr1gr_SVEWWgAyeIhm{H2>uny1c8;N%Vlv z2ihE-Pi|o+S9Aq1PTsEM*w!9MLQ(=d@Q78kL@{(Ru8#36{BH3y#@i0 z7QFyCEE$q0h@vP-K_x;2rnAr1JjJ$r)b1}5?%{g5J#~h{!aTdoR!1K3o^EIEXbt0L z3z`gA5?G78hgw--7ZDg8eVE4}8@B6`&0@Y@b2!FU_GjhZA8u|r5)a-Tm9O9aoQ?D2 z_7}hMn$b=&7$oE1PY+8W#06LQV>H>ePM?|eWio^>ne?93pch$@f);{LMqvIraFRJ( zUG~$D{a|=4u1B53_mao}aGK52Z4&WFHp5;wba$IV0p+YgZOxS?tK+B_wmq3m{!t3L zw)EaoJ#6_Ddbysz9d(}2ZK+{3(%Z0Mv5D5ayHs~QJ94|+;odj@s-Y^1ak)JQb?2PEhC(+`vHk8>pJPjY*}6*UEMsM*_B zrluA9MAld9iPx!Dhz@$DijrJ&PT7ulti0B?oKjgP z1Gm?D43tyk00qk>HlT*2wD?15>{6pZ{iYV5IIyZu0U z&>UHjn^I|dB!Tj8T`rMRf;4dTy-Y|A2<^LO$OXI{-(H|_qO|4JL`)?6Na4Z1d%Iw z^n_yZ%PGp*=I>r$>bF3Ox2?X}AUzFBbYqVd`W@Ftb3wH3JsGuibSkv8B>kO(Hwh_$ zFm`{HU=JH|#&t(?fiXjTIEV63Q|3A9E46F)Uo;avoX*4De~ z&0i93(&u8rU3NYk>~V8iiF-7%(nv50Xp*@l3>kObjK+?7^xIJb33Xh<&>H;tzN|gX z5t3p1@=O8e+(QSVkgr}pX=iCy4ZDn~y+t=ZoUl!cl$Ze?JEe?!ADQ~2)be4^HWT1p zLV|3k3kg@A*`NKf^-i!VRZ@*1PI2_9N{Qcdk<{7I1p&@-bv4z9+L+n%U{2QCj%|KA zH7I2&V?cGrh%bb3VEMeaXoa|x7+~H5z0CBPMbSB1+E)@Vc78ZK^TfGosfSohozt`7 zx>+kA-*u3jR&;6h-++-RNYwBiZl~|yetBAD2QLRNqQ3(@x##d%g5~^Qr>D1A5QG#4 z1pFC?woD*x0?ft!mPom8RJHLozq_3AiMReIn2rRtL(#}Stf-2UlXN}i%E;k+j)gHR z5?=^JB>&Vs?x&BzHpefcoC9Y9Habz8a2Wwddd)XvL7%xt1PPy7INBTua_*eg zwaTMtC^PSB#@X90KSUO2ZkTHw!tS)T@lEGF-p}}_52aAyIA-nn!)7WcL?K&0TC-uC zEn7)GFwyNlp|}H>`o%DMQsQFViW2@p z{MuPKde+W$*y5R;ngM5MhhS7*~ucPG7+)JGJxvnLHo zDvIZ?<}nm~Ush*<8}6|~la#ZQ^3D(nfK8k@uW1cmsRVNnf_H#l^nT)|0VLgi0LGVL znUhjW?q+ocNkAXR6Je1MPXyc=I_WqpOvF;>+Lzg+1%8;G&!}D}{us=uwCYUYs$G^B zZ}XqX;n@!GFWIu&M!o2<^Z_L@CH=WyTrszFesNtq(|!<-4HOWw+ck?Y++$9oMFPX%ySokx3$$vERL(lm=R8H>B?t6@@vew ziY|m+3Zd6*=)+^v2BBHx`!0~;B@KVM6Lj#*>%pyP% z+T+aBP5>)l&WOwIo_d}C zjk{WbD|*F`lGgvJp(0KEa&kpkft?+OS9;Q;7kLQ_i7!9DaT8J@dy8=kaZrD+zA=L# z^b~-jJgW+UsN1FbFU~+B65oWMsI1FW4@5^Jppbd(?nLn9sds3HB&GFd$l2R*TOST; zim3D=m!DKl#1BBESrfDE#jK{ko5fKvmczA=lED-1EQ)CwLO&*Wm84% z71}+_Yy7+c{ORm2#owQ6WrkhJ zYUCt)Wp1s@HIZibNe{nIJ}5(5IY5dwaSLDS9wShJ1l!Tl_*naxPL^U+_JN3;T?MMn zEKR#3c4)W{dQx8d!u${YS-kOhE5Drpk5B&W$K(-T^q*tx!I9Z`Q zzFIEHC~iaNSORW?JnvNSn6U5qs?ge&6hZ-A4a)1c&aZ6tD|JM1DAOqC#kB~!*HVBD z7J8KQt;rN$XjyoVIau)jcLse;_BXcAjo$E%?|Ugn`!l#!!B?uzxyqOYS_8a4ewy=f`nY20 z>$%Q|@+5D-GB;n*kF^q6h~&@!D?Ucu;m-d;7CpY$%P6d58i|1RrQIqeJ!)#b?*Q_% zGompwGoQIe%>6j?M`a#lG0s57HMoom@XqqXX^b?}&6Wag(H4p2A)bRyf z;cnX}blu(|<+O$opIZ@;ON1ezX-zV)eH}FM#5Tx&7O8^RX5T1n)L!WiN67h)&I|=m z4sMms8TJ|z`xkGPujUJNyV_K1cCT*4!4;7_;3K;iZzwiv}`Sfi>7Gvw&taD$}Fi7+}>C0rG?F2f^^<<3Cf8pS5@ zY->%+C!3a1oozGm%PU<$xiB)Pm&hSC4*)zeDswzVBD}=)wD-ZuDpW^$ky0P%{`zjI zYgsV>*2m@UbpUH{6k8RKhpB0KbL_dYtyVAp;$IAfbmLecb{nz4K=1zBr{YUo5MP23LF$>t$f#*KYNM%fA>JrM7C1L8ebfVHEthK2`Z1@NIwZLApHgxiH zL*MUlxTzEkJDDU&U8sQf+q#-f+PAJ|M1+ZqlRB&1L{D74MH5sy#@CbAbx)(@E_|3q zK0KOL(h@bZ-EtYuff^>O?2QhiG^tvV784NFCbZu0o3D@C8e(pn-k);qCICx-Ik~X# zM8N5{vq7IlnGZ_fGs`S{f63|2+AGf?$Xw6wj>*9kS>^c_$ zpNfDvx_k$?ru>)i!|Iz?`Z1flC&`lvv10fr`g- zOlUl%5?^pHC?1#X&+NT5t7TZMtJ`R^$+RPTUdUq~DBtxSK(N9nNBy!Ug^lbs5Fd%`1D zA<&0snf(KW#(veaTJXAhUiBNdew7U-6+n+ddKw|6jH0XklXalutY6Mg?9=RjfkQyc z6-&#w(21~9AI*O6e_iyCI6ZZy9ueE>!T}C%puV1>=4*N!jPFQmXB#K4uOTK1DAr#5 zMm06$PgO!CSRkb{q0`lUsU}QGLq8D>_sk}SPud@KMf4$^_u$hC?TNGfimB$zXi7?w zpX26DfuDI7S`|0dpwkO^vNz^sXE+z|JXa^$YjSr-0C*|d;H33c7Wc#Rpt%^d;OSE| z=+;hdHi^>)qPnEY@Z}2Q=Ol6jf;Wut2b!t@qra7wUR-)Q{w8iIhTaS~&hLJa? z1BrJEcW5F`o{brj#6~O_ZYVx4r~o5##nBvps-PG&xZtV9rMW6l;}YU6_WY3dKTtSe z@8Pwr$iq5mG$NHT*Jy5U)wH-oq;nDG-_4j+yI)a^>p!MPGuMtgJ{L&mJd)O9s_Jmj8)l z(lBZ*q#L@oX;Ye7R-T*x?S!u2+))aG%H2Nm+LP>~;izsQ3o{o(wppb&c$=2 zI9}}X>Xb?=U7>$io?a(WW}|K<{bL7=pCtH~x2?_=sM)@hhXtW&>h$b2{&fU`0m2lj zYh5Og%3^i=7yoSdBE~)wz7S5wrU7Cv#7AN4tSOi`rkToheUP!aMiA=lx9G|tukqoeTvC4LlHsn%=@g?M!wybUeHwpY|9fqO3HgJb6 z_-0 z=y^<<+sf*&=J$nKX5A1RN1zdhL=^U`STj|`Sf`-2PgJtK9B+Y)jQ|SVSx@d!B zahK<$K7Y%J&ataz69RrM5h}Wcwk>4@?$@30a+@c05-P4u;sQ=G;ue!Kt2HDc5_7z@ zfC0kZ$-v(7{Oee#g-kxG0(;IlVrx-v@z9?TzmEx-Yx43eE#=QO zFG^^%*dEcPSG52=24`5@DkWjgJlIOWm{_MvPh@*c8rfYUuq!EzRiTT8A&LaeWCQkS zVsD8-SBP^8Wv1zN)G$mKXIPv(ADBAQt&UPOAV-lZ5!{aT7)#VX zuZhl#MVri|Wo(#|^_73h%jkyjvO%=j^69Eb@kvVjy577KpM*oqmYLRYIJlKAEhM>o zG0y`h5h-S_&=FXhM;ERw|BRmO8<5K>zkMdh1LPt0 z4ZqYejfq7^X|H}8p-`~o3tI<16pPhuGy?D){YmL+JV-1_ed%Y>v}5sJ-SVRJzN#f~ zQZiZ(KA6+$<3JL6D;76t2eG#1uE(qaZ6vd)+&U0jB`8moiDzp;R^L_A6}va;qhIOo zeim`IlgflR+@Deoa&#Qd)UsgZdODlF%p9uVQ2VYGFs${$A09@ILC-_xP&)kdsoP*S zpNcI?805V3d;9i?xjRO$c>{rJ!&eM?A!`2%w>qNUB!bMDr)UER+9@LBL@s)(o;ja5 zt4FX}$x#dejyIDpDF?5KznG&V-as|N>ta4;?XGFiBm5?3?eFq(TwHPLyTY#?hZZ?8 zSd+EuP+kJ7wv_4v+xlPmb63t~Q{a~>yxI445e*r&Uh#s@@P)OnGCl5A1{$YSA@}`% zGYC`4>`U(FrEw_&r>(c-#o)qIXlJpt3Y0_S3v_xhYibwIFDug#R)1i-c}CbQ$98Ejw32#N?8JT+jNCE{#=H#znu4PHHJ8=;tZfT0n$l-7tjKX1GD=iDxov^6Su-0zaDbG4SyVNPE(0$}m zldw};>X8mw6sChUehx0Q?C?C~uuo=a)Td0fcSgv+)y&~D#FNZ-+wdmF^yAm8PC~J7 zCam|iw@I6jV-^2+%7euF_I z*H9Szrv}-0xg=8!_P#12kDII})UaDZb646^5co#s8I4`6!m#pTz6a3wRLGZ}R*r78 zPmV@6=A~~VEn;@bJ`>rf5>lv;bj`^Oj4(RUZaplEZ!t)t&NEyQd*<4FDJRB8WW4LE zJ>~NX1NFO)H?GuUAdGZ03!elvl>dsQK~PR+MzA*297_yKA68QlrJj%9YU$(bM30`& z<(ut5G{O{{>75pGmB*t&AUCHQ9uwhkHvn@gJlbe3*~$xvsWUgipa!#FNEnYxme@E3 z$x{wrXLsqjHfFb9(mx@5`FS0k#B5VwVwL5sj;8qtX2{lFZ-v@=qHg9eEctdFAc|`& z3xKqBI&sjio2HPCMLraAy7}P`r!oeVkt-tBnF<1?`+T2ETpBH*K3P;GNtCAy;jcOL z8IM}#o7kRY2DZ&c=p2)Fy}L`hEnM5RII3PtwmBr+d&6Ks74x`YMN|+zgF98I^dWK? zoJ2G|4)#IQbq@cG{m?Q{%G3{t$((Y{_36T#Z4onc3ZO7b3-~SrUWS~`o4V=k&|(-y z=NaA+47^Un4d;Uv^Kw6d5Z>lop1e^EaJCY-D}h&tLH|DcB5uLl57~w3()94oE%Il4 zs&P~J4acS`v<+|r=K5cjhGEWAdXmEmpR$!rtentZ$w2-r!|Snr0Ci4}8Tg z8utCUT2Jk*qLLg1HQSXrmii&I1w^hk{EK#7!#O{XiEH8vvLRVO$rY22zOyb2uqH$e zlZha6T8H+e^-eOSlq97z^D>GQ$)pdFm41Rf0qOivc`e%kvB^EENxkPsF(K;^DUz9& zhYV+NY)r>UT1S{oRmR1rk8q_h17?JhW=>;>3oo93feZc*6jHftyYCgK=m6jS(y;`g z5-si2El1DXP?_h?WILctUG}LHO=1{Ri%N3l_}_Kk_MB>8_irKsQn0U@Z|I)?E*O?Z z3ZOne zgCq(;YnwvZq2?NGoOqEWqVAaY68#XeE&})Dgx#Uxl%EgeTxLlr5vddme-q$&?o13( zGO-1=zT!6<-&iiw-9pX%+exH4@PcBT4&_k_u#a&3E)^S> zC&}0`xy3c-&OJh0i~b5o4`C5Fj%ys8Mw+}9qBOiF0_WCPBPnpZN@j|!1 zaV!OG371l6BrN%0YZ`XK-P;X42`Rt-yWCCAo>b*XVJ4?LfJsLKRk{<}->Rn*_dqoX z3WpB0+lFEe!4ezo$}YNx#*Yo6LZ4-M)&>UARrV0O1m|9&u2Gn86hkCz@G&)d74^CF zMnw^sJtz^Z5!fsqGCiq=Qv2wd)I=-_C+IBd48XG1%2s?)@i)rCgGv!KfnH~;&WnDm zCpH}=Ow?*_-=r2E-zBS0%!qYizV@wP+iM!=Qi7&}tSPkv+Tu~Bs&i^`b4j}$0Fk9T zmjSl`D!ND##<^w^OLN@CyWRLTcAjC zO>*qgQoYOwl#6&rZM#`8fyOYv^W{)ilRp-5R{{|EhkghIHdy*y6UKmdSi9Ub83Uy?TfbMF}&jA&;TJS55Kkl|NP~O0>XgMSjZR*g#y7sFpx|X z5eQIWNvd=4oL`S)-_A`|D&>D%VhpLzQk-z)AvZa?Aau+AG#G+v-_QdN*J{?Ox2>G}~I4b!~kioQ5X(I8Y7Bn5>6V8~!77YYf&f>5B8C>02t!rqm8 z_R8bEd3yHu{~h}1T~t=LGE1EUA3NfFHyqDV(Q57gK%K&;`|y=Nv(MxpL-yPF^v?bI z>xmF6gXjfg-?V7mM%b8FM!v0o^kYGDXQn{2l|F*v_zQ`7Kj)&r#L+gmQ`1N8x9fdEqtM_^) z@=c&@)^gAPH2r9&O_R0>(j*R3d;2*Bny! zWpTNxij_+i>aJu;8Gq}^U35I|(GR`-dHG-4KKeE4=jipwgZ>tD{wUM;8N^&&EeYEs zw-)LtbM;Zho@&gO!T$+g8cg21d+uW1VXcX}%9ED+{?n;E;~Xo!1Q56d)~q_UrnqZQ z47$8-c#8GtbeK*sfm}zwJbw3X!cfNfl~NNh-x*%BvHXgXmd*PXA~LnJ+5vivabFr! zB0Oa7V8}p#BY*)Cnf}cftdOyCkrHbsu<3d-v;1bSS{}+NUM6S-&`)D$}pGDg3if>7Vq!uPzuBb;UQ$RYpUitObKc z;eZ8^m;y4P#0M#jLkwpCmOUZAP0Ic^%V*H-8qVt zbx|@!H>Kbx$OBb#<#;WGq!WaNV6X|=A1nm`uo?g;1c0y|AP7@Gy~8198yId;DRD09 z@>Ae?9P=v&EO=xeuyajcrLXfI%g?^Ka8>gvEac~ZzS63k-rFCcRd=b4Q#z*ptgR_r zuzIC-XvvKWq!mgmm~UF!lh@aK^-ah6qIrBZ)ArnLOh>^yna3#!r4x3GEl1Zty4!QX z1@%k33fecPiHN8K8HqIy_D8%o=pr(}=1e4xGQ>1f5F{)w zYf*$_moE2nbJ35f&5L&jJC?Q?w#4P5Sz)P!aj@N!R$zS-)3hn^!>IR z+&R{P?*CHPSAIQv;-;MvI$93vWX9zX%Xqg?-kLeO{Qx8e0DXWc27p)(AQ84!Kam}e0uw~BPOu7EPiWv7ZxVJm`705Le?-;i=d%?G2AoOfN2&3Q9rl(YiO z6)3kGs<5^cve8_#=BQAV11JER2-|JN2taoTa*%{d)ie^=>;N}wX9;H&cI|X^C$NNg zct)Uxt)0Xbn5>aFmaSfcF-Y?0BK==gX$ga@zC$jfz zt)$7&Ql?!BJA(RCw(@rK@Ds+woJtbx-iqH^oN0+jucD7#MqP+B0FXd$zc>#Dqek-I z$GIgbW{km`txng+f~k!%&@N+<;~b`ds*$MLeY0Cv#(OX0jIwpjeHGwS07oTdfFfIO zSm0n>C6wp^t71rAR;_eu)wCGHY3|E~)Vrdg-Z2hhbbvll=fcZIJXf&e3G39ah}y6{ zCM?RQn8A?;_z}PW00C-2nnojk_H(78Ft)oTid~o@go0+w8n6je`EI_Sz z6v48ez2p0hbL8cD?-D&~?#XRAk4))e&}@EHVwQJA9O{AReCMZOp2m;TNk1lY!7zp4 zmZrkOQ4BKdqN>;QA62;#>NHd^0aa_Qnh*l{u21ETR`MSg=r=eG8%m~R&``*;9?{(N z(;@dt41uMpidxaf(KtaU^wu|>(2^b^hC3ucgp=7Yq|kBnL)zA7@Vc72OAXp&CGj)N zy&w2cLq#rM0^gmh_Y?iNM($r3kg$YXWtzTO<#E`YP}SEK8K)Qmv>zAZ2$0{r6XISX zJ7%fK)0j)ztoZA2y3#_D08Y=EzZlecSF_Dr1Uf4-D7EgS%Kl)mEy#WxJ{*9P)V6#HxkdsvMK6_o-_zo83fXsVUL-V|zQL*~Bsyyun zMb8PgnD@gi9`~A$a;zH{>~HP(?DgOGw*2}}R)_e*vF6?Oin#yiwE6ZktURs?KjQ;A zcrR)ho89R7joDo2Xw}#!TD(zdDwGkVrVD|xIcU#DWsup!1~A`^ zsi#t;s&{br)904W)JC?A)7vF^wb$nLOV?ciUx)HCWx9UsC}GP!KACZ@sW_w>3~;Y_ zrJk9w6sOx88LyHn5ZWtu6Jq5mUo#cJY{6?@J_J~qUJQDw01%%Gq7xJV5qq~Xy<<3_ zC3)^;75DFuXT%R(9nnDl>gdYW)2o#wi?9jlZ~?pqfDQl;U;}szz-WLWO#bc+g_ty8 zv4qMC7cRHOs#Q-T^RW4tUKd?!4f7$u^sM!{DfjhNmUJ57>n*JP-L;)&RX!?K`W)8p zsl#C9_m>h%7pVQ^|>GfwWetPdzvPCOXzzWC@ zlERog;LM_uuj)%;VkwA+mO4O^C&FAR0&>xW*WvAB#VRP{PAY^Tc$|z8H50v0=nJDa zqHhh=X(jth?0IRJE=4thG^7TSguh9ZaQsOwNkGQj02 z${I4uaZr{DoHwCi9MhyUMzWDX_XxpgRsgo&L;wwxp$z0AD@ZsF>?H6IBn26W=&k0_ z0RS)o)&TZ^a=>N-v;iAtls0Iby328r)#O$}f$oXp>9PN3#OCM*BGpaYJfliyP-fde zXsV~fzjjB+^EKr_=?V0RFB)!H51vA51L-X}tlE5}D#*!isJlKbin^9iO5&BG!Kh-T z4&0fNvP}vkxX=X?CW6aMNE*SIqSJ94t2+vaS*KaR{&ZhhYr*Q*P9L`ZJia#%gp+Nd zFXx@ZyTW1n$U$pJx~H|)=$jT8QkXgGnWAHX*?bZw7&sfW90+m=9753nnbAlE=G2Z& zm6n#}Q`@y$g&94*8`3}DFZSqCvoD|dO6xay>g&#_Er*a?pCHqxzb=nkeBN$_001Nh z00*=Kcnu&N00e2D-T#2IMhzG=V6jAHOHE~8947NmzBWDpANCBycHh6L)-PqN$! zE+pDT#*{Z`s#qFMrqyD^Z%Zh1u*kweH<~kDjpm3eP-xFYhjXuM?2X>e;cv8inxjMR zO7{VX7bg3vB37=?03Ez%)C*&}e(dDtTBlyC<&9;4`KH(@Oi%F^}`+Czn`UkUd->Ne@)&K>PUET+j`5x?D6rZN9^}A z1zn}XBc8W{rl~dI;#i-N<-4zG>}kd2-2nFsNhI_qU4bQb$9@A+tAo6q%P?0?bAdBK zH+Pnv2<@fww4)#xGgRRRF#VrsWNwvSR8DxvZtbbxom7nwZyyPkT4bu1%iQLAebmc z3KfEZP`-M)8&$^L*=io0m$xiA2yrdRO>I-TQOU?%7=cT5| z;TR)RZDP7<@&NiLee;l(?G%Lp2BHd9U>Lft12A%X9hXvaevyokHy1_Z$Ts$QNp%p9 z3b;h>omjW7uOa|Mp&PIT{7+L%C&TiYNIZ^oYPhF?3a zIU=+*maxI4{D1yStM)9OEcM^0EC&HvFTn!;AE)H;KktND`qyw!SWus5#v+bj&jw;c z-FR&p<;*A;PSdw!Y93L!@Kbj*r0G&#xoHWfD*96k(PB#_JH(6T+H8z!6={6BaXovW zc2P;qI`@!nt;!?v8Ti8(&O^WANc_CB6Po{F9BPOk(aF3Z07ldwZr|_!_&5y;2*ZIe zs7!bZ1_FU#pvWSJhg{aCT<6Q3P3rR|T1hTNT&M|pe(YB>quJu?GjM&|9;f~D`@Xk% zAdRE#v7>$apZ#k8W6$MMbSD1~PACM}NiS5sQm@nX{_3B;Ts2!r<3zh<%*`dx!RzI^ zt@8FYlib*~pCMPH z*z&|7XizE(3IxG`uwX1G3kCwgfUuA(Gz$d+p&*K0xSa7z&NnZ732o+=OPW=tUVwjn z%epNObJ`a*lI!*1^~2KLp`*;1b$R_fJpZ0#`6y+!Y?EAf&%braOI5I zDJa5JIiKTbJB{nFM=RMr4YqOr`@3GX!jDTI1L-wWnAtU%sGgOOZ@Ckc>h0sVubnD# z2vMmHDiST$^`8(nvnoQmRlU=NlodNi*lbkc18r~W%S4x|*vridVOKioA%G%j#G5tl znJCj>%iIPGj0gfa001U!L7HYGf8=1=c>jiKKK2kPkv4_ly1i0wg`8g=HZbG@*1zA` z2Vs_NQwne2X!Y`}Gh{<6n#VM_Y3w0i6N(TR-mon4u$DO(FmI!VQz9E3;Be@+Ip>n! z&VLyGrZB@BofASd{yR5f8J&gwO=3n;%9N9FLx|MZ3nG{(%nO}Xx#k&{MMXfM{LrXw zp3%u$c!wj4*qEq^)-pn+xtmpiPez2!;#2e$zXEDw3D3JO2kkjoEX$+vUmknQH6r2t z*E~~14%~E)JZ1=Y5)dy%5IkQ9>Xhs0Cvv*}H^wC#bxm?JG`+O3g|GFn4BKzN>;tsh6aS|3^vGCSn+1-_ zbYKm(Fv^vkllGB?7cp;eensnkleqnrVnxS3*TEVGkke=l@6x^i(K~?h3uxQ3uumiq z+`1uHyyR&>_%`V6I>_0087cRzj@3xjO_pQl#Zx_nc6uJVppfbn)rcB7MKN*p#Wf|L z#TDoN0KdeK&y9``Z|4dUe=%<5CB{`B6tb*^C2=lBDn0Dx3s)2lV8q`P$HrvieB9H- z+*=5JP!~!Oye@S8+V>E+%_iH*+{Z^sZKIgF=6y$X>oNDBL8?lvULR&+*h4 z^{LRDdEw%H_X2TT14UZd?8F$cz#z}cDNO;;QN|LEY5^=vC0eJW;E5mdh5I#ZWSgfG zUh)(zG|%=ACWr3}rEg0hocEAB8=30)HKi&Rzc6-K5)JT)z617?SCMe3#dW0dfPnbU zL#PNv4>fC5re!a&2Yg!;txRue{Y=c{u{w=uLx;Q)$$o8pfz)$42zc#nNITl!ZC`v! zghie9i$T1$g_Xq^?3Nn5h5Rvb%H-5cF$_t@oHq+@k-8($B>_;*hZqH%)a2d>c zDQ-jy@C9ttaFkm)6q8dJ{@M`mo(?rtD249!fHdRllh_uzbzPX3Lzr9ArGZ`zN7GKx zgU+&im%QMi(vrL7hF46DM z{*^eVlM(Dx#OTTcVK!#Hm&rOh^8>~&xdDQq;Jz_o&3Gh1`<+abc{3skQ8H9TEogd% zDk1D-9xX8VR8cKelT&gLf50jWM1V*OWBB+?IbU49QFIStQTtKxsGwe25WM16vVKxm zs(dTPIn;Q=yY5ooi<-^oGSjK^ctgR?%t-Kn;lItM8fnF+wMYQp(~nj+@S;|KE#Fep zi-Jp81tW=hL+>m<9*8!*sO$Jt3XLg#T~JeHP?PkytK$^sZ>%Qr1XCUJ=aF4`@f3!w zW^!RIz^i!WNq0+u{P(-|{o%}IGvG(hrRSo+Yd#c)L=a>clcx-ux52N$Z0F{F&81Gw5r_*%R5cF9hJDDUMCz$aq)l*|45vHZ4 z(7VYGSZmE?yD!GqG>N8kWstaqwB<@mSi?|=+B;};+yJt_F-8yx0{yHI3w_gd*Br8e zuR+0$JgU0+f(GQ)#PY~?y%}{exT|y3e@d+Wftsf4M6ZJ)7=&_Fh%sP}heK&^FijjY zkzLzxDm4uWsdgWTD_ziTt|y$xz=0}rDbH;J4dgcaQQ|;}au+_P&yD-qDGf64m0?2e z=Tjh1Ne}ayqIKP2Np$^B3PhFCt^aCm&n|Z-O)6xE(yY5~VG)vZ2Vyz>VvrNIU-|r% zPh_apO(yGdDj*!X!py-qXDsX&IiSHAW*6Jt7STZ<8x#2$v?&K9H(Rl!sI;9=5taAv zKO}$9una8X>}s=Z=HP>KI#xh={BMCD&1U59}QFmzlXPpDQCve zh!asL#pw#_N?78-*RvP=tQQn(wfV4cbwUS1RLgNfM25rA1SQA3*r$M^p}>`_0*zZ7 z5x5))*gKDe2z$ApQgmCtB^XG2)1Bn?X-~*!!_FRTbRf=3dU^WebL3Vxgsfoiz5&hJ zP$z+EUPg+BN72~<*kn*l*XZq$?QMV#^=0SU+2d)Pq2cNhq9WiRn}eR#2cRo#jGQ2w zook;T*!_acM`#wdc$H0EAItn)D+6bqL=f;L1~1S~Ec=d`6nFV8wj3{K*ceH>Uwia2 zKa&YpFq|LI`gbv?XRic^TDMVnXM67q8OFZ0*%)NwJ^ z7)*8`YEq~vd`&ZeXip6c(>7bGx=zFAP`%J(rvH~owVU;)68-vs?Oa#59g!)KR)#*n znm^hYDor0~+n>m)V{bc4A}D#>ap()6mbr^)q`9qcDcQXN-(#VVje}X&LKHY9Bka1< zTc4O<@4VAJ7%67|NF=jk+s`FliIEJb`&YI7sa z=(|%DM%_x4K1sS|eHh*Fattb9f7-A!j6+iM9rIepM8-hFp3vCN#-&-VE>zUB#6cJz z#T1Ded$dxIr)`V(u1{r94^RG~#5!B{YuX(bbe_!nd_lK>W$pl+>vPFbdpVC3$ zE zo&tyQwO4$1n7xU_J;sNK4~n3(1e<;}zS1<-6UKF`Id4YfqKSt#UUY3zv-(hw>}X&Y zCX#KBz)1XHhrzEb$NvGQ?P2ue&l1^dzP2&xBh~D_Ibj>~{Ypdf2zmd=8MaT!#wc!4 z21Axa`G7LOrF*(-);rE47LT#M$yWJL%3dDFuCTuD6xbMWZt!QFeTP!S1{;&AI#}tJ zZSzfj-~+k$1r!yM2_kIH?#!38xq6Z`AD{a1{0)ij5Uv%fO4E&X2LC`?13ZQeQMkr8 zlKfmaVFGU+R0qmzRNgicP&SS|boe%P{v-QpuSid?P=~d$SRF(0Dd!YsyG50rQ z*Ury?(PFA0g<1rb)MoXJmP=9`F2U<8yFq2n27=1I9@0<8iL-q+iw~m=B6c{9;#!z? z4edZ1R-DL4=T)K1>gMWzTrJ>+@Mp2oxx~AQJGWlIJpAUlGdqhRr%7LKQOjo=;7LcV zMyidl)4LsJ%YS44s34<00<9WA*!bz3u?;yzT{l(m*o57r`wO%ywm03c?k^ZSB601j z67lUc$q|qmxj691471)Fr&Fs>T7h-(7y83EAzEle+x={@914K2OeEqb2XnAQwu6+v zOfg_}DUh|fGP-T>R|lHl^k*Hrx-?2y?1T~Oesy5aZq7*kVbsBk{28m)6G`c;c6b6o z9b&8dtw7_+qwnNhy$7%@pM90Z;@P0Qk^9wFO0T zG&`UBZZuFCDSF^PQkHWBmNLT^rcuXJ-3cL%m#x7*xmE6d>l?&Wj~q;*-joeHE_M6r zZ#=#m2@7H&>^J5GXgg7fq?g>ax8wq=y5!z`gtbQk;G2&|fCwRw_!<0v0OWsV&hAb# zxbnZjs*oE0JnB1KU~qYXkRH&+2Z<^utgsCvYUPW71*D5(Y3IwB>LaWNV*+k2!I=ap zyr2YQx99GM7@JzDG=Q7-;8oDDXVRiIE#!IP2x*)>V8akawe_Z*Rj%Tkx@h^CL}4@1 zZ|bks^46b$9P8ZXFpR*GFT%fAgBCR~+#$WG@yP(&R3d3;oTktdQKo#vvmdY9ue#PM z2_=BVU>(RAHof>vV+vPozTYX}Bvr{TM8PaHQYSvZSoZOX0K8(8msk&j#E>sNGzLOU zlpXjXz)*ZK0mY_{OQcjj7BwJSDJ=h2jQe}*efpFLEn{TPpf{QL>L+^K@2CrKO_r2e zU9n?~`Z}O@)l3NmN93-%H$sslQWqVY>R6XC0g6aIAn%vuAE-T^bldh7q9CbuG0(LcoTcj}GU&S_K-yfHa3>RqFASPF#S%e2n-X zg06>p8^zQB%9H$mA};!YO@M`D!F&k<7fF^5o7>YeE?hgzpPQc5-&R#F7i(KYK?xb~$q&3Ag4jv#t`Bdl3BQW1EKk7y7eVvVe(TXEtXKQp*468PT@hw=> zL^xSxr;>R$LChz-LZ%V7eeJCcy1t?@kCn|lg>%s= zLm^y&d^=<@=Irp-39gmm_Fz1X0k{4w6|cWK|B)e`t0pwl(;cG*Gtbx{NwrbgkLt{h zd>Z~Kxu6eVGN`E~?kWxF0^sH--%10J%{TD>jvX7&i0p z^@hKp-&Dm#3McL&rUrTN%t!Z4+^$emPN(_zi+Pe@QU#;F&7={>z!-i8auasCbD1+v3OF=ZHFoTvtP-g<(X)#$3)A zJnL9#r;m&cx9!C81VZC0$lL;Dk^~z@9>A`*mDUOG(cyTDmNEOiH~5UnvQ)9wpE2AS zyChe8l+H)(p!BE;1tyEM;VpV3HfUYNv$XIq=NYdSk=?25&#!w{F=C*+nvo~ z&l(2FNv+GM8Ol(zE`TdJJUH;H7}70k<*}y@Pf5U&)>pP(DoA`;j=7&{%HQ$1XI;pe zplSnv+0Du5dZUGhoFv*laPcFo_!C68$Sc3qY}o#YoCY54$2#jE2Q#lM?p`CAC7-_Oz4-<+3CXRi&guJcYjxe2|s5 zQH1(Z>ivTmGK@y~K23>;ivvs>aXtv++`fZ%$!i>_Ux#rSFL?1#5RD{Mw;-C}rSk&J zuY~-530i5Zq`gYQOml@p={EHXq|${#jMArR0!+?ppxKn za^t47r2}`il5v4(fnpSFDuCRP?QCgeX}IZQQWb`5J&H~YHxRkZlt%>a(farc%h|Da z?|>+H?$PWsswb;kScX%SyCSV2PkbNysCL3nWYH7#z7v1$4u84-rjf@Tx&LR|9q~hC z8AqWa-Zx;#G~*6QDBkxv}0JfIIj^fY<>1)k?3r z%#{v&D?VKyVo8NGglD-Dzo-*$j~qBgAloS~+)62_ml!#Zae-dU{RRisv+Y9tt8O%F zELiD(Qi7eyC$TN&@`d{i7sq5c%`e3C)tyZK+WN}tv3`446ss(4x-$1yI>O%G1yD5_ z2#3^rAaYJ9ZD(_FbM=9Dnwa_}Koo-R(^eT&!W1h|2$a3yn9X+-Ue&7O{9O^onM-)= z9Y~l};X#}9>oUP1bTmm#b~lz6;^e-kEkqjULR*V`3GLNql=1gcWEJs_EnTxd@3564 z8~j$fG5(XW^oKa06H3UY=!s(>wiu1Wszy`0TUoH^r3Q)@h?|154UaMfb^noXDPuFGCS#s>082)NM8Y%wTw`_Pw)8*hQBE0^`v2nP~G+_@V{fE;@gZLu+G_n(>sD#DIpD9}d?s zhkJr}$D7J!9XDz(zdBy1=N0Vi$Cx6tkJqsia+*bF?n7C3kFGZ5Z#E*Jxr!@mZ&T4| zjJ}0s;{mr@(W#dKcl8mDb{O0e;c=DQv3IQ;y3gizo6PM@doqJ|dF|uM7_0>5r4?Jl ztXP5Vv{OP7V*IV)bH1BJz2Eyp=g<5!F+Sm&Fuk=nuXVllEAcYlaJTA9Eegh!&C;8_ zmEsM0Jo4^_=a%i&!CWCG@iKA@Jgf!73@t})V)(0xavd8A?rnK^+MRptG_|g;SnZ%5 zcrMgrDYxpS5!_jQw@xBC%<=pCh{qZwDA^s1f>*${%Dd(-d`qN;frB`vDIwB#8;~zJ zD`6!%qn{-r2SeZi0OTx4f(KnrQ?~YA2XTkstdwBqtGVSoLlDg$|8A5R^Sh_S91_0A#}LgLF-io6GK@yeV0ZiwCSc zfdD*aBP7P3sUoU_P2K}2%u}jE%uj)0^QplrsSU*sP9S%+89C>|isqL1BLYE9>8@&q z{jxT6@q`R^u+$hzp^(mBrw?vLj~w7CUH&klSgwq>wQkJK`XFbb%P1{Tc}MT| zI5;l-)R4DfJS-H|c2wn>6EV@H*)zynFuV7*vaU%0HUyS9sdK=FA`P$zdyM9F*eS-d zs18LG7@CPK%HvV|O14P^>}FSLO-uy_#NSgn;$BgZe>tPN@@bRbfd$3O?FCy$)}Q*#>2hBV1Hekw?%Fx-eKZm(LX-w_M|{{hflPg=_wijSrN`*&y( zZJ~+6d*d&*G)C0uGa6uZltHv2JP?Dof9=mK5D`D_e#ZtzP%LK>C!2~>1F;~HR7es(XVJJm zN5r1?H(+cQ6*(_Dp-o0`7evq#i_w zRfo)iO?wnLbBrW?WN-*rO=%o1%3_@YSi2sbfMY<_hBhr&gzT=U^WbAYUpIOm__HUgqB@;)RHQ<;`|j%b#6Qt&$J|E%?OB;CSgMJru~O)Hb}c*#&rGpF@< zRd2BTr1z@$iHj%dWIiWILZ8uYP+Kc@ct*TeyaEDox}VggY#tbX*OB(KSA>V60cA!5 zKJRipr>K-F6=jPM{e0YXMFcM0MVK_?TqPdLjn$k-N6xI^kgJXBrXusE%;i#5hKBPT z!1%-G&-cL%?dUQPsnT(lgKeTv9Vx5cn0!f)4_e(gJ_up3hn-Ep>}^OukRuhEbUO>g zFsb&Ne=B4^-mLlpOWhECmVp7UUdpB($MgMYwp?XHunlfcypwd!ko+}0sX>AVkryW! z-)e2APLJ{Z4Yko$iFa%h;t2JGLIIj5qDfA(?e#m1wa_x|CV895>>M%b;QjWfEQ8GM z4W1zqmB43xG1syLS(8+VurW=U`CQDMAp(Z0w5F&@`3(1Ps>|{jb4RiZX z3S976HH}!mXed9+58V+DmJEibp32Z9M>gmA{${!uAThT^;1f#kE9Yke4hGJ_rekT4 z555BMahLY6Xpq)3XvMb(@b`1(l@4%8+#$JY%SRGq#3G}GoYLc+Exp*ibF~3R12}~1 zw%7MSX%DuW#f2?(3le^N0Eqhto%L!3DZcJ z|EKTC)^k>sRE)q||GMPfoEq6F-)GyHGW7VF6PqMmb@Eik>yjY6(hKvaIY@PF`rlnT zq0x;~0Gfb9tU^y>vFVF^!pTI1d(EzY!6*9k?|DqOw}-_9xyLe#57HY-(@v)7b;GLg zIbG`@SypUMORA4FqzIK1;s;e^ARWYc#wlOjl?q@!P5ol?qQ6Fg3-*Pu2yENQMy#88 z_k=wKoibsVy*SsCLbISmp~)2bcq!eE^Z6ivUnxEypZ$4*Em+OWjAOv$=_d`io%AxOn>I;a&^<_21S7)+ z$;Nrh^pNg=%fAQAjmMvMJQ(%jnx1;2--k;8zbT5*z#pzbtAFYN zou;TdDTRyffi63KyC9;BGP|az;@S(Pyf?;Hh!bspoT1w60|5e5BJza~$V@;Zd~3AY ztT50;a@$AC-%%1m?OkD*-19}8i7J90WNA%~z-RE4!H-h7(jkjk|TZT-%cktt!fUbN^a>s(8& z9JP&P-DCybZz%?i=(r|OjqC>(*HQvQ1B|saD#T|lYZg=xss~;6(AQo$##_98l+EZx zhLB4gsfxg}5f^p`59i*CPI#%61X(SCZUietJ<0Q)6=I^u-#Q8uvH<=}IqN~}Z!1S0 zxs&EElx6KtGY8d;ZW~5o^Y-iq!)-+txd#7~<=qs=L#pPNkurI@Z0R-P3dDt1{ZXt0 zV#4(ti4V_=y2iMSV*50}W%d8nrDmIy1dk%Mj8S+Qyy6Mi;aPejT%gP*<^NP=w86%A=KxVgh+{;;yEe@sD&s5p{SjWxWf|hb#W=a*L#ySoZB%$)ej%klJon2ID=rtj z!wy7{v)z&*U}L4SKA5$1NvuVOE93n(>kkzm7Q0s@>gtl~7esRfH+zO`yhZ}_j|QYd z+IXp`4S#|8{PHViDTyDVLj#~b;JptfBd2N#X^0>$2KDzY$7f${opJZLxr@^}}x ze100NqAAX>ni3^3tj=?Eo_3(93^nJh{K*58vNI`hZGj#}osoreVPv(I>mch3;(xtm zI(tJEF8(MYj!ZF$36F%g*)ojuvV+q2I?GD!vBCEjT`V(o&?^*3zI1A7Ta>^;_pS{! zKv_)5j~xq)OwUlYXuQfYR>(W1Vl9)RsT|>*B^bs-1Qtbs$v$swK6mt5uJFI_S)QM& zz_*RHko2tJ9_NX{0J!c{vt)%#Y(0tiq4QESha=9uo3R3Sh6}xhfs=Hc$E3*+@ty6O z6m*}|Q*miEG(=B`<36~on9_S0(ABR3oEt>#%eb{glip(8w08~3mD_Q2K?Hxg4`nOFE?pDxKoj?* zNB;O{2?Tiq2OQLXz#3C9%EN`>%f6t~lPPHm*QIXE+>!18~B+{!Dhumaf8Vkq}{OZTpGRZ5Fzv)ig ztQAyC0K+TuE0WLDPF?GB5SsjxINDL}x&Pim zUq5r^&Fa-aY`@zoVMYjQU22&0t`+8W@0cr&G8yx$H41vIDJVchMaC+L} zfSMC1IEAcDRgN-LPFs4vC4Q9(tw71pzyTOk7*I+K1&3i_&{!}g6bXX?VW3!uV+(up z&GYTg4;^IP-DR>xYb|!(OLRN`f9u0Pf$381OP`-7xo|fheuv>^?L3gTdU>Gv`#qhP z)BH#6cULWNWiRfR|45!z3ogfaolRr(t=q5bPw(m3mz%qoCSL9|bLSa0%!V^jHeCLG zYd8Cb+erdhurkTRqewq`y5_?n52e5`rl|fsJhEL20~0josy+K zA&gK9pnSvSXD5J91{`(Y^^f&XY>u$I?a=^T_nI^wjN0*?ajFo)&|>UB6mN`(ZVz*sI88is=bV8~cVWeO2O!BB`y zBqa!i>xrIy{j$Be>z;VmeLM3>TIF>&aZ%7W_g>G5?KZtRTNd{Ed_K+hHJ_a?zWtka z`mpoY=9CS%|AWJ4-u~UZw&ZcycRA z>xlDp9Zs5UXV2aC?N1y#|K#y1H#GnKRQDI}^2-ea`u>qO)wcYaFuzSa^Yq$O0cY#2 z+mmP_>fqh^mZ^N0+9x(sV3D4w!>>n$)>nkH{(SAts(ZIu?sMTUg)?#Q^#yA}9Xr`r zlt+#>*#iVB*8`KyC*Ic4j!vYR#j`m}&`n=wX~v6F$QYD@50%Jf}P8bso0>gl?P(&dK1WxV69CPv9+oe{pGeo&AQdHmx z{9Z+V?R%{L-YrF@Z=3x6r}OrD=KJO7lSMvH+h3!-8UMLFYT?#?-EOCM(jjD>s6Orj zwppT?XqGo}DQsMLbe1;GFeS8a^&N#sEPeR#Dy)%bwutH+Y#}p1kvX76!#(}bEDux7 zS@{}IiEc@FovZcfR36%QIp6&|`MzXW#iGBeYL45rMwTKm;UKuGw0H0&+3JY}*ix?z zNkA?COo}dw@WDL5V8}p#BY*)6nf}ch@8R`U??wKshNx&FpUfW4|ywp9_3AsuUwzA*9- znG&l@i8>@}>(QgpFKecXEpZq{FNE>u3$XAnVrrY69v5uOMJx^9Lf1Bi<&Yi4Vo!e< z!g@LIw{~V{RsBW3Qp#okTlj1O8PrLPLXxwAfzcP*0a(P#ZKKve1pTNL4YN*j*IXSS z6+E5;2Ki3{0l@=%gd|<40H1w9BTIoP#kCQtnb{uD9Drm8*aJX00MHM-0SagLP-E=U zgvJv!F1hNpu|0#1Zj}SBdyhVIRNYAMRh*$vNU^{w4qd<|34biMJ|S&FIS+2=$b%vjFH zKL-Fc$BGMCV$1Oerc+-Dc z8$H^0Xp?`hN}zwO|1$s|W`qU4bcX581jNQ{g5?P?32Z-yNwm)n(!O&KmeH2~%(GOK z+tpv;wR5VE31TIlbhU0;Zs$9|Kn&DUz^QUP_{}@PTYIvNcDaDp(&bR(UiMMtrv)VB z)Fnx77ZHJ32Ie9?ps56GTPe!iq95w`*y8~Pla;0 z?a-2*ZjR3&t&G$aI@chAOb6+f(^WF$AxWpW__r)oPh*{4E;*31`A>$cZ$A5Mrks3v zb!169PZmkpja)5B8ZQf{sX*^1uv@}`vNITevuGQyKq=5k(XoI;l*tk(BmtuP0H{hq z!9zf+kZV0fQW@=0yIt`ha`;;blI3Q=V<+n{X+vZM3q{513AMMwaUZ=*9Fo}TovX91 z4a)!WE1!4x-^!2C`@HJk1KOkJU6bov7tUw!5Z30^21y_3r|KEgDO)V3)mx+`eeV88 zU{2yn>my=?jN9mARGGU8de;?d3Dv8#y#-T>ViI4yA9W1Z?N(kF;zstSi$;*%YI-cZ zQBck`wJ8}7m{QSop;OYO1(7|FmG4Sk$xtcboA8jDndS$e7D2OH%+83DkpRhIn2J1v zAhHmtiV*>G3u{#H&~Z{ZT#3}lZPcS>l64d+9(+c=g<-Y~h(ExN001Q9L7Ijle*gqY zUbwJKoN8wmp8PhAHo-;FrkO&zxqwl#T*cxdv}Rzg?xu28c>Z#eq}2_U}| z!mU)Ps=x0Z5>2IV-SbFtN^N(M=F>VuhF%9QHYDv^=UK?CY+=g};>5O^F}A|NF!_RH zOioyQPbh4z=rpE)}xQuB<^jl?F>kph2bpKTGvB5Xcvnp^!xszwMD{-A?e!}eb zZPY7E&R_z>pl2@bql z9BeIgVw&`UD4NW0-ywFkTOx%%jy~q5q*q4{-B28y1T@ShbQ|208sjd8Oue9q{Al{| z|MtDdBjQA>O8^dl&H~_1-IX*5E$o3iSzY`$qA#rXooupuZzb_?WICsqQT9W;#+U`+ zJ(_qIov$m?wQ+W3TGU$=uD*lQUpvL{%kt{TrhUp@Vs7;`vAe8O?q^thF$Y+Rz?Z1EFZo|}cnxX6nmAgo&uwdn6AneiNs9iD ziD{gSFL6*3^=O|trxsI659c^~TDJmL@4#zYGQ-#l*xezV#Cl@{FPi!E>2KBl(0Di| zNm3SG4d-1U5EU4#c=Ua*A-mzy&|PjMM& zb-@Dck7;#>b$mM2ggeF`vg`BYK7LQ;o_ew;)JKP+2KKMvR zaX_a3Na%p>qin@u){cAOf7Bl$L}8(TRdco(ZKA+H&Asrw(i8CyF(Iw>dr-FenN4=e z>lqhf-$%sG4%IVM2mOu&P3h_Ks}*bj4y|k-@c8wcWt56NJ-lzhTAhb>q|}J)dab@O9lQ zexRHpnhLs&Ke|h{fu)K^I}h=Vi>V-Vr-f3p$c_xN<7)Z|$VH zJKfL$GEsL?)s@Lys+bDXaL1OF&NdC0(VfZ`wm?T0WhUwR*n>zh{SHKjr<6;~PBmvo zb;^6v`wH6~Ox47;wucGlzi81T?p8Au^=4w7QcoL1I=%kx%K^(;$!rbWG|k)a6lMUU zL;=`9nNc_`hbJKOQ>VPytHL||JR2#FMv zy6yqm5@LxndJ3`2g0aSUuqQ)k+r!{Yo8vfhdu;|#*%ybGlpyLh z3o6ta&2$?daYTUV`cXRpi`7kUe<+jY5oW|dlvZ2|c5>bH(c zsY!t7nI>j967k!dduV!sKTpD80l&~N!Il7E_2MqCSV(nb3R$dcMl)l3y`oT6qacm( z@==-S{+Xbh=kZpk$OoIliBCj@iyV_0$(g>Ok9BqEk4w=~px@x*YbRH&oPMwU1?@&_ zh*2-E9SWyZMU0r72|Bu;Mu(LG)d6{q`zeN|?OKCKgE#)XEVG$6qnVXC1_$pCmp^sq zM})hQ6y=pD0@vl|JOc<)SeP9`7!`p)?`Ar{$&o?Om-gq#+Ofej;l|!5nC^~fy4h*JQXXuh3qVQafa(f(wf9@q#XkhquOU&HaJ6CNbr0 zaOBmV?)X&UIocU%eG?S*bgzVAxrG$|r@D(zBVW^~#-imFDI4PJ@3Drs)heSZ@7i%N zX>lSRaFVU-Ss|Nl_D>sG>sVAW6=gLeH)PY2I7e;M^iDa8TFGCHH-isDplJ=7uoQ1U zr-BSkXB4MIY6(j0lr>_388bRJNc3vM6=v)-?W?@;HjSWff?MIkW{xbS#-WB|`N>X6 z3`|L?s5`dGUrn|bUugQfR@~blW~XmOSgx02$mGKOggidZpQGHhN-q|LJAgsIm_h-( zRl9Y>OhG#-_F(<~cH>Y58knN@g#2}Ju&M8jZzi}f<8S(c5`Y{*8nlX;@H0&lp>C-UhSOBLU!fs*D zt)hgZ$TgBj@=*vmzu!{-tgTiaQ-(S+@t6_qc&I894l{ehyS(i0NM>Caflpe^ z>1{<_ab)Gp@#!sk#hC^HuTzml)ZNPT@)1=ezFoC zXSjCGqVPw!p$A2r6VHlp)=j+_jk{|V`G8U}M;`{|L($!zYfcUHupw?)MaG$kX~O zlj=xS3aMaSBDLwO*6Hj4?Vha>u{OCX;zTvW@=`Nz%=5L*Vy6r*`gneSxx6=?Ted9% zbGL_%nOQ+Eg49`)McdpE10{wTVYBMNs*!+&nZYRIZPSRN!?gCCY8IFkSrGruNpk*t z1+knk6X~WB-(&rW2^$$)lQG8WXZ*hCcsC0SjXO5HmT?)rh89_Vff372%5eya!7AM; zw03h)a2r{=40IVvKcli@1ZHEpv9>^F`2QPtVw;h7kns)OX1F8Ap9o^OG}-_X3AR_3 zIE<(X$UDR4@Y`84XF>*~ZjV7UQDVE(vCVkzrUz4QhxaV3@dZa@Q1B;4TCaN?_~^T} z!}(~akIE_4RV6Lir9o8$aDPymA|eE(J?WhrCTQ&WC@;h)2`npbD#gR>j&NV*9yK65 z#dnO4)XiT12Bba2gM$1&7N&0`%$>$%*|R#4Ss5;%PP|(=t-ENO7u7}yAbGucA9!5U z<^Nec`500mGezR3`ElFQJ|xy%F^LYUbSl!;9@{H;y%fE;)-!0lXBpdR(|Nr3Ng)@e z<&2uR{hNhxHd0CD@QfD5IuQRHj|HL{J(0Q?TvY3juS86ODvB1DWRF(XL_%d4CwGFq zy$1t~jIE~x>m54ZH~V;6o}8%R@dTY)-?k;_hxU|-%tlvl{Gf==nKHLO!L63YIv|L9 z&@`bG-4Iby&*44Gr5ygQ?Aoa|E=c9`4>%%4@XJUt#1U-(dj5E4&hfb=va$h{x>~Vn zdYS&xQ7>0-z)FlM8Vjar*xciU)KeFboedLzYm&B%b~QqUt76ov^dH;zNBKB@c7V#t z#BEu{fw>m88}`x~DN&0bWQC}{wt|wtCh%)Skq3yc1m(YdU(D7S+ zv-2`9L7ge&y!sUaQ7aBPd0^mP2$#jWTe$e~gy{rjcF;6bB?*5J5-7fI$C5Zc$+Q&( z)KeK+BKz#EEOKBzaA4%a+;U)VNiv9SrD$EHKfqI9?~|5vO?0c0E8-cCTs3nGFtQl@vPK>w{FV5&=JC#x!4d@=k&@+%84T71cp*L+GP-i6jaG zJB5W!H;)__wB5wvPlHTL*P&Sz5K7WrPOzB}JgCgi z$?s-r8e3W#t^flikt;2#33kykOHk(d{awxYw4a;%u_^7}vpsb!i7(F` z`aa2}^Zd7%n#Ers6j+T{yHT>={T;AKr+#RL@eW*E^l_r?i(Y+;{e$O&Z7KnAMy7PZ zI-*Oifcg#Phs+I+5Xf%i+dkv2Ajw{3diQ5s+CJM5(nO`Kkrc1Rq^l2vW+Q3f@#srv znvSBWG2&2Ha2mvvEQSQLlsfhdpSOY=AoBkIv6jxxmWBBdC*MtAsm`5hfijbcL^qXA z?q22Y>7X}{o?QWUkIghCOrM!+8dbq~^9hW!WIpm&N3)-H*z@QEJt0v{?u?aX_U8}E zo7Mh6iV{M~F8OguU3fqDJfH&Poz3Ps+d=|El#p!sb;@L;jzCk?-4aQ0!rQ8~K_rqK zT#CETUEnb*R{eXPU{R)}RNo@=7{l$jTVvWH@*1N*OS}GO(o$lZW&kM#yu;0_>R zWYRtS!kguZa1pR}{uHJ&Bt9dSW=Dqy62gP~9J}nj)?RH$=4>Yx?IG#R1c?C_AP4@h z0&m}0)&T#oUq;d-+k(M2%wJk}%R67bIIPo5W7|SyE5e>5IELsr!Fg6!j*$W!@u{mX zxdZ^5mebQ7j#qqfi57H*^N+Cf&>7o<^3k*(U@x7ORxC$VWr&G-a?-z|YlEZj7BH&~)oEltI`ang#2>jPQ^a-(YfIGEq!eGyFayOafoxNUrgohTau`E4 zY}ux<(1o6XFPdZi+Jk3yVmAO4DigLURdS?EEl=U#R6||bEt+z z@yMhjcu4IrBuW4q-4aCi4oR!4)ml{ck1G1R9c1Lb>ke=4u$yuqP%niAU82mNvDBjm ztZO{(LHvdIQTzoR;2d>VJT~%2=-CI=k))Bh5yrtIts@oMV8&T&r?~Ss^yy5|o@RzH z9o5MOX0kJ(!XbUBk1qm$ zPxCptVt+d_cgCa^P%-Ia%II2M^$tKB{D*rW^D*q zbD;J-l0&8-PEY7=tQVpCFJ8OJ^>9DFx<~k5(HwjY&g&~&aaxg9rBz?aW^@;K7|`R1 zMwGINy@lMN0GK#inK^G+EX#Q6|NE=gT>tYryHNK<)sjTjKf(lD3Q;f&yq=9Pe<04b zFo|wU+$NE?fgG2Q!{`|kIjv^sNwGQxLJ%1!fG=~0RKDPPx;Z7 zcW!P#{v5B|{)->p9_oxc{}Dhf2V8Brc=fa5Tuk@0JDSU)frAQ~>x*A*NxK|(PP^HM z<1bNf_z4YDrYoEWgvmH}pP`xW9`WO(x^>`0_&K*Yr2(uU5ba4?Q&&9%7>6B6zjdu4 zgVeep?M}S^8gW0=SY}pmZ8l!Gg$Q57%sZ*EsWnS#874&wbzJlQVYfMQGPFHmA>LYq zMLY|y$U^+xA^h>z#5mB%*ivpXi+$GRPytlg(4GQatp!$9o-JYQcgXoNRg61YhzT`2 zKB{t?rGk_8$X8tCwA;I!yr~W_dWj|C_Zchzd6z2T+D6t0FI^6miFH}KNVmwEwbqcA zei{*egvU5VCi{vs*=71_V{QG1zb{S)bRjh}F(3UT0vhY0(Qk3_)z(haIH2Z!uHNL2 z1?G>b4NTQ~3=$XEI=Uh%X5Wala4&mJPF+ydz?1zjs*9&@TS;a-WlodDR_<2L-#MSF2vj*EC|RH*K6te$gzO40~VJ_EcjY%T}ZboJFI)j z(T9W|N>S^EYpABQVE0ENkISX;WgCYFrhreO#$&*KwBdvd)ggXTwvc*G)`O3hP2h|R zTS6x>#?QzaR7=-W75XY{R93eO_`x1YPtSPsf;y`5(&pV2sq)^F+X$?wVG#u@KUNP$ zV|z=j$ET-yc1IzMhWO>)chhG0-Oa_c*HQMKI*^Macj*G3;EJkayzK%j#NnUd+9c0C zauLv%Csb{$0})DUeIMutC7^(|d=IB1xeva*-+L7G?uJ*$z(aQIXP{V4+IxXKXzuKM z`oa2-!YKMi!NdgvomTKjAKi^gx)4khR9OQy?d*owwQFA^2kUC8+Y%{sKhR zdD%e;)q7;c=7UZibhc@tZGXVhdh-J6asB`?jK=vc{VPqmw0R0?Fq@gKu-qWyeaHf>NSaBV5Szf}qJ3IaLYWv$w-936)u`l#B8t-G zNgOXNU?I*v7)D1H)s$0cQxjsHlb*ofz3whI zz)TDN#uwJY(HEO{^ZT`$jnOP%`SE4qyly@dRn76w2jgW(cZLm`XTb=Wu5l{!b{oarJd-2et-9hL!pk>wRF|E^k#jAAz!@b;{H0Z#nZ3-S7l z6yI35BHE<(GXmbl&Wj!Gent5y()f71R@DVf`Z=v_JfRl=#TV=g0Zh}iL^|+aDLHa+ zAN8e&hf=4$;vy+Qc+6wj8M;}Fw@jNYtAU+W)gvPKPVYN?11kE_*4;+eU%Y%YFQ^7* zFx($I^Mtb~KZm8zeV0y-H}r!*6$dn>Kh~%&^jcNt;tMHoLqO7Ip=i39vXn#9g1S%w zPsWQDa$T$at=DHGh4QYH%gIYQbN{=GS5(BnCi>c`SnG?L8@q!8_;1#D8s z)~|KgS;Qs@(a+OnhDte9FJqJ+X6*U~u%qlddV zZn`eU;~onoD{hr?^g=!bya)|kUL>YJ(87odv#(@K_aTzO_kk(kB><^1 zG2hXAm(iWnJ~DM8`xfLS1?2ZpGAC)Zio^6W8l{kH7 zW{@~51t!E0GkB|S!K#^zhXqLRULifW(rWhDTrK9@pJwl5KgD}Mm+%M+YT?*{XK3|* z0ZE_}?hI{IkT98k4Ez6YBcf88dWO zfK`InY>|y)BPwI|?oaiG;<<&7SJa~^?ONr@jR`lC06T5IX5Wm6J(a4z9V1 zC0C%xN-i8qZ}&79Hal8)mm|aQVR@IBqva&r>4NCQo>Y5+Ri)|k2AmgWwD*r!zN=hr z5_1>(F^8g|l&g`X=xYr0M;%Q$0*kvtj~bbN8W1>wMOXm~zdua^-Yp+(MDzQZngVV9~YIUSbb*1{BDx*GE)XnWG z7B_8b4i;Po6WfN-e?lQ(6}82J`!kgQU@Sv#=Nz0NZw^D#*ztai10k4&=)VH_;0C_STICvRs5UK_qOV`*E-For zNxI@H1_{R1hE;NiA@HEuNa5x-L+)DFmb2(cOIKwwba%F$1Mm>SUEKE%hF%$P&!or4 za@XgoO!En%be5s{ZQUK4j{buA*(mxk&_Wme337P#gJc)rneuGH_7NinjA zn?*#~IwZOZK!5U2_%E7AO06pwWhFMJqqX}%zpcBd8>l_!vQ?;cr&l+4+!pJ@#jleW=yh2z0))~vMeUd^)6ljc@CPZtb7Q*|9jQ^m$ zG9%ZBtGR8Gmc;$=xSb(0eG!kPXq?jJ6>KpsV(IJF<|nR2PNr;_`yo@K${E>H?$p|E zC=(vw!ImNRiExk~DcbjQZD{dHgN!{tMac9pKSiafSSmvtd^ZhKKbwOqSqSJN|K&z+ zT!5CIoF>fni;;$V1mRS-WYo{z1y>6Uhb%C-&*rw7>xhA#K>zq)yQ)v?Fw;aeMh>q8aVE{PS{GtK@!O`>r4UW45|HFpy>FOa zV@hL~2_{bCUuoPK^1cy28;#JR(XD`|hcu5hA7BwfDvng@;+AJCRk~DsOZVcvmDs{} zXAf~%a@EUqHQ(hw6NO@E&E@W(R);pIMa)!u`y5JMohR|#RHGypv-J++_NL++G2`^V zP{$YS6QqdRMbi&nN~RWATBM%qNCd*WM`ZGg8QnyiNi=C%40rg6jYn&VSk8HVc1>Z$FW2GQA2*>+DA{l_p6NE1q- zP6ijp>`vv9&5@_;s|gh8jNC6YWUj4@XgN1&kiYtv&Sb(8FSWoZ!-pFh-my=hgF*3g5^UUb`dV{C4C~C97W

    5m}9pG;;f>vd4y?@ehf*zyZ<)F@GKx&EgC9ZE1lfO1hfgX2wxH5#Fnox>Q ze8#hQCcJe!ctk}XBXzDm+TH+Qganc>IlK(e87p)<3qZYP3Vd*}uHSHZ9L}W!=o>;2 zEo>O?lFT4d=2$%zr?dI_8H3H=&8qCUz!dcL{AcUDf4do=^pIl#e%6m=jOt#Jd18Xx ztiG6u#)jH*>D&`unx8|afnT<-JxusweU#d4P_!i?wQu(bR%d7gZ0aEqwx>hIqa%)| zT}(kXb?CRZ*&unqfn8$1gYy7PF1RoMNE@>@7zC9>M*dM@b^nu(XOh=KzLqH^I>hsg zQk8}Jks14rcN&^JMp?S2uWVV3P@R#iTG=BQH5p}4Z;0*%CN-iSTXs9oVNV?lRS zaxUj>suEIsd|a^}=l?N;p$8hqx?%H1S@DGEbefn0kAd11pnl$cA0zSB`pMu=?*r4d^4Yoy929ROS$Vu_s5GwNngKgU_;Uu^ymgX( z3Y&VR4Q5vO^^vI3W@^Ljm*ANIQ4g9Np}P0)By`!=BHSSI@u&=H)O@Bgs{K1ar9o2C zAi*RSo8232W$qwkIDq$BsWB?BaZGEMu|FXP5IX4 z1p)Lddw1G%9=-UP*E3eIl|=@*F21om$E!Gcs_U2@w4HKJ%xw3?e79Ynm)Bggx1S#^ zP1^d?zJ5nemtO9{sqU8u`*)!);4hO=wm-jLw_2)tn*o913Q&ZC_4fNx9$^reOuM@` z9L&{koZ2*#G(zV7_gM_L;mF#IoxIY2S5i%M35~aamMnK6w)J15R^t-ZJ4OeUJ z@x)cAJd7u35SG0I+}3hrmxZJ%rg{OyKT`#WeI`dUGsMu=w%s??QWar_bwPTjO(2f$ zFgh~;(e?3U}M4!oSkv%TKEhGIw=eI#_-~kMo{*9VYXu@WtTB%a*p2LjsRxYNS zlxR6CpNro*p!3!K4YSUR|240zmUx4jmwoGJPmrXeVQmn|+^r8f=u0I|J@`grV`|%h zRjLgI|8lKI<*#P>=v_H9GoICIKAmbF?irCH4`7^NKZxry1hES~$)hT80o1~b)5ju2 zYlTgSJTpkvuw5bO*zR<-ak`6C`yHl{sl^@poonny<3=HN6T(YDya-uf=^g>X#bsfs zv8hF2LKaO=#dW*QdtO5=;d~Yq5+Jnzpz*eVW9+7Lswf7&eo|Z(rE-kVcntvQ&1zuN za3UN5kY_thA;omk83w#S2uu+<;&+eeeS%XF$7%bGh_tN(jJ_n0a8q#k0ohxesFu5tL`|se;3P#%Pw^1t} z9*#FQAQ85o_z^$NUVJNlpr1YG{Aax;hft~BQMRZRQdcnY3T~!LdP$p|NG)&Ds0`Ez zXc8Vnff49#GD7oEmu$mNr4Jd2GC_cspK2i99?$7Fl%kMoW3!Bwf*{2-tS!U8ifVbnZd-4efNkm$k-_XBSMq`q4~iXj z0_GD1)sO(Bhj5*gsg2cofPDZuz;}S_0rmiZ8~{gIhQ0mSKBs7Pi6 zbFe9mZx#q*vJo)RWOJp186=vz-1J#WAg$?`Nr_6kU`n>gKYrsRcmENc@Z&vReQy^B zO)P7;NHrwms4S()Y@UnkR?xQ_HwGo8ljV}+hS*0iwPE3xuJq;GZdoF#KUt*_iV#gC zNx;3c8vF7xfJKP3~*ORh%LvM)6v~@y)N_{4;7}M>wou#@UFbA1$pgh>4fXg6~41 z=207!p26E7HH0J1OcV1sn0B!f6H0XaFrav=zIqXW0Ay*aOz<=#h6wN6+YgkZZe3L( zMz`thqw%&S(7kj;`$jnx{IxH`x_A?d{iiZ4!I1~}5x@WdBB(){ra$ga$iFponV{%N z8mxy1;Ua`LXjNj7NOF2+8ZcYUTlw$#e!1g|DYo=ulymAZj4eDW0UhJ3BWO5ono8(R zLaU+JRQ;GyW^xyH^w0Mn_sq&6GF6oB{WWtO(+o65x~&kL=nsuQsZkCe5w8@c5mn*> zy40W!(=tjk?9bqA2bY%2{+IhnkgpFQ#(A=hfArl5w=vCQEm*rjZ+SEnoMq!)q>9M^ z<}&hOseH?NSnc86lx_}E)qFHXSU)2#ARx?Q{>D&IK<)tAjyt8qwdArsHVHh@BfUx) zm5lQ=7l!YIjmCZ;vccC{`|N_2&>NO~Vp7)o;kUXbQancwAG-qrIf;~$-*SwIqcr0; zFiTI)7?QHQE40oM_oFx1k8d!s`TW?@^vF`dWB)!J(q5Kk>_s1=_xuC_ z#NV;e^8*R@yRDY%3=SAz^73U@<2^ zbLr1dn;>aM3jW;64-MEk4_|>USAMVui?9!&@_qOL?aqxIW_9wkMVE#^_|u8nh;wDr z84)<_P;b8}M3rwSj&2;VTv^5iTAj#uw@9imtt_o`wT{OWOukA^NR-o+~MGs!GtRX+(cX+@ar(h@^C%m8MU^>Fatj@wj{;2ITHl?u3`#wn5Zf^6mKWC^H9jg zYZD~n3Jf^p9#&Km8 z*aQr$E}2xyw$HcZAKT#dq6qtFPSjqp0B5&k;4YX=R65 zr&HeEi(S{WMW?@s@UnOl#W>**s(4amRS(NXit)tB41?Fe%C=?B|JYNXoX`9iG`;Yc zP*5lvq>EemTP&PRI?=5nU&o#E_i8ryodei(2_ZN)5OQ2f3^Tl&xS{g+_I}4z>8^)o zz(Md=5e?KSs!o>gkS-LnJ_se6&m<|N+6lR*Ubq2rUqFyM# zqV7<@p-C3oAhe2UVpWgiMOZTb|0M=H&D}hj8OQt#@a5J+=K#IPR-BO!SBtesM7B6v zK-B0ixQMDs*(v8sHpsTVe+r(6s%_aO;CJNS%%BD<%64i-0J->w>C}5D0m@=8M zp5m8aNrOQ=5twvGN5_~0x?4VQz=4eN$%KKik}fKNR)Jz1GpHosEdyM^;R+-Pf;)=M zya=OG(+d~la|a6tJsN+0A7*z;OyeF)!PJPtd?C08To53z!{$FT&i{Gwfe)eRA9p^A z!vROp32A;uvhCwYNRjj*p%3@_o<*SNc#c_zMHU%-C~UYi>H!UN^X}Lo+MjS8H7RD_ zv=}s_>I?>W^KlUd>xOg|oGct$3%wZUMRK_+p76*HXudiMK)vvkwy$htjMjp-{`PPU z$&_qqY{4;WZK%BGgs{U{y?sHvZW|8dq%VIB0Z}Pk*WV!G4ZV81Oi|NhNh+Lz;_B(jiv0>7F;~+C_a=@pk`sAWsVVHd5 zlI1Ltw?l{Ahq4gTWk4K5Jh$8!9JOY|roXJI{rfBPs$acr)+^%VhB}AI%MEPF5G=J( zR1u5M`OQngPaOdOyTGEIEd!uu?_y%>sAmj~dk8b(M+G8;f65N-waF3$OtfER<#Z~XYGN9lx2y}7avwkP|C z8V_&1GP8=I;;I92xXBWtXa%5CLhPc;g4f0X>C90!F5v!|}f-tVX+T7&u7J;8iuZ1;zOf7#Ci^f>uUJV248FrBD6+dP=Uf5d>iD#KwW6__gC z5CiKUe;!OBMKN8d>J(_=k5o)*iggt#{Fi^qg^PqIItqxTT)mwu`e<_Xq`gesJQRGe z!*({02+bB0%Yq;|I&2?8$~7#61TuOyMq8KYGnUwXC%I0N#@k$$^2`eRbpti9gm^lr*a zsCHEc7GXljhw#@Ah(tit((&)0sc2756TOOQ5Eb6=$UO<$p2p`?Yq${>LJx-O!TX}z zDIwMl(A}7qROp!7*n=yk^;r6t8@2_W*{oAbY~U3I%rZf9p0PGBg%%hU&n^g@|EAM& zy$LsZW-4SiI1-q>HwN@!fnYawys{ubdEsl(#rV~rDO%Be&_$lWO@MsJFe z#uQ!JA1N*O1xfoF)tK55Y150pku|#`@y8T}MM61Zlr2n5-kY= zA#Qe+j8*-)X$5}cMFK=!T2xBLQ`2Lun(?VE%lGt%n3UHM5O#cELoRph>%QPHRFpE& z&7ND=urhpeFo2Le*1>mfdfuu^aLS~|4pogOWhuh2p~}0m%1#di77(hT09kV{8_-lP zeA}db@2wyFgIb?~l4KVR%`?mn?Sm%qd0Dmjh<-E5P36sW?!^p%7&1qQj?;sMb)Ovc zIC~t)A(a=HjMF?!xfGCLm%>Grve%5sD)+^{7Vihj(RZkxq*HS&vca-w*Dls{`U-O? zY_zdH{Js#}A*;=(=VWGVk!u6FWmP}f_-N!UpUG{k`TP$^aqUr*Fr3Z(o>%BlH_rAa znIZSEW;QkSQ|48dnVhtY#lA)sR!r33iPl77C``M*o3xUxKTK)OpwWLtIr_?qh(1H7 z2({GVC1~#;n!}i2?C={Y7o@;U8sx(Fbv+UdrX3seCx1H*?!cVrFT4fI9#(<-vZwVr zYm&9F=;23yl#=B!!Adp9l%k)P503<)v*f=Hl0q^V&0)TpiApW`3qf;ZzIQcOb8{oG zYxO^>*4eiTjsejcTh&Zd5KRe?PNOBf#hd~%pvXT26Z2MN$Z5CZX$4f9iA~<-gWX7- z^mY2Kb}OQt@BMlAhuNAbE_xl)g_R7Aq#zeL3p>U_%I+kmFch*powsk|0NJz>|Hd zv$vi>HWLhXtcRW<)KV}-E(;eG*?SJpr*JNd|C~Zs`bK@LzW;Gj9%L|zRi1;}bcmO? zPkv1@Uv2vi-j#y8eHsco$ccnf0W4&?LTgafbFMoTDp|Ozy%9NbJC-d2^rTl^b*>`I&ERr@PH!114 z8!j+2-qt%wL4q>uVvwN)Y&*9w1%yM0CZamQDplX1Z0>5~DFl`@4^LgScy5A&uIlKX zKiAf%Skr@DxT$5}DPtqrA(gJza{fE_&;q14f|CQPcv%8p&ZfY*+5PuP#iHGIcS`N) zqwq`xqGNQbwC3QNha0c3>R>Yv!#yHMhKs1ge9l*84*4my+oRyUWxtctI!F zaOE}q>18_YC|7GqxRhN~vc{zPdNy%<_?@t6+B&#zzMPbJj$&0M(?rMjpkC@hK}i}3 zZuS(_4Nez`m$#c70kC`nw+9xUQf9%DdY&s%sZuF(K_JkP^YQH%7~rwaLh8F2{{spF zvAAp&A(T8Y)0W7GfZ@ZOKkpuE&f5D1p#hU)ObON@oS1CU{v{!{7;GILQcKWecASMT z(x^~s?|At)_nZz;x-`XmNw|i~2{CGiWUR;ICh_V7a^kTXOP2?vD}Zklf%uXlfen4o zYX9GoY4|+Q5wK_Va}oh(WZ1oe`~;6|4=ScP6pOkIx%I9ryW1kj2EjP@fks29{I~XTUJvMM|Ku8{*7kUjNn+lXVAZ>%HF$-5>Ww zMS)7=E5?D0^{Yq<0zBgZErX&a+Qf?E$`E^tW!qw8DB%Fpy1GzovsJKz8S6<0^?d>9{~Aw49QYWJ-D0Qk>LjglUn$*qHkh{m!tQEj3add)T!xe{z%0%K4~ttx_%5}`yq4BI{db}&Ju7# zl}=?PF)cpz8G(HM6!8RS!gN^#%StXetlkd>Y>QkUdP4jP%h%b<4?L6|oIp6#sFB5? zU7g(h5UV+oUbRSYk~l--uB1Nh17Ec?=OxvRuq_G@0@hgjR4t7y#Gjy$tO~$t{{M13 zsCfD9>vIk#DVc;QiV!+9uZ9{N=f3)RKF%YX{n{$M?0)BcSnuOg@q;;(1;^SrB@-%$ zP-_b;2d)b0tjK_K(jFBVsGi&YSBaRDIj6c>>}d*MSv?HxeNCSJYqJa@-)MYMz;EHp zW_H^ICoDT@D1=0_d`YDEUpf0OFfYyZ3P7t;4~+jV*2iZ(G+Ri{uc)V`6%db~ndB9@ z3pLiX=EOit0=2DtA6?h~c3o}FGL-!4H@YWl_09QK`p_f9M*vS^X7T2^qX7Fsrs{}n z4~QIEBzT$X+`G~L!xVj7N_{RF!Ns9Axx0ytZCXFH_p*iZL@}hcLG?H9Z0f-y6FK&y z{5|G7E4ceM4?43J0K(!T>j&;_3!0=)(YKHvkgxhv3U0&H-QPg?v~)xyg!1iE2N=yd zr2X)a6mmm9_C~+fW7gX)`<%-Fm@&D9I^4yr@@0+`J zt_|Q5(tm0U#3{m+>K({aD%6$?6CBR2J2o~UI3j4W{a|Q}=%$dZvm3PNVh#(0%pbtU z!(;y}NJ1SStQzWL=l+-$4SCm7QM$ zswSL z>lOHt>9f-TClHB(9^hthA1clcQqzU1ipatF+FizcR~;^5>mrPmKINRYR+>X(E^`2k zHf#3x9K3f1+2{(r6E-<$Dup+5)YM80bs&j;C3-}B?&J{xT&e8Fr(LFsyW2V?8zn3D%VKbyze-)yC~a}|Q_ao5RO$(1AWVbq^1<}Ez-V=ILHDPL zMRc?fZBsn|e62CW1cYcZM7V0Kzo5QUJe^Twu(&FSB6KcB@9+hF7qHe)_3VSiC#62Q z+2eS~eMq3_ldNT(i}_yW2XlaJw=wT;aNO7yaRPAPCI#fq{Ln2#FBc&e>#X`Mt`xxy777e+}jv z%{|!QTGq_%3)N_XQaYVU3VmIKx=v3Ou)oN0+7&yMK{PBZAV_su!UE5OB$m>pF#yGI zJF4}-6HBm+JOfTn?)91dQ4doVEVKY`y=x8IduAn3gTP%g^P&4K(XsDjQR!Ypd1u{} zEjB=sAfFSO=mMA`Ch_g$GDJ?K7c}U>|6-S2r?Pf<_&EgSvh>SfD6bpcT;6=Cuq#I- z`5WbfbPZ1F)=hjLm(HXdnN+q|0&@JbgRMgzXm7~d$&K9zaMDe})=4Ae+$dq6?mv~o zx>rip9(|6aB};plIN{<5KrM^?Y#e)1o>CeiAmYkI8ev(^(}-k&7-HR1O0CF@ajMP$ z>GMnehez*2reR0=JbA#}Gor$7gW}H&p;}@Gp>6WswY^-#G=ZXH-*5SRINq9-e)8#O zI++_vJqY+rBOy00*6&G%;Ws;%C=3h6Z^^CcvofCSS-9Q8tI8mH%0w3~|9!i9HG?TO zCk&x=?Uz%jmd{flSHXwf@zM6r;YqivEl2l9%j^IEBYe#rO-{s&TP5ZLZqEY&uBjP) zoyK#rJ4Q?|eLYcJVqO&<-2>yPl~0d}ZDzic(?`Pc=>6SpCB156Wl|iNie+&LmLT2u zsu9e=SDcWS{Oo}rD>3k$Lvx8*Q5k5qcaGwsIjD`UkSBQgxfa~PH|HM>cod-B)mD`BW?Uc%Q|3cKeni?xk}Y_r&#}rsI)RE@QnAa+7f@$=xE+3 zXzTh7wzGsmP*j?xFlG(wV-L?@hT~D^s#=I$Jd^ploB(wa3ywDxL^#Lpv%(9W!vdBp zPy-;sdw1>Udk=JeQKC`ZLJ!1TPQEcm@Q2BVw(;2!{soA+mb~42Lp_o3&Cy2jTlbSX zpsAr~<*Xp@_9xhP^uORIsCRkI=el~n6vmLx#eQ6N@FL7I76x;zi^QCA#}-pKR6VCG zzLUUgP^SnWtWZx_Bq%!}_sna#-|iRE(fsdj)S+PGYZ|giV$aBo9sCF-N)rYp(3DV_BrY(>A%BK1d0X1fSrtyY1@*zb`czf~LLgC%^E`5bDTIeR1riyg@w@>vg|jsD#coqu{?z@a<2D_TA-o$k zC_6HMLEXqhb$}WVZH+8kjRl) zhVtpuZ(gS$*rFQz%^tsGvp3Y;VeRU?CKCZH#(58gt)f9o-)SQ#V)!cZn6s~aQmsvh z7Q=ngax)9*vI^^P0WbMlQ+E0@r}mT2)PHRk__T(c^7{bk^9HRwMtw`Uk$h- z>oU>wnF#d+@K%EGvIEvxY2vQT%aZLi{{?9!Q3e!)-IYJ_3kTZof!@s_Wm?;XdB6Oq zFVE59|MeBgI(uLMWNzXma>?sjRb(oqpTB zJD#k2;0w@hay?ls+=@cE%;=UqFPziQJ_xYj%sK6^^GkxAqV1$WrE0~HJMiLCH@sKr z8Gs$iU3VqN9Je%wrrZN9XmNseac`RgDw@01i$+A-tbji*iW(%uN&e>Ros=^yV1+s2 zz@0KKYJcJff8`unX2l$(8iebspLnr(-7P!=LSz5kIxc`Bo-ak2r6a-X(s77CU-&f; z-azB>+JK*aw`MXp&}JHx78d`lj=0{zK-VV)nu7G*h0SaqoB@MBHsAneXgf#)^I(5S zHbBTu`s7^hcZJ36yRI4tSMNzAJ2-S@l(DN#^YbdI3mx9X{eXnW zghY3+?#s7S8o!G4BQk};7dD17-HkC-SG}gGTbN?J`FH|h3bpa^i7npZc=~#W81WUq zx*-8skx`}coP}{r0r9Q+0S|V&6i?MOO$uVl!VQzCz?ysB86CnP_gWBPP??R)ydt(P zrFm_=vocN~zQ}8cv|ulv2V$V!6P7NlNJ=*P+h<~kC1kmEDmovgf!TE+4_9?Qvhwla zG9;UKNJ!eTIE7d_zt1SQUV~dZ9m=?pwZXW81CtG5)`pqXGE)&8Me7Mm=Vw;T1^t^9 z{6`mjDI2%^x}-rPV>L)^DZAV(e)Js&P|Wlqg}1^XRjQsz8ip6yIMk>1gian5DK7&p zB}@B6MyfuAPRQfv^DrHh-7?_^SH6d<%9l1fy>H$^I;27EMP(bHmBdvHl7j-BN#2lU zM0#r}NN11i%Y%CPZ4=j@(g?K>(2i&~X?$;e3q0{ZWZ_V9KGBK;cwN zFHN;5-TbO(>ymgAo$HJvb2l~Iqjg9A5n4myUyejqQ;XjJWpr*<6Pkv5&8=Obi0Z4} zQ_hHxFqB&I3w3mEoU;oOcWfcLvP~aUE(Va3HYemc|US`u~=or(a zg<{0cYtdQLVpf;d4DWfl;tPsB<)R8lQdT<7>tESRm{1H)_safH+tFq<0IgMx9@fI- z3=CJsXM%YO)V{7`L>+NYDzTI2ywZ>xf<$dlK;Fy$31TbvQS-f8NxEXJ4xlSCDc860 z%%G2(Tsn<0bc>7M0coNVC8Rw_jcLk3qH^BE58a#?xvy@pnd$)b2mUcF6;k z+Eph$?Xpq9G>?qybWiK2n(GgWWf`by#*z28*a3-4;!8}Lm7CvzV*wsyJyGiIUyGYB zB2vGeT8UdfnGtfm`(3Ax$pJz6!qjRB07swtl2jIC%m8W`bX2 zPe!tQ-1whLo;5YW}g2q zPLlv5vfX!Bd=2OhWO6e1#Y+D1@`1+&AHq-n6I0wXXvxvMOoyHfVVD~}KrAV{=k>bH zds(xWq7NYeUYgi*jep0IXmYOiq|!BEzb}eo%WkCwRgRKnFKh*+;##EbyYxKXsglkt zJ^^Emk&1}p*9i{nG_z8jM8!OI&mMWcvu4{_V<)D1T<=ojq6%zs2U9^cH@%U^K=(bvXh4$BJ#;9pbbgByI9mV(%C>i+HZRg*tlLrPhNMqlGm2{ zQDf3^^%HCScGMYw{_bf$U9Sfb9)B9Qre7Jv>S9Wlt4{)n2wwdf-90TtMd_^kEXk&0D6iZCO^uKjI*;o%Abc^P(hhF#!AX~A>2f)L1YsHq=|6pF) zd|BT-eM2NRXX=u}o%t6$i0!m&a}sO3Gj*O3{eDhe^_){aYy1o)tX9_fs%o*oFFFffap~Zc+)bZS81iLgzu(T$tD_O@oNq zHJlz96yHbRLBS*JvK-S1+sT7%;r<_#qMiiLk03djQywM>oTU%$-u)}}u1X4IeV6@a`sFD(+-Ousw2Sx64W4UC>sSs0kFWRP&O0^g#lq8SSS(-g$hA1 zy-Pdxs+{qcy;Vs!T4k+il#e41spROn^uO8tRHvJ%^1Ldoc|Xc=wPmwI^@JJO$*fw2 zsj?9L|4~}iaLLjuHJlgpnm=}kTYB2M_I|u4t|spD^VMEM0}m`Ae-$fy5_$i$zs>ne z_vd0~erYdBx+9eIYEP`ByC<-rzN_r&mpPloFOYiKP_n#@Fwi^UpO^T2NjSUOAN_P4 z;8x1CL33RGjMuaa{=Tb}-Pe+Gx7`uPrdojO_4XZAD*Reooad%D1&6b|3(fl>AL@Tn z8XRDlnm+(U&RVArb;zh2zZa|d_{){ANv-+a)=85SAgLV({Le0VcxYQpA;#dTSJ&&^M zHCb>|d4#>mjT!wkuNe&v`)73rEVK#4bhJBWXhE{*p4M4&1iO}8<|v8lVQS<*2cq~z zsEL&U?ln5gnG~4SGgM~;ayBFl;fB83E+_|*bEU0Jecoyt>Eoph-OrTne}3mscYE4g zc9PFz=~+IE%;~;i{2Nge%wdFEpP%Eyx`ch>v*mwu6?Z$#M}NPN0&YV=fUux6CJG7y zfnc~;C>IJ5f`uTUL?j~!nXUa){QmWxef_tbPIWTku_3PbWR;-)ql?mKc{O``Ws&)C zUAMnSeJK88{=Ed@b_{;weR)%}SniE$&{Op#8vk&o&^JEE_3*E@71JD_a7o)Z@py4- zK7sKjVCel`Tz>9a4_4nSc!7#3Yie2>thL(28!ttOI#myv4ROX-!7P-%-%9%F2nC>! zSg0$@^qULFMhacEcM4YU3g+-?dY5JhNb)aO;D8ae1h?07zy1P+0bszWEJzCq1c79r zSSTV0rTSmDIiA#4Ti+B0IGfe3EU5+)`+q#9!&}e&=z@nt4=j$Y+Lzg4>eDl`KLZ?ikQ{o|mQWYvj59g^ev7)CPyIQZOt(al#u2{3N)p{O+q?XT} z{z5lryi z%D+DC9PFz-G}~ssjh%fzZ8!K1cJRlT#wEU7T!ZJ(3_Fr1#B_K~Y9mZas^zQ26D+pILt z!h!qP1M}6u=|H zW8uj;R}v}jY&t2gN#x!a13D5w3|Ph@2B9eEXa412;sLl{P5U8((v=?tutUe+}E{041z67z+jh z!GN%!EEo$013{3mWGpljAqv7ks8s7dKR=Hd#x8DGo@GLrDrBiwE1)+cbiHH2;dlIW zSGUl=2l&hQD0FtO#$b=HkK$arlr%hIBnNT%B*pb=Iw=^(_HX;!-_POsmyfnlyG+yT z0sfolea~SA`5AwT-+zKpgAGgD&CLR<7y?J4n{bP8^-74sQo~`7L7rBrqG?)6Jl+%$ zZuHt}pLNbau#VY$g;TB9=u&(~Ig%3nkEQ?=%Srr{|h|p!9zL&I54N+5ueO z+Z{K@tku$PHRiO(JPV5hQzow-3d)GT9i!=*svmAJ*UB-}sje3Ijobu%JvT426RMVnA4k5()%@BQS|oUft`*-`5wk*E-EB za#YeQs=KO{p#861U{l<*8;wkzB32*YwE2IJ4PM^xnM6E&GG&+7{o&}6#6%07d;2ZY zUpE4q3@m1UFQSg>hb^s0*)S~~LAU$=o-*5azJ%1uh4L1&Hp^_o;YTSXGq!K@+dkPN zERcZR2xz?QEU%5J%zaRMF;`w(o_VSFLx(=5H7- z+kWCA+9)Z0akETHqRcDmir>A$B11ue&{$3u4GD&UW1v`wG7y*o*FJfYF1M*#%DwTK zp(Kly5)1ybsb#w_zsso1wkJLC@&9G6|IEQ7s1^{PjLQGkuh;M1TsnV`Z{z=7;8cA+ zYfed{!c1<724O>%%N|NqEe@C-YzRj72h4PjYV1nU<BZ+Xn z$`aBQ(^|rXUQ?t@aAJaAFNhQL!XvoF?6;)GG9E|ZSXIuV-5U;jr%F>)I3Ond?4H8^ zilynAkw*26(S+`lSz*e_9XDwV82}IjZ~y=xxIvo6CjZY836xJuUDg3Cw4O`!c@ck# zIeC2laZ!T(;75X#ThSE&7>13jL9v0aS(X>y?HAjpAcswD=aKtNE_DD_?^%G!)XcuN zd{Z03=B?Z@$!%yWA1|5T+}$zUiFIKlgbqP<=Q9m}M2hyT`RkyVR*-@4HUj!<(c?hR zFMZ5Kwf+vwI9Go0dHeP*{{+h!yZpqi`?aZAeDx-5v%8lqo#~+_mnJr`A?TZadvI+a z3}!{L6UwG{rX1E_<0S46J(ESh%BWBK*!& z**Nl^NPmnL$w@G-2a6jFP8mOt2o0y(=^Twyf(Dw{1)M@7M*0z@89k}UH53^9$w&ee z6c&n+9mGOdw^qc7bCD=3DLA3Pxi2d0(DRb|ds4vm(@=78ltmMqh2E}uvH8S9DzJEX zhGOp6%Z`HdtV$kSf-0D~$fOX|K*W2MG2K&(^DY~JT)S9?ObBvdw#iKS<| zLY)I|lwa()E;_i#t7fkh#Q=RQ?Bi1JEpd&qkx)yhI-+3c*Q1?M!4jYj%6GAjGBwPo z63iNGtlwbeZSG4rAhAfNcW8l_?uoi<{H=`9Z(w^NTWow;Y+^~9nC)0nhm$$$yP=Eq zGL}d?Q-;X}yy;$>4QOpu+w05;?S_?Z%R$%T##Mb;E<6xTJsnz&k&L@? z6m!$prMKpq2KZXxGhsXD@2?UT_(`nkrQ+GNG+mrexNm+5p3LVV7pH#q7-yNCsKMGl;3vpcG1C|LLs$^Jy@VFuoMM8!iYm;+(HalP0$2;1sc|VIcpTv{-+cMNv8|| zlN$)Gk}XdWZyg2s|K0ekTRgWLnuqQ~v@{D`3EPM{5$%|=q9WNNI$d6$fmgQ`YmE+g zlatKWs(r}OtiDx-?lZ5CJ-bXA6qoIc9Ff_nUYE54=X!pZR!86}64p?e^#&pX+hmB- zhZW$y`NyNc(R6?TG2ZCLaFU;>NrMjF(eZ(!BFjRAB5Q)j?xs{*V+uiM%X*KSNvg)8n_ zlRvDwh_|sDsal>tlb2 z$HuQB(9x<$w3tRlb5l0tjY#fj<>euK=`rHQ1z$IO_SbW*+FY2Wnm6XymC}L@? ziA2dAy@A)r%#j5oEk>URht@=RI@IPYb3Y?9(apS+>ZYzlnUn$fMYuma)uG7>zC497 z)5?xtz(dV_5a#UbYz3I=*!AxXHatP>`RaUdNc=1e=)Wj#&-29M200EZ$0)SEAZ#3J ziAkD>lR-73hiDAD{{`9W z3LK=5%epPmTgG!J!yCV9Jz;SPwUky^hN(`+RFlG!jh3$XtH7D*OIIFbVQ%7n!x7H+XH=)J?!$J!M^y3 zI=y&rgA(T=Wp!Qj>kAqZnSH1F{r$rB)Sn3}{1n7GL=F7J&vAk2i`vo%f8ARiJ5<|Y>O{75W|#atES$6vYJ*G-~%Gc$x#Ba zh^KaY!}kzydt9wo+lTh-s@4#Dn81DD3@wOre?U4RvACr-NSwbCXuam7;X@t&h`V%6 z@u&LmtF8D4Zu1A~zpW$-7n#I<>}N!8XZuMPGa|P59toZtSLp!Xpv-TbA7zl1g`}TW zf4Eo|a)3p=@A1o=yv(;Z1OLmjh~3hbf*qA!2lg|Cc0t|+>VC`v^TX{cZXWuF9E;9} zGY;3{BiOu+Fr8M83fPWmkDpwO5UT=gzr|36r|A7yC-6_CrUj&Ezr?VEb0i){b(|q* zQzjJM_EAy_|zGj;y z0W_=Y6mwgqq9ksWa5fdd&FH{m9>_Kgf zy@OAdTYRY2UZRBj(PN=(w_csC)-sFC8;5k~vH?-pE1FIUBg8c2%~Ax9m0HT$HK%g2 z*ehzW@;08srP6!4+E@2ZPN=}t_;2bW8_lX0$1PMBN{u58F1T0*Gl7sLjGFHXuzeW$ zoo>7S?MqZUkj3U^zBPNw_dPS;P9<4a9Hng={SVSViKn2`Fg*P{f6sSur@vf3|EPru z`~c(k_PH?a38@!_13oI9y@Gf_p?uf~R_%gra>{H&OSlDy>N%39T2!4H_dYjw(|XXN#oU? z6S33jrLexswyuJMV&ifO&CtIS`J1fk3>6m>nrFf%UtRHrS|DSn*?;Bmq)nh*NludDS7wsD}40poV| z-3e^2353HAQ$r?F_pb+gF{TR5bCTs>$F@Bw9+z2nQv4uLdU>S+0uvh5NOPSb@+HR1 zr#SRWF|<`{6bX`^E8L4%^FB#|x@`;KMhZIlEZd{dyI!z=&wSb{&c6h@YK>6z6?WeG zSHo>p{D5qEN?+U`MM>EBpjDaKtswBS`lW~X{4gz9SUcBf&Etxqwp_fqwk1inkAiMJ z#xL_5Q0jBUc?5D>tk#~c4pz4d0!+Bfw(Nu}_Id-CHW2`hPTxqbJ-a6Q5DDs1uH1U% z3nk7b8orsFeFKn|mj${06?~QDkH4%-AW&`nZ?xt5>S1FJwMhG7pQXUVEtK6zdV%=k74=T(*h6tM8cYh zypUNIEbH?nrwhlKM1n201{ls~g}|KwisO>%%1Ye`Dwo>|ARVneu6~kr7@DtqFW5M% z@6~mRaibX~cBbEdEfA(~`^RFiLVi;vyDqqsRBfEw;wpT;`{0$K)Z;Su!UF2NwQP}> zYvUwOCL*i~TY`M+~$r)=X1HKyJBt)H;=qz-P<8Y>z|-Ja55F__tjQD1UQbOGMaH)A}(Zg#_u%P7wH|;Au z$9(7gEC0C+>?!Ss?*0+?XDw`{)&AZgcQA8eO8}&lCmG|(mXmMzrbh9GQ|F`5)2SewVaTev*0H9>!2YhiR?GbQK)ciF%8$g?8 zOh9B;8`B!#ri}GTVM0W$;rtny_!i-SL(-w@oYfb!Xs%9bc5PESrZ_s1rwL2}j9pI49X4rULQr@BZ)l-}wtQ7*=9{VK!1mpjWel1Dy$;hynL8Qka9v4cF z?N!2aUKDJH#m}MPPAP0-p z#{m-&_JR%QeU~4fLkV#yuS3JK1bvz=9o8afT=+jAt-YOiJ6Yn84KjF7z^Ve>t;&Lk zLq9i9PWzy)g0$}#Phs>2cP`g{m@Uj1ZUE6isC2v?(A#0NAjJ6+Yt-sv(VsG<1+I7&JVH+T=ryq6TzyB;20! z9jK0YP8w@2AQP+PvTZLPc9?RHIflW79h1v#aEL^`{Nt z1|G+MG2u8eW2z}#l77hy)P^_Wy(6>MLy~z{uewOn#SkRP?6SDT;o{P( zJejrcYD0$R)SJ+`UT&*tGY$W}?6M%+BWe|>o61QQ*3nGy6ZD`Y|60;>#ka)tyHEWu z2j$*~h0{j6qEphFW<49rgA-1&Kh01+xE=_CNGA{zlhtf(Ojg_B9GDnc=A!)StWemY zldRrUU)M!iqsw6c%u&8xS4yp}GbAi(H&l=g_rPmZ8DEG|GUp~kE*xBrVt?O_@t$=) zarzHe;D;SYzXLaxH`Xj$?*`1zivCbZpTwrI{6VZ5$40}Th+*sYq~iHDioByY#Ci^( ze_P3C#{Um*^Y^+FaxI?XQ=p#My3T@A%~reD<@I|L zOb)(+`s5?nVrNPpw!siM|RY}KXHOABDyyB%NXU;JyC9a&;(4RnI%VsLC#dT0UjQ(#N|GTBg%GImbP zHe*M71q*4dBb3AQ5tfi@?9PQ*hF(Dn&f7u@J0q zvy<)XEh7cMGo$PM-m{?94MYZ=Z&c{9N3$NAjNS3<_Bj!3#^^Bg?bCh zKop!;_>3heQXZa@wU8$Jy0y2qgSC(&JfHsle=k+EXXnAt=8=6g*}-WvSRfZonAm|C zTjk@!)AT4BjYim2UDXvMj3qasa5ULy(9D?)V zX%!&yO|?QTP8~u?GpU-uIc}FMoFBwxt3N07-VK>mxvonB8}yK(*B7D5jAPZUU^Sv* zcJ&B2$xgW63Vq@CZddKk5l|B&@k;-j^HC_6Bc+L);<1S-ef>*F0DrGf_bvYHMivXO zGL6;8p0H9q0nDmNf#;v)XMAxA$BA2#9lGmi1YdnF9&)b4N%YDkYn8Uz+BMi*zMan` ze3JOZhWDiW5VU)=a0x`x^^8FdY7ZZ)W`;}fs{Abm_`QB~I;X4E1i{1bH0xssr9D9p zP$rt4>aZ1qh+^G+!k{-QH`Oyqp0NgNJT~XDmTJ+lT9mR!2`l zDbaP__j=Jd*nZ96A!x*P%}|({3(5=iXB4U|2~m*BTG4@0VuBn?Etk}os3Xa@I8av0 z;d&;h;>{o@;xvD8T)ho+ZhJ=7uB>l@d-gskmG0bgv+x;z0TOyjhwNDz70flw9KOH? z0CJy57Spp#Uz11<+(xMQ1obqy`}<9Cq>wt`YfKIJ1JRg7s(s#fmusyqJtbeo-0se4 zCcD$#Br-n{G(YSmyr1r4Or2nUK+HT5NXj#dGUPWQ!T}JiYopn@iR4P|Yl7V(68y;o zJG(i%Jmv?7cfk#7Ka(*^)V8XJ5_qWy-9o`f=psgnq#$bW5|I5As8R2(ml0MujCM}# zns~N@*$O7Mw6!yfYD$WVdJrBYhPni6cN8qx!lqjMy{MnH1ZtHb%|cM7t-7|MlhU8Q7M6Om7T>$E4J4g7QK5dsJG@Jj$koXv3Gsz5z^f7NHk{f#yh1pSqBR# z1w(id1iKt1Fa_3~n%2Y5weuE4NU%3+NnA9E5FF~5RH6%U$kK{8Ayw?}vc}>cj%23Y z3B*0W5y~x!kcHv*S<=~;`|xC^?r%5+lFxl*(ai+|^Dr4&xAB3MXU%LVYgr~rTWOe< z+~o0oBCuxUM;PXj35i95UOM!|RZu7xd0{_zvCX`LThwOFHaY`~eJruL8;|-@q&B2Z zka3C)BCuueqx6g>CJGIolZZ-)zgTlVV}Lmn4P;$)LPT2ITq^3_>?S-nl}XkU(^REBK<)>En}z3f+Jbd zN(k!GKG;9LKkl5605EKak6f|cc6Up|VCvzl3fP)N${|&}xKGz}u0Q%@6t{eIkboHI zeN$`nD3QQN;Up{V`l4QakXm?hQW-o`xTE&OQKcC%{olq}1hE+*K(N+QWLaz3ONYy+ z_;N7#o^j4s8F_$}!@d6w73p;Wd?@9DEOl(+cn1+X%IUuCtYMFprt#H36u~V%^12}nLcz&Dw(3oVA0Mc!uU92t_#97*mpfDcGY*n08@-Kmo4T~)20PI9IEetA}mTOgn= zXmnsCXOLv0(osJxFWzDF#T%v7YzTRWr{$)fDrN4ih0xN{;+Ph z9I1aiLdbJ7cv$dndLR%a1#K1ZdElFUL1*kMD_((EGV5c_5vlMN>Ht^j4tB~VlmNj;NGKTZ=00Uy%D=Y)BW>{7^iz%iCf~gH z+w#y0Jx^4>`yEbQb({~4;2 zW4*NFz}d@n6K05a2Ba;kupsr%QIZtdG_E@kq9e(DrPqC=HPIwR+KjfAfBq`C;lk<&OlRrP*~1N8z^O)x zu6AIiQgkak zgAq?o?5>dnM@a@t8d(c0kAX}Eyf7NH+V!q*gFriqjmjCQR&P#Q8&-ga@sD~OnUG67 z=!NmrNCz_VWk0#%Jq1OJ*hVzE@;tJ0SL-~8L z7{f}uQvgR+DO|HN;gZXV>BAj)xTA{2O-*;skQW^i70_n7!J@0hIMPT(o=Ypy$IXg6 zEI2QVx>NU2(0m+wxm}j2LA#%GRsep$Iveprr_iB&a_Kmdt!xP-($$4?NIy4-{sg{u_aj*<^qn4%V^NH|MYIbn}E*9R=}-A@DpcCXIJEU#xBjOK<@ zsRS-{MFX3}W?N^ZAnOJAdw#%-1|7UGT@!wnlljf2D+XW5Egc$JUY<YXExW4ILf1x-3CEL0HYzn5&~4w~41`~^a#Bml-AtYKE7%Q?YsZ}rkU;1| zh38TW!1YDi19w6;VSyOPW<%1uFqn9oO3OUD%o3O8%0pwxp^0#-^Z;yNUI$m(YNFkC zQ*!PLZIXjR?i`8lAYu(*6HK%z-VhsHY=|>>txV-!{Ob!K%suOtCI4Gs3|!)*R+A;@ zV6j9$M94+y$Oc%n!@0sTOyDf~Pc+n$0YK7UVPqM&yu7CjPbR56;ci{810^su6F+{I zCK-w>Rwf43Eq*`*@gr7Lpg`ig*19@i3y6)|YwgK0wqOU#OgQDMO~x!~pcq(Ih-f`d zS_Q^6Cr6_~k;LaOda-LF^jMl#D-a~UIN$iL)ow-(U)%PsF1FolimjYNii2gQ^1nf- zx!{pqmA#ID4V3F@1aaIZjg2+WH1ZG1Ju@{p&swO-sGb*s_p&(J*JFoY#3*ll!~>a~ zLNT|Dgd5tI<6c_uGB#LwR`O>52ygij#$gRwBs@qG%;HcG0+Fo>OdVvwe?=hh_0QPN z^wkWt_5g>q+vO+_o5o!jkv)1jYySehW|Pa&B1;)EIel{sMb!lvdi7%CTNCZg$_295 zlw?~V87F1LZ|&!k42Z^Nnmj|@WEc3H)bhQ;uv$5j16q}11QbS*0M+A@j*24v!2GdN z)*4(+Bhl{Io!E z4siKd)27!$v_aZHO0f`%91Tmx&7b~BY)HD`9Qt*6QD*)I-yDfh24z3gJR^BiWy)K6 zPh;IS$%hwlJ3+i6iY=p)ssCH`f{M*Xgh)Kd9K=APuP@4n#KPu6B@6UFmyX!Uqmj2A zyQCy@x;LRg12oidtRD;t)+>^rSRT-Ur3ED*m&G7Fidw@~-*4M_muoGoOZUbM^MZ=J zDYVEMSPF#MPDRP|<#UEF7mU0}&$632i~vKM2Sx0oM_Zc9*(t(c@GmrYD#VKYN01C= z4O0G)wFVujl_H7cHUMA9ULttZhmlCI3On*Q8(Zw}uku#0T4y_KXf#nL&!e^9gcJCo zcX;Vjed?TQUEjnxK2&+h?`y;)s(CT>Nf9n}WO1|w2mu~c7%(;r35h{~uxL;gBn6U# zP@u>r62AWT+kOHr|v(m>4o<+ zx$0@MUNqVN%qKVb{~*v7Iq#(xN1Ifg{OoGKYN_vSS$A>v=#ya1mwZhTNg5dL{bmyQ z`SYijRQeWNIexsSr25N6Ip?D+7R$SO$?aSw9zS_QXN3*y^6sW4#3HbrQTRV<)FAs8GdBNs%ZV8kLvPY}21GH?a@hUrH&*a|H0vwjOy_PXiBpx0U6x`Ume!Tc zH>yJ(TH`AQfuXF@+Vtm{_}Oa{f>glKFn+ZS<6753 ze8INALej};#p)1{cavkzN{4AbsCo&t9_c?*;SKY5nwwX883GVA=Xk%jK7Gi|U={T% zp2D9@_&@DaQZ#SKNA-4-dwxp|AS=PBtJ^XDcmCU*ALRsO34;M(z-UZ23l0K-fS{O2 zH3|%ZVHCfP7e0Qzx!*rr&i%W!)l00>rPRf7Ry3TCZicV#zaQLtKQA-)uCcUyF}F-l zs`dX4{l!;&mdKl{-Wy8^GcnN&pHVXzOSClQ@MXy<*3@_hE>*o! zyf&GmG)(ZGCQ?60!qd4XG-G9;Rmxi<(+Clj2e*I!SN<9ULSVq?EGQcag2sTbP)sBk zrOS+O`T65?lBG$ynp0WDYDq}3v%Od36>ewg|NIUuCH%kT&8r-KKcv#VMFTzSvw-w< z9zIr#`Ca>~^FUEtXiDdEacXlz1K)KbB38>h|@EiqgRI_!<`gf#{OL4dGeOc)CW0>gl^ z(25cYgiHY`D@vSr)$VcLre)05MajlVRRT`;_5IBEEc84--~CI${bKt$^#S+xzg071 z{_FPj7t()^O<8w{SsHJSSb2C>U!Nv5;y++b*Y4-{I%SiFb57HGdiLmCLQlx$T^q-X zZm!#J!jrNKWw^DKP&r~|e3FA2upiIpo-MpL`VM9A56bt{5A@{*^c@-l`VA@3NB@qe zEe9c5KX*L#VqqLa?_E1ofRH%q5o>Is^}kqbnieCzkadhGTALzDSnHx;!zJwzgCPO{ zjsXmr{+vcgSg9fxrF;%glnVb`_J2CyF|^%Rsqfrz8uGt8GsILk(|tP2yd=h|{#$Pt zH{K;~bjpheIoqlX>QDxxAZSaXJ$+ZRc#&OA5Pvh?%XU`MMGk z#^qkI$;Uf7xMc51)HF_J?1RzHNH=XJ3Ahp#H0uPlw5Po|CCz9m@{>R6!yqC*e@ydV;DmPF-A zK!->G2?6f`^8w5USPx(V6wmLlM_Hp0s+U=9RVsNJgQ8brobR!fIR6OClzx(qIvv%T z1H07XjACXl4b5Sq)jC|fp3*=1z2-OOHRc=r1MnlX(<@gtwLL@IIk8u$Cd`=AYZQoc zpqfR-Bcu-?L3MpfONpk2y6unq_GXf0F5|?0KaQfPCa|E$hxZj*~($I{DZ+{ z59c$kMZ9ubo?il>qKsdUeRf}qB=+BtdgNmYT9sSmYw)U24(g0rPU4<^H@o+oB#xE9 z+a|ek?0~EqBnj@>YNN4+SLgdvUmdsIH1#N9KwlRH04TAwm%(|Cr~=8N`k71{#l_4N zDxtw(J5+4tdcqqPd3?hUv_RDUDupV z$45xI!sMmi->-S(tiA@A`l%JC*FDidsRi$a9?8C$! zpfeb=ZdRVL)nkux@h?Jo1=CE?RVW4@8Lu$g4zVDI(`gc4)sVI+Wol)|ufA)t@8R{u zV1jwd9{FqGB!MiVNYYm;N_=jh#*W)*y<92o7zz-zx?Jzn=>P#B zJAik9<^!w;+yIR)`@i5U!(#@E6hK<7R$o>eARIr2hAFz{)c8`@Hb40FyY(rrDX7)C zTWP)KDA3_FP4n5{^^#y-j+rRdX@9UeF z$H^xQzu2l7>LUD>zoicU$+61g+LF$12L`0pNRz(gt)eE0u$=IKMHaNCAaqSeJh@_! zOkx47GJrvrQX@FPny~TwASoxg; zn7iiHddxU|rQ#1i$i&Pu(WiSjpX}0x%?g&Yg-vQfRVdtig7|>-!2J)NG##JE&0KGw zO{Z4y`tIkwW_(1;GBqN(rk=-}zjgZF-*V&h-MxJM-Ie)xa%bdk7^yPgq#f}DMZo7n-P6@g19$1i~d3R0>*>S(n|424K^cBF0=pilD2G7_HWsf4w+-OL* zH?R(c;*Je51io3+YRcrw+4J7ykUY-M4qmR$WoEYz7mq^zsNT$i%WLfQW$ojOh&aTM z0|GsxN1Uq&_+t>)#CfgnTu|SE61Ll`tCA7S?tGL1byWtLpSOa&&T1;Vryhvb>!T>O zS=V^t@H)Dtw51ijrbm6pE8XDjkms?->|rH^%iEJY2(F<1zeScHPqnl#J(+u%rbMFjI%-f(;o6y@~?{I5z8+r;y!g*>3MqFF{KzT*q7_v1~kg?Vt#2|if#CY!>bm1oREoyPdC2H;O&sN z0`HPN<~n06f*v`5J$-%B@yaW7PM9;>cXu$_V#dAUO^AcHThy>W^OeI-K`4R8_tT|X zfj|&uIr^}RA&Q{IFP(6Rn+MX+ztxRot+P;D;$CW<1x&*YD;>5X%v}*iPb+YW_`-k5 z_K=v;P`P+7-h-)w0+H$nGu@|gHi$pZ`GaZ%w|nP%IxlysE>VLG{3AAo-~=J*Kt{6* zZq-{m{aHO^q^G;KW>oR1gT-{6ns1R?<=oBWnVkMc8=|$e0Bt1r+JMZj2V)GwJNc1N zL+Wz^99!5MO|JvbB4R1KQtrP9YUxF$wqVy#`noRF&Kmh%@-8BPMuzfj@Nvh#=c8hK z9GKMYVjT{Wp5k{QZ>qkV3W4^-5}u}DdugXRpt}G<3jni9Ss_)^VDZ|Kv@A} zPm73QYr?8qW~33_$I%p}BLVz_BPTBd*(Q#eR@8PSjKheV7n<)RN)9hnG3#S3!o9b1 z*&H#5hqe4$!9F%3h#9Gba9@oyV$e0SFga;q#@Ms?N*=JqLfxtnrX0jyN4~8;jRBvb z0n}J<&{ULZ;ulZ=_4+n8a8|aj1Bj406hilVoPEier1hqjD7QguAQHPU%sfw}0ad+- ziP`%D6Vqb^a!<7Hd6UL7HNEFLSyv*U5*!Ym8-MfhULMy8_>G+Y^ureBHGB3zTBfBd z7;BihJ#T(9*v@mX+&b@_!cyK~qx+Wy)ZgU>)-QlaiNCP6A5bb>H6Ot*bCizG@8SFY zwDh6XMbf*2$8c==ES5}ri>x1nAMp=HRxJ?L2leh(MZar2|48;YmYI2N>3kj2sQp*s zgDT;vM)SdC1^#!9^)OO(nGTj1G@cm)~2NiSE(Aipy`c!FQRe$NN4Pxv20uJigPNZ=%Q zVyf{`^9!3|OF|e<4!c2;J?f@4&@mo7GmqDJU?TcU`9&&DM}K7e&{10Gk) zcN$bOEmP}+dt>fpCSg}zgcR;$l}i9iK(xQ0gi8?Ag0ZZxkCn31!Jb-GCNU;oX^U+( zhkj+cb!OBENeb2_3xceL31f9a1i$Ol1pFmuE2mJQDBQPR7C?3;%`A)&!Oj5EbU{H-suWD z)5~9sA$ctVe^B|sN4;sQ>6<;R-c;$*( z3Kx}S__gH{3xhgAByDPaBLWO9E1rs*v*BsbnQF;RC!y$JOh4#J2dLtM@Le|58^6y7 zVbZK5Y8}1Bgd|If7P$%C!tGdU(I7*A=$C21R?1qaqUF~#I8NHR;C zcZv+TaDLb>ytDYQpk@!CrY?7eWF04q=UAfZ2I#p`@3>pJo+~L+aIyqQ_3yz)o>M8S zrls+M>f<_gb0idQsbv!{gj4S5YZLoul5-nL)Du9-jY>qY;h>B;&W2uarP%r^Su)Z)bm~U6!3NzwoOE$r?S3FJv!bpQ+x6=FNHlFC?MRG`v+Saycb?1_S|5bC$Vq9Q0 zX-^H3YzaAQ$rGGOKkgtw^2pfs&7H@!Uwkdd|H8y2AU}X@Ry~|FKcM9uN1O=v28q)W z^TcGLNtjD(hZkfziigq9XJJZE<7 zRAl3tDAa1PPu4du^^0Z#*^~&#bds~BSd9wjq%Mg;ks0BV*w4GhThTjB| z7}gh?r|)%ryl5ou#W_(vfPuLS?8nBRuvY8o!B&&t(mMTh(8Mu_plO?;^bb5%2PT_D zHsdxjxMj7?lhTA+=#XUlOb*^kpzJ%gh;(#V!TybpiyGYK=_*6r@i)V)CHjM!I8wfJ zN@K8ng-T4QW75LSwda3k1%maddjaFkU5D0&$;1f!7&ebmTSooXdk%MTmE|PA8%nFk zx!1WgpoMPd6973CLRd)-{IR7yF{H+hBK1o+|7JD3gz}$t8hCBVQ6I7xR z(NdFxUiBdekb;WUcotY4*;pV9)Vqww{{_I9=#GW!_O2tzOnC+NhC1B7cE zzw}RS8}Iy+3>fM#Ee*i`iD2)f)YC_@#84oDb#V$`_n%}n^9c_{Q~oOQVK;Q^hD~tn z3`1M)w19LB*ErjWx;-FX029|`Sz#(vpXjt@>|)nAcu(SExPN1fO2hPZvbvyFV zJU14?3kF#=d38cHxDIwrErD`+iIzdpmjpyJKTHu((gLT**QslUD&D4Z70IRt9!er( zS;7F}K0bbbGJ&9&NzJfexfGN|s;Mid6TgaQ4W3Bus?6WP3|t+?o)tjodQyPk1Pmlq zB4y(MLQZMG+)0o{2v*FJ|2bESFXOF;MY=04s0H}nk(v;kVq%GM%N=EQwu+Q-G% zq2;+Ayyo;Bzl`Gyqu8s`O%Yz$&5_h$>16|CnPsl?Xrk*aY%<7n*4qgUPUf^b#zyI@A*G4D04zeeBj*9*mdV)X66b z6votNHPJa9-a7!BTEP!XIgnM&e&#R{g*WqWsz>h)Vgfj(_`GnjfM(3Qzu_2uwa4x& zzK7$}ah zP~Xt@pj5lg(u~p+v7FLoaIF0&Q_x`D>DQ#>fP@*5<;^+T$3Hhr`ewV^3;o z$?JT3RGQ}tc6&w~c_Dx{PKmWRp`iZjv2B6l4<}&j--9lCK14VC-pV-J24QnmbFw&; z8lB!+P&YoYKxOGPxaqL{hE|oAe5a}lXM4x|ocCx%1a-01_7Qa$7iKS~ z{aPgbuUd$=0sG5U1p?5|xa$hxDrYnj4)HH+00tR)jL9)yS0zH}ej$qgBD#MfYcHeG z$m55d*uu!;8oMaISyznw6G)mw>qHu=CJBTyzr=~$V+LR6w7P!>fsh+z>P(FZlVj*^ zA+5W&u(XoMjeCwT#F?#6n1HD!N5_n{(!&$5%I|C0Uv7idpkNto_CEE9*++_|?548% zfYWh#FbC2v$R9iUpOqCSn6BWNHhv7j#75{se|j+o#NRK3^C*KrqIBZ$og7?} z(*~WlJsh9X&sfZ(huYYx7qI691Ae5Ia+CiP8BB@Yq#xmV}$vC=}XeqvCFrJg<*yX|&#y985;5uS6o5 z46BhQYn2J2AMGYUPUynDqeCf|hjM#Pu#PCZ0vN`2lMQ}FjtzN6j&=csXY0RB?kG)z{m&H#3>b&W6!_NVX z$wMZ4aiP7IOMD1bw+c3oE!aF~(xo^i1!y3tyBS{4=(&Rx$YJ~b&6zdSn{y6Lp&0D) z>W&%b_1{@`+;?FQS||NHw7gt$+ClRMe(tHvpz(s5s~y8tg3?NN1bH?B|2uV`xY<2g7#cg_T(UDWG+<9W@u$d6*F^M z|1EAqLxg`fO)D%=`-1`vv9NiWj!*o^H0|J7Sn3W?S0UAAQ-An{kD^c!@OT~U_^5}S zq;%`i%45ju$Y|(-7zw!b+#@>Sy7&P3-6{G-^nwqeYEK30;WaaXIiY5}Q}^7#9jEm# z?CWUf_R7n2g|5pOxSc?6JE~?g$=RhnZ46Ti;(3B$DJnsqDhj+X(8u|AHcpvE-+BPj zkgF^|TxJvBY3&}3Z!6L!JD2rbr6>cfB?X^V;9gqF*47INV$IFH0X-Xh*T$d)U;y{2 zIlwZEFpIP+Y+leLMnJf}r-M<2<@lE=$CKa#63#|iBVTHbUZJPKsc{RHbMuGq!B@@! zCl8Mqh)?0o74nn`y}T?tCM3X-tN<} zgbefix~6^(7Y=x%A#(mjF)+K+k)%xAib|(nb7$5R)G=|0JT@mkF9Ab)z=-psBMlpa z^0F^n{OB0e2@Ep-E_ppdYwt>ns? zTOx=)hOE5uY8|P@{%OVw#?qqE&p*;yB>buC@=gVx!gU{f<+<`KJXmD8vlapzyaH(W zK0amN&Oy&4MpB~-2U8{g)`IfmP@5F-8WsvW%{R6BgHx&_2{)j%WOCA&^ZqQL##P7*;xF4~!@*Q^2QEs8$y&fRanZ`AzWJfFuuvj($jL8`2^udIb z+-kDa;y8kY@ZO1WQg4wGe%Rs~C1Aw3ZdG}C?rm?|HYwX@wxY{F{cij4qygc2Txo#- zJQi`BwfS{uJ%eX_IQ?8fMs32U$P7#m=vpRH=$ofUpxbMkO5_HS89dm-R zSCQO>WqZAv0@^7~wT)La3)+2-%C`HYotT(_yMIR#>&Aog`s6!ni4g(cAn`Z>Xz(_V`P z9KP-kbos%TpqYb1d-ngNCvpAx`JG>rjn5p>YPp_r3OHH0F}oL z-$guj33*0%X)`r}`9`JZn4f#D2QqKk{?H!?E$BYZFKsxven|M``C+tC#2Cok-OJ)_ zhLgoHcnV5DNJikuh7*wDpHP3 zvKjE(u`@z6-^txj*{0ufupD`fNkFV97JxpCT~^EyZ%)HZMg2x9q?rm)TCNfOchHzs z2J@vOP%DT4lW>#@OE{!wHo^t2LwFnYPHm)${L?%|&PC6*w|lrtNrslEJkepB>z(_Y zk-kx?(o!Bp21KX*3%m-_0CzjxJV~wL?wN!dA-EZeLV_hQH~j?4Xx^R{V;?p@ueC!&7H?-mFYc``ZsBY7}JI6#ygF1et|;D zir2r}mnn$c{TVCuHl2jF>J8UvN@1(SWcR6H$^HjWqL@V%I0(eu;y!RNfdCawSBAPI z8hh12`nN?DRZv`=$AR#Cc$rXS?3E zuNr&g(IsE&=|ow2asE|pr1z-kz?i2jJWwle$~xj}NmwNvwVt4kI^fDae?BI*1`GU-rgi*o3J1s4DC4w!g$mj6`xJ@=GMh`;qMD6 zP=evE8D>xIi7CkjdF44vR0(fe<|@O@V%_?kJA;A-xJI{wD zCf1jyD&C{~7sh9DHJ)n4Xeh+i?uu#=lH**nnJjNFrJk)I6XLNV0B|kKoBB-lQnJN$ z38{iJ?O@Gpjo?$jZ2Wk_0P@0odl@#WO@A+C4f!a-JG|BD%OY7w7s-GyjM~gO2_;~T`w@7FX>W{aGCR%e*vUm9yEF?te1fP~-EMw>-yUHX?U%V67u*&> zE4z8sYAMxKwWe12XNxMUvN_sUpw~Mw8`yUUMBHP**Tl;LF^#5NXopTH{%-z?JMHzM zr6+N?!(kP{z}Dg?EQs9yF)&$Zf}FoilnV$FP0Q<_SnGlWaxG1eXGXmGBL?K!)9rt5Q;*m6J-Hv)oWMa>QkRR{I>i0^j@U z%>5k5H}93Y!?ejay-#3K}5V~k^SQRN*)3u+xJKnd)kh3i3)1K4Kb1OX7I1uYPODjmlw_bV$<*Fi93mx%`U+sULyD+2o`al5sC*Y_8*msIwR{@OYPqnKpToQiBi8KZvRe# z%|!k)Ub1MItymCsSj#fj{T!)hJn#q$W)ORmcMl(G(2R3@v3*MK3I^+=lwWK}mD6z9 zf^vXZTi&pSAyie9ge0Q0_E4p&#pAkLq(S9YO+%}BYbnV=b(4Ti0SuY`lvZj?kqgyN zA&)WXSqje;XW8w~7|fUD^PVuVrvmShO68U8-aofje6gh(?@D7cU(AbfZR~Qbdy8LM zE};LLZ|uhWJN8jYsmZ-t7H&NKd4HCbDOcyk|9xn|t zw!fk=TjHcwO4;rH+INc5&Q*CYwO0hvYL{V?wqim!Q{tOw%jY}TA#l7oSmQUJq56In_N0F}vZX97okhJhoD zTXTUaL?{i%>2O%CjM&1ZUHcU*#;C$^!O?l{jMQp7cX53KdhKd`dzpGM{Gt4z{IUG8 zh+-H)3TO9lBdo(^37VG`cEIu=+Pg;dJRY3NT+Hd^xNZ?;Z|2WG^CmN`*H`o=CvVa%cE8@)@Rz0I)vC3G%2Gh^umJ1?0frv2Nko)0MC>cPC zp{xZZhTV*k|muEWsLNNHPuypP?wlr(=a1! zxW9b3gWuoxI2L2w3o}3${i@Gl<2(mQNoZ+FUQ=vF3L3pvuegzyf;oAMYpMn2h1^Mk zjn#GK$C@(8UVX9^L`)z`B?_W;@NA{-8CDNlN8OviWtZLRG{&BDYs^=rS&r=1 z-wdw03C@UeIWm^^J5M*F?$9f3i&|@(lGd;*gA0}0BphkVw&khun;288VoaPR*Y9wxJP9g zi)TAsgCY;`BY*)4nf{bIFj*l~Nl7(Np^4LR{mmOA&AVRy9pfy~XIht2Bgj2l;P_|W zYZp=9{mUrZBY%!*MpO93%fBm9nJ|cQrttLI!6+WJ+xyRJStDgmPIWc}Lo09RV zVXMz?%jCF+mR{DvHLeoRg;+mXkkZIaw50^5G3Lk zsCUy-flreyaKENWgDo@M<@>#ZhApb`(z*@&Uq~109D6UZ{ilh1#0Sj-pB&En_~}<) z3(al#d|Sh@hGXc8zR0fL9q{S_`2g4sfE<8G4S;|IDWBayj-v*QR#05EoK@vYd<&K{ z!rZDpFWm1IPb!V|KVPWZzjfJgD{oxYXUV9SQrAmEtjo$X-qlG#aCpmPuC+)?8{{CGIZ8N5c~>I< zrCHYTK`K_lHcT@vp;>rL=fIT)6DhW6Fp|FB+Kh@8`%CR{9P#3c7m`|Ge6tqN$wjs% z?digi4p0O&m?IHE zQP0N#>;PZ`s{z3QfD8a;0xFy~XjLsOCDigi4(rqLInRgcP`@F(e(n>^HQ4Kga>&&s zPO!T>qmDI}*eCTW)55meT&UnVGqg7Pkoo5Q^Fw;NErs1X&?*9QiN7_+9IVs zt?N06zDp!=2lP-g+KlCq216JVfaTpaF!JSBJ@IL8JhMi+!z5ElPNq!9P!Grkz;poQ z0zgOz07jSn_wV*-!=nX?5Gq%4s%wiJ$mjW%_eVJ0NVTprm5+6!_lC|Z*`3&SYfCnE zorvyhQm@);S!Gkl<=frxzBKkKA$nJ!9X>vb?&em+yveF6UVgWQCZIOfJut%#uFq{X zbGb6%NZ%ifCv}OlHmKhMt#D{6tvN}5QJ1MHO?OK;nFh z7nmd}k+JCkoD0tWP}RrOVl0hOKq+gBIq4a+7r#93NzD@?Kdx$$9MRRt55Ze zmBc#z&Q`xkptAfUA+oiC&LZ-V`Y1*Yj99rkjA>!hi+Z9UZ`J)}-+e_!VubZwvh z)9mY&e*VfQ{QLCzKX302C2vi>Y6rB;xJx2#8>SH~)$P$Dc#*>Oh*f16vm!{<3|%21 zv=IVbi*emW$wg&tKH{G9v6_{Zd6-2Tz(vk2sE{HM;b%*Y5hpNHPG?ZU)FJ~OqRRtK zY_xBz-6Ea6tIbI9i#utsWI_G}Z~y=t$w8Y2BL76?7e$k1OqUAhVm?H|yh1vdHD=Jy zeKy{rv*+li%v+rYgc6X#gckJXH2(UuI~>~YjbH+1nP0s++!9TxMOB zb@G|Jq?2(2u`ze+?sCae`64iDjnAyCgF3?c)ysXwJ^KrrvRD%|Bo*T2>*0}v7CiBG zqA7L4fBi#i=8&aZ7kc13&Vau)hGCK9_4n|tG^qJ|v4VbzQeJi~+a7tnf=5D8uIF;Y zP~~jZ$A?&mT-&j{fV%b@iz+JDSl*vcUfBlHDPT*Tt2RiWBCu#fdaB_1HrM;ESc+Qg z)67PqL;Sp6qF$(x5I(%?@<59R$Kee-2m)X5sB@mdFm0BnaoB+05GO{lD)fjvxwNf< zf0*zVWS=bFXf+&wgH5U&^VJrTm2AQxHFGczSw_*DJK zFHBV&L0Sd<3Pon5o}=7TukA znxix@RKUFTnrT8bysgs<~8Z9d+54xb_P;R(th4>sQmGHr6UK6%r_h6 z0k_-7d7vum?AMrTp`jA|A!U^Q{?ZAftz1LDC(keGA~7TX2RUzO#38Wm;9u*X+M>2= zl>l5wmZQFPvlm66AF7vhw+*3CpOPRnlb8&#z+7iUOQ{P#PHtV>7GDd~*7z7gl1NAV zhOHBrpt@?@;otF2hi(+zlJ#ZiD(vKQ9PU?ME{nUT>UT43Z1hALQrz8JO)>v>widAX zSGfs&0V{E3F&z9kI)#(Br=XWfPXSY3w5CHWv$X5oE4aPu>n%N&wnLRMa`kQJcgQ=Z zg{Dx*H?m&*;oHv3gxFDGbKP!{{T?Ame?s$;{ZLuHa8?)cePAf4rXlxd5Z7wSY!8rp zl){#c|8GFCl1z`V4rGdL!1|v&I$}l$*b+QSvo*$zjlra6?M&cbE`_RJX-peUA-@a- z^v{@WKEyOe@|~P+9_)kzYtyshxS0k6@it8hEiw+GKZX1o%qrv{=pY5Q25R>t+rZOP^HMd7 z@|8^mvnLF2JX};Q%#Y8bp{TaeaJT87Kqd9KIF1;cFMw|e+>K`QOz=p0A}Kvei*0L0 zayx3P8TEs>#5{gT-k?6w)VWqrO3z0*`G!D`De*wV?fd*R5W?@|7lLQHf>xn^KegaW z8iw<1F`p$j#^135wWfGt^#lI1A`&!tnA;Ws8Y|Ec2spKWk;-m!}(WqlS0 zt47WZ5cC>yq9=nzq?`{n5uU}x>PvL^R_}c9MP{Qr0GV`0)pEjFi|%%vp(u3fSzUQY z#_LeFSWsI!?7y$fN<%D<*o|1IUzzwNuveiqwyJkc^_kwXo$+a)BR zc#!C>um+l&&kOg)9rz_IHl99eAjhI9*HZ(gu=%-0KAU1(szjv4xi!k1V|C7QzX-g$ zrj{OL{iRJ1O+3K7`;?^TbwSeT%eN41=3CB{d^>JTtikA=Ddh~R_HdIG&~K}0hI`eK zmyMJrNSg1O!l1>gtLL)x8Kj&VM)r6pcCo0{yZsf6FLRU`{s_1}vVV!)baBt{U_;TU zf&JtUl7ygJbXni+C6!<%wCt&o)@2zBELAUyU}83wQMGiqiuZ)3y7nchF%PL1=GDRi=N#vrIn01z7uA-4GE z0IGvqUO|jmf@P7`?{94n#?*W7#)|QVTEm!Z^jHYI_`{``%U$CJ6}zK;O^>SlCSs!H z03l&0NPM)=!Rk21s9Q&Fecv>mzm?mY90W7iU$_!<)nX*YrwAr$;|SYe)ALB3;r|jr z<0D1W*`j%N=l|A*tRcbjA7tkwAOXr8c2ff;(tp>aW+KK!PRjt#8oLBe;IVJO_gE!O zuW0^rEv}>xVfQ04cq4US9cHvY%6@|t@69j=8GwOLrqbkXX;F@;SubL z5zGaF5Uy1(@jdvnpyzUw@=euU3A`2|$}`x3@xd+4n4^W*^$sd8b|0$fyznde$_;=$ z7E|c{vQ5`ScS=6O>z!T3%}=sV2pD>h6GC1oDU^RFqbUV;D~qVdEFrHMu^)QCHi3E4 z7G4rtMG08I3(hEvk>>v%56-Y3>o^&&+U9iAb7AJjUj`hbZkg6;s0W&uLVi{?YfJ0& zP9L>qu^r-hk@2#MH>wB((bz4({IUEJ#*Au8`U(sfZHvMNcVEcBE-=SjKnESx!Q~>| zZ=hT+6$U@b>fYqL%qOB0q5JjBm~W@{C#hOrx(j^t`}Wz28=Mv7M)vXfN%*EuUfYM6 zEM5FG#1RMwfq8d(jP$KbBo6>(@=^>FRuNQynT%tcuX840@(>cxc=n@>4HcEG>HroR zsPDKXA0u=+m&Ej%#dTN8T4Vrmf7`cpm9{Z??x!7V(mQV0sXhixf9X5coS#!xwq=AqbWtN{~gqzGC z=7v$lj8WLDE@=4tmEEc0%|}Sz>$z7RS7jpS1Cs%tY{@_<=)?|mFQIj!X z4NXq8+uBuH)1=s5@#Er0eTl;KxtQ!UK*8#L-u#!O1Bi};hZna>X`4^Vci2q7K z#Xe_}_xK&|p=u1jk*=D?@n2MJ;s(d$Q6RntHyJbpnV-_4tPysFE_ zbWNy^DzZ@DD@3CA2B($$5KZreID8@j;wU_!g{!h|P81 z=kIhIl8sBNF}(?OunydR>I-X16!6s==K*2L2k8OH@+(P@Ilz_Y<`orO#mfRAdi@Cd!JliiLDeD?>I$cyd40{@ zxZwBoAja_`;4xVe02gLxm}fi|QxPYw=}wLx4N0UIS_^A7G;Pu*D0ZerhrP6&A4%p&+}7uI+R7hfb|As=D6Xge{g%l+%Nz{o225 z0>ms4$L&=xrvXUBppfwtNZ@YoFOg6~dhj=4E-BW2%CDv~%XFfWrU^4HS1H z%#zso|CG&_QIGE=vaHJKeAAJfaVV}X*=Htd@4KwGBlQ-5Ea<)%&;leSvz-@xU+vh~ zArnV_GoJ6-jro-DEFbx(`Wseap&$7aNl17mZieb2=|p`~>T zA0Oc1^27e0sTqskgQFEdMXu&78-=azjaNc22R@1wKeZ-g*#ZTAW$UG0(!gjj6K+BaFPP)escr8iee9*sqX$@>h$NKFyk~At> zViy-29)(Uvr78KhXnHBDRlXxus{Ginht6LJzkav1C*| zYtmNzAXb_y)1r16XvQ|!e1JN|drI`_2B^oZh;e-0KN|X248$ z;kdK0aW%H@vKua_KIDX=C^mx7G1s$?(INBKM4|?$6jxF!B4RO;SMVs4?1JK&^+$w= z^}8YD%yqPO>m!kHhy|>ipE5buZc0Xw)}AZYtUo0n(4@1qyXxL_z3trk^)f-@%~B0o ziu0?6;i;L(rLNtJ$WngpumI?upQ${2Zj%d)Bp0=l`f(Q$CEspVf4mqPq)6KVW^w!9 z3YV=9xSBhXP)wNlC-JM94kQ zikT+mJr5a@@S4&%zg-EJRqoqSXiYrVtjiJ#&Mj91smF(Tn7KNW^~>|U{_Yh2lDJ5e zBSLPl`aQGar_>GsUqF zJ_s6!8Nn^)YyEy?y=MnQnnNXTDHa%$Vjd30;=LN{_1S<8CPY0TpTGw&{@~X^Eyhw} z9p|JX14MgHCSOC%J#jw2s3N9J?-v%aO?>%apWKSiZDIq+I@aRRDeJlL-qn8m7%Dq} zpdA3L_S$b;^i!%-(kr~4^E{!gmJOs9?(_;Y^8w?9NH}_Y&mp&|*V4|ksS$%QwOtzI zOU)RQ@S;*OviJtU7F?!`vX$>G7U%Z4F1Xyo8Lhxb&P>f5Z!3s(EK}K_2>+SfN=Sp+ zlsJIHLfI!(W%e#6c-W4r-+I!oXks&VD4Bf)7c>5;PXEwXa=lXl>dK;F9d)e3)rhgb zVj0&3fF%JnJcP$ljhDy0>0iisdsJ)hcFAIin$tP!rDje3V^-4enw?53Q;xZ&;u#Tk75+Owfot->oLx0Eo_w(f31jouUe-6ECh>6im}I>T11 zZxgzU)Gs)-1DIr}y696*I;eB0Z8ZyekowJ~SZrwuRV())ce#ApptGklu1s`xB-qo8 zZ#2|53H!c4Rc-r3U~E~a=srE?{F5B{x><vlh7gJQQm5@0A`LDfaw`x%i9Yh z75S01W3T8d+9xn$cNGL8tdUCXbIxPQjP=r?GloB!ec1vQhAoY=I;rZ();-)t3~Xl ze3&tfdi?2SFB>!@A8(iC`>Y#?JiCeNP1Ryj#OpsFm8ea)O7jb41x3% z>Ob?^WqQK(UfJTsQFu$3L@5iSLgb4u29lw9YsUOJs3n7+HC-|Pl&YFePK3RpOtSyq zv>4frKODQhb%=Apj-26{%~wvEw&4ar6CAJ>{5cMznzLtDfIWXlbZpCiuD4k%LLBG7 zm4s?d-f9X^!b!^dkLRh>#&}uq;E+~v?yFtPO-l0XAA-N`80x1UAHqX0&18z!fpB~f zWQcNu$nK&z!EiE@VDjHO>6*^(NbTboJMnk(Hmt(=(xF19pm-Ib1DO2@H&>Bq36vgVfAV18Qaw(wpP}QK~8Gg z=^!R0x;T%ZZ3q!ZV9(=(Z}Hcx?Eadz^zD3Ckip$jnTdPU2-L#-h*0 z^0ow0KVVIMA&|Krwxz1*ito-!3JA#pXl^j5d(_eb!eu8F`A%H6qJY372xddG1mbVw z{UT}k%{RG57ZpUc38Y_+NB$|i3Rs-hMW?l?^_rn(!0`KYCpg_xX9FO)LQ{%q^=_;C z)>bKM{Nfdcxwa@v8VZ36wJGyj%;&K;&=?At1%&?IN|1)+buCdV`-D#zLau4hin&u|V-ya#Pf0vDHN*?ihlxq{g`rA zM>Q%Pe#wmi9IO#5{(fKQdqcNIv2m+3#gq`QovFJ}1AXwl0x(~#jru)>!6S*qIY7n4 z>=HhT{T(%vw{AFKS5v?qNm{jKc+1&PB|6wxWC36YwQ(1}rqtMG?!p@fbt}T1*oy>D zaruhlk49&y=#8uQe z!56HXA~$-6adFH&)@H3pa4@IzhV@&S$QK!j9&7m!)(Tb3q-{WjDf`J7VuCWrPb_zUF0mA|~y5OVwLF+7P^iE?~d9peszy!Z-B^wCr+Y&W8s&13~!ZB5yao>W4 z&P<7ef5Ro$@?y;cPhF;l8{iYlFn*5ym~^$o^Ijk-EZZTa{8|ei=O_W@^5l6`Wq2iv zIJ2q$0tPt}Wz1Nkt-)^P&ZMfa|*)Dt;z_`0glPx)vtK~L{wFQnKzwbm5sZ0 z0`|GObnf8MqG682V!x$PEa~v4a!qE|1Jl)1iWRP-xWotM28Rw5^+J8sL+EU+Z9iNc z3%w>GW&S@B;?)Zu?V-==_AIl$>)-H)#|e+D0!ReepPghnW*Kt3LW83^pEzBPK{OTM zHGN`8a>OuemadQ0(mu|(EHKdH_iqvi15KJHgsZ>t6){7V{J1zh01Tzz3c?gRym#m; z#5EKxq}XsfKSjDxpkbp-V9XgB!waa&ec42H+t9ETWgE8Qz$=;+Mrwe>t9_J+6l1!L zef?TxLcv%8@h8ut=8D=cIK3O<8JIL?=eG8{iiz;#bv?z-x8VvbRd8o_^)(;M4mfun zyeqLJa<|_8^~5U98>5z?qhRSikpG^entzhKCSOGdNVLK%tAyA{d^5zPlx&yGZ+dj1 z?;d6Nx;&Zom3Fmk4C<8>+qs2WnMkktRYLalXB|#_3$?5f5!yfKSpV_g$8GWP0eD2| zHv;!ediCmwNLJ>uJdSu8#u!p40g@qBIX`64h<0m5FBB&Dk%gz{JEAT)e8kDXZfT6sgCuI;Qh~YWAD7Aaa6D zl|{x4O9Wi4M`Gcm+1WI&hz1@l^omAMos(*ua!BRXL_+vF9KoToaislBT{VXGwK>5| z)BV>Eri>R9r`$)Tbw6%TmC_k7gC~N(L++HP2oRa1oZsRX`|~HcTC!;r zb}4|u?+@H8&+iwag;{pXCy4x>YHv7{C7?ep?Kw1`Qp})22DprMO-eSdPdUW6e z`o8NmQaNSUo6Heyi3TeGrVC;Td+udqlfPLYMa?XcSlx!0^?}Q$y8(s9mOf~+<%1Y`jYnf}cftrVnGm#ljS3^IGCpw=Bw{N8layI|YkH(NR_fV6u})Zy=9L3fq3YB!XD>b9-e5qogPs%H*{L<#COb0lVN z_V_zIRuE^&hbV(vrj=CkzAXngE5_YC%z9G6!M}7$sZ^@wHgR~w&LzA&P9uwnbu(*0 zZYy9enuTnV zvly6z{s2h_m=53)1E2=LeLy|{IRGI{{^$gK7_4GBaaJi)$l7xpt8I<+<{neS;P%hf zYaVOxaoXLtg;5ZmDf;nUOV$(Dm-LMvd-maIs{LAs?&t(k?*B)YOKu-~=F^-WWJjF)Bq50QX+L~$! z!9KN03Y=(-sLpZDq{gxs3xsn7l_F*ofFhyj+1w)2A}AsgwLo!zU<0=Sr~~5w@PKFl zi?a=k7HE{FkuFs7IKi{1t(`)SHpf$B_B;ES@|Q|w|HHJ?$Luq_-4A80|J@f)LH9d2 z-6jBOK$gF6;ORu4F8-TeaPsz^IX9`a%TVH>w52_kau?kEsm#k>{*!&b_s8{jQURlK zogxE{CC*O&h}E}J%1$M`63Dp~BQ-b<>;8?6bd9#@d3`;xh8z##o(mE&ViPggP>Lr} zOFC|nkew~7Dd^jl&`Qvti=e%R_JUOdTP@Y0g35QXL#dhoFbFXvOf^lJ_+GDFrtSoh zB9jgSm}AF&{UWCBZk(tJyV+4Gn_0Urlt3g#_6oz84j=$J0Bi@q2h;*U5v6~B_xm(p zv4qJ872H+chmke!3)jN6Xy@0MQLuMcIZS&4Pq=W3p^apO)*mUws~F2IO6X(HB_utR zbvSV#$*P#wv*+jX$!^?7#{QgrA3pYg{8*BxfmYK+CWZb4PVV*j7qMs(G#JNuIy`#I zrxK2?DBr+0inwI=QLBAg=Js~caCWE{39c;RWc6t)tYizE7Rn}8a@HXeEqC(nC&b(t zFCd}HH^rDb^Z9Rk^(^h|8H?ozYi;daf3rp-GA&3;yBt!%;?Vh!4RrcWFOR&DV|l1U zq0U|xXR>;8Mj9AwZm9`R(JL9!A)Gq~=S$&LWfc-KFKYogWAD9bR9#&8mv&96O$p1E zhMH7nuWMC8?p>59U9Kp|h}HDaw{mnN>;I*fMKtv^UFs>Q=vR#eu&%976fot1iL>2l8# z5uX{r1H=ck1ONb_03RR(DWBN@kh2DiHZWPaX$exNu*z0M7n|g2QPSnYbry%^M&s}6 zGiG&jt3Up|#A5Q2u;j|vcbGgs63N5^?y0=V5MAX)i&n)B5=OI=y{?Utb`W&}*pqm; zD?ar7Yzfi8YnW)l=2KDMOeUzH>i)|ll;vI`QlPijQ)rSr6o@b;vv?v$f6u(WzyB|a zvtyQiUeZ~HQYRz{fK5vw6yH>sCAL;QI}JFJK()&HV&N>uG}O+?GaUe; zV1)$?Ibbxj$9gy>2d%O4HpcSHU%k)8fw2=;}A9Al>>WzS>)_ zA69Y~VeI3(l#^A39vo%ylKHY{wSkASeI_ zPy#fs@B05{D>N&#%hQ2L=!o0G_G|w0gm^RmyjWars`@2PswYE*^XvR9&jTy-+V}A2 zYX@61?(tvNVP?{1Xd7uq)Lct{BL+}6_PMiTF>FO*v^AAT6x>VkR;q8&IVwzoLHg<$ zWA;~U=xp1N)-?nbGYJRZpr?=a+2dZm@T1DOc<0rx8>-#LdnxUxL~1qVd!+EJ z8Q!#JA#0V!(z!~O!OaY48gmf`$=!hHy}`}hU=uM$P_PleUOMlClobN$&N5hiZZ|qM zL|@kZW{eh4St4A7yU_MmJB{7$ZyN<3&V@T8Prjw-C6KCfk6XsD=^lOnT2zT%JbGS~ zsOUeS+r*Qgr8>H2O6&VM{QR6N^7nWCf4(_+rfIR^+oNQ@ec1i`^ZLjG1y?|tRrWhv zH&GX*m4@`i#F05g+=gNik?fV;mzK^WHeHmWd8x10ewmJ8UaXUy+!peeDHT{kcas>O zQp-(lG*Glcj=83_qw#p%+`hw>ssHL<<^8Uc%izagC1(7o>l0ZOJI1?K95#aBZuwE*~6=u5_S=U4L`rvb= z#AfaJRs)6%)^9F4gG?`0vuRet;)gn1@82O^q=~rcWID-T^4J$^go?2QMMw|ffsd6)^lrB6mc}n}*W&V3@p=SSZadPS+(bO-n{)_`qNgEk}Qc_Jknd-tiuXsdMkLH72*8wyn zaF$VOwK#Ba?riDi)~9`Nfb(k1lC7$m@{5$AIt2XD-hYGj;TON z#8HN_40i5T&ZpyKj&kXf7boS#+0PSCaAIMwq&+|Ev_Xp;z5XHVCR?V9YtY{jt=-ND*v^6kRt{w64s59@>pDdPU! z9A0m>^AX(m!>{=EU!3|D2#X}^f>5t~l8`p}CstEn#gkYPkF7jdhMTy>@YKJx1Bncx zo@#KN0A;?>1;V0RqGH1P6O^*}EecfO)`N9BNu(!AhAnc2D-k??9tozqy6k90UAFm@ z@St4)5HoCHPEPy0i^BVTrR0+z1Di;|<}6j^gzk9c5B())8IG0Gl6~OaWK;q)Jr8V1 zd@z`P!@Q)#V6zF-OrJG*5ZnIaRWJh!ud4pmq*4l;7L8p9>MCfdo-ok98!1P|(7n|GV`B{IoJYWG$@ z{3St6990A?5nF=BLQ{u7tjAimdhRY5hAssoUB}_g@}*%D+*D{weYiW7X>@s>OuA^w zktUIh;C>VWCZZUj&}e{*HGa*cp2Q-8ngMkgXclN=f}dEG!mMJ!YHw}J`f3XakKp~+ zv*)vjT>aBES4rCID{A~J+b=9;2{;pc;W!HBFKoU#2G_)|>{}GBET-!?FtNF#hN3G^wG(1=omaPb6JVAvzqUcD-21V27XKthB@q2)q;>u?H)zj*?aHAsT z*Am&WU$$#Z{x%QVO99`j*Qn!dcGi!Q{X@f}&mJ_buj%6>_Ri}sc4mXwGsYcHkj7wx zxL=uvg9>kEV$Z+5|kjTtshR)b_r{s`SL5QoA0>Q(SVVTzTxdBibg zO;Rj5;`^%_IU;w3a<0z7*6bISV9txu{dFs*dXThFJ>)NCsQe^d=YBnJ$rIqft+zV3 z8+ngZD=#naAvfH){>iQ^+(eW*xcHZig3?qHE|woTW>VAqp#BbvW&#~S3%50xFAR+l z8Rcpgykq-Z$m=mzN_s;ao(h&bNC#lAtDIy}xdM7i7{SmsaS_nFkDmr@pY)a>QtX>u zs2F(*AvA)Ie2h&`#LV6 zTY>|p=Uxc*)s0&oAS!ZCrp6I;)?_&!>5@to-y?Fdo@7%6;C|a0+_Xo(c%%{eVC5CsHSppQk z6@Ea)`&2$=z(Y(` zTVmVo`$+Y-#>!U%Y|@G}GH&+7^>F8)Fj>?eqv;*vH&2v z)*ncfn8+GLC2C|silnkDH>A83fV8ZIVT@o~Zb@hqn%|JGxc%Fd1C<%jr0xK}j0O!w z(J^oDlebhI<>p4$T2XBC*EdSru23ThlrOm^J+ylglC}ZyRe_VCcvjxnw-+G@0seLu z9mUOz-H@e%&=;wG)CUCBeXfvw*}DUcL)wLVu0KL!_ZRwgbEp>kuOJ6ltw=CwH>0U3 z=ti&onW^=5?Aby5=cRy}LDs`uq3?9m#g`q!&Ts}0iFV$U^dQ?RcSz24rZ;de@X;-r zP*PoMQek~i-3`NyS<<@#UmzG6r(S8S(|dL+Hl??98iC&!gJTgGCK36BP8;y0vjh3| zE-h_4AXvwG)}bCDdEkoc48YI~<|XoAom)yqBF%nJum@5txw_kvTw6lOEb7Fm3;87e z+ra8Uf(Qz{!T1C0c6i{};h06cM_+7@Q9d~A-0H&g971v^sLt7`D5FD_!$ma#@ox{KA1D44|x8KaGq;RwQiO_ z4r;WiuV;JT>m|E0p0WlWspGuqb~C5=46=#|kiE6x-3Rgq{W9X~=E(4ehQys83f@}~Y)qMndW@Wf@Zm+E29yymQX4aNB<}$g znx(pXNB>q6Ki!~PgLK4j(PYxW2agwmABRx~NF8{kn3LnpXu@l>kew`iiUD97UGqpU z9-$o4Y(s9q4Iqng1(i_bfv>9o!J+`s3PY#eaB(NbXW+{AJD- z#YH#JHO33BVIYCY6)54a$15&+%z27n>1C*t5JabmSRfE}Oh?@=z+^Ylx*ZE`|Flk| z?ON+hLRBBYc?Z~+MDy#nW&1@KmU5%QZ`mn;6eKIJ9?TGgno^#j8W_(NOtm+iiM`6Q zew!E}IgKoKbP~iX;km@Rqs7P}d}xbXEq8e6*VqaV+Os-l8IYJ>$+hfrG8a9mm|WcA z9LG~VI2w*%Ke}!%^%T~AN!w82;z{AP@elxD&lrC!E6DIM_YV#I=?GnRClym<+$G;Xn!jlZbxH2~pr3=1JGMrqebL>4P2X3}QB1VGuTm*Za_XJXp7 z6KNEJ*e@VdBfTptewj`##-29M`$SL-7+Z7zO8rQ!hlq6eOiggA}^U zosVX-6J}>;0#=IEh9L&UX0Z} zaJYCEdEHmlO$p{e(f4IM@2*&ssMB1naE_X*tm+U%dvetkfuMLl5lw{BQXkw-EGBjy zWQx8;Cb&!+quF0Z$B!HbHLBlb^`Tt((fIMoCA2BgnJA_uU$1b5CY*+>WdJEpgBem8 zWsn;fgw{NdXJiWFMydU_5=2Ep&vNESU~ynA;CKCKh=f1nKO(0}^&}qXLXoH8gai@9 zR?mt7nt*B$6CKs_JUc?Y*6%yhFNg7cNb8+=>`%5MoYZ*5_DPYK9)OE6A&Ai=5spU5 zMF3hhuIcT%O}Ltn7M2MALj@GeTYLz^Tg(0^G8c_wZ7uiA-H04Rb_xEcLI?oUmT|EL z=)2xx&8*aGxO~{_72%aSA~vuTaGXHhwIPhpETWcN2;KxLI$ur6`%c*?)uALa)`0AnT=0o zsPLl;ZH;bpVAgA}g$Jru@T_gtNESN({b4wF{NvAwH!~|g4wFFfVk+iAxKDM`*`8f> z2mz-RdI!v1QfUQc#|Yz`W~pD=xHJc><963SYt-BxW;s^G$9uX)2?<42qEz;phJ6Xh zcpKw=yIFek#}2RIGlII}=FmV->T`jucjq4Tz;^QvcVO9!b(#}mSK|@_TD$z)7A;ii zh-eWwMfUYkTcs$Gf>2sfCEQpzjKbp*%AuN)eHkOtIC3b0)UQ6UF#^vz8%1nk@ITij zB;UlUwL<odOUqx?5k1kWk34`xNXpzjG_# z(OAguh|YpbY+n4c34&%-8OT&=zZRGHr?%>=;OWq^EV)L*DHC0Ev!5>6SXcouslP&< zUeYHWaabiF-97DuW?J>&-KYLFksqKvDVPolb3piPJ>(=CPW3^I96(C#a39u6khvv5 zjqZ@=;AoXeQ_z+{RGHk7_TX~Q?P>Z2O_vZ3u$^Z+v|iIx*fHY}z%SHeWZ*blV;Fn< zo*4DL&w`>8zg-cHkdu;j#@!Io?FOu6>cj}xp;sP-Xz(aM#_RAVjZ}Z>|GsB}iSq;X z2Paoe^*=m5NLv>y@|K%@F}~}dx@g=0`}rmJSj`OFiWG!VXO0o!Em+;G%{K&y5J9VP zblL>N=gi~>eaJRsX-R=}^y_zQR@G_~k)mP*P_n8Ub*nzj__o-^(%MgP04>g)clLCT zW#mtJM+X{w_hE*Cq@)s-UH{G|l`8W;zi3d+|!) zFc!cg6lj?brrI;>R$3F&`Bl0;z?US_G;mQUfNGV&fhLI!V*j;@`6E%`=ycU~bUd^3XhLW_F|mU23x>0eaZ5 zWecA0mm`<_qlG6+c}s``I3%F(`}w>`7Sf9(%sPhq!}zX&uY{D3<^L4PKHQNIPo+Q> z*DNH|hg>%fjd5}OAdWd0*nfbN%XU~)CRsK;Mb&=qVuM(b zk2@E_jofMrqkk-*q~L_Lm(rKjrixb1mqD%^xPW2vjON8iir z5^lK-9=WhtVf1Twc@hQVI|0w@=D~Fh-qul+RaFr(>6&^*<%+0ZrYkfrwsk+9Bq4PU zr0H;?!&+&I5 z#Zk|))s(&sz!?OXZn7PqAm5pvYgs3`U|fb1c->Uy&Jt&r8BB4==|)`&TEwQoTwi+~ z!4X?@D5Y5_6wBC8_~+4OCcmKV0^q+aKNZTD3u4&zC4N}V8RFh z?H>}84G4A<81;yP1OJ*{eL`Hx-2)!$!!W*@ZUxutmsso3?{nIRsVt}}Cj;Ia!Fix= z7$|@SXC`7xxEi4fJxZ{vdDst7mOYfDdTyiFxVUc;Rw>N<)ksKVq2H zTGsayyn5wD7PBrT-d|I_pnbAxHMTA|I*XOq5sF~_LI>lVTW}3i;LO@y{9BS3#9W*_ zpm0Cp<~g2iK%&Vr+7Qcgl&4&%h?*X|s`}%|A31*3wUNka@7GDcTIt*WlECfHprYgPdJ7OqX%l+O&XUd{f?m2;~cBrJ> zDI+`D7^2-zTO?5#C_~6BBwj;zLzQ8(lR|=_{l*4GYa_b(H*vozFNlgxm9DI4!5*=l z2)EJyk@E@xn*j)0LVzdbrTvGgbis|d#>x2f#zrIa4DYJpI~wcS%v<+FgsT;Rn_3(X z0uxO}Sc24M5q%q@4bMWUq3}eI43XkU=4&hj(nSh0`UQ{Q*AOCxKH}%sow!Bb?z?`T z7-FI^DAs6wyb%T_iKVM&Ip9HnnmKvokr+Vxf`!nCW)#JMb@p!X$L2>13a|eIQ0yTA zVz>U8uyvtLXco@PX%Z=oDsWrKtRsf z1;lA%5^ZHRxCsSfdE>ob^Hh5SVAdG$B&nvP@8343)80{Xx4PiE%Nj_0i=D!+!%hA7 zy|3+2?&|ryw$Mi6B&Ksu*!r3f{oZ+lY{qQ$@Wse1C(w-xS`qkcm$$UxQ~uYCn&+%s z*s4(om_qlNW1w7lUi1Lq8R$|pOq}fopc6hhT$pKoT23DtvnEsy7D@gDQD_{<$}mIz+2Jah={7~5O|4BaG5Mhb$Ss2{O$$Q;U^ViYD|xjUQy zK0cxXFn|rkD=}W&gpnlbW`%ZUYLS&RRJD3a!nZ18ajHw0U>Rwph2b@2d}H12Izc#& zFjyG2hP3z0p3!=S@lTLhwxxz0`z0C4D=(;uwF+^_c1kbJs6-&s*Zczeg$NjWL}RD#8AAhqNFD+6 z_!WJnWqDMNWASwsqCB(?%_b+BvDjC;`Zul#*U0(6wlzOg*h6z$3rH`(yEZY1->?Uz z=pu#xZ_vJ|k4kj$rMlH-WMi>{F^VGLD^8#M+;|{f>^#+Ki}NVAJHD(VR^)BrxV$#A zE1lAb$@=Od!`JPCk??>0uY;J>34ifiM(MoNF)1s{!Bkp}|4`OccTOhZff{LzrGs4*Av$8)Y zq)0z|Uhg7lTh-ZwVwN?muKtwsHN~$vZqx0?1|UKCvYSgiR{P=UR8XQ`=$+VFDp{LB zWz17v?5v-F=HQ8l{269IAKVbsh|AP1lyk?a7q6C4Ya*(Yw3Oc1?@Z7gjy- zD%t|142@ZkJ9fhcj|$306?6@^CW<#!ZIFC^r1`GLbzL@Ab(tt1RcJ@5V=1+n%xb_M z2LaWMHWv(5%YU}A{B#Q?86l{;FW)&A8zVjR8e$n8mVUzgH!7?#x+?w9dioS@t++At zy49PP$z@1r9rxRG7ZEwpmWRQqJ~uB{E2Q2}VS&o}M3&q0D3&q=TpE|hfugx7o_F+Z zv}iTfce*`CXypn6lHoRe3)&J{gSm}XnVu^$;kaeupV z5_%f-JAsxUTS|q)Q-@L6BUEA*BR_%;IV2Q7p41E` z!3$GF>CsT%+z<(QZC(vrAVGYv8)iPiUKl!IdZ>+!MdOe2C-byn8=VT`5B&h|-`DLlae9GU)%HZWNtRMx81tz`HY3Qjwf@$40U z3+TA7CDA)&$Mya4ou;s=ygi3BGHB;)?|*B%(4j+IZG`8@b%nJEx{9}5K0!0tjYoB8 zgxb@89r!MNe~#AMHGbL9rESh88ZBvSzyn4&+XO+x8zja~ammL6=X%Qfd!EX!F8ppk zy_Kqb&>pT@w#e7*CU=Sf-pa!{--_O=LafN6Lf*j!k40ZU^DiB--d^ipzi{Q8l!_ZWz+2*(M`2q zR;mcR2$ft`Ks&}^3K7Q{F*bP-kHk@Az~7Nk30Bbn!E{RrejdUw1X?S{o;_s%JzY zlrVy8nGQXWzmd=%b@!hje4=<)>!x*2R|UUGL?x{799zb!_5F?LN$NljSkd z4n8;nRS~;g)_c0`5%PAuHWa@Sb7)J}vIoK`5kz#7 zQsaGT;iXRSJ?%*_@BzJPLhyFrBV`(bVZ|HWz6A%e50HNbX>@H`okMmowLBu}RRF*Y zfUp?>ATR^a0F5vE|KIGnrt0XjqSt$qaNls;g$4&nNgc`hDJa?9u+@A>|LZo9D`$b$Ye}&C~em z?4zQ9Rx}%i*Zo3kkM({n#)fnnYgpu^p&a`?2*@^*3A-gbr7PrIGRsG~b0^`F(&f8U z!%#m94mGGW4@8#f0yf$*B$e2%kKOAhnq1}W82;1Zc3LvW&88~ z<4~utFI_`VfmDh!3Zh? zbhlUi(jOlXJn^8|O>uzhHc-9Fzx+)0brn|@(iBL0?Y`rA>tAN_PbjpL=Tj8)tT-q0 z?z4U7NeSH&lV#vaJKAp}!qU*vN(;As^eYQPzwFlk)+<*dlg#lo|m@pIz z1_HuRpjap-3JF5NMUezXs+aAZ@ubC8ufC~`ZAnY2lE7VmeyshGe=_s$>8^XdIfnn` zUyJV3B^JL$ytn;)Y0h$r@;U9bowVnxSYuPUA% z7V%c=-!3O`5Ca2PTT`z-P`H=b`8hG2w`7>O;xQP$DzHhU?tWU`N$}D9ViRr{3krh8 zfUr<36cdF8p+XRlBq35qeqVpgi7u+{kx^F{GU}XX0s0@TZ|_G=u9ItCqW%9<-S}Rx z;O`T=9jWtwgQvWBeEYW5pX}`Q1%0RVBl>^7eiDaKzh`ly-uTViiCpK0F`Kgu09Q_3 z01x-8GBj+FZSmvX-vC=KSzNd;)#X2hGlq_PR+!)8z`O5T7380(1H&xujnY zmi+(x{R90UQL~KB6OLc{iDH8-d3(L>E#M~Tl1j?S+Jl8`7j;KhfZLshDG*qYLBu+= z1N)xDjYAWgo()mTFI4Y?9b1l>%;AjOXk_G$##qT~aV63h3&}Z>6|{_yq!h$rTH@@# zltlPDL?R$G7z-J~!Jx4aEEEeF20<{8gy0odn%=VY-D*seHB)lxB$m-YSDVzA={vo> z-^V}w!>0K^Jv=;Dle@&+neQvLc&9AiZAYK$>EL(JG-`_&4_u!;+}~uMZ-g(O`*a~s>7NCAJi`>&QW-(5);&>>x((Ybsx?B zE8yJC)ffk#O9;vZERf&k+cYz4tUs2EeQc-FVaKesbiK}y) zYzb+q0c{V4z2ixt`0~?MKFPeei-zavDfW!hPWl zNDPQ@w-vor_gGH^0QKmyIXgntRWp}3(tP?;Qu)MBvic=YaN}|bl3K)6y;Ly)k_l0_ zvxfJgo$k>g#4zb^a&RGr)~HUz)f)5#GpQ3CO_b_+yV>aq=#J;u?~QA6sQB(;mOK}t zmVK5HpTNX-uC|+q#m+SDm^`7v?MY3go(4p9=1Vp{hdOH=dB}vc^7Y+XH->M)w-5#4 z79VS39*3P~Kc#aB%+X0rokBd;iFoL%UV)kP`J=9~8s7LF&(e7o3hQ+eM2s+G53OHM zGVLxZ5>3Rp^l`+wBvfd9?YfSHTh;KHqzr5 znE$ESEs2o2&F|laSEYSx`g5zr?y7!(n6(NbRWFmF$KyHw@Oo*%Pi@aMmzY3lQf6Ut!d91%i}xR?ljW-wr6AvJq!WS8so~|_w3JVyz+3pGBQGyJU!zF9S#XC{ zqA+fxJHMHE_CX8QT=Uk6uzS-Sip3kSWh@QO(-O!~Nh&{c((zEnvi^!sIl~>G6h97zNS6_O>kp0s_N`Fy zS>Dc$?u$>DNQXh_#8uxnX_kCBPP6HH$OH+@qIFMOMs2 zqTY03e1X@uG%FVk6{$w40be?dn>2zRyY8-1J@I{T6lFX7J{VB@#9SLf(1;t}uoB=) z0aa{z4?vochcTw$&9Ao~BwVf6eyo!LRyQkOR_=&$TuT>})nz**|A5Ga z8O`d^D?yP2)K;_=RI7v|ikQon@(mI3kZY!1&8YJ!Gvh_VP^TDd-`%;S!nF;WQ=>=! zgjUO!D)0wWs0X-N!8w0@k|Tsel@sF|L40+O`0Z3=e8^(X@Gmb9w@nP6()w<{EXGI_ zgf$>=hgjqPru({=sMMnb-vzam#UmHRrcmAOQ(P7>?oC?!Y`hyOoRW5d4uOkTF4$tB zd4Fp}Utm_jgmR#Ecl<>o+ngSJYXj)F+<4OJN={L$?oem~o+*)k_?eQ?$^Zc1gZON@ zmV_V)6OVU~8p{ZGv@s8-*lqD-DROL-0JuvK*p}xJcp~|j`dg0Vg$1XLeBzx>1;rCq zKN3NO01tqk%%Ou##BHawd-R(jVgNII#0l#VZOv(zyi{{T%{=!V21uN#>lzZOw@IC^ z*+v{!AXQEAgF7>v>HUeB0YOpe=lqq-Q~<~Z^C5VMF3 zrydqfK9uQ&daE<^DmTI}3Jw+MT_jdAtS<3uNb%ETTmWvL88w}Eg@;qg>F<4Dm9g)T zzkjSlRJ~#kw=7qLaSt@ek0PPj(|)q6aG3uqJy%RGIDXA+1hvmCR*S95j3`)GyrB-c zeaQ;JroMB|J@Zuo5VH++K?H=on^JY+)=yGg@vz}O1Tc{O;PN6yG}y-5*{a_(v5V*E zo`@UuL8wFnwUx;rN?GNw-W6^9` zOkO!y|3Zk;0o5%qYToV+U3NV7xTW?O6;D8M18ja%wAh} zfi|ZlSCT|voXY*|z{pu+#k3UQe+~rttX9eT3Cmif$mBHzOMnnkQhB`MbhIQyM%&}O zp{OUpZcB-CVN0Tykok@07!EGWoO{A((F|k)Qe4fL+p87R4eM{v!DEQNdt+1^7wdu+ z3W2Vr2OpYaIm0|$?Sy5d9|^JI3b>6Tw-ugCZRbmgOwY9GPuGW* zpMV+9=bdV^C~C!rfytxtno$a|vX#IxuBl6j%Cedr>F8N5#;cu*8HQg0Qi-uI9&1?oPs(YB{||*fLAsTWA>K{RCn0<5$WczI}#VB4Gx>q z%h-$|P&HjG7;4<-t?vvqu(@j@yK-heZ@z)ga5>Z)eLq9mh7IRK8(&TxXn#4{tH4Hi zp61Eftjb_z1=hMzlWl58jX;F7=&bHyIP;4uNiF$uHB_DFnq)m~E)n zU!FD6e4`E}!k&N03}EZy_f1K+7STXze0pKM$SL~1UpqDvU3jcJ(nG&bKZ53dPK&Fj zEYCSW_sbjwj@cg}`hzY_)SsSv>Iyy7D5a&=>zo;+NJ;d6#qiMyVV6d9fuxg)mvRN5 z-gZ`#UT!X`LjjUA9HCSF#59)TGUBayL}krR@#ocpy!ILz)hA9E-uw&mEyL6^+`CF` z7)juxd^F7#mFPs8X196Pi#W#Qgo4laduUuSU2FHG2VbnL&n>eWt!Xhd=Z1$Rds8mIL={<4OykIkdTP`pb8+08S^ptHja$kX3zfJP_wzd?*jhnOY2u2UFTG|yG zDSy?p3`OuuobBDGI5;bAVGNKtF}`Fnb*%dO8U@7T^ba&Un~s;XB9TA%DX|^=^tUZpd{nD6RSok{a2R^W64687j3&Y=yFg+~R@D8>A6=OF7#TF-?=a-EPx)W3C zL)QhS85XCvvtLRW9j8d5@It{wk97O8@< zRRUA;bp=xln|61L0qZfjQ9+rU8q|52jKNrYb&S%ZgOet9A^pBXONyM36D=;SRJ!@X zD@exUoXQJlFiy+v2USpn?En*{Mo55f+X56WR{$?pt-;LtK5^FuO`FgEo@M_kkwkrZZsCGt(x!5z^ zLOm@MA7%(GT3nLQ>G2 z7>9fK&bS@szf#}HJHXUo#i%mWv&Il)KXA?rLYLBvhO5-7DfL75?G2H}dz?P9^`OL|rsnfVlagK; zzHfmx6a%On$5&(1a*rf>H;@-bn7u@sXD%ZqFgG(Ygq>Bm5W$sY6q`g9{J_gZ_7=J< zY+un=2bSLwqU);?kj%iT3;w;{dVuORPgr%&T^XnTXD}fu6nBbcr#28Y8X|da(X@JV zXnDB}1-H#T&HE`+J^wj;Y@8lNtUeXS(>W#b*qKDk&H-*HNkimxuZ}^)YW=7Hksq!e zFuny*9L?m|^)!Ch7CnZ+JWasBG{2EmMF!NLDZqU>c}KXV2Z@z*1T)AeOBS+qd9S@E zoaeFBiuNlYOz_!~CZLk+B#?SjZ)=a<^r-*{P6Bi83xl+iTwr~7Q#*<=9w1IOvVb%T zF~+U{vSooA-82N*DxG&J`aNzXVlXbe)xq%nwb)ot)R+LCgcEhtkeAH$2TXP5faA9E zdrfZpja#>|Ry{)E?GEr+(=qjiHz;FWZbqLJL{T?rATYZaGtu@)CS?0{L1aK}VfOeM zcDiQ=r$nr3d_!O_35jhd*F?%VCoONX@V5R;vN{h*OH@+j+>w%?ar`f?WYv9yQ>zw> zpmcA19;LF?EAFj0@n(7lf0_M7rIF`-5_$0$I7Q%TGaVNwF$yDTIuDrv*(<(PoijIS z*d`=s$H(`=BW6F+>&!zrNGY`@;c9XPj03A{svZjgR@r50m`Xjz4%FHPfBYk{e9EtQ zHWG00!FF^K-O=E7hj%o8M)2I`iuqiymArAf&j!O;U*J5Rb&7%mG`53m}Q%iX|&>G&T z6ZJG%@2aJLM*~1}4D~9DY91^5051sxEt%Of5qCw?dw(!~Gr(2hVntr!xIg+woO__S z8>_g_9nF=Uk>h)3(~dIn`~dA;Y@vnfPs%1H@WWmLQW8mrY3N18qr*&#`-s0szmMiL z!aXHlpN{`)q3Yw8@cZljdz~XHEW7%_r9IZeOzCro;^OW7HU=5$!Rc+htJz5mYm~u4 zj~wbVsX-Ha9uSArcBbNiMBv+C`dk#9G{s3fCB+HGYG>vpLj)p+CQ4_PE5-xWf^&38 zRG97)l%d%seA#d?In?&uNuJKkcSyPI8YZt;(C?)46PE~sDa)9dG?R?XeRU)zt7FOm zW3&Eg#)4z!aB$ZjSs7ufkME57KmagQD(YWv$uMc=O;bvX$y_~#1tMauF!)wpW-4z!kAv|m$ z@2z{a3Lc2R{6Q2L5@C82d=O zYqem`7Wix4o|`~Q6iiTokbU0%;raR7w}yP034RHbR3krh+9IHFLpua3;iq->fCgYl z8<9u3^;OyDo)o1RXDqMXE7(#|pFAOf!@xq8JGghzsi5%Lno);OJ=iS3u!WfSeb1L= zl{IXAdYG_v;%Qs&z`Q_`wVq7R80h z1*z28^8UL-KzHB=&v9q3GpRnVo01VnY?JOk8(lJxyq4cIzge-wZa^Vd5%CP;7oZlMeCCZh1iH&8|*0mkhm7w?FJB4X|mrt+O zEkP;m|Gm2p^*R5BySFVvzI{E&?zfF!HxKqqfq#bfvmh&C64(pWBwI@XeGk?z4jXA?x>nCmDLrYSSf%dH{n8Y$b zm`qziDcO5Po3BBjODMZ$1eAq+LA{&=B|-a}AHV>fgP>Sw78(VFgJ7VDC?*OFf`cL$ zN4I&zD_4zGNhai(Fx}EEW6R`z|Mh9H*tevA2m4oF`Tu%J)zhDmK4s%Ecp!{L+zd`6~^Q-gaDpaU@{GcdfJ|ZOH zf+Q0nBlCEt#nBke16|9ng+zY{g*)#lR7f*#_MYn33#N19olDzY3wMAqB~89P3JdSp z7i!~lqC>&?`4gKRxP#D7v0(dzVl*W7AK!5K*d^f1I12^>fq9C{f`%a=M5YlV z9(`T;@0*vGb2JsjRY@gYBv|qj%=~HgdAPsEF3Q`#e*M1b;qJO`{`_g)(?R_k{Gj?q zFX}(3{CK&3Gx>(P;eQRVr^Hd}Z-h$C#fwNQQte+MKg*{AB!~2V0Gq%wc_Y@4o9l%Lr|aHlIe zM79gbS19Eh<*Wo{LI1D!fBlMJ&{&QZDg}cAV4zrVBpC$+K@~Ucd&}#^s>@_%F0~?G z6qK9L{{G*Huh8A^@EUxN4(|Tw@2PO{E`54s{Xg`qOnHTHY5T`SRI&5_i>Unqr)`fr z%cXB?=r`GdG-3+>d8R(brYa^of&1U=@S6L*`d9Q~`TXx&_yTfYAMeNi77ha+$}Y}&#Q#XsZ!?dCB>@gp<(6sdQV1Xk5Sn%_37yUz1lkJr>gA?)az!x zj($Hr5;lfX zN_em7Xij|CVYDxiU{`Vcf4}|LFT%Kv|JXABS=kT&Aq9)ayvRnW)E$s4YnodLc z@#WiHJ@88P>LxKM;}AoRsOz7cKM3u?C(gQz{P{8z1jiKXi3#D*8Pg_~036A@;W(m^ z2H_>LP@SxNaYsA%V$&-%XCF*#%vW;^<^uNYc(n)v%T`A_8lfW#^w0-%L6`{)u@VK)d= zxSFfkSMVjlH#X_A*oB&~P0u=(8^lzc?e1(CN1FIZ;5tgWOzvYU8#stFLw#E)^{%X$ zdsdgDZ@QkZz2_>8NiBh>Tlo8GDrYRod!;(VJpPwGK0?6YZgD|P5*Zy_>FCxs zSXtHD*y7V-k!>LdIEAkzsGai8QM#eS5-TB|!*qs~r&wmsI-EtXsn3d$m4jyN!<*ef z2-c_%S(E|{2#Ns3!qFlk!pO)7Tl*)~GlU{0aF>C)s|tz?0EVQK7(lS8oWK2e--P*! z)hL*~0EsEd_W+O>0oVhm1^{3OFcJ1>!Dxj_5++)jT3t_}^H458_OpfJv)16ezW&!? zwkZXEbqdtQTs5)wZ5fD5J4i!WtEo19>j@>}YgnTeyorxTSKqJi@bH)uu%}L~xQ-Yv z^6}VMUXP7;2WLJ-wZeUuSDMw!bKEx9ToAOSU05CFR2}v8-C5Ip_><8f1k?uy0_Zv$ z@Sol9(s92EFxqCqJDg#rXL*k`HLWDFqtEt9Vh1i6hdlA;?>|k0f3Eo0=<{bsM zUe=!la~Kf6FoeZ>BV-C?B9?&uP=J8MDlmYkBTN48cq=quv7-r!6CzsEYril!t(H1T zzGJ)HlmP$2!u)*(SXmjm;^Cinr|3gUNX{=5Dh$nynk~14w zP-6ypXy0BEr%*~wB}r-_)NAB2!~yD{-@%GEabxn#ODh4^?ipOl$POQ4AXzlFdpN$4 zRnEh@Ir^ zOU_NnB-pln8r(XmTe$^TuGuKA+OslB+PGOosz?}7Da zGd{Df^dx*yCsd~_zj%4dX%JDMpDOOg?Xh+-I_u{~Alrg*SZEM$i8r$*i!Z)5wSWs( zV{O!7b8RfD)}yzPpSZE?$^+3k5{Cn2T$puuJ28~PN#Ee9usu1e|ITsBxviW2Nwx%bVg8C z?2{9_UXq5j@H$fCB!DU%*!dIs_%-`fAz+vgN7B*5Xdj%F=9qK{bzxDNac{7^q~=>n zl4h@0;}I z^@2hi$y!`Crxkbi{1}5=7j~Z0id>O71sDg$j3~Yc=Ljmde`Fl?SCAuaDw^^b~_zX#1S%D?-bHXuIw%f#5kjenN z2sELa9C-tpPnk2F*fqu)y?^;`ZqU!9yJc9Jn>~uP*I8rsuA6smdQ&*)qESuWYAXQ* z#|%jMZ0;vAzC1(4L=hqEB}s-J;8guG6f_64_3OIR&KtSx z1UTu|E|_`nu{TQZBynI$MXLq7D^%<%L?+zrgCon7V!XP^l(#n(vR*ezt$dCs%Dc=m zDJJD8GQ!u6U6`jkn@k-=Rt+84OBO&64TdQ+YXoF=RfJL@&Cb1wFWOd4?k=<6S}c>D z2uQ>78r%StOcwcz;scgSv^xQfXBJ;^?usNdD;F#Jk4@~84?t3h(9xJILi14%8OW(X z{J5d^sH7Px%_U+=P7CL_0k8dne##a<-IgYnHYGoL6c^$=aXi@U^&R+cZIU0lV*_8A z5<&mvSP#-bcFy99Ij3k!p>xzwQUJIW@;>;6De(KC+(RN2CxqsD-sGe8dueC+1EubV zNS~%8B$n_?fNY=n*_k*rjj&X?Ep*pVTnnk!oDq6b_LgA1@I&i-aw4yfvC05YQ9Z~L z_}|9{4aoqH6JrWVEaY@cvv7ITbwxMc!>QmKh-_|9FwmCL_IrC4Ifc!=Zp{)1HuJ3X z)Q4P;IA&xT6NJ!QLt*0L+ZBE%TV3xr>wI``%Y;5gsS>t~M&*Kex%J6PRi^BMnTPZ| zY~ogs-pTPV#<0e>a7D3_YSyriT9T~Qmh*IHod}*HkGVHlPis}igpBs4a7l_9W!%oy zXZ4MKfS76_?4Ax+$RtrDr|Po(saOC3nNw@o){B8x9kT8x$lm&WWWhm@owHwNj0b@j zh1-8W$o?#53^q6DOpKbdQH@z5S3T|0N5w6?DX-sOlfxF6wXl0Yp!H)y415rQ^(cKx zJWZG?+3_|ZIlT5sw?ueLoy_R>@NNXYsy=L8ti)XC(t{hREUbG3Nz6_*Q1KoA)w? zZ`m3Om$EzcrbVoIb32C&QQn{0MLVBJ?H$^M4dbTu*p;HF+KH!kMBK@pzAjCLMrpCn zVy54O)2Ew`%~AbAU{<|sB4htTzqhm=ehAuc(O9Qc!p}*mwy1)qJsI({MmSHgZYIM~ zsc3ue%#@1D*;h+<#FjsyB-m^y*5E5Bw>k4PIphZ$v~VNexbBJ?KVk!ur8!koE0wG|xis#-F z^pwgk1^2c|ZIodV*lPPr)(Ici0FkA+k}j`J3ORQXfSC?F?;LKut@%K=NBzJ8#oGOq zyKO|Np3R5CHQDU|7Mxh;3@`W;?HVj+fK`gu=IPA{J3v>)ns)pg6aT$*GwX05%{P## z?MS|=T>LZvY$Bfb7i3qcZXnZ_ih|K@e{xlaVI*SkoOGvHsGL5#kMgH4O(K3nxHGAf zFYRyFf?-fFBdHnI#dt}saY4DP$H+%7lnuLvA`Nf3*tuB(!3)vKv1IpytSS+uUu1CQ zklcmoZc`+JyXj(>aP*Zz5f^@3!#gQSM()$)>k`*+@43Y9C%w_>0Q~9U8ObMv zZ!ZHz0doG0>zDR%4qAM`+lkYd`iy)Wz>qY50!}sc-s%STlLDx8*`oK*PtgL z4wZdQ*ZM<(19q>aN3)rrm}Ndd;XILH0Gd9YaYgnmc&zf7s$7;Xaqo0-%*k4MPL|y#Ap0oL4qH*a1EXRibLJ#i+w% zC5<{)n!+3oiU$M5Fxr&v7J8rUqc-1}5dlqs>Mh2?^6WsDbzjevE}*DT_#y8Y#?^de z3}`Z;>l1Q;m%0D!UQ0m$mQBT<1F=TSjlwKKk&nSm!$VawiomUSQRqEuYdp@+M854H zLxmr4DD^^<;$7$L18)MfFmQ(un4>8=Rfp=2+;CJ|i@ra`AHLlj$)HBLYN%S#H&0&w zCM};>K_o~`n15jlFp*ehn_#JsYmiY5ndc9kB1kggWN*`R#rd$aCrEdE^%^R`t0S^W zX)X_As)5!tgw7zf_{)~1K!>4R?bW9Yr|Ako^!#fOy*yJ88BcENMaBv&{%vM$TP&Hk zh!=Z7C!xnqZaN1q|XKNN8RaBqN(J^d1Be8YSs5ZzWn1LQ>Ouj>{KBYUGf3 zrLaF}ML;T~+F7krN|t9C780fD*3Nj@2{}FK5{sa!!)>`MiHLq`U#A^bF)nH#MCC=$ zDKZ5P)RN6cMz#q9p8dSK?GELPQ={|TMD*CzeSZkpn7xe`Weercj%BI;Hkaw+yHwV` zX5@Xf{)kX)1~h---!{T6pJvab(3DM_-U?}CB`V?m3FsuT*!rQS&u?jnP%RxNqN{p`>)n-ny(XV>DzNUt#5U?#pMPhBLvEbX_Kn6e}kX5NO;E78}>I z1Ml;1%yDi>GkW}x316wppP6!k7YfkAwBxRwZ;H0#Pdeu!gwFARtcdT`f2b z?W1OzJUhsz(3b0fERa`o(Rb$(OyZWSdi+E67Uw6cMDBMJ3Ic z^GfUt(Wplwp{&s^EFSZ8mzqbIRx+Gs zRw&69x?{X2Kn&>bmRqySZmHH(LM8o;!>zneE?R_i1(oEj_(L4E_SLBRFm~4P0;jZ~ zA3DjwhYdN+qo*kN_;P+A-oGw>%xIU_p8mQpnZ{YKQSC{DdikV_|CoCi<3iIts?P}DP(Uh#`Mbvy& zu@!UA@p!pUc;s~2Ly9RC7z3nCGn+YKVOf?AW-i6r9Gp^6H@caHisN7z5+~N6vZU9= zxozr?_txJjpFN14ps5ybnF`=~Ct3C9vFAqvweu<1Ov6#}mIv_LDhoU9RZYF;Ho@API zdRA>Yevfkj25``(7xoW1q1tj|jS`Yo6wW?lJx$J0I0|o3*(!!4ECr3v__1DhovdS9 z2-%tqz-D2wQvZ$W9SHMt;3y*@pZA)x=oZ64!i?oW`z#c{;Fl^JXz3s^?>@n16>(>> z?03u#DS_2vwT7&fXZxjl1{T}002Cc z>d;6q10kl#EVCt(;ya}-g8bsVp;M2x_$Xyg_$g_Z+`TV<+^Zm-{H`Cs;;Pfj_@}43 zxVO0D__40wd5CRBwnb2jj=(dCjA;v;2WQQ)o?zUS^!7{;>3%YjWvd23z}h8K-^W+a z*h{0S;Es`4oyjR*9hRBlE_R;>mc;2rQt{x;?rFP>l72K#!Sfx-Th(^C3_BK7NpbSj zJa+Z;gmg)k2N-vd_k@VwC%=$xrXP@tS*Z2v0nEgd`{KA{xL`Pq$&+`9JShGWDRZsDIJoNg)F-&)kO;(>A5sB%lnwSQ*?UL4` zY*a2T;dCw zsE>BQE2fNR@TRFPK1fKk^sWkT&8iFqQ^%drGR?nj z{=m1^a!$0!jI{BFfil>JX}{9FIS1a@86=#2>*UlgsWGX^&W!<51Vm^vubvf9jbPp{ zwP(SR9%+YM^*1s`;tr4^4lkL69d3N@GmH{3`oS&uoE7gI(i&}4I(VS>2w#B^(Tq?=) zP{8J{I&K?8STfMDCQ9EmqVIm)YBrcZo;-n4QType2@ENt3RyA=J$) z>8o+~J^L-1cImg+dM@sh#zX!hDfb`Bw_hvu5AS_z_dZ;|(SO(SV|(y7RiK&>d3oLq ztrhR;t}m&|ehcbiEOP`GLzdnT-3hx+k3g`!NDDvkb($P zU3hwfOF|;51fyX&z4eJkdYq8;-2ycX?abh!&;k~q_bY#}08UU~Oc)al!vR3BP%I=P z1q8t%pv)vC2?YXSAs9#3$< zW*sBG%lg!b)n7yU4{0TzX#})CML+$$ZLWO~{jonDE=Z#rqZ(~2e4JLg(yC~4F~9TU zAC=G|2dMt@V^$v4XCD41QCmldCB|yQuIF(FL#JjN55&wmI^SDAv5JN$8TKaML^V7* zR>Y1;FKtdW;27nVZz4`W?j6^h*4%=A>}^Pm#bMnW3W1tGSpbxPuxKzE3kCwgfUsaJ zL<+8}BMM zPPAl6SQZRQm6Xv@Yyd{o6aRnzfB4D^1_HsLv7js`3mpQ(L6B4;k*<2LHQuV}#^!6+ z3pJUpszl4H19BhR$*K73`*V;rY?r&$Jv^t|S9KJq{yEypZ0qZ){MdR_jjH-0qIjn525Pb3WmSwoe~d^aIAR_{Q9_F+Bm5Jpq`r_r z491%R*>=hm(3tu~G7#uI7OqKEDSV)sRw$8LB(oWytgaM}V9rWWGbcDFActd3pb<3w?$flS@>N6l6Dtu4{L zAddwv!ul1SDt|->sZzE>YHb1)Q$5z+qPwAviW%(p7}I)EPXy~pw6 z3rJ4M$Vn>-CxFkg;9$tWfFpnbHWVZeTOR3;Hhr{m=~-D`@Q z)Wu#!)l04|S&~kKeCP7x^SEA_w`%rwzn}Pb{huA%{2uq?n+L~#54Y78@c94e_|A>` zcKJ6O;x8{@u3g`~%q>tigz-`hYT{npdx5V3VJ++huG<2AyFRX0o^?XK+ni#CT!=C@ z?sGU3O1(I>Z0_iiU1+oJht@#`+C*JuSSh?ZnQ%fiu2`iRUT}eJ{|bdxz=>a&1R+88 z-GAT!oS?v1FeWSof`MWnSSU3L1cHMgph&185rlrfn%Bpyp3`;bWovP*vQ$h;m%tau z`qcja+@4=Je$Vwk-F&0kU&^F#O|R64+5TL7h}`18*7SU8*$JzN@8{0symnrvoNT9b z*buO7I~ebr9^dOUE+XvW+Krv;_qCZuo`IaVV=$&wT(+{J4~LFCB=@r0Bi#!V<;q8$ z@xh9krN|hRx>qHgJ)x$|W@1oVPmd7Ml&5r0BDwMDIeu#jUFd~&(3r22tIMxQuyPF!nF`3>%8m^ z;ric{h@~q9%f$LvD*^+?T&3v7Ff6$d=+^U)6~phu)kR$)B*`h;WLt`j+8xjc%1~U} zDHbDMRwW$$#LGxADa46dA_QSUz5l=8{fnT$m@pPJ1%%;bpqNM@QCxG@ahY{;y6&bp zrb%+wB2=ybe_!gX$k=(lyKNcuU;a_~&vkxZW!y8qk6`L(<#)+TExEg%%3Ghxb&JE( zG#lia)3t!wjbP5Z5B^Eo;KUlfa3KIykG z2n@Pn1%+;^64hNT0g|#Kgjc%3 zvXB-y)*%}Kps<`QGYSQUf?*3PwUWLq{OitE!$c&wq1CM=N&@2=T5x{gIeBdaUS)^TH*J029cVj*W6>W%B7sm8a{GrAjfdM#b^)6Jw=YDd59sHpoMQDJqmu> zKcfYV#8acscqKJQ+W%2ce?$@4953+bdfj0HS1H5Q=eMt0Y7=j2|Lj)EuLU@|-jbRW zOPz!M&vSp{WDlGV+YcqL5-3xeFFO}NKZeigAvwc`!1YS0^Ny5#6r{&RGX#$_bX>B( zu~1Vsc|{&xZ$pGDk#UHKxg$NZ_l$fH1)DZ_ES%nVQjdm6n0GoP)K@I<7|;sZz0 zj7z*4zSC*`=5%U{i`5;88>9$N$Ol!I(wTpQ&4$0UyQDM5SwX3$VAk(xDAP!X4F@UX^XSwk5rq zS1>C!hJZi=I?$=ET01UbP`)F!NCpqgN|0M?mj4C~v*U1kC=Vr_Yk=P2b8nA87F+#c zOFou+;LcT+3mJrYtSD^xPkOdFlsrF^Gv?Qa$-X_yWUQ}h;1m@+*@uVk*&Q*iq*fh1 z>Xr1R9{uZB}f(vT_Pe+^tdQ{Ub{UGEY)lw!9liNgsRKr# zv7~zdys(JG@;-n(*H%_?rl`cb8Hu1HV^&n5To!a8ypPWY648%$nEXx*H6UDnfFjp> z1Azs2AIvbqW&F>r-}Stk+{g}Z&_Dm4JOqN`C^G@}5sm|*G-m7)`@b+Dt01q9@XjS-mPjR zI=Uiyx0;y_K}sT8iwCiLO25U)V5}N#0|FPINgIBc_Op14Te^!q^Yk>Ajl8TRCUqir zHueb3yQ=8{ge#h{>vm#XF`4sfY1oCqe4G2!! z`sfFoI)xp*7SN=eW6jHtwM4t+dqodxu!HbE`~j}2Rq?%1TnFK}aEw?7E6&c#;azK6 zKVZ=CT8Zs^VMmmmw~~3T@g@e5PL}2?ourNev_E=zJR(vXhLgb!<|ZqrK2tVHSt4`9 z>K)=sm(w@2b|QZXrB056LhrXlE>MZPieU{MJZ^`bC(}~h<1t=hF4SAQoDPSA!Awe{>Dyaaz}~d9e??^>3}~Y^Y!a)-{`Zw1u&njTX=VUCpBHi+ z9J8 z5pb9P1BxyeY;GQl70j5wayNVP#GS0Z;t;o-dWOy^@5MGHwt$|p8+qpQ=-Zyf8LTma zxx=1Gs(DW@N5E(7&sMBPOO%_GtSiRf|E4GVlG!CDL$hEp*++}x^jX1T^|C=3D=Y;t zi;E>Q0Sg)U^A_6#o}l@BzL=PP4LnOk@h|i(JD7aPzPA%EK`rUgG)$kDp_R)4*9+Vn zy|UXTzYTF_^Xk$xYL`ykV0M)f?g;Zj5=6jr3mLJ8$uvU`HnJr?c_=!xA z2ZTw7fcBxN?4Wx&_)3QEAbs}s-OdHK)EE7xS_^4w*g&9PedJ1JmQpRwt4QxSr5DR# zWuS=Y5~XuG+Z$^R-hwlcD83$mX*s5AD9Xi}tq};;PETW5knTbCcrB{GFEp>)_5Fi9 z&v9U8X!6cb;pzHgfL&%|0hLfe$yKkA5Bb*Tv0%v=LK5e%S3S92`bz1H_lF@SP0qLUj=B$o|u18JsFF}L~-eHAR; zs=)qET^3$nvaO4q$YR(CO#I*E!*S()`dUEF78#L%lqS4qC5aFV0d4#+WYb zG2<|&9AW$9H_MYcM_x-L9*p77&f*3@(FQ<~8!1YdXT5(>N1AJ6zCz8pY-Vz1d@0U8 zi)9G*_>Xs8J<^lrYBR1$RkoG$)u|nRNcE_ zx1T~IUAHJVyL#X68TT&H?g#2a&(dc#z-F~jy0ZLq)C}JVNE=X2u5tTXPseE{uTE}{ z8ka+uzkM#tjP7Xz5_T9B_HeXmfnwq@L&w4R$57 zzph*2VR*PzA!bsEJuUt0bW6@OZ`vHmUFrWLIdZBYDXGDncttbsoVL0io8W04&w1X> z?tq_V6jWlT=8Mra)l7HqoQQ?!@A)+wSD``Zt}UNkC_mBhx%vtyu+qpMa*^OGd6$t; z)G7zAds|s;$FYH36CQNZi_E+r#+$Se#R^w;6QZ zXyE#Q#rGS6GV#(I@a6OV@0SZmxeJ85I09X7E0Yp+v24bQ;E;Ti&Au|2bmtv`4ljP6 zDWz>IYAd;e9&1d5+WQ~`_#k`u${I6CSn-+r3=Lp>**S^k+JJ-s8>u(v`pp656mtXN z1@Opp_T@cr6+;^8b@u>Q9L>#z0>mzb5rtFHo$+Ra9cQ<2Kg!~bh+ik>jc>|5=F(yx zZ^){A0v+2vhiP~)$cz;I3JJ~n{+sw_bca%QT!7aW>WipSHmHwVt;u_uIk(V4Z$d@z za2UN}DrHHsLrzTT*?ihBptTc(qW1OYpoLS307l?!cr{XF=P)qw{W}G@;@;c|iu23& zLi@>6O49)}6ev(e8-;{|V4zqi777i5hcJo^D&yPjd~xbsr7o2!rO|C#w<_nb3z6)X zK95GTli&{rPHq`*&)WBsS?P8^L44Qm{A23&An5tdl+lb2=CuzhN!#S;;!r%VwL`+XA1oAJ`^L$de|GS@;p;A(n{X&w|7P;T=0sc+%alg%R3~v;a$Y?;||y)3J>@H|9}M47J|fZ zu+S_-3k3?nAs~n-A`paxVJq+Nn)vmdHN8<+c~TA4#VWNr62E>n=O1_4vAF=>PJid~ z6?#Yh)cmT~qS6%m@ou-TT5m(zi?WD1nP7FH_*F=K=*Gx)ijN(i-3;Qm^P}I2{MFQ( zu0;yJ-?@UCy{!(GVlgs8E%ydweb2hHH>-p)Jq=p^9b;6@6@;+eeM);urdxWF{$uI> zmISK70t>w?=Aow!a!R8Z**7VIkNX<)Kb1B39XJvRuC`%;$jKWY)PF?~l3>7SFd7U6 zg92dCU@R0H2^2yVJXc-KH`PnJR*5o2DR(iulc1iz*Ad5R(s_F!ek)V|nmBaH577(l z$N*>)U$tR0&b8@2d(U-6{X}9i66*3l_N%Cf_#GPF$hB`ju?&;mLAKNrR5#i5nf-Gh zT=Xe-g?Q`Vt$o$YY`a55#WfEg*|J%L?t>=B=}hsa969xpyfUr<76dMHs!a%T4L=jPH;XNfOv+oR*0+KV1i)siPG$A6!5e^MnBB!t>O>0XcA zx<8G~zK6SkR{J8i3%(E01G^)H<8`M!lMOK=)7Av~OG6pc5TT13N~05@TbD|g+fJT& zQ!B+`wwHk!Xm{k83hkE1DJup^YQZr-B?;Ii5xFU|jc^qeT$6||TP>g?Tr?&M1;WBW zu$(Lu6a|EeP>O&p^`|a5)X8_x4t042mo6`Mf%lzD!_RH!-~T(ik9MwA|Hz}YTjwT} zeAisGbC-ygVjXp4Q_h=Hs6iyYkO)l~2PBvhc=38~U~ezc zFhxzIsh3d>|NG8wWUmFHlvaSaHwl@7SS+n%W3`v#hFvO{ILS-F-04i+ z@0)6yLU4^fsbWtE-R9T2D}e)FY~{OOM& z)O?{V63?^j;282U*z$aniH2@}M6a!h@x+xsA7*TTr~7D99pVyH2iXH^#4Xgr+SZNbOWYHAs(@s5VKvzg^SxQSAs8MC}g$hf?_ns(Men zK+8iY6Y%Oi?RM*%y4=#4*ps4pPr zb}oCU<#WOLf3;#%PO+iB8Z>v&7Q0labWArG6}|gR!6=v?sO}N0z0?C&9l0tyN)>Iht5s}6*OQfgCBTFVT2}|Ui??dnsp^mQav3#eKvOhTw`GMvO3-AIV5&7ACIC>8K zW%nBj#)lbx(2~8_e%9)$m7LKn9kw8z=`f1)3GjBirikN(Tm!3}x^e53Ml?jz=8bp( zc@%7nJ5eCK%m>XBLp#M6g*eIsXEf_VBystl{$I0x1PrKyYDHH2JF!|-#70j!d9EQ3 zCU*(Hi-i9ey7rNGC(`ezF)F3x4mOO*ESc66JSr7Z ztfHXLqlFf6Y9jTf_yKj6C_P|1__6wazefn2?z3MzNbmlrwi6K2j;$lRFC|kYvi5gG zQNV4rxH$ly;{W|Ovo(ad1ytV~e5n{eqiTn1=`=!3=TSq~Z4N)` zd#J$cXZbc#%B_HYLru&TfPBjWT`}My7sAmH$psP@MD<`{c?#fzCU;#5nU+#GeM8f1 zAxVxPgI*{b)OkvZlSwIB)!2v+c~_8#8Mw*ng&~5=7-$-gwpn^@= zOOT-w3e}+wn$@bFhCe-LzH*E2&s&rua_NGrqDBJWMzbxVs*M!HuEVx^4ZU3foSh^4 zzKpQ66r7*5&%_nZZ+2J!5M`FL#|wk@v<{^1(kns)Q)VRRZGc374dUFNMAA@>2vm8n zoeTWmU8X4uHRrT;zO@a|BKu?~0ZUgi?=n`?%r+d`B~bwEG!}PV2|P6jQ+=dM;A}%E zu|!WDuobg7HJmPx32dq@`HK?jKV(7vq24trq3s(Z$c!bJ?y`DK0ZdqN4JSkdGsIAu z2Eni@pA2p2t_=vZn)EnHR0q!S_91g!maegk71@>uPA%iE-#|IhJP$BW(RVBo1GxMS zoS@pR3P-&or3eaL!v#G%otfrtJd9gzSx!Bg6egAqsZSg<5ne_=tH)X%j8XDJ%Od zDVd~Oi_b$<7DoViF605S08eOOvro~oA-_Z}yD1q|5D5I?jk%(iyI11@yOu*rRsfIU zd}}9+b-V((z*AWdA_ni#+1uU1h)ME@DZlG7S7|t>1yOwJX5s>&3n-ROlsEP7<%@dN zb_I?EGFTbXfv`d344EFZ-WTfv$-C~`hJ9$}#UY*@eR+dd>WjuNPp)drZj*c6V5W&d z>3lwt2r|#>ZuNG}(@_%K?Wi@B%z?u>FeC6AF0o(+-W&#fVc3Nn3{rL*a zlFDZLCwQ{|^InWApLQw+axO;CT~)|QCWC+_uF1jv#aMh;H%)^~m=)_@EjX7+WfZ;0 zr=+8H6AxPry&#$+v_yfLPiN~e_@``ucG&@xq}vvDIgD2{nCFMwRZ?B_5dd`A`wZ5H zdCUWJE00$TLZFK$M%MJHhIOIXbz5*ypLK1 zhl43mNE(Iur#s2mH{KtZ-Lbn8^M=R$*fN(K^EYD14SIZi9d;I#^{j{*Wq&DNGeOgb zZqwv)uy@`9PR`;NVGtOIBAc2-7RqR`Uqc%@MGj{_`N;P*j+fAb~m8)}&G{SP(X0Kirf{ob}{p$fgmj zH-A#3VY_SLrE|p||HEnqr*u3%YPlHJrI@E$y-45jfFULeR>mRLz`C_F$(w8%Qxh;; z!-Yatp~+?CjK~?Lxhvi-_F=cLj;%?Teg)_f4v`AKJu4MfKrGKnNr&v()w(d8FDdQM zI)YQ@a`4+|tQ)1#c#JDgp5w-K+ngAb0RK*ss&>fkj(|cls}F`w!X{T(?^EBRjEWTk z54MB}ZjSDCKbDo|hM6#XZVNq+mzbu)1x@ffKRKpn+m;POnH`Fpi<7~HT) zDNU*ruLAiVVo&}kr%gKA7?=S2CD-3j{{5-?eS3kpzYDL+`=m5*)#;MI()0jBK)k;Y zj$~+Z9aL&~c2;mu(_TFH0?aBy#Ydt6#Q&h5q!ap=3VIfvorPMyJXB@Y5r_B7soz#x zXYjsTfl3`{#TWX`2o#!}L0=x9`3#Pf?b3;|2IxV)?3@wDQm_i^?Yw1Lo#k5Jgth(^ z#U7YYyGPh6;5uH%XcYTP%mAB~en1I8AdN*iLRk#6Bs-^IeMHa6hxr;uX9NZ`VS79g z=UiL58v3V1&C1IbT}~c+Y=foruj#=p=R7!~k=@PzP2B?vhFql;k?l0@dO32D!Zp36 z>1V$g>;|Yleq-+#Ob3yERbw>yZo+=oU24)uC9N=7ZFsHVxS+p>({MfyFZGSMT@F<0 zaY);yU3!2Qkaua8yUXH2s{4qETWeM|&>bm$6g_*CrD=96tt;76&k=%s9GzcS}Xdb|6WP%-x9Z%m{8|I>Eeu}6XQ z-QN_|y~iX$O0ELg%4xH;lnd#Drmehz>W$zv_XME;CrABFo_0Zt&T|OC1IMql2)F#_ z@YDEfxu@yr&is#Ay*vN16TVBGXg*j%aiF(mdXOdPmO16l0XnrxA}2Zw?}7*Xg4TJU zQ=kRs&Bs}!cUo+iqBc^a_1X1|L+6?09Us0Ms{tVe-k7?a zS_9qyD+V7V;ASu608U5WQ2I;cxP~O>TRZ5a*xO3-2^J9ky@wIGcfP_kse9X#ipr*;oD^P^S|iF` z;NZaJIozAkw`{W2y6;A&Z^LPx*)(V{vPgLqK%zU?(cZu!V6hK$l7c=-P~vf?)>!QYW?2 z|FdRwdG{>>WfR!oeh2e}y+;AXVkf9QEKjX+5t8m(z0r}KW$FtG7@+f?i2wit0nM>& zcstU2__egcO5^YpTVvB2KKN>dMisSlukj3R)3UnY$WZ@Q+F zkHF3za%Mvd)JCMTu}WzU)*#D@3&mLG69@F@)Yomb*b3JYp#g2FppnyoM|E@`ingl zamw><@wVy{9*39iTNnW(1cs671`&aO6&vNa^xPHL#4NX0)6+eh8@X-?>%5=DRSUGDuL`E7D~`2m^)UA3SD5&}1@yL*L6NL*9J zo$Q5&(Bn{aWIQc;uv$~78%Z{xG(2kNVZ%~Yu#NWWw*?^hI(m&ezPv1Nk|@cwiF1)~ zz+E;=q$T^=-}t2pv$CbH1RPFscYYrP8K}H$ z&m0{Tx~C%n>=}3N7fPxLQz@?8T~7DxY)2_q)xfO9n*=yLD(`|ALIoNh zEdQI2{~}I8&lHfy2kP12z{V7(-%CJJEV~AMqt1KKf#rLTqxwL%V_;gWhy`8&VqqyP z-x3eTDh-se8~5mWK_M)l#Yup9WnLj53g}L=00MkV;J6v3^-KqB0GS+!;s~fx%-LO| z6BfheLG^*q*Dvao&{5`zN$2a$bwgAH*A62IF`s$0FSw z_SWKnr#3A9G6y{sbNgDZP01jh#Wbp@3korin0bN3mN|#ud^2JhwkKD|TQt$7hnmu( z1EDzAs4py9f+?#d+;8Txy!doR2zI@RHr3YcohVdv2$7Q{bYN$+vL9csM1dT*P{bez zLci|E5Cr)YTHFh>kRf0~mm-;e{@5un1CVSe*V;g~m@zfBN2Lmi6=oSyKm#x5jnv2l z;XZ7=e`iZN_1EOV*pzp$_^4sR4L-N#8r=4?`6u~N2Ar`=Xrzqwa(WR6ZB@VxtR9*X z6mh%uUC>I5i0MO)Y`+K+&J#;iYa1qkS_fmML8UuMG(|HJ!4vVeDTfa3Gz`AD{U7v@ zA8avk^-gqST81;Q+_MZr`@$-Vm{t#zqA4Ovn{nZL>?6#l$C2mtW^QCIY?T$6odtW$ z$JUXgYgo?qpAuS@!gyReHOo$QkLWvkoC{QRK7oHn!6Fmip!PeEXXa_rF!o@!J$}xY zlzgiXNdN~zJ)ef`qrBK8$-i+Fbh^a1&HHb&DYavG?}DuUDeH%-LAoE~B@Gm?CCr?krcf+~k&M~>-zEd{0BMDeNPEbnm(lC@pm)w2#{u4w~dCISt5BdYi7uLel zc0e7An1N7wF6vH09p!rflQG12?v!}wUk>wd*l#=ipWO8b0A+yr*Q*uD7BJFyHzy}3 z`qU);C)erO)}-wbJ;_P^3yihdU;QCfya-Hhu&bM?Xd!kf;^7=S311)R5!Mi}wIDhC zTD~udEX)&axDNPYxQ)qH71#Q{*DdiNo#f5)+58fMg z$$EyHdgCQXqZK=1O~a9(5$+KSblDw3X>{%%Jb5KxhR~DBDm=Z&u@aMD8uQS3vR_b6 z7fCoxCmh>@UC!oL)?)|=+6TK8klpLFc^ZHY47fsI>#rIW`uddlIRIjd)b41h&)=Q^ zr(FX!f8*Bnw~j(Kidc?@uqgHG+vJyVNQdx#V~I*{qfOY1i-Lesf=-BOicVc^ieO^B zm2#D|ti}e$(Y0AQG;AGW-M&lZ>}2`1OE5ge`z z<-g;6*&9=)+!wHdt-S1!d+=`LdM%6*@IK^AVtb85N4Ii_H1&N8ddjcP7Rdzr|nkP~xxxbb2 z2Mf!1J@F6z?Tb~+Nrog`ASk->ftM-RGsWJfTF;+&c`aVAAX*}utq2iT1a%O*rE7jI z8kW*}kAh?63YCPr)lboMy+Uu_Es4vXYSvO{W0H-<2ab}-<||XAwMIID7|8^MMaN{t%ys5q z!VqP$2of~tVs9+dTdqHlyYaRhWiP=+BriN+IjPT4a0WkGs4SkalG3Y#2hccfZYzkt-Axz2(&Pf}(`Dwe($| zCWQXasTxzDVLVAD8>6`}>T1BP1TT5nQDsQtRHQARj-byk3Ltj;jV*__+Vjk{<)88A zr1F8>4Z>Aig(*Zd^%!>2BHLWh99ockW(fv6eX4H`|8Rr~DY{l)>m2PLe`Og^o}cmw zc-UUQE2P>NlIpZr>#VB=dIdN8B9@&w%J1Uz@CE&8D4K|xX{80tgVZM{0oggTo0E

    3}B7>J~+?CJV9AM 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%0DY_bCH+hx3IOhEVK-QWFZdCjQJ&lK+-~lB{L`A}* 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\Nxnz0`yA(r!;mtr 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 z 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%0D*a^G)C9Y_Vtl9zK14n3#455z?#$-f8@I_xd|} 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

    7Rghr&eTq0lLvkris<1i|kKdsZ~ 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

    t+pasY$uJyW*G$H^wc@*FsAdSY24?8i~C-cvF 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 Yk;rpTC^wu5u*G+MN#RCWXlTy+YTcju6yg^EL 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%0A;L;C?}*RQx|K>!e-&Lcskt=~y-PeE?B@p&e! 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 z z*P?z9_+bicfC*-N3NL@{N@k4SsU5dxuzrQ|KgheWqT~xT zMn9{rb#J1cfTjwG~j(y+& zssA}IPCKpG4tL?7O}Tpz?Wfn3)!If;w@@HIi-d!o+KjM;oPB8E*}5zyzz?N0yAl8< zqM7Y1mDhvF;M9J*(MWLjsR55JwFG5)JCD8THEP@OB5Ng-68_~6rw$^gV;4;NvksG% znTf5Z2i$NRr~9%)!ZHCNw`T=2R)*EjTQY!(= zdCNK^n|?SUlDpB8_iDOX80`{M^o+6HF(GRz1uL zHf{F9T=)%51{ldc)P#nWIL=81W3v25gY~uNlo(C>EUPwu^o*BCPhKsM5Or z04knbK9>C~MaP%O0${ZXq2QAoKZ}?@+!`V|ovtDKjd3m1u8lXc6Jz*k@==~qCK!Ky zo;;Gp#Nw+tnRtek@r4d1bm|g10T-t2*S2!B!>A1&+1Vnquou?fY458M&9|Zk(fs+_Tak{>I8at6~juf6&PHppRC97rWKEqYoU) zoe6SfOCs)T2BQ5gTXcEZFIc6JUCwu4K1`U59CbDo2D9=x+_$UY!fC7OY4a1UQ)G}| zM@;Z72&?(nILkWgo z9S+28=JdGu{+JQdz6%ucs-=PCl;}+E32!?(7``~qnBs$kVdx+*4gM)Z$X@d@PRF83 zX^alsT9I4n1-Bn_E5wy@BYSE#j^bv$cwJ%uVDsqbQTojOSP8mRI9(!0l*k*1*j?+> zy2jf;svROL?QYfg@8MPC;ZN%2i*7Y*+CBPn?n>D`t~JWPC-rmEEq;1o3aHeW7h39SF}p3d9LO<6S;=IZ0P$ z-uGfAE2|EETtm3|@d3UeJ+qF~Q-PJJq_<2Mu?FEu1UMTtQn32MUgCc8nvW-?5yce? zaHx%Tm&IthH1Ysd( zf2y{y5ko;P>gr#^P0U#itOyhCZX|@8vI7U~tJ_iLrhnzdUB`nnnCf*h zG0Yjun0q)M&Cio0<=P~fKJL_u@LCvzn8cLHIU2xLbxv=*&T3k>b2<8QS);5B;v}lf5-$-B2*tu{hRV;^ z%rQd(9L*ay4{+Bl*S2%Fa?hVcY7p+^`D^5g?hZ`oP$Mr#R_&pBJNW3ajiEREa|sUT ztP^r98v!qYjp`ALdBg6#BiyS!?zV0&Cs-{Zqa=J=omNqqA)jo@CuHw?ajE|R{UEqd z-}7^c%CBeV8*)FESzP!|SFB+=2%qY7C7aQ>C?)G9p!|^G)Y9=_9_qaDYSaYN#N<(4 z8c+lWa(!eX;Q`$9sfQce)&OB<@?m+wnw3bW_@q+&{E&I%n3ZR?3U)am^`K+J)z909 zX9R+@<7*V``Lnb^u*CW*9yi)gvT1xKVLz~6xP3AF8UN>(3U#(nVA77g} zWRl#CbkO!^Qx%`h9hYF8!b0SZT!S`rQaYH+;_Xeed_Ys*{Yf#|j(|QhCfE3sXs6a5N5M6%(rT3|7plO|)LIj67sZ}mjFjd&1hCpE&FjRy@qB7}I&}72kz(F1KO=Wrxgu81s}n+EK$>y+^p>1U67K6)WmRhK zY#?inbYUQQSF_IU+2+iQEqI_w+7!rB-h7-ZI2bm}N-mMBzB2JVGqyjufNR1%6+2ig z@^#`vSO*wSobEjLlareRwvW-g)q5dB6y~&wfsfXLYFG6noQ%_Aj0X& z8kAm~`RbEx{(KnbTKw1Afb;q+N+~U0^;36KIjLiF2CsGDFdW(f?9h;opLSXmM*UV( zg=6JzRC#up$@bupP!?07dmru zdG}sN&PT;F;x%emhN+Ti!e`KF`Mc<~DTO%% zs^p&9%SqNVLDg0zS?_~yjnC3_XG7M249LTd>C~*@oEjw;9R4tRkpwqG=JR^Ri7kRT zV^cLYGtamkMG8wC_0Ke-t$dFL(m4k-*+o<(?+g6&+-fHY<8Sr@orkE5E&_u#Y+iCK zxcX<$E#gq77#hrekGe*DjWGX{)wwovukR3;Vwsft#UJQ>VURK>-$;p`Me+fw!kA}p zaZ3o}n69`hM`(iZFq4-i`$%0Y_Wth8FhwDm_xEQRS^~d2s}eIJQ-S?338BW-oc!ZN zNC?PAL?MOC?hBl2$w&lp)9WN4=7Kw1?LVG3#5T`kjITC9q`zZ`SaH>79?lC)6!Wmn z&tV$|`DjFM@Y~jLL=gL4L?c^K&|49w-4J4**9iDJo0(izVn_Uh?{@6VxPT zC4dN{uCka1?6n}7MP6(wFCO)8-uu$=KOO9>9{mn3eP{H40MU+^1Df8^%@&qlWKKfJ zB7nCtSB7@Rjo}He6??9=dcnPJp}RoCd~_l*Iq}xoHEdN3xRl|evPLCVY!oEI7FFHT z{34?R88v-_|LbD&4dmGr1_P!~qz%!!GJ3yXSJoiqRfb`f`>Y0Shf`BTZ=PUUX6gFl z_&y!w!^QIEH5e22ZqbaP@&hyF+-?MPuU5!7SNVl*KN3}&ifct$Q%G;pF~PAYBMIo; zo!j!y;PaRZ-FuntEfnXcrm)8-MIW2Bjmnul^M6zx5j>jYSrtZ}TfG(|D6aGoG;DJJ zGbBcT$NO40WXs@hSJ3la2yA;VLujYawM>F-1C!p~660nuV&=c~Ty_;rL5?`BY4z8C_ zFGC4?G6sxM25;}*q?YaIYKfD{UjH%Ne6DPYs=YLIMzm zm;1CoYxv%!K0nH65#Nb{gBV+Hy7v%c7mp3w#QYf?0nJ*Z8Be>nO!XZvi9K* zi1o9SD3o-q8}=C-tnP)ly>h@ZKeex?vm@;pldDM5z`N=}IXYh5eh}lTzQMz%sfFvL(%IUWiRjW@ z@Gsa6N1n==-cIX`SP6NW%E&9sq9l)@m1;iY$<3bA+>R6tYu(C%%j^ufy3AP`CXvp9;Us9 ze{X>fV~6)1TmE*RNbNcqdG$}qyj6q>R=NA=ZnS_-)=o=hq ze;asH$X7g4?1DhLrRysX;jSy8NN4{~eCrYdYA0Sz^GH=(z+9#*xnScnj`c@k1z_M} zy{qf_j~0}NL%agCJwvN(Y9CUcCN8`P(dy(TZ{|7G=k2q(q<50|ZRa#_6PY;QEJ)L8_fDmHXu z(D)2KG0w(^fH$s*`wJMP9SRdzXRs?>@8OoMsHAoWU$~N~!!1ZpNG>j>1y6%$YA+iy zliJ2AE0=(?M@&`GT0OVwX*-M(#37uj@>>_>2e=&9RQbL6ZDg(L3r(&=R;x5Tl0nd& zm^|}mA#mIRzYv#O02GN@0Cna}PSnCWvs-dZbS>`K--bKjFJL7ZG~Hm0W_f^u{2rBx;(eEZygisHT|vsNNoW0P^T# z!6F;RS7vaZ-lqarge)_Mi%EMOQymqatM#2*!9a~Ojc|)4)X|GOX9|q1SRe#YO3tbP zfM?sF+YFzmG>Zu~Z*ZDu49w^`wPKSbF9QanutgByT{NJ+a@SA`BO|)>`r|G(RsfOy ztfzu+5{Ar^V>R2KpRi;K8&_FEBUFj6gSaG*mui$0>ecl=PHR%)reXZR2M6fP3n#1_ z#i**lJ--;%A$9?<09Za}ikNRI7y*O91FR;U$UV-GwJSxB1{Px$_g%;R6qz@@+!q$` z3(?+4GlN}zfXgJ?mp4;8tJ)mQH@m}&iyIR^8H0-fQjl&OtS3;J$mN+?Alp8}flKWhpI*S3k z&c{lE&op)$la78FQsgf3I)K8@==Uog;QSeRPJ6re72bSuU8PYt2G~OG6S+BsAp3K5o}tcq0RAWdPIPvNClW%|u()*6 zLVAFf&`Uhwktc|CKL9JxICn~yHF2B$fu+U4tOb^Mq4i6}`2?5TAJd4!1l6O{Mu^_} z;NVPV@1LW6@}X${a_(DO`oyf2|AD6{u=JGd%RcYE@OcFmWU-s|WtnazCCeF6SIuWrldqKk#=)Mut^4egkdQtB1rP1vt?zE?A z8{*HV-wge;U+4p1{ZD)P0NSDK(6kxn=y1GCdGZ`#!OQ>z3&B?})u086|DiuW%f{Kyc`D#uQX6Y>s;_uok9Xy(1~a0WL^L^j(`u z?gly|8}g_=8$d|*SlyRWHUR807C*Y-+gE&*Oz&#|*(6$(lXag$`JcV$K7fx+j?*Gn zA*J`OBLHZHKxpl7f#t?$lB$rCp8>yP3uaAEJ>Vs%zROPl5xMiA>m2O7jH5Bk8-?y9 zll$voy|7!%>o0?tnyZW1< z28{Cr;Ry|D zKMhA0Pr!g2)ZZKGuBxH_`h0mvP{OeEYp`|&l<(%hT*T~E>9`W3jp1@32!`siTAcRH z4AflvocNWuK&t_h#h-1cKZQy}1?bznXZ6B5={W07>@NOjGA-dqpR4NJ<&Tq4A(Uu264{RW6-L3UIdG zfrkbqT@_>z0+tgRGyBJvV{;ZEue`D*PNO6;$lQnXgFJm<=I}{>piR0{$c-_;m~hE? zjXW0YFTN#{SWu9B=bf6dFc!*6czH+Rmvx;(9Me>q%0xzX zh?#0TgZwndaWUhX1Ye5<7H|Fi${7Qs!NP>h*hoxv<6IAt7BFs2q&(zdDh+u3JWKWKiN>mKnSd0@+ zW|7(Qa((ufX=#jsk15!V~}}GG`;v)}nkr-M%aGz42Ip1DWKR zDbSwB<_d7n8)CjwOQO?w@l+1Y5nPq*BL@kV_o6wSilj?yb4jgEdCSTRjTM^1O!y;Iq*T>9NF404!;33!0%2jRkELyNH@WYz|S?R+eg4?%f%<3B|W(wBd%89Vqy=m?QOTG*`h{MDjiK0lwUE zbvT;T`{-@#BUPm81hd+crV})=GXd8G-vX*UuK5V&W>66%fZvhUpPdjaa=n_tc$+-TaFOKtw^tWbLz57$Rw zB8?rQ&FknTTR}OoBBNAdzi(~3_@A6@0AsdA(0ON2VHdeW`&RC;pQ4{_LVdRcvSt8XentP0=AKkb=>{kLoDkHvqxv_I?eL2onbIC&W# zYaxwMVZJQ%=S|=Cgd_T_U=_6&yql(8NZw+eC#kbnvW*qMc_Q7bKd$AYyRvba>y#z( zzhql(nU^EurcnBj=otOXH+Sq10`^p}6_4HKS)8NeYflR?OFw~MezWYoi8K0=u!z!0 z_NnBJbYN9{CpGuir{77@4ltSOiIXe>zh}5F!a9eR`{8u5fOupP)~JPk{7k}7SEF+l zx1yNER30`k{DlWM=j+t!wL>(#)^5fr4!#=9*D5i&YGAZ*slGE5s%A#s($CMAFHoE# z+LhSv@F*2CZP5h{GVYi@8=ewD(U1Vcf4fB(zz6k!@3;XNgcpr$=_2ufn0EeG%f-CL zphNCai_=T`xqc@?qp$7!8o_U!nS{@dO1h#M5AI!F^0odN4o;Rt;(gSaLdw%wWR$&3 zMk0{zugJ}JV6~UAgh*f_r;l_xA#sPJo`YeCZ+VH7r{|^;5kNB&+kS<0n-39-}m}rJ}l?EKdY9fAxPKVsXE~-7A^(F zXoX}*3*WGi9MnHCDipTI_P4J_l;_x?+R!nTC=;zSFzZX8Wq_#8zQKYiTw_UyZ&dMr z81d;omrP{@*k_rECKyA^QK1yGRZLWdepr;C?L zO9}*B4bPaqL8`VWrlyj`DZjRqH}_5A7cq#N{Rlb${N{`PADtz9e`j9jJv=&^KQ3ij)!I3r5*C`OVfFsFU|10z8cv~gQ_d`9OF9i`>RyVoob5ep| z6R9Rqi{kE7%(5Sb9x+ph2CN~U zvZ>CQXl{EJX(q88fHIH_}~{g6XB+84Pzo0IJ+QE7blkYUE*uKw;&FFBBY4yo&)bA3l1DcAv^ zx)!3Rqmzg9tcF|39&uTdBAP=6nzfrA7E4&$Po*{L&M#zA`FUJ!HiZV)51WGWu>1NK z;BjCqte6+guGP~A2Bd9^Iz4QB2T4M3gnYxJSa=PG{o6=aK9CYk9vEj&7i{^$#B? z`51m3_=1EN5gBCJ409e{`BfdLH2Aja-Z+=& zS(Ob>TYN7l;Jb%?0cms;A`BoTu(8DNRW$J)lmkb@Cqq-sJZ$H} zC9uX|jx7XoA~ovAPWw7HkURDSh9y>rG$ZFxi7`EBR8bQ4eZ5?BSk@5RA)JLb!yxPa z*X#fww>eK^zG+ejtD?t5>44``gjJ3f8rRrd#I73lHEdL6&P2T`EvRsU?@%Fk7;kK+ zpV46%)cfWgqs#7q$`vvMYGolet~4g#jI(+ zMF-ZSJ)%q?3elhko9~!1G-5F$_ZHCw6}2GN|EAcRo~mN>9yze8K{X(NcuoaYCZ__m zcXla=;+`6_TnMFPVSoTACKuW(1J7T2Qx+{ zVpN&g@W{BdE{5X!cj3^trHwUc{gs;VqeCO`sM9gkMXWk{Em6h(L*^d@5hhoHNAidI zwYM6_t8LG=@q_`8G}Z7ru!!;0>PyePm--*)IhQihK{Ex$hRBcWZj56=Lt4lPQZ{Tv zLGu~DkQ+5!7n%L>h!?fz(~;#Zf(P;Ice#OkX zAfXXx%7TAELH~Ou5Nt0a)rSPOg}=l|?Te%vnam}95WIjw#>32=(aQP`Pyc^12!rkC zRn2FYRMGUAG1sqFG8nE?7lYX0HVrlS0j!NP_8OpN(&?c z1@r

    a|w(5A#UiDB%RLUSxH0esr{oKsw*d)ROxa=Ufi7g0CSM?vG3D#HwOZ_KDlg z6o3w5+-Rg`VdtmpEO(2*#UiaT8uY8F71g3|^~}i90P!%0PU5zMJ{SN|7J_p)Qm(P3 zor8)P#u>3t&!YQHAG~Dg@RZC+D7&8S;XL7V)P)-cnH-ydkz=&*MGUJph5OeiE&Ji>hqvig#kD)49U!Bp#F*7L;U% ze;}Q7r%y>W5Te6Iw-%OQWc zPQl4(77-^ptaSPqPfulG46v)v=m~_y*92NFF3F1Rz8&9g_qLj^w)Dg$v%DV!vFcM5 z=DVOjD2qcVq}tT&s%3AX)nEnhyQcrM%*CEZVq`AOHlvU1y%u^Zot}pvWT5qz9`6Cu zUuu_B*-zZM6!Setq2|v$;-j;M9B@6@_{sjZ3(utwZ-(vvVMK&~(T@O7y+D^#`T$eY zZbEhinPLjC7{Npyb}hb$NL#>RJ^cpEI`S_9N9Yldi~s>1D4FOG8^-w&k z@3p?rM!!a>n5BImn4DnKsm^S=2gC8*k8ZAokrY;tpvhpI$eD5ILe;?5^YOpVyDv{D zre`#y0feCUh7>!%I>oGj-chEhMD?c9(YR-5$%}w3iS=%-ikNw@cy8P; za!gszz)BoKt)W}>{)?7RCUI+onHs2X2l^Bl*XS3_AD4zzJ7BD1>0ugW4Da*!FW^ru z&Laq)a;b#W;7k;AO!4?ysdqBBfpVUBaUTzlED@Sp$7wI1VvqV&49XPj?S-zlOq*2O z=gBy4+^zAblFu?XO?+}D=wyxj42b6Hd9Xz!a7Qo!;}gWw$YAi&2hp|{m6c1&L!D)h zAOHa&%Af;)k`QGFc)>=1bO1298Uu5b0@zQw&QQToNRI&)a14n_{c5M5B3mITz^U9Z z+j6lOP+R0p&XgucGH>09{;Z0x?1I@)tuuux50nvueXJp6CiR)hWA~@`kf^yvTPim1 z+L-Nlu_yfQrDxhv&X1!@ONZ2k&G+yUJR&msCn#waxLkPw6f*U0;iAA2CSgO8Q;ML2 z-t|=P8%Tq5T9a566xeFSiD~oaC~5A#0W4qe6NKPNI0f&Jbh9@o>(>F6Ce3UCvXw<^ zWsg3zqnLDRJJYcWEllKB$qf_Up0*idti~Z>QWAKyr8^Bx8Ns2InkOsj;~s`v^GCQ2 zW8;UK!hQCyIVig>N$y1v1P@+a^JBYqa9#9LuSvZ!gUy_~@P!n>M}uC{c1`fQE=?r% z$)UX7UELc4g%Ljgc0&^7Qo(Pwru}K&v99<9R1jQqS;vCnCG5EenRUpIOeF(087L35 zFj+bq3npn`vw*cI0e?Q4Kf4oGlPtm;_eNVeF>t&e=7v|HgX)u@WF#|fgenCO$ZVyO zjT;<6B06@Lh}+5`!n(GiN9hkR_x6U)@J>GU`v8MIo!O>b2hkaQS39r<*8XE!NDajh zncjw9hE*xP|6;@stkW^X6f*LM6C_Dss%P z)ae#!8xfckzql6Yk4MOhL`V)6#qB>zTc^-HXyr>j#&0^P`nV8Syn1h>Tn;AzCR8Xk z8WaYF17N_|s1^z!f+rw|oWmFSzbMH?9p!?f=qW%l3@;~^s(GFGxyK8g?x^?JOkNEU+++;egVd0EDPJ|9r{Ma#Sk~1%p9>FkCPe zLIuKsVIY)5H4u=(B74>QcP~k+bH-iDvgTHo-u|gv>wp*Hc0Yl4{k^X7mx~Pc@7CN` z%lmp%k!P14UKLsSzC2ICAPamaGBdUmueo(#a|rfp_>{fB9AY?0BS&$zxmaH*7pC^`v(W(=buGAKO+8-53f&|1uZTy-R;=o5d9cye=9Vv2Biy6skIP~to;y!2(ZV2lo`Dx#`)g9 z{OuwV8Z(t+Hr*v+ z)V2J{H{Z8^4&7|l)nTBhfPmeK+u`AFo?EBK9#YFigHH@3r&m3Gjxw6l($=##%h%JK znB{Yqc^j3Qq}yPjswJGjWg4%k!nuv8OSp}$uS12jppk$anh{&S7%78)D|hXY~2 zS!gm4gn}h7fLr$W^WEpR?&>OPvg)oPMcGAw>2I9$zKg5L|InXnU*&@5o@rP2+Gk%c zXLQG5e7^YU%gOupcEB9rtYVW^igvWZ0GE)D@WvZ?@ zEaoee^pBrq?2>uxq$@zTveKn2c+8jh4EOeaf0l3NgD>01JN{r4M&~0{%-H_*_DjuG zUeETNYIno4LG!BhLrQH>t9>tBh}jkA6*$El@3vrsx5*k^2t!ZYpkT;AfFpnb9GU*j z7;O-mdwJ62UVX+*6j!tPDp@oxf+dw4#kn(#>!DKLAFwP+W1^_Jya&h}c*ZreTU(1B zjnHTF+KsPjdd5w(eM4mteY@q`XtWRE0W#|9j7})K<f7Z6E|i( za^uomI@F^o`!`L2wUebaRx`^W)gg9rNv%$GXJ&G7*mF=f)m^ZnQv{kP4fR0VGo0W~ z3eiKe&jw8`=C`Hfqe&z~y;hhdf`B1$*i68uu;$K@dU+ZKj@-RFl&#abb~uJgt7nfX zA92;TBq)Ju=dBlimG>qXzY z2r=}Q`n({i`lf{nb*!YEqvar9uKsvYyDj?o?YI;MNL@&Jq*J8_!;rqdLj2`~cLpJZ zdxQBS(F|fL%_wY~p;86shMLy(*zG)yK&6i{c=J)@f4E3pmA3tgts-z+6_a^u{`l`4 zCyv7tHn9!EJxD!@UVC>|9{dJJKSN0E`pD6y1y~-f;;GSWDN5L*DKZ?qMWg1+&!5X@M@fu#N|SRftQGx=cQr9VN{0tf{75C&AIG+gMJuF>f}^!X zuC$4?35Y#(b(YUpRogy;K67)EKJ4U|L1*o~GuJWd%FsPIK=Y+&ys4GxG28s8tv1H@ zCz^B=w#%8W3{s?F*D?qM#%gCRjOeR?v5sQO(RZI!Ieuzlz55WdF_Ahtxlb@%=@)-! zs!`axbyjAm^S|vIUGSL~jzipovqmE{AYEL!FHjlJbWrt1!Tw97E^UwDDTvZ_M>W{O zoA1QzqUi?fjvhnzIXx==$nnj^xv2M2XPMczyHo|~TizyEDTWPw8)>EfWPdg-z5)o; zsnl}|+k;5Rn!h-)A|klavVQ?h$)A@JT2&=(u9zx|2#bmTZakaPQfZ^H6}TGT*_4vs zO&`rOPo9!2aZ*U%l3&vL?gGrF3Ny700>@Rs5ZKO|l~9VQDGD_nYdmXE`UZW7i5H%Cr5IsgPKK>hLh~>4od<#yI9i# z1J8;N;GTwba6o`+X^dbO=yo5#!d|6hlqYu`gP>qvdB1dfy?-3&}?vc*k zfR|yq4ydH3WeEmWPD-rjAalNK-=!o!Qk(Rwn_>UEla#kyG7ghQH3t`{V4PhT=XAgh zTV94}K2NJ*5(Lb0x=$t@pDvHsyqS?|c181eAu$L+b4J6Nlm{WZvzQSDPg|GpiI_gc z<*hwKrA4)G`RZMmA>GmE+TXBkN#cVy;dF4&UVfGQ$~G`*M_DTUR-qgUyh3UFHdIQ6 z7>LU@EIx0;sIR%}J>)Xn>V=7U_YVjdSU;FlEGZ@T7l;PY*@lz0X_NWgvTEd%$l3AC zJacWVWh%jaKLS&@NReTa)p1Bquk~NRoiA6UF_zrmk_UWZ+MGrYGXbsh0H-of+GPE| z5ZI18n4?9ZLM&dNo$Kn5yqsL1=yXM!H+Gm+SL;!ff}pka3yWwiTXx@QGV;;-;nbK> zb>5ZgN(arq!hf3t4l&;8tvGdjT#1Fk(m*Rx%t~X~R)F4dUpAwm=VbW!6^!2pD>w2A z*szRN9d|$m6zX<`iTLP9NVVWL2)0l_hrW8<=KOoO+wzFZ$-dz*G)jO z@TRyR@});v84z^0)AX?`wvwG|zOSBApKO=eLBetI%ip@pYJuI)T}OD_a3U4*dE z6^nv(q8!?Qo*+MGklJ8V+eYosOfEyU%eM6ix&=%&3{a*yV5MT569#S>>qYl4Zsos0 z`RPSLAwr9-y#dN=78w=vE>bVpRFNno&$A#`9_-t1W!r0c zD~nzgL&L8X80h)vl3&L4br*AYSB?RL!y_!PS$cQ1iz{30;yHFm@~T^x9TeSHE>mjt zdYcDLaq%FL@Z!VNXPw^^0)f9_eSG2_rk7rg@MsyxAR;A!pzn^!hWO(VIR3gx(O|uS z9?c~4%o0xyEy40}(`oOaxC&CO6PuCa{E?!D0??$AjJ9v6c_0B=BC%f2lWAFNU9pkC zF@oz#?8AKLdjqXfD>`Thx+ll%pA5r*1^Ss{@-Qy<0nAlif>rynBZmHO?wnUt9AwCd z2GTNuswv^xQ_9mvaNy*Iy#ZNMO<15q5GMtJd7D$2aM^6z^et2Poj=gnZmL)5feph} zw{26rjj~X;iBpPnj7CUrarQ&!Esc*aR#2^u<{{*Bhb}^3O*KXKIV^b<_hnd@2}1mA zS2Pm$YO~II9n7%Q5Nc9Lcw7=DyV5Cv%fVD=I*XD+s*2C1YOH%ENu^uaeH}C34S+w!$Rr+9~)iou(K&cJXTrAJAVrTGCphvP zw%T`mx``8if&LBafgMc|l@ZVVLV7bWG8N?+9H$}thq_#0nlA{gkw~+9@l#fa6fYJn zHMvZZhgSWHomb=9rH8)Rc>B!wpZUKR&opxdGh97;>k8xC3Lk^xaVhN!@ok7IMGIS6U9VM z^QfmV`XuJyZCsLKtb9SX~-%2-r9^H9J zbf=Q_+=`{{B>E(-MJ9+$5io^92{XovQ80NMIJLO_g}jNxtA(ATaF)^brk@}N{`enl zO+&tW?}HTPZC2!_?x(><|NFG>0~TnTp-SBl1~%N-t?mPB3XFOL$qzusM@3;GV!m}t zKDeQX;KpPBvCw^C1S_thRm{`^77H7Mu_!bfpa#Fbqnzm5FOiO)v>96MS~U6;{1sX% ztfnY(s(7&@Q0^3=14~I9L}UY>_qiZ+MB-KV*%#k{J|3!3)GT|eW=%}A^vrMOUgz_D z(&p#h_arM1%Lu0Z8bu$+Ti%v`7aoM)WW(v-RYt0;=&xQrtV@@Vx>0uL5+VFucW+$3 zF+L{!6s)|Mg*2VL?L9(l{ANW=$qVTJW%l?(nsrYekR?v@DBEhGkeZC<7pgMDW$-3O z_jH4ILfUi?#Au8J&G6M3Bz4~UE!ha`r=hHIKs05XaO z#%VM%YFh=NykDjaz2AjLrdI$@1A4rtd}0O!n74~j|oCXS787 z$twwPRXr6mWCil^&arr15#GNYz_c4C?d$-%!BY?)V;`sD>K!lZ2k=Ily-ZM+LW<}+ zXG_i%ibV*;*z0qA$X<@ug7k8D=fBaJV)mbT8YeUZv-xR+kc;RM!0S`bvlt>DMSkc~ z6!B66v*&8CBD}MBa3(bhQ%F^I3+6g4C+p3qJ;?m(3XOG|!+Hs9y`q+Te~`HyI0eNI zaUxoOrZx%2E$AqrK*L`~s&tE3mEaU{o2f;`Kik(KnR>IQnJhfWI&+_6`bE4iDn0_$ z9nBXmmkY}VMWUr!=vrNJ9@$jI3}0=eOq4)eH5{zXf~D--S8r|_x8Zo2>~MX^HzgdS z-k~s+?$v*c?VUc8=yl7o>_CU29&%A;bd8Ex?Y90L0hOvUz#)I&it=Cxxg(DP03{{4 zczkw~H*#{RJa=dK1SjFCOUq*>mgB7u@Xc8TWo7SrEb;1gN+}3&cOibD;C8xFBDgue z5Mh5t(8=9(7&bX(Ny5x}l!6I$0*&xf5R8OCko6+MKjpZ!&0Tq8Z8nop-}v&NA$lby zNiQfq2{SZ}etl#lMUkI=EWt5KVH1;J28T zLcNZUGpLz#vbxT}24)sw2HBc@^bw{5bTgdP#$r}!KwfIM_6J$$^%W=6^EUro+$-+cGaSUMD+7$cW}kqQ46Xv z0h6WdI?naOHP?0=4Ui{GUXb&j;5-9oAEpC(?AUgi1zM{D2a~Y$i0}tG!-W$tmuf}v zfJU(0cgnwqmFypu2mytE_*Q*4Ea;O81m(mNUsXJa##WtV0g>5wp#HpokCuA{26=CA z+m%x^qe2*=#zQPQ~Ran7;Z2(A96w6BVdZ9X&1%%UH?JwTN^=HtD(5t-3fC7M$yPgruNEyE-{6 zuD%5Gx2lZ>=eCh0ZME0mQx*<2g>`ov`{FwC&lwh^Umv@3j&(`Gwb(b9|e@&_UhtX5h_DYj$`u9i|VYshyW9h_i-BKlu#@Og~r zXs!HA&gOAsstYddgy0BMbUxya)l>fb+vU)iMh{}{P#QV*kk-OH61aq!aTTGf; zm_0n4PhzG`Em;rSf8qlkcVxy)JN9Hv^XQ;$NB%GMAwt)1$r${8fbO`u-|?cL;)C~? z_tCedSqtpohd-7=C}b85%fi9I_bRb4@|Vs@kpzV~xkF(>(s3A)yi+V^YX1k_R-EDB zs$aTmVH>0Z&=?A79SU=NBP!D`LO6-V!q|d?RtTzYW04DJ!cv!4l67V9j#LKtLbHAV zH#L)N7p;Gz69n$0z*^~V!RwdIB;ttj)6)C_6|6gqq-S?{vrl?ACqVC&#)f;|UHQ+L z9P(vQ64`@hx1~3eo|bXWy43Cvb)UexwcqB>-mv^;DyK~%B&(=2MW+*%Jb_s-EsGy& zhzupi&!B|gXkK2aqt1ZtAgeo=Fl=D|_+!o5}9d^Mi6f(nb4w2>O6 zRXO)@q=-v1qz!ktWskGO%~If!C$h0paDO;=73(Xq;gs)MJ6mACX3&7_WQVi@xgID! zQog@|71C;U(w*TRE;0ZNtfeGt*P^p?JCP-Ypw@ue*~+GEH71)|(`-e`m4c+w{QJ^dG>!u=T*z9U zpt@lOoPrwh{1L|&mDM=TJSeIE{Nony3qvc^sRQu3h03OhTnWqy)8{&@D}07%4CKSqC; z=w{AYkKJBTRl5>^19||YEfP(^9K?X!ySNHKi|^^V{<`VUFsS~-f8QE5olvs{ zy&VDCuQCCRWT4cCTcb16R}I>-iOiETN4FZ|vOIPr>&n%i&&Zf?|NW{C#6t-buVyZV zV`M(tqjL*K+a3*BK6b+q31QKOk!`ZZsDwW}0*+9cU?5~lr7VtM+fB!b5`&G&V?KH%|Hl3 z0ZkoTbp|9y_4@!vA|Verjf|Hxhz)7BF&G$ljmJe(mb7nWzmtPb#M}I)Hl?5lAFI1g z|797)7b`B`elsZk12@t30uhVZy^RGN#q1NGKg+=dT)q*_q=vYwxKc+Bd zlMT|3FJ}e5zZ$8X?cQ*)wGd3s4TjOq4l9NJdI=bu^VU+(M!*zFD{)~g%+_ZvT(2sj zL{kqt%psi{I-cL$BJ4g7!qdjJf^pUL8a3o8qxp8#u=Idgt>Aap3%H}PE#XDvpi3#o zNO+b97{MFTSw4}dxwi7@XPg*614B1nM_RF`xgXMbnWiIVq@D9YiywA$YnyT> z+jU2BLN{!UC6BJP7J=p+^PHR%*6z-AGx6FXdNO7?yY`z@DP^1h#W-`HO+ zZpI^_O-&}n_HLIC8F9FOjz;i4bXN<6S`dvCeoin=-~a&d(hC{(IZ#+202X`QMO=je zUPT!y0F=BK#BAz%PIX#X7N=1T+BYoS~*BY{w_$C5xcM>u(>v$-(n*3vxb(@&H#KZl#lK^4e+^ zMI%U7N)fzg^m?v|MjL@koRS_zN#F7p*p9O|_n3&6bi%DbPX7*KPb1@>$?>s^NYEqj z^;5+r!c^FV@`?GWSAItXDMF9Z(R-941VUgtg!}ORC9$!GC)M!C0h*pOtBx0hf{>|VUnkmYj-K>8!Juw7yxzwsx}Dxi=QsML5h~Tr#T%gax>6B#-Jt zd1-)n58Zu=90tB_#4hm6TWK@MPKidVK$9jPhIQ=tZm3wz^nlRozltF_6wFHBfe%tB z)Ff_B8i~*y3X2B{fjoHQ>rrb+>9&geE#g%{W`b0EXb;?nJXGU_U?(7JS=EXjqbs~k zEfAPwF$~^15^V`0Q4dw{$ec z6J5P(%98Eif3xw2_nWGlnq5rERvIKn`y%mdI?$q+&0b?zwmc%RDjqb^y2#y?cH;4j zJG~I{tST=VLU1kQ4gf0rgekm zRqygE{L!7aF|g09c;lw`B`)oKsIV?z0Q_&}Qr6iM1@O>90r@#3@7tMitM!@_EA2y{L_$;RiKcV1DGg*u*Jo zV3e49{<%88U=PY$xOZg&ZfGmWv#4z_n4V&?h+SEUwl4~55bhC^xw~K+KuX%}P_>G9 zJZ5f*m=E&wflF1rBxPh1Ot1a<$9snKLl%ism;DuItNk7aA(2PxnKq3Z28wZ0YpKr*J!NU` zmO5|=ah8Us>Zdhu0evNSUBdru^Tizs>f1Z+DG+PE(BdYgY@_j`tw|myXLtR$2@Yvw zE4K=OFvot8*xWAQ(Tf zIvfC)M=|%vw~ehr!w{3xTIxDEll1lZa*yY{ia5}F@{Td1fi_-$twVv1SQBVA@}@YN zG4er*#K-N8+2{O;+ew)MJqS<78y2oYPPDL&A* zPHXVKBq~2WsalS{%ovLn$;MD=otT3d0q4gkKR8!1!d(g|GNg}dMb`p#QKWVYETE!M zwINpXcx05Yp<$#4hRB-7bm_BV1g*W4OJ;R6UeOQiR`JOjDH1zj;hyyF{iyq!WYY%O zN5CG02v&!uBo7>}53vWqW1x+=7p2Hb(N4g1tJttPmj`3pdFB&({N%M zqiZv=2rY|U5r@pPZ;Ks|Ds=%8*;I!*zY*)6LHf@U{ z>!kY%6+@d`oS4fG@|Z_EY9T}U&4}LJ?!IGV3Szyq0O>Qg%a;*M;TWEXHDG3gmlZ~j zLduOBO?{mG*MCT>fu9K$r@C(cbj9caZOigRxg7j?o2omqXqB!zfrjm4H$%WuRddNqXf^SW8yH>nSzm^27vuk?#`V`m6GCKzKrk}yrjhxs$7?j`$}_(^VV1?ZFhXYiHjbzP1JIN zSBUB-$)gm?w8q%O8;3z1S7zx43tZ=_IIpz!Mj5iFZ`Ar4hHpw&G!E0LiavCf^}cpK zdOQw3DIkGpWx^#FQd;Ogy`sy(+5I-t&it52>dl_j&+K6An)SwA=rSB$-by5a&E0I{ zMBi`*KB~%VA!=gxXV*AMJj4cu7FiFcj2NsB>;+Zvga`jjD7imkvHlhJK9^V^vXFcI zzI@K58$R!T)5J<}EZwWJJRe3Tsp@y(Bp#ACYr4EN{$sSDdJz)?{ma*NrzJn7Ta(L} zZ?I{#_{sK4YuC80^=>K#)E1Ao?y_pkzGH3l!0+#}Qxt7eY>UlB3j%QazBePOnf9J>-{);#EUS=r)__ppJ_b zyTBDF+MC@kZOI;uBRN2{7XAl*E{t~Etb?Ya0@G$60s~Pw6~1+pE)&nM2Z7dck(TwAo>A%I!Je7RQseg?-s9rIZkXC$?p*lc z$_@Ux$)|5=+>jTY?T%ZfHkrP9DHBm=P*(z0Z+HO1=(2ktl`;%ovOhU7i4u3ikeWFL zZ-2B#h#aflsGBu<(HS+^d1?Spc^U^Y5LB_BP2M ze2=ck+7crh60L+<(;`rKjY|}@3Czog<9?L)_1mJ~bGz!&D%(B|wkLHx2)eRzvAfpu zfs;86#-?)X<5wopGR5QBg2U2Qh8ltHl8~#`4SFCqnkiaO=Z-YUT`s#e4$}pbGO5Ao zURRWmbbbroN_Z~<312_Q`~LQ_?k`wep+?Hv*C){l0p2;k)u-=Ak-gEu+pU0?y#bZ@ zZ+u%L87|+^h|AAeiBPUBEz_?m4RAPp*+*7EcAyF`}e|2 z!hc+{^XjkA;6Z^jzXTYMKhz>ys+?&i_!5_cb~`omi_u%;4slRE74R-0KwxteFknLe+)p!p!vqL}*VYkbI_z7AtZ=hxV<1p-lK%-M(+? zo;?Glj|S;LJQ55X*=rOdeCjOJRn-l@TDnWrj=-6fDxybr($5b-=+F=sm! zLCY=NCww=Ws?ZuoX4o5%f z4+{^Zf2q+VatNSG0qk{K$}W!3bUwF%L z&7$pJsC~*QcIGbKeIElo2+EtW5M5lG-G+5bXWgvJM>Hx7k2dSgYsL&_O_#ZV<++E9646 zVt2HXod=ZNVMYKMN&ZJFQW3O6yN8LPl+eMl7%cJS5V?jpygkEM&5L%AZ_}}m@A)BS z;+IW|lJ3~gH9ekS^r>pkGhpPFH`_?}Qq8`+gybX7elY+^8ud45oYi>Mwtlp#h_15V z4a6?~!PBl|6W;&N66z>);_5PvfNEqh+??BiodI~S$Y_W;&Kut?ujHyU21!AG4l!xIu~M zw_E#}E5GuUuIrmmQ(jV&115sFA%PAMpfbs$Nv85LX0dRhIUZ}`hevO6&6`LoZ2_7| zw(abvxznO<%*hI-yPE)5OO~nFwiAi@ntyD2qNKCfVjU`K-eX9Yh-~ipHM#KaBz0x? z@N0$9#1r92R4X3ZHT?IhXe5=g# zh$sMfU|AJ1e~Ug3j#eA1u>Ac&?&!@xu_t)6$WfEqD48GcH6Jy8M9w4khlaN%!MAD> z>*4K|GTD&90dyqA!~Ivuos*gc?_H53V;_>4Pof9QukCvZ1l)tQ)EhCD_KP3yu88JRzkMSZuuo5c4n} z>q)E>?4OeEeAzaQCD_jO7X_cQ#G062;N1Tf#mVVpr+FmGrSskQ#cv1lgEat}KHmoI zgo}Lqg!XSgb*R!M87qc4?kwhuD<@i}gd8|vx0C*c2MzyLLGB|ED1mocRLa|z@A@g} zkGhm+#43xlPH=_uPKEmg;w{ILS>!afW!7^C;s0HGbGiN$jbb8f6~cjTAqer-c3p94 zB6PP9B)dclRatmX#mxpMKVhNw?=Z?=@=c`?aeG}7;^l%xX$Jsc9dij42Pj!N{Ak`E zSp|`v?QV3UuR)2LT%ojK_Dqtvw|!nqiM~z;X<-%!vEQ7@GFCBDc*^OlM4OHiiC=e2 zQgiq%1F)7Lvnw!;<8$wNxzy}*gEvp+?mE`aMh}DjrF4LmV~LSB%PI7a;BPFrxGuksFsB1rpOk8s6~d+s*VX?zv1|G&vvVQ9yOKM z)5mINK6DwC!>VR*ulV}Jz$hTest@NVnT3fRsvfbSceRsEeZ-sxhJ1lLjfJPT1nJ7s zpyvkMa6^%a^9mS)cY#kPFiY~_GRcdUAm;%3-?%BQCpfckAc?`^aJ z__m@6i~f(q2jUqq`Cdv2EZF&rR6R^%$5gCXtyWo0XuSZsQv9;mf8qng?%@xx^FFp- znLT>7-K_heF{96+6Qmx*i+okhfxFREHN3cQ`F+7>i!DBlwE{f}lWWJLFnc@3LVDd) zg9e2D>!{dq6RzH3;CRhR9f_!;9B97!TVfu(^IR zeU`G9%d?^VUe7{r_gPL|ol^!LX>7WTd#6~Yp3yEJho@U_=Z}27{4ds}mX~1A7~$e| zmAB4xV|~=lb!27~1Ja2!L|Y(5)Y{E4L1W6e#!?f6K_eyu5dZ*LU1t|s2~vVF-8(Q0 z)Id!7&f=WgC@hi3%-*%6rzYgLn@P83SYRxok||@1AotuQzJTMIz#u$vfOzB3j03s| zQ$N4|8D@+oFqpYQq|2>qS1;e==ll=yb9NOKum2x9Dc!=CKHd$Ev5zPtRTM$endB?> zb6*uJBu`<2Gbvj4|8pIxI|wOmsob+Fn-sQUxT)8XS3AO1OVG*NUAAbVh4^p%Z}0wc z=^Y`ig6EYTH>8QOqp>DDf&)2jik^y*nyd(tm}JO`cappigwWrM73f+FD%8Xv&Q`IO zl9-$3fe==9aw71+v+?c}8Rka6s z9+#{y3$5eT9Is2aYg|Bl%(~%^0jyp;86s zS9e@^^XOW@&Kw`ebc)UlC@yVs-6fa7kdNNd48>W5zfSWFU{&l?zA-*DxA$qk2t1-D zS3#3i-^I)Jrk8?ZY-28E1NPie1KPYCsDzC3na+k{7SSlfhN?kK-z87Uy@E+Mh^ntrsIv5A$6?Raf%8^gEg?m7vCiYgDNAhZFIN%4txkGDbHG=K660ya(f~m*trk&z z^ev-ap4^xE*h9((cRxZWKe7YQ^TaRL;xF*(dT?Ec{=f|d``p*kM*DSHaf0=$#HNXd zSatlxJBFk93!mH($ZKDqMwk8n@Ajy}W(5mUX>(L1(=~MRPpOasNxr_M} zy0c#l(EYe#xVvtYTKL5+`vA&oVshNe4T`fOq8BO9xrpow!E7-4^kGWkv+_T%EB=4J z!nZ>f#=ilR+7HXMBih?3bxv%?d4sj+kL}z!NBj4rl#{b|u$|bf5Ef}eV+DvO7jj9VV~fQf zx~I5MXD;3UPMh@m+yCw-<-En^iMgqb_8*tF^=qnGS2x@`4EUz$ptg=m&J_#aep@t8 zK$OdS`a7>8%iNZNEQh%5(~%;bt2QXTBk)(^*M$rl1W#Z}L|8hD?4G@vdr2_InOOf3 zl7HGpJzfI3f1R`HeP6v)X&pKg_D#2GXbd#u8X?Un!|~r#=3@-yBnKulpwwc91wbWV z9m#5%(=r(%&=;ChL=XppjpZ|0axhPX05)^8tT1Fj{seFVB-9`_8YBjT0${jU&K5Ed zhM^KDge}$a&Be=_$=3MXTX8E{IrCA@eZ;O2e`w`C^!MrBT*$5)vgz&uqu_S)J>ReN zYg_jkC$FWnc?X}iCzsPoOjZ88qeFHy{6@)5PaMo2o%hifA@QTs%&~ZC)X}qu}iOG`Gx;|_KM@(d9F;yA# zP9khEUP(bH*%-R0iN-b(m7xF@hT5-wHu^Dklma?9fQ6_l-#_i#aWoqg4TA%4uuv>y z3k?FnK`2N@B?yqhB7aK1uO54vuQihLYh3D9{MV0b&G+?;-0~d%zm{*9OzIw=?fV+N zEk=L$tYh*wCcek%0-mpL#ee14RsVk+2SaJoH4}C}&Q`J}XvVYS@}5J)%%!hPoa(j; z=W%}e7%xxM{0oLYRd}Tg2WGmo>Aju`bA;#!CqH@oUHR%xXE_ub`q{d?o&Lat>9^ob z?#jg`za!#mif7-)vy%2d2~QbNvA5;H`9zu`e}n~$KA+=j`eDVGM@0c8Vxhp;Fcu66 zl!8$(NGKu-1V~{}h*gosahkbO_Z%|h&bh7(@5wo@^aK6hyQiO`*}ad$ulF! zQ=6dzeL<`L%kFIK@*kd(uB>L*X|EG8F&Jmx?L}j&@NRBQC+Y2Z{gchABW_zPRh=Gc z@?(XrwOr6_xx}6AwFh18GW+2Xn@tq57VmfTiE3bY#)}Ocd|f;HS1ezDvNE6$jOGMw zLHGat|Nn-e*r+fn3=N!tV4#R95h;X1VRKrjz1&^jH&RnCMb*~=s`G#s>b%G7J!_c7 zx+lI?w{+IL9u0V1!tXVnzPgm=t+pNBfBVX6yS#Yx&)4ngcV~RO<=uSW_UbU@WUrvK zhep)PFXm6*s6X;g-x(HPJbY_w?YlWO(_NaR=>e&Z&h)y2w0jwj#fm;B#wqFx`qYL% z7!@LpT9`kAHR^&NL}r(0@2;qqzYp=R!rU_s6N#ZHTz=hVW12l*wcPUudU>-4uhk=M zsa$(?tZ1Fmhm#-Y9DmkSA)quk4F(FqfU%$~WD5lX!9b8iBoQbD*>!$-tD3BmwB4fe z)|XJAy72jzxb~k(U;A!%-D|>KeYzj7R)^M9)c?T`53L_Q(I&&!&APGgPc~i8_w#wi z!uS6>H*=jk{?`wEbO7e+y38f)qlDpaRQ>^N`zElu(L=qj?W#zLl~!q=qr=-mz?RFd zuYU_Z1N(o%O9yQasKC$|kn~|xIFZVSq{(W878FxUz$3iZe7ZQE&5O!e?>1;t~?Fspf;46`#BKfiMMetHMn2m_5bE~b4rOd9^>0>2Q`^$E3 z{ftsHxd%=tUy9ncZU6CAw%U!5+T3Io;~}ET0)5O4efEnA4vf5f+$L_m;@%i`H4mzE zw*5^j-_?IPBN3dvr-l)FAF#Onp56zv2a$t7)<@Y^h)uofz05E)1t-HyJbIJ4=y>;d zHICBm=T)&>%wlySVy6>2M`2Gf$UKFqF-gggVVCseM_pHlcR4k4mcpy|jjQ}7(<89e zdt5&TN;|h6z(L|*ZB5UtShl#lx*TP)im{i?iBvTY%I8_E&t39cAEdJua0endc9~a7dIw6GFwCEZ8NfL__C?#gPz4uEPXxOfowP$DxdDNG$d5;qMz=OISEJ^Z zb`W|XQxL)0THo)#U`R}+RBoej!N?rzujt4og=RSeSI!P*`t;hGhqj9EiO8c+_`1+) zOiwiY+i81M><{wO5!uJr9@?_YLW|!?J5v1-ekBr9T>${VOt>lt|Ix2~i@D{))N6Rr ziCPB3n%1jL3*aDVaQCKA1xIX%8IDHVsckgAL(wfqZ=}l>T(=6b z71#XDqKn@VTphOTFLLU8P%_Y~#w6B2{DmEp)(V%*E3xGkEj$)10(L*tixI3LAe5Lz znnU;8_aLZfm1NXnU5Ds?F)hNcqfePqGRQ%}IT}|k>`uZU`fs0fDjpZ|vj`H;EGbe) zG^r+xvY>X)LJZB?65UF$f!nHYnE;~RkMK-*dO{=(zZ$P8Xpw32{P{L}sJ%S%SZO zYM~lSh<>d#1_){xX-g`&oC|n(i{NbGM?BmP{TLvUI%CAPU$5=Z|7|H(ko=fRynugo z_N75vpnED@WDD+Pbq2i(Xov4SKz(gXo{y^~04a6{!D$FsyKxB!s?=g0kf}s{58}F( zg3ZVOzHi(YuL-=dRSCfGXS;3c_4*e@pT`jULRlQLrP?3M{306kdILI{E>RU~YDD%IbZIGB~^wkYzBHjdN?S%-s&4Jq)+N zERKGdtkT~(*_RTpJbW!hLL$A}wqQc1JiOqpqMRJ8t~qsQ5bBa=p;9F&l8`3H6}CGSCQ@&D82Ke|&o(JjK_an~3h#Xx z!wCm2apRI6ZvNyBU~xfC^L8MD+=J*8pth*xCj~TBQyQ|r8Ge%Rft@%cPGzY5Z&#MK;ZitKtT!>ugqNPvSMa&E#~*=t`~mgUN^KVhj=qX;?GlW|LKHxcSfY!=8S-fAZ-o33MTdzEdM8eI@g3(+O`@=v5*$}qr?w3cs} z(prNKbKRT^pUk0jJ~VzUmssXv{bJ>Sh>>XZS5dJoLCEGkDXy}bA@;PL%unIF*k8c5 zc%i!Xb);W2_57ZJ+7@*MNEs)L_H!*8LgT=?G~cn|LuXu(WzDei?i@Gd(pB6rxMbavId4 zwe#V)l4DX=`@EO(s+Q!09QW^LY&|61-tl3&y!P{gLIi3~>%Vhh^QtOFs_8 zSZbPr`cP|Vw|cF+4KnbwRs;Y&l0cS`a4JB<9JHTMOC^jxNG@FH8#qR!gA6rWDx?2R zOO)qrBAG&YGaONDXhxW?$>A#VP5ZML8_Nrb+cKuK zKpF(NUmyhJnC1VvR|_U$)P zrDl`kzj{BibC*-`q>_JYYYjr%3zfv|#00Q!Y5ud9`m&S!klbEoTpo&TQRrD52Y2~w zyoGtVSCWa*fgRPJpyN&T^|jc$-Bp4M44Iz4(ilvlD^BEF2%j~eN z#(et`6LT|?c!K2o{(SL>}NY&ET`V$P7NCk9_GPgQ>oW! z&i4^F5E_#gR9FE!0_*&#Z#<45gxKe>>vaGW{1f8ZJg$bJ4Am_GZjcsF+9|8Ed;%M+W~@vg>!l8|-g31x8*ggo~p%UCp&r@q5-oMR+A_wYiCw{yyg zuQB$lnuPo=NL^uL`F9}Cl{7Kn5|@4CVGMtb)J+qjawaaasmT(7Yh(^VWkqU30qO~u zLoWav(X}1b&{hT$!PN22OD~z>4Z@Cxo@=*~hHh7xkTVjn>|n%|RWfW-g%aha*dfyb zpG<#MG8w95+qf^X_Q_)Vo{0@kz*9vW3z%`YeAG-EjME4M*#Rp~Digr^NR9f>WQ6_>_fm z2jV5ARJSJQn;5|7^9{viKWjwUsDyC=SqB-d5=8fk+wQe0Tvg})TD?Ma?;K;Z%S$rbqWKjd;T%LmomU|ZYuSRc zyrPfILA(#O`emj4y)*LQ_~#Ms$|P>hcp=8ggQ|{6l${6ljqV9Z;Kh7-3zGvwZ}Yqa zU17V;)I}VxdzKNXKzCtK3d}D9aewl_Ih=5fw+U?~HyZBC!ctVO&;)^bU(J>-IJ|@7 zF77Z|xHw)KP5I-H_8Qw2$`HwrN!^V7>P30+>nNl+*Nl&&F93SJv zo*qraKAkH)y6FS}eJpZ9F)aSUC9&YDkxQe&lb2zr++%*IURTr{j-{s6nGnTpzl;>< zz0ARrq0I&mbF!UAcCM7Qtco=rp4AJCKILZ^btp~b>I6X3$QvM7W#nQDOy`kP-Vi2% zWLVd0v+GonDLqNZT+YrlJeu<1!5AZ zj;mz!9@Q#+Hd?(S%Q|M!ds{H4I7y_%e&7*M%KxS}B(5NlGtc)`Ad^bU3l*}$VomgG z)iFD67UiHC@n3E-!PJ^gogW}X{Rfl>IwTbuU;ci3CzA`FNNpTCZ^ji0@}k^A&(pIE zGZF;s$;gMWGHW-OXcx6adpyU<(Yv;w>$wMbPOLMzV59e{jqyr%c+%$G_|#rFG@h5c z;~0+B0LVChyoMFWf8jt~G!svB%(ev4dPgJ6Lko@>vX~hFby_Ak`2sQ9xa5>{02QW; zZ5g5_M0@2~pge7A6|ej#$<*6mv+M-zcuLHz*m_TSw*F0ZTE_kjy{zEQcZ;hwGsd=1 zWkYy=@p$=vM;$Q5rtS$pVSNzGO4~r*qk+juqM3MU!5C;oov2s6bt={tMdP_g!>Fz$ z(DyMW$lxCdnZ|O^npG~5&35LnIPece`E@)f2_ilX1AtLFA3&qw-BBWvr~9@*PEE&*ukIOj?YpKOiKsa111T=lqynLw|ww zeF zJ{O|}0+{ImIc99TpT^EU+{N13P0ZL;WrS)3HU)}oQ!mC_?&A85P@ty?;#qz{YL*7m zz&qW6TC~{%kJ#cmLO5kv$6q$}dO{k;oB4n)Z`AxeytChn6|O$~w-;H30mE45vFd+Qenou;{9YXMAT~6^XB@U;4FW zs0gl6zAq;D*ZP#7Vc)O2*%EX~+kqiNvzowxpua<8;RNsZ%~I29{I&4#SlBo4psCrW zvM=4)wvKX#FIQnZ3B=O(J*{qVScC@Pz=3eZ+rlipm9}>_6Id8Ni|uzvHS%!=i9#vJ zKK)x7;$$7CMvE`Lb%s`sa*L@&dBr?d67;;S0U>u5)YbL-hF4GPCc6qJf@9r0uc=R$ zzoA`TYhk=8RlX;wKmD;GxYq$%b~d-#{s3U)d}^#uomH-uxj1iju!CtgK(y*4l;c!e z&u#_CrQ$^;lx0hT+ddE_Wp?T#vh(&zd^UQCU>1Fo9Qb$`tJ~^|gXIqRayzAy>*bS6 z0QX8F4ZTab{`*`iCQA(>`{?4*%#@aqrD8?<7W`KH2)K+U{}%}r0qGxFv_T+$cgUu< z4GW(&qb|4sq<92`RJ4Tx2R?oH-?#Xht`It_jtYtl6}>+gQbvJP54&^DPJ7z`yxZMk zi$nx(?WiNH3QfD=mx-|kozRwX9$Tqd$HA#JQ9QW?SYTs(9%1BNt&^?dm1c~w&Q=+v z`@2>HmqPvMB9%pY)ww@+23~vp$IcqR@=wWhMEUQ`upH6ih1!18#4`po`ixG_{Kx3} z(Pa||XGONu4h8B1Cf)=C)<9E)pGxwd0SMpAeo$`QKd0RcJ!I{7`kj_Vx5k>lBA zpaR0I#fbC>yV^eJOO|Z>UI-t4YreALvx>VMiC{|T@bLJ&-$3H6m8gKc308)Fk}iO2K(BMMSSRBwRC9{W|$ zjP!@6>Xe~h-An@02~jWOo>wON+@ezOLuDAj^00wPTx1iEd;EZEW1IO2=D77MNizP#LeTU@!7q|9 z@SJfsSH6Yd)?&$tDF313B(HfYW}^S(6Yez7h&W)93m1#HdZBz(EH|!tyoZj*o4ly# zul}HcUBa}0Vk%MsM(cbcC5fEk$eg12e(!U-+VF82fnnXU%67eFuK7m+JrRAIH?>p3 z9;Ev9NrVG8P3a+J*mQY-X{T?~L2>cVB2Q&&Vx#wN_=GlR_c`#Ci^1&=mfhNqTHPUI z!vIMCr~t7T8<2V{QVtb963hn`HyUf(m&^zZ@dMpfs-N&f58k)z12EJT4BuR_`4~7N zFNmdmUqZ-L9crKCG5d?=m>z1OSqHnU*7Rn^C<_8_gGR!xiUr-B`4lD~@Ksr?E27=|#^X!9;mV43om1?O-945#&ggYTVx z75Qv0peva_aCR`|o|_m1DrrtFNBTVdaqN2&K@201msZwL0c-(X)cLUkwOi>4^&c+W+a29dQcNA$ zJ8)^E&u90Fl!q+EV&slqVxUCP`Wzx#H7i%HH}Fvw+o~&JMRSjUVc3s(wEoaWB&4qXuQ1V2D4KoX1%utJ1m-1k!{p*Xnht=F6}NrIxleF-(Oh7Yz-%Uatd+2 z?`aT4-#AH0@P^FyN`@28`sUsxocpq?vLw9`Y*+!+10)Z6nOIp>K6 zHG9R|gOw4JlIIB_L&eX8+I<-V-;xbwP>{w1Og$*% zEyB9fq5GklZ|@vRVI=~7*!GPY{N(?RHP4>!u*De}<_Dg{t(BfvB@LAQH$>HZ4v}h| zJ(Jy*J`He3W+g%qPnON2Bj*1HDa-rq`lK)4)(Fb6^$3%kE)?6@SQf!oD50+ z0Ug)WL~ozN^Ur^3u~ATu45^WiJ#iQ zBXcD8`VcC$WUtG&KQqZ~!KRLC9YuCVxd7q66cC59{YrzsQ&k-H7dk}9 zOWm54ZCr*N-a;@Ja()4%C9&5jH}I5nE~6ZX#y=stcqRP$Jy2WB7xpO_C4S~!ovu&9 zI=}a&Zn@djNAg673X~ypUcXr+!bjP9j?Eyin`CmnfFSnvrurV2!I>YoQrQi4U03f8 zf)GOP8u&=!Q1+hb-e>LshMKfwX$`fZM-Y*9y-)x>Ht74)!m1j;+Zi||f@Oa*z~)4d zZ8tl)cawL6TOHWyB)zdkd8yo`N2%5RyO3GG{EHpIFpW+>?|}&|rag$yu^T;{$K9_S zE;}WKi`o||?#L`$i@`bBsr)eR=!KxEJSqq)lnDk~54qH;D0p$DNrlLNlcL`Q-lT+h zbNC|kn#5*?5Sl9hFzL(1-Su*pCP?`4!G82|i@6Ad>K`2o`K%$2&VpL)+?@G|^{am->5%6!dSjI8`^R^DX7(0McssCdH-Rn)EQbR7pr3V7{c!N0>Og6o} zBw8ENm`hEBip2z#W0Ce)1P>zq6@JMzN+LMoAO}-SNK@WT=nk_$T0|Pg}-D-_A z$4NlOs+_?U?bgsDTD2Vu4Hk4<uqw~Ir&zz_J7hPRa?jSV*({l2& z0S2f7H8fz;ym#|oDSBz)T7<_)f`VF!QsZR#TSRWOQ7WmNdM~nRBV#%y;j|M*JKCNq zABzZ<{zYF1X;u{Sj~Sb|V4u#Z-k>kFLUu-EQI>3V9B$7a%;U#paNgtE8uwIlHkL*w z#UmJANiPS_;RLW3aMB1Vb>@~16;|2II&~@T9uXp~56w}MqgdZWSr9`l>Xz?=JGg37 z|0KVKVlV~w{_SC3*E{qxuLwthQ*3WulBEA(kFuuUSfM?wWuoh@lGsy}1pnYiYg4!M z*+QZSS6%ixm^jc2Y>X$4Fhml$U?g5KLP>|;)m6Yd9|${vVl(LI<%aMoKB{6iZ|_dy3}&VtiN&BAiQBvHiv zo-k1z_#y!yeP8-h4@NS~_jBxbDxy&yr9u?Fu%bY@#Hk!+)8LO{@Ammje4S0HTbzLz z9Y?OI3dyZ(MQ4BS$hy0LzF(P%Bi5e4;N4C@s}=u?%Tyiz#gWsWxSvv@Gpq(RZ!(O^ zLYBesB(bN2D-O&WcDgYLA3&DM-*TY*V1f$y;loVhEKRbGQoV>LG}c8VZ#!DXorv}F8J_5Mu}DyB%neot~y zQi2BPIJkBc{kWhamL;^1X*-H6QTu;F3v=f^_n49 z)=q8|c;v^1g&iiyjou1xV!3ZYfEbclhM``MkN?YMyJg7R+)7|UR#x5}#h5Y?U6)75 z>I6TGY<|`#I<{&e=$NV?PA{11=uskrPyv?1;(35Ur6M0-Kb`+WJt|z7 z?k~@}vqOh6qBRURJm+OtsxpjFEMXHRy478!h`5=@w6PWu)YHJO8yS=~ntjZ}5vB5f zjO^x zG*f`0nQP-d_t=%^+qvl)d};Gl=8iru&AK|sp1a5$pR1Pp#Fx4s5gf9$U(fk)pW%~Q=!D>fC?g4arJTw`wyNP1eZ!9Px4gPzJd4gZV5O|z@+ z(b~jF-+4GBU#K;FL2L#l9|nrl{>FRr`!)5M9~mvRWR7C7tw?c2m=#3v;>6$no=MFgiNRaHWhp0Ma1bER-H&k0}ZCzd+U327uyLO&s{|}KtG-Re*)ak zHC<_T&tBt~IL_i|33N=`&*TiqST8Ml1hgq@V5q^ZaVcA0%59*Xy?mZR@vJ&L7314I zN9HN+dg={&>t6=gAEFTz_#OzGLJ^k*KW*e@jA?9l-<$0_U3~aA$_zRviYVkz?!NV@ znc>5-nKPs9Y-7vf{d5@xZJmN6wnohp8NfIPvygLmw>SXTP641;$i%DiJLTjeYaGa( zjpG=pzmzxaXo|RW3Zu?z61_A$anlw$u!QLqIUYusDA{^LEvNx-t8M3Zyi5dw;p;AU!ypJ48xG=2 zGw)4P{Sv~PlhJpYQ#7tfbM5t}@v%(%rSz|Tug^O$89e(qdI@2pm%@bLd1y?w^5NYY zKgBLZDWaDlHjJOY=*00B@Q~fVB5FR|zs)+H-C%J}#garDkBMx&cEW3yQe^x~pV8|` zug4In-{ZTbwwihJspLRtVs7q2$16-E1;bL{g`k|rRuM#y4CUm__#z`j#H%*3>D;|l zI$%?CBnGWTk%15K*doBk;a5yuFi~sbQ(DI;A?%g^ank^E+Z$rS+QO&`FcSkI1&>(k z&a^(sqqyC|CFByy@NF?dAB$?HDpdS9bnS(9W2821v>3X81r6`Prxjw1DUsQATkzT8 zLySPj-w5wPeD)X8fBcTflfocvjLZmlljX)iM?Pp%k#Q&sWlXPpk0~l>#+>fgaoCS_ z0Hz)-wStrxlz-~~2B^t->r@2aC-QQdfVlqerbD#zGS`adE7;n5Ylo4a=u97Y>?ltE z9}@Hs_08_Y*zK6S z75NjdGmq}2i)b4SAceGLYtF0KbYn=~Pzw=&c?uchuUOJqzFe(CxwT{8h5vbMtAN^3DUD)ED^;Ez}drQHNg*N$Fx6CTCH(5 z>({!l2!w`~d~bH8Dl*2unUd8;QjST0+FDIE-~ts+(x-Y87_@9`|0(zFmzhcpX9S`x z@*K%*=N4b%aS1P1vtL_L1(Ij{p;B|~7#4^i!dxnOv9vv8-1K*M{g*vR9%tI48({hN zGx%^lUHF)qOjMcwZ8(()9V@0zrB1;2xTdXySb9C}Q(0C!Y)>@m=$)Svs(R7=$EPkq zRwvYQ1{M9H)Udd$sWDxTK}&?CTb6ATEEf9CD&%LUJV|9c8uZysO@~{SQ@{aISlwbc zvCf56ukjEbruyJ)OcJ7dW)zIl;@j&s_RoyC+U2(yc z*U9yy#d1E^nvWZXo~N?VZPHv}lUj_+ZK!JvlJ%QI(4lW6TTdSq3Covl$>s-OU@B68 zYAQVe8Wbp28WaVC1Y{ssXcYAAfQA4vAy@A05&^VvOKp8OhipB?sM8vPM95+??rxyQtQ zv$W7pM7p{wldYIvF>i!${!9bRG10oCQkMMuPw7$KZB*t)BrI_n#-1Ke5jojlo8of@ zyDy$z!+w?xr58F*pJl5WAKePyJmg#nD$}_X?akN;S6wkcRdFsFIArzxe~>9^TnIvg zz5n|D|0w~W*k~*m3kCwhfiPe!R0{c6b}FR{e;zu$Df3t5x@mr_*TA8m|34v0BrvUtax9|1(s@VrJQk~|Tz)S@?lX}X zNUkX7zGYoHJV?S9*p|+WfMA`k@to~8e6#Q~udl=onp6ItcxeV52>%e`px z*!*dLRvcAMh6X*572V1^dg1)cdYcT^d!R-XADRDs|M+MP76(CLz*tZgECq()V4#RX zhk33!txD9nnR&$Z#EYv-iit}L^E;okbYEnGl-RkMFxJq-km?;pu<^>fdY`{j&U=k>;G{rtc767Kq9lQ-lxeM+|ofYmXB z`7n;i`A>b1WkFzlI0bhE%T-7lvYz*VhL(-yleX>zh6uHReiw7Rn<`sHQ(fM~`2aQY z-^X4DKuOS>T^sZAAjw=sr1I~kmmY*;WhHq^>GHi&!K{k1<(OASU(@ekMA&Fn8Vn7E z17W~eFcvx#f*~M@l`~4Wp6010?)jRlRF=6#NzgNvGp>W!sFl5^(C7aw{V#XSc_02P7UhUR z`RIr+WB@=BzyJUy!ai?=c_Fxn7k|-< zW5ON85+c)Da7Lw2)N?oh%VEgk<1#697^=I^9a6xGgcc3uW1{P<+x%Q5C>*8StDD@% zDp4V>Akye}5&%S3gBXsEUUSjr#LYnD!;Rrz+D%a=p{|QlS@>1Kdg;yT0vQV`bTFZ* zqLh!vK;I{4u=+q$A%5k*pW$DYR}|?Ttqq;qzpl->kEC2-%lX}WT^j?ORr0g>=wa{% z^xH1DngQha+k~I0gJAXsl#V)M6mMyUXMrA~@a}cS(+C!fZ+ftLs~L zi^8xG?{Y{Zoy1z1>vxDu9oqrGBaaI_b8oOij3hHgeN1~B7=&7*DMgXn0*OEzC&9)K zkkvlAQe`Jt4v>)aZmWo{-0y&B+d4gM9c9SsgF0TSkqPKFtJ_Us=Uw1hlv$gF(>%$Me2?KePO( zd_n8)0o}?iU;7^{Ozx{NS*1Ddr~21uoQoLT7N$YIYYCx_6VL;%MZOa`GQx2?i|%lt zvG?VM#5WVAgp~}{M1}|6PjYH);EJE6@F*(o4|%GF=}sGPRvKhUuXW}q#$y+6yTP1r z@;ER!{#pcu4>rq|-<3M*app77jqz5@|9l4uK0PztEhGl0P*6ka&$VaU({PZXNMILG0kzs_xbCc8t$Js4< zXEKHNcFBg9XDlN8WfUXJdb~Wo)4(elqBa@;NI#j;=@*VLiwFIacoz|uF{!P^R> z=VfEi#nhB>D-xM>a5Ds9tl zip4bjt(jh^0h}A3`@1*R-qFeXM)A6E5T`S!bZ3eAC1~3M%myl0?BT3_*yNiBi}?lX z1izI39;rs=y$0VW$CY{g6PE@IQdKYhsQqJ!^UQ25AeT0MdI6R|&;CJc^W|%CL$6tBnAa)^0zA4z}eg$<@3JZR0_wAKDbWi;W zw!h&X@s^HS>s)f19XoDNmnL9K<7@p59;`s$K5j#jw6AA0Yqqp5IJgi$dR&?kSq3;wa6+pD=rJ>8xTO<=^$m z=+I%h8$Oz`$zME2PC91MA#rwZ@xzj~HIJj82^TNM z$U0fJ22yb7o$d%TP_z-eF}h(kf-h{EBM$i;52NJY;*YgBPv?nWEI=xMyuP6)qWMw*@A*Oi9cWLk5=Py)W$5B+`<_w0oxsc3hdtgT0x0q?har3zRu z4#S^kBJ}hL#heWg_ZSgy8LYlLX#zQE-;NXm>qUpXyvsYW=y(M99!DedpVkgBf2_cW zueVbC6Nk}K9`7s|(h>{KyJzvL1c7AynI`y~zm*0pRR;;%$c4q+f#`8)`tU4Q5NJl7 zUxwg!;;cp-tzxLAN{IKxgA{gKW>}MT5?M6V+M^|dDKNT+zoN==Kzj?38GR-&f_=T% zCW7R|84si;J|B?`>(ewo6eqY8`p*<;kY=f;+YPQY(B&w>IaXi892jGGdD#Po3s6*A zk1a_N8luad#c05?u&m+KmB)pL&ro+}=svLJbfAH*_T1eVU6*7o4*p3zFoY?G00Iz6 z;(pN+>(CI?me54+ScEEfNcp#FPyw(gx(YQfX>2bSyY*OU1{QQCN{!^w+o&!kIXqJ3 z>%4#ZTLE%cbn}w5pd=3bBDh8vKrc(~h-cZLP^Lf+o=qOM* z?6mqu)YVz-$T(T%#&cY@Xnla+Ou`_T;Yb6}vAfUe&Z;*l;TJTqTT zoQ+Uv#cZh{P-?~OMu%O8m<4F}Y`X=Y8DH?`aqK2Y$QvmNrLf}6I;3+!y(whR9K!x< z)pB&6vMZlKN?ITHMmOP`S!Sw1Q@?JX{C@aqZzvc38K#NC%Yt@O-q!4~w!UIL=(|_k z?HYD8kZui@bw@3vo;1$c&7{x3a+emZNe9>TF61c=CS`AY=^7#k3XOr-xbcvc6DImGJ7U$7&yx^9b8DR0_R@P zopF818e^mb2#f2OgHSP@VN%u_(Lv*vaV7Pms>U1ti#g=?VO6p6JtM3Tm=$@y^5Nn6 zjf}h5kP_w#tQ6NuHkS{H8Fls@NG{=8wh(@ zQ!V5t{B>KU&G~H1`<_UM@;*RhW<7%U#8J!kt(`ORO?n1<#b<_=+Y1q7M9-xR=P5c6 zZNmKz2}LeXj9FAKWW;{GoTK8I5+|J^Sg7G>BPHw$b3Fln@~2ZmlOzO&`eI>^+4-`+WvS$)z_^pB350B$38$`Hw?8srfsTe=wh#EXNO$z>-T2^t?vtvjYeW#ax&OG*cqq)<- zLNDlM@%!U>6taCO6H#(J<*V31d}!ZGyFoNHaDm1;;!g&s>>=nn089`*z5S?7L^MVj z3LzDZhl5TI7*5knm)eAFMhVq!UhAzSIHdDcCzL`dmucGRsD8oYZKLT!!qY`Gk4L}@ zH5?aQ^cyMnhQ~56Q<5vwS-#I?@h)a2(+(x!XLFrrH)sQco z?8cA1R%8;fi4x)*PKd+z*>p?e+yoZb5sHl%!Z&-VfhdR$S3Y+>Vb2%2xpE_%>032r zE>|HE_>+IKh>nW86M=I7{wgCT*@8d4P-(RYU&KpN0(cgolkg>g)m46^D^Cp~!CvHT z9k7)N)zR;AxCb$pKF%PxfVHF@0#YZ|l8!G2d5cYcC`~H-ugUj4zU)o}oOrCkt#1G= zG2YfxmK&)6E=vPY_0^Q7pn-8fd*^=+FaFNiO0khfBAPfVd6H&Y^kkt~r~<{KZi?zou;Hj~00i+)Gu=;%UJ`%gGRyu!yCq z?B^Xb3N#8|##_j#vBh|K`G2>&p<0B;qGA1Sel)#5BoCjZ+}8vz`T{6#IcW&hBz?Z- z=g4~cedRvpqc7ZI3k(G)?2R~)P@j_lHueOjkWj#m12D1{}tGiAY1ec@ZZwrs%zT+zx-9W5jfB*p6FrG%+PA+=#P88L|mw>vs1}Xq7KofXN zzUcx!p=)w!pDXyz#bq`gAnc9DRD_<{4&TYd!NW0MR6HEAgixh`(V(?tQC@1y#E372 zsgoRK(R1?DV%lY@_RdfxPo4C+F{V7-?vZi_*;u3-=VN(t{CZe&DlEi1_5cMWGvUTJ z0pM4hAi{T#f=3~p8+3xAl-ZvoQ*>^}1I{{!Y z@WJ4hj3`w~n(nR(l~7~NymeYt*%}YjA(9XKMmLk0{ZvuALPn~+K5guZVDu1zu$^ zSOI-^?-l#bWYq4YJAK7DlY)WbVN(kz!DZ@wKq48sEw-pv+=J7o%eK@%{8o*5ziK=| zm4r7wd+5ka+gK>wJMbEbtr41&&tkKX3E;PGDQ#4l8Ixp*?ZJ2_TQ;x5N2bU3iS3XG zqf^ZVHha^b48_@{I>Q2n(6^-ze2Fx9v-VivK4wRC?IG9-{kIY;Rhp*wYS9IG^}9}Y z;cN;EW{xq~H`LegAtTV$-CA}3zw*b&`FO5`Y7baQBwTxF2WKAO=^-@O4I0iomYR?j zWp(00CZ5-oxSo~J8%1sxAc{4sUeJSBb8ROYvl56|$_Hx$jP(h&(sZdITOS%RQ9fKP z@c0Vkyj(S+-|xK!k-&5;iprIbG50+(I&EFcW1$-jTu`A}Xm+;VT+lWl6xH+zHD5U} zY@KO7ZqG$b(S>;~0+Sl^L%M1Q(}^$>7nYSp|3NTK2qL~%t-`s51lUkgDK2mT2#ie= zAia1o7JH)FMD{}1b=y8&?};p>_(xJq{P4N1%HTt}xIc+N;^HV{F#uW-DnYqo{3daq z$EO2kwSlp6Ka18n3v}tH9Rjl9A#!-Kc&UF4K|N;q9-_nd!A44&@9JeM@R0S!>zJSl z2ql_gn5UUfeKJ)u zUDaB0#HHbsC}!;wIt4$p(=5bB*C7Yg1DTsfOqO16cmAe;pn*YQJ<{uOKD7vEya6qBNqH=z$^W3vEyU09oYku=G8XC z5K5eg=1qpxY9@ts?6IsjcywVtwt;~RL|Dg`>7hBbdFUpXtS{K3z~O3k0_)wySNp#W zU&2VG1+=^v%9{jIU@0KO<=IHZCdsfGu>^K86go(-PS{ploS8A{xh&s}Ss2qZS<*l< zEo^}&JRHjrik^HFlJ(3zynph)6;D?Fj_~;Qhnss}3uJYyt3}*zr7`hA8dKeRb^zsS-WSqW}pbuGsVMa1dN;t(|_ZXVi*QNEC7JNB19ky zLqiVGoz2*Pj>R}lAWPiY)(<%Qv6#P&kq^>>&!7{Nveo%??j;6v{GE12*TBEY1ReU_ zbb^6C@2VFPqNxM7SGn;dC7Ky1@dlZUUATS^Ue>cRHSW*d0i}qv@+R|lX!((g9I({j zcsVgQPQDDDzMh}$WjrOvAyY{b%ZeeUDbe4m;7dROBON(~ek3vSe}0N6yt#I4*G1vm zd}-d)*0FAO_1RU31blA4-%}RMt-C!zagVTFF~(nukuE43R?b5xeTFa2xqx*5oIKIu z0eE_!3ic)Xo&q=`%SuS8FhpO2^>?tasMY%rbX0dG*6;ia&IC_*NtK|r)Q{_@*H<^W z@mzps1fsSTzEFvnKpBPzyu{~lu;n58rHKJu(c-RAsO4T#9IQ-ic~Kj%%#@nW+q7{m zJ%!(|DBz>SZB|67{V7?fYENke5en*MJ*99%2`s2i|nV!Hez5hR_@00>5##d|^GAquQFigXtg0$1_pstN-n6oN0h` zAqJ+r!+*$V@9uxH*iBt%s*V&{yKP^;U7jf@(t0E5Qj&@;Du`m+Ae%xja)Z;By6>6j z9Z4qt@}rG*Jp9(09gc6-p-Y8xR><42rv$!Pk0}L~QMnWDR_ecRQlfu|$7}j{mj=53 zb3*>lY|3fmKd7%O+#mVN@xd5@#J!*WLd~qpyxl_9?982FD@JbY$JJ%mLeDgbKC-aD z!_u|-_zes4z$Fg42}IsmiUlt5$SEZ3p9QjPExD%*rvMi_JtvF0iBHQF2 z7nZWK0aNqPapn%J?L8f*s;Jct9$H~bP}**wN}MC%TY2@mjQWS*q77UIf?Nf2f^?ln z%OqAV6wdPs#7n>jpI6v-m5u$Z2}mU0-YAXBDAz%H(YUTG@u-YEeU%EHO(@&vp86us z|G+@MRS81qPasF4Y{9MQpU&fWEgg5In!%t3616E!jpNpp4yK?vBiV{FC3%+)1l+OQ zNPKt7DZAl^G<4W1>;M-P0ZacY)F?dSLe-kO!?fI_mEiwO(>=o5@x#0MQv1^QebCG=tXi_HALS%C96_%I+%Dvj zCHYDjt<4@$e3%pRD$uV_(=B6o`q;d0Vx_}w2iQPBAR-l1uqz&sdVr1~p>9V5&zk1lLTv%|0l-AT# zn0RDBEV(}lL5BP>h9{_CVu~k)I3!{ps5=g$s-Qrjy1L9JmZ@OOgwF zLK2!`Xs;(}QH-?+1%XH2k$fC5`kq%wa{3*mL<4xjbSe$ziEZ7uIl(=8t}-e|lU=!$ zNcRj|cd>4>uy1T;@S(@ElrT={Vx=bn73cJa11ZMH=OO0HOP2LOmVU!!9(qkiq)tRb zRV07jK{AhRc?3>l_$XT+2;8-5$mJ+K&a z565q2s-N|fKKouJca~#r~!lvQhE~gJCrWz%poM5+|I~ z-&pf5Ec|}4AM!MXa!M-`7XV}07(Gcm& zC?TsMI^k>0{A(Dy2b1x|?ovRA17dbS8gvEfuZ6(P<&Evnqw!$|bkyzDd*iE9zK(=K zAI)L)fqLI>eR_JOxw2_KXFXXOnWL0n9#0MUMm6<35tFA_`0<-REgN6Gn)5;9ZBeo$@a23;Iz<+{o2#9O^S&%g-gs zRwO>Y|CUsT&gis}f$EmcFt5;clcedK+6U3A?WUSFnYLA0AXhuNH>W6iP2J@*c8Bmb z(W?Zc{n0h3rzN6J)}P10{!GzSu~!)mmbiq`VA(nn@K8p_!=rkg_itCShF~jX5|)B zA!#pH5m%R?y40uqVQy1X!nCI}PvX(UmGA-v-V5AC!7aF_zSI!2KPdsCbB>A>;Hw)aF+n0dEdcRYC)_ zjtBTmR7-_>aeI3sJiQWntWiDu^&#OP;I#=N4Q!g>C^FHYLu`tFd3R3KY|E6Jejx#l zhFVSp@i={@IiO1hh%Gi3^E?(QzAg{!%@0ws?qVCp$pXz9ykZLni;?p-vxZaO<$5TG z;n5n2{ZTUtJbX#vM4UyiKsa1PrXBOonr{;x{y-idHd7k12OlN-GYHs2I$S3;=d==9 zr8I#eyr4XiEpEl$5s8>jMyp$wkp=vZL)Bn;!k{UO!W6SY-O!}awBF9QoyXIh$L)!_ z{ButymL;>brx>P!IbewBMgN0 zlm`<<2#x|Pg;-HkniAOSZJPP?D9_;WI%ssGK^a>N-?OZSirbjFJVxfG)6f&A#}RcV z-8|_e&GRSc1g#a~!AcFGwvBcN_;CkVFWAWH(m71|nkNisMzY$m;pCjFHREbRGn8AP zaT2lXlf0y$Py)IPFJybXO@2y0w(qBuc%L2cF@gPUq*5ApJU9W=3>nJDz8|3(uh3Mc zAFoPrZ}i|+Kz%Gt`CJ)L3^Xk-L%(eUERr8*Y&9_Agh@4tnxvAdzzHw+3Q~Zu5bg#B7Y0@lzXrp zrX(-P(ePze$J=j4G6>eG0{>mk@hYe-s3CpYQ}oO=imt+*ET$z>$IecWG%1!eZ43MG z82ZuiBxW4s6mzxlkdP%p!ATtQRMz_OaaF7CJdil2Fdw#T7b=Qob+O{*_Q2`UC*ELQ z{Z)xX^HyQh5`IgjS7^i#GTtKETRBj<@p_&GWy-SgceOntU;M}!UdGUq1}#?3>hcMk zAm_8LMcWDTPvD^W=LCqwJDDEr5%4O_w@=%J*`F(*Ao9r=kl@X>F*JKvVb783NPjFf zg*R0A#Q5a!tT#-t7!^11b+C-b^ER=ez*E>rht51CXC+qGjs(EK^x=BbMgucss~Q2_ zAr_!FU8tsF;w|4?Rgn0OIG=zj)+_h^KIxj%75>fY3d7a1LZh5Yo|R5xs+5JEI~~dM zm@~)KKnMybB2ATIQF47=k*-t#6izeCiefEiERiv|#%hbmrHnAECk`nNXCxdUoC594tx>sr9P#1H7vkJ>VfycK*}uQGLqZ%qbjL&uVtm= zgo+KyQ3&#kZl~#6t!7YVT{DJ@H+Yd_YJ|ELWnSRp{-p#yRncV{ z%pE*Y3Ce;bc*JBIlD6BD!(xch8UNv7UQ)+fe6BPPb)ItOMLBMlW?vPiWnZK#-34}`Tk>eOrx<&JY+MPK>OUVo4ZTkMpi?)h z0XpqeS<5`u8TIgdON$-0PHUbJ!1ajaA|3NF9$BdWN^V#Yk-w-*NZh-STN0^?jOMrp zQu@A}p7sXg%JZ+2+uH3!ioQ|3%r|d}2gDG`1uZxH#%b*XE@9mIZzO(+^rK~VxOp&L z_T~Bj>@}&DH#=3Hpd03%m(*&En`ACyyCC~BE9|iQZW^YK?`BA*!~^d27;^jiTO1)! zkRY3`eSt>$_&;Vkvc~6K7(Hh8gNJ%+k0vd~?BBvioA^tN(Hi9yB#&@3b>gn}VZiA*9F=+vBLYU_-Sx#KzF=Qk?vopaW4 zm(S1}&w4LD*8jQrtd>5q(>J%L==Y=j{&U~w{?n&#wlD7Eer$g4qlsBAh~vJh>bE|l z97OWd#oN#}#J7bF`t<)T`0eyU9o;2VaFF|zf~JN!0T0rDQ_!L)^f8C6_zCK_G~p|e zCDGca3^mx9@NvC#=T(4OU|t}L_j4!arEGL+kPz)EgBB1wnx^U@TM<4F*C$h+HB=2#NN~(zPp$>id;_dHI^- zy*H)TkBXJ!k6;h%`Yt7H_J8MZJASW`SVv6cVBgjM%00e*57#&CTwABUUDWZ_ku_Rx zKR&Lh>9@PnJn;SdQHJ3mr?2b3gZOrU{;8!sM_&y}?2L96!h^g4iAZ|Fy9T$US2v0L zGgPLxsqnqGc)X0}W;g4cVpez>bgOF#_qVcTuJAC`?zo%XFn73)gHE^nDSlsBtA&V1-zV`NzjCH(VFXL6+dO*#2IgQUn?aZkDJpUg~U0j)vKiTY`3M_uB?fXC1 z!kYfSYiE|Rx4NFccI;c=SzY+gx=EdL+8%j^U=y1PC&Bb`k!9lfo#ZoMlvSqOsJw=p zW5@us!JNZ6(9EJ-sB8Q*|6ZSmWotehKKvIXPuQWm3ploACPfS_LP=rAzIWNSrKvd5 zvb04%NnV78(VDfncDBVj>BI zL;)GbYkf+tGLpF5xT~mMsuHLRbX9jr^ZV;YDJ#+6wGxld*lf1H)e{{NMUlMf z;Z5cK@1^^{iPu;ME+jQY$c$(IT?_s)Qcm)@2o+nIk^YOxS<}Fb&IK=Jv(?NZv>q3W zdgMQn)MXwWDt=h&1b-hg_LXtwqzEk_!eNsMX{~R7TYL|HzKn$2Ms#=iGAASgjsUQ%A2VVbf^X47}VWBW!tkeqy20<{m zR3cLdh5BpL@+D)`Hz39bJ!+((U{OEi5t6Ige}P0s7qc=Oj)of>Ixr-9Lw^AKIc z9tf?9H2d%7f0MlX=R=fTQvDbs?EvbWIgu(GuBXK`v4*9_}8>e*d}mouD46$Ptt~3=V?AfU}TJ5+Vdh zK`?+`HuGF}?Te{WI(OFi+}C_ebL_qDf;_90b3PYwlY>luSZHZ{R(mtP-w(FWK>#!Q z@(&aAc`CQ4dwdF?&%S-Q>7Tt;?#`;`vxj}6eq?Kyg1V{4x`817Of# zEI1P#0|8*6NFsM>G3HfWO;$^pQa8bRRnjX$z4Pwzyy5R6e+}9)z2EfT&wIbSKdY(i z?&xA~U^jWc?CF2!FE4(Z{iveXOLR1_{kpF5XC0+poRVKnmbQ9VW$UL1)vKyY?mjEB zyzjia!w7eN95ffqSo&}Dv>vEQi@h8IeinOsTt+cPn3~%A*0}Suw4w3#Jc%dWh9EQ> zL5y@d*G|qQ*;su=IRyvKjCS55yy-e+n^U|Z=bDIGPn#5>RbyBu8PKt_9+|?OAlmiu z>Ikb027_UN&|pj$3kC$lfU%G)6d4Fi0d?VRbM4=nnVR1ci7%Z*xl&O9o%7-UewBz* zmciopyDe-Ruj~T97CaP2HOI`)!l;!mi0CultdV zsWZW#lF7MwCH?U9%z-Xb_apJ5%ez>BZ0$U;i1kb}0oRm0i_y=nkQ_cs`lt|glH_T3 z$cPj`F`(n>y+7?)uoblEQhkF9pqSyJ>Dz*%0Y4Hz>V;~{h2~O4TzB3MStepvk5!Y6 zB%v(YGG??*SBK>_78o)BAPC?904CBwn+7HSore_D`H+rl5E1R(xHnMmnjh1*wo4Zk zB;pmbdq@!PD(i_flVz*VyW%J~d1ix<<|Xk7cC9v`o$ zbhTgv$14q@V@XjuO!{jA`czoV>%(BbMD8^9!!*(TzJozGa}3+yu4lqR$B(1PnW*HN zm9kP*tx=IS(YGZ=#wcMkZ1!YSrki}i2MS^-F#A~H)kF?s_vNKo-CNb?R)tzAz8 zL+sdp%eoiN@ZXV>mzs9^)9pRE#38JHCt_e)??@d4urpMd@-+L4S#D>}gY;kv&t{2H z!rI=mdR1^;;oX{Uzc(lZbJdAm(G>04WG}E7$TQVnlrKmIv!PrN@zmA=_}Cqvs`t=@ z{|u!lKv>>>%T+(M`_z_r5&NtU)72t3VUy1qb%79aP62 z5Jt}m1eGEe0@G^#@!h5h4>J(1uU(-~<;%59nZtBD)EV5@J)koVIz&DI?k;YiiqCNq zV7jV2CQZqyog=SHXYzxAX~lxf0>qP-_imywQzIQ^b*V<_hG1C{{!+I2%SKWvrz;j1Dzril5Cjp0lYH= zGW_}gbH3~NNpxbMJ+A<`>r-W@%S60Y_Ovy8B^T6+S#93jE{^H&{8f^x-F(q&ufIS- z8OW0q$RkYOe`M@HcMS|Fry2LoZZvO~J#A}#8(zDlPm19HVF#A#WbGDn?iH}(8IXG7 zgOt;4a$&k3jVSQI!;q4vjMhpwNQ(GW`W4IRH&bZ;BJV@fwGlSxSpd&b@#G!~FL1kV zcnm&KzglHmb&r>yqu4NG{%vc#)l9Nk+C`Pu+sK_V@%Aq<;zsjm)Y1`TlWrn&(Tf9R zu^1J;)CSdN6ps`93thIcd@RWM7on?9(SlsZD_iPP#3|Jfk7ExiQ;j!B354~cG zf~Ur7Wc6ONR7MmG;4ncav?XX+N7;a_42g{hw`36ZtlNu7P2xWThe3S#omIozX?u3A z#|XD$yGLxZID*YxN zo2hpl#spNG@mVs?g&mFLUcHt_eav(Vc7(dnwqp&=!Ie(XYS|m@cTBs8<;`h19TW|J zNAr95hZ7qPt`U!-Kl3v)_q`Bq_HW|)h(Kz|Uu+1{Zvb4>8@bIN>c^VOKW<*5Z#`JI zeKNsZQQ=_UR0ZNk$Mj=0eYx!*VlUFyV7eu@9Fe1~S?5=DX{-kQijH1eQUCK16^-*Z z1FSEYV<|;irbM|p<(Je3R$uy?SV}I3Qyd0-Ek{)kk(D-~$4ty?R%VH)3U6Sovt* z+Mlupt02JHb9q~ILGEGBd1T8c4vqi(cGh6#^Z4z(#Z8Q{}!A64aMxSkmCE7_r_h@bZDBQmyrtpt*0#nKDbMW zb@l91fv&WS77L0%TXyXh@932x2bC+qw-WaQwb<(=sYa*x+`ud*Gd!d0dCQ;y!hMF!jzIyN z1F}k=-;)Uw*Vx{<1`TL8Rnl<2_w1Vpn)L=RA34l>>7jbn2YZGrddcx;mQ;KJ%M6NE zD_w#?q1jI4J7u<1nZ=_}KbRKvJMnseH;1#Sck?kjrTS6hxbjH3~~j+t1#;w2_o3>xeYqb z>ON41##?qnvg>(cDg0(!Exw&&?zyu1y-ezEQ*WOa+EX=Bw7VytdG;(_CcFat98(~& zP15>aY{HKt7FrAOJY2$ivWTSM0BXtHWKdhayIFddRKZ1=t8%Ngl(HJzc98$yn$Tb$ zyWe^rap6!XZKJya0-dDTJlC9>Cq|0f)EQ*!tJCJo-UB!~V&;M+xXlYi`=}KBfs!XzXG!FIGS_PuFec+#-$gvYz<$}A)FG)a9Xt9^1 z-UE}toQ}l~!FvD$X&|9Mp8KodgSV$w_HC3E#u<*p0QWE31_510y^2$QD&~;5tVK3k zD1(|-tRa>XPZ-mDL@X=S$z4Q0uCZ57`Sks7@=+1p>nE;1SasG4P)S#*2 zL0J@1$R)^T)9iA&5-y7A#i&h8wC|}e)BovOnYc*sR5mWp026_8bLx5LbelPvqaAgY zfyl;x;O8mEnP)L^m_he))*vN4`DerlCvryzhRXqG0V|x9-Ke*QMwnKig5AlAqtgdp zc^MGv9j4lmY#NGg&xErQLuQRE(s^qwRTyyWv+`cV))0+qH-#3M*VHm|LA84X-iTzH zQ7hig&-`MJM2o=>BOEf%pAWn!Eu&0AW57?ec_CObyP8IRs2D}EJ=TW3KS)!q`RAai z+lyIw)p1My)!@`9EDH`_pQq}mD|HVVY{8V4N$)RPhU-usS^>73l1hcklU}9+FvzLz zkpv-C?`?!}F#2?*$8A;daB27}MVJ}d3#i-UnS3(B2OzB&XL_RdJwN~fQO^KTbUnqK zIIIZgJh(uuC@p{3sQ!=k@G{57$?m9w;8nH#-2VDHwNJb_aWC+E2uEM@sLGM6i~!KM z;cz3;)bBp<a`_YuAF;P<5WfxS~SKEd)JNicn{~6ogBcc4N3u{brSD#%*1R8)@4n!vhvl!7-uRnw}>|= zP)zI$;r1*36L(4BxQR&q>4W&arLN}dWC!7z%}&ij2rldM;wPO4d+5?iSq*?S{wW3) zm4}9qVGvm!08L}7V|UtCXpPV^vvebYSelb=u$K^gph&$fP;F7~vU}R4-%jC59_-vF zTqAt#QTPWhzWPAAu$&Um!Yz}Xr{m8|WcJeZ7REE^a zb>tZ4cZs_94_l6-eGLlQow0=5*2w2fPv1`t|MG4ER|LjY_E<>xMZMl7L4WKcY z2l%>{o^reV@YS|^1+FHpm$~(`;EQj)=0cqvOlAelEUt1RA7Ft4ByD#C5JxAQ{YUL~ zqy=8<9QN_s_QH!y4wxgODNj(0j<9=~jGCvBA5vE#;5Nb^2)2#}z$q<6YH%s557o`O z?#_$q@otK0K30$3P^HSc?KDEeZ_!-J(Oi!yln6EAXtc^Vi-Grty1|*@lw_v-nvDzK z0+Cqo3wVGY%HKu^2Y}-=4XmyRXI!KlAXcUA>J#GB&uX3zMsCyzct*zOjU#Fa;VOVo zWP|j_6~r)ecQ)25d7#zB`GW%N>LOBjX#p(2m(OK#MyGBJzpujumO0{H9>dV1IZtN> zKqni7My%-C92H73-J}fXPXjS`jZMS2-<31@)_jvy^RSgw%@k`}7S-W7=^bQM)Rve} z?EbxusWXfFXA?pUPVRw{bM)_v*G!ymVY{&>)~FYwpo?yt6T|qU`-{^1_|bJM%a#v5 zl>7TYutq(zV7oPca86NRm?vC}kotHcrX-f7#`2nebwlY>p7BHAzk`l!6s7_cqUpD6+|c znst=^1DpL%?d%8k>DSxRgJuI;Rfk5ZLKJ}&PT<&sWJoj+A{cUIcdlgu(br_L7t`Vs zEwe=%4+h}r_2glBulk-uu+`8N7(YTppYpCW|KNp(kdI3sL^0c7hpor+X*Ke0V(0=8 z%DOOBU^5JgO^)wFKe3IYceM20UZ zONJ6P$g)P&2}PFlMa3tSplpgmAANZ@+Ec85x6YhDpvvq&{o!CxwXP2bQPp+#I0Z=6wB*q;ih)XD_nFg6a%AqYykFr#$;ld`C9D2VeR)zBdPE#C^I+z?e*J758ko$Ab(WC6x zUzom+mx6^ute5D|A{OIUXjug$TYD3a3&PQ1i!_TYdst0}LGE$Jv&xTL5M@hAUYI4X zzM`Mh?bw#g||`>El&u zSx69XpHd?8HLs8~oaUYxf&nPbzIgoXQ{5$gC(0el?NW;*1gcF0+D{M7++_?^-DOZa zsy!PCs78`CKm_|sPhWG5d22x1#^q1qvy3&3^Xvi0R$BRQ!*pNp3&>R-v;fCw&U!%o ziCvQdZim4YS_3nOuCd8EGTP^NU+h<>Q)g41D&Tvm$b%H7tvrYdj57GAE}m`3mM(yi z(ZD0qHC(P+J!$k2d34}O;Gz_1Z}B9?mz_7*mK_)RS}BBDYZ(i{oJUdZzbL@1LUEDL zwZ+i+OFKXb1McjLin<8o+y|1r}Qa zr&K~&^p=IgwUI(jeuTFsCB*GOx+WK3MYSt&sX9oRU$!UVl%G3znmmN)BnfQ+ z-rNc$F}r6>4+RbypXLle&OyV>k7Gl}HPMKLXn3?$avPLq)&g6>h^FN!#2Zz(J;B5~ zbkX5J0CeZOzCU->dA*Sn(Y8+2>CjXn`7BD(^9&HjMCu*f9y&#MArmf*JV1#hY5{qA zoCOQ&w7e&SiZCv-EnXUYueF0(_m{U7tUZ(V9IBxJ1 z;tN%=(Iu_^+PaPSZPW6&prQ09u2m`J?CaKce;Z80CltDas{>_~oXP~1-V zk|E0%ZsMX*k9SXx(44Y0DG#Shz;5Uvsz&Q*fOgG&M-Ezs)Ob^uph5LICA4IgiXn@(rt6Or?)|Yv z5oE{=KHTt_rNji+ji5G-Bx3l5h4hYvXoM$I#FQD|cvQo05l~{w(5YLvlm1(KfxwQB zRERB|sLnB0gIz+@7thOg;+UrHu~hNj|v z+P&4G;_PkOg@Mg!e{qT^84u2o2+g>Nf4QIBg0%*;F9oFdiI$nlvHeGY&6x3?fo~=& zC*?}-mYArKx0_A@KoxTs|60STCw!cwdptI*lEceC-Zg?9{)<)W0an4vb?;HHsB!>R9$5k>q&&3J#K(ShtdOJW`y=(lDkb= z4c1-i9{mGKv)lFel+SU|+5)2AbX-))z_)SE*c))HpXkGSu2-n|7AFS!o>a?`ot2#y zvn{&C^TrnWCAZ7r=V|xN!TH5G084smo4a0+wjPl}hvH0`Knx)aGz$Qes=+d7Ap9BC zNX0H-nVswO{;CyOb9vg>166284z-{#xvw;{Zo^-L@kNu5o_+VQ)|M~@ZE%Lj7x$EG z$O+vUPAw`nVIstSHhxQE0x*LmemB{1$$*vmwT`I7UQvNz*Be#zqh;;#pcg%Syobg5 zH}HB==&GWD1Mjac)zS=hZ~R9EeM-FFd{ouoXL0wMi`Gh`2Jy0}8e+?bj}jNO zxO!k0|IL%vKhAc@6d|Mr3Q0vF>7ae^b)^CZrWe7Cfw zlxKk|iuGr`V1Nsf(*UmNU}FBz+(X9>N<`|>4&%Z~?PprO0xu5AAP^-BM24QxcqK~{ z_@y`0Kdy@Yxe!~gE4c;+_6PjLRR=zCQ4x3|=HO(~HBd9Eza$pbIB75hwMrcVRC|tM zIiWlR;hIcRstWC|yD96)vQS#0ynm`6K^J`cq)?db0fnNhge?&KaljsdOOl+(mFG{j#*wyx!r0br+XG@Z7e{hctOb>Vq3+Qs}oe+8=d=q5!P%|7k> zQ(#u~0XhTyl6%9gocH zh};5+=C~{uo>{TOmPhjRKvgznN2Wu7Q>ZedVw$QcaP5k71$(qAq!`lDUm100Z-On{ zwmB|AoXQ^)Q`-;UPC-7eOju_8G>Si3d5z-PUOdo0K7UT%wwZ+;S5J+i>d{x&WxF#y z+aZ%~R?dGy!X7wF?AhrK0Pl<`tn@Pz793Owz!j6aL)a^8C!Ps?vI%0wLG2v6us9r8 zwZ*wYM4*Zu(k65HpPEH(`|xrY>?-H)q%d&WS^`h8gCmNCktMZEC1~=gJ}GGsw)wF^ z{0fs+927_!GP(MSG2(($h>gDSC6V+Ec2&%Dg?t|Ux}sg!#O=!%iIIy{dvZIJayZpb zH3k*jvcIs=rql$FJCpJWuU^YRDGgaiYfQmLGJKtxwDG}E6UhSdS(xyOF1ASMr$+P3A?2QOtV=To}SW9IsBcA zOPi&_tT{+^iC1}ok}mU#XswLyJ$_z5#7cEB9yTatmqd-MK(I#+3N@Z2*)bMClfqt` zMUvve)Pf{$s&5R_;85UBwh|)Vap7lV++uuCW9l2@V`#?LQhc!3zlL+?WgcYk zt|s^-+&JjAO}0%p+~LXyQHy-O|1`eorvl4V?c34pQQv!dUbF0U#N$KTq5be08+BG* z>>p_VkjR$quq3#V7A9kAv}10J42Q)ReI50^!S$#SM`juA5@`f%Z99#=LRY=8wD+6j zK;+J&4w?t=@FeN1@lWA^nSN#8g4~d+2dT5F;TmJj)({@6$+F?x+9wLx|A%wNH``t1 zOr*SWe0Yx}U}bz55tygvE-s6TT+_=R(TKCY>e36j(73C#K{`1xOCuO~cT1o(-TKUc zUqCUGL=(!mUFTxua-S?)Yp$-(Qi3(|Cv*l@FVdY0(0ga>w`JP4!zJO?6}?ldCf@g* z*LuDPy3&bs&yy(Sgy0gxR+0>ua{V5%5{1%YeWtVM4ku!e%}*qHJ7YNmF4Dw92oKux zj?ujufaA^Z5mQhI!qGxMtQ#g0ECw{2j<6Sr;iY)N?sN6SxYRt)I7QoJaSS-v_i>RK zGxvaw^PNgrF?0*aS;die?_6ENRFv@uE^9gr5`4fPT=)g+(j*|XX#(CwfxrqdOfI{| zF5dcs>s>K84UpUnHvP8805rf zbMU0%7py2bT+)CSZy17asmPmmd=swzmC_~Ch0)UskvMiXXP!k*qt?h`fkPL&J?{Ba zSgdmTE~u9_Qtnferx@>Zw{df_kzd~~0UQN&b=}l$n4`x{t)1?Y&=L-@BMng7fxC+# z6v^!kQ@E*KXmd6&W!}!FRuCol%BkcaqG#uW@*Jgz-z3>LUOxMJEac^$;R`dcX+M)X z80RxzY%42@ITRW~uy90-=^5Cp-GlW2>y64~@P6^R(ypoY2Xg_OrdC?CFf_Go_h#Qc z*UyOZv2XcH7~uiLxb={w)lh>f>x}lKBv3yI4Qx1JH_(0rrTV}Fdw8t;8XGu1Fly>C zt+G<(d&^a3=Z^AYfFvZw7O4e&@O3-z0C33#l-J^!-Y6ZrRM&6Cc&H{&je?jpzz}%y zD1ndU6+N0)6AdVtjx@2&<5Ns&PL#3Xwa8JgUf1Q@iyYOSds4i$4Uk}3f)r!+0x$cB z=PI7)@5rH>Y1Uuxn3#6|qgYz7zLb;Zxg4PL-1e(4P1uheoginf!n-=A6u0CxnmumS z1i8%NsDUo~jS$MEF69xf8JLJI#Rdj>swUaHhPq9~n9iA!-A%JtG(pf{+8eU@@my0V zVvvN)3cah4x8s^b6Y>$*N$LyP0N{#Fj(vv@{TV|qeMp;7n=Px7mcB;ptyOs}hjt!h zT7DTl)58bHk+L*tt8ZYWR{Xjh8i_ias#O{`THoYc5>H`o!CSxozR6cLN%Yg|(x*S? zp{CatR(=#5*<4Vtb{7~1f(}^H_}Ck~j9UKVhj?2qa94Z$U@+k_nF1eS_BLZ|6hh4y zFNwHkZb@R?VxFBw`$)eOz_e$w;iaJS>GR5V-5*7C{Y5DD#$WUU__&Jwv8iB&?<4KU zk7o!@>{WHr9~63hZNX^a{5tun?QsFMf%}RfF7KTd+F9@P{GnT9oR0H)c$h2WjSrk4 zlZ&IWgIfnbM(c+t0%Qr9Al6qn@w*M;U&G)J77MkOMj01&$=;#+5>5>-A4`QpJvMkj zhTKCg(K3C%K0@cr0C2HK9tAznHgUB-?9u~ri^*%TuxlzN#EP2b=t@bKEl7K@Sw~$Z zA$|&FS#}dW3vNnI0UIosu|9v^)Z-{PKx+c3kQiJ;H1(yXd&x6zk5q);n(`xA48Hx6 z00<9%OUPu(5V7;9!{LX(l3yiSb1B-idbWybe;4W<%pw8vPVx$vTl9eKUJbsP0RLNfsV6zwXrw_BKE_Lax#1xtP%|?%Ma0#1l!-ia$|o zHRb=wG>Vr!4rgC~wNMfD&5P9?s`q#TP-vv`J<*fzx@uI~h5yxQ!0KEkeNX#H=ED}? zsoUF1(O9sbh%m!{(BM!RVh;0W9xzIY*Lzj=~X0i^grsQzYx8F9HKd#%V?D1;P8$ujirl_`?N3Qi8D0Hof`@GGPCGTlH}O{HHMsM} z=aJ=Ro(AAmvmSf3*cyab{q(WawwrNkiod$8g*zR4O*Mw%w5b}OwjPNl zFd$-i$)m^6#fPE`YcDFQ7kS}0Z?o)eA?Ek;Dg6vAug1Ci@uHzOBD;^#e9`CPQ3mhP zc=WS_khcOCbtP&|0f&)dmi_j~t;z0t@h?UEUE84fVTh7=TxBF{bHk3LH&RQuhK+x^z+4Eddl1D6mEh35MZdpje0&5($EWF^S)l z)UQ3`<>T)|8EP~{-mvh{qF8p2mU?x>$fK`XBK4dtnzXn zzh`HK$@%qZ>F{i?Km7~-f=*roFv=8rE~UzjTeVp&kd|BcuO#0^AgE^6G$W7{P)By$ zfCBkvLGy6T3z%4Aau_ie4r326xGjI|Qq1l?OW{`Z6ej2M{IxL`drhUbC$jt>D{uT# zgKQhPT}oMea7%29Fbi3G?hYS>zb{tq!bs(q2ttFVAMSX&D6bO|HWa7pjdb)aJZHDQTI`O(sJvsp&f9I z@NL6BCv;N0p-fT?g7IEnWZtil3FV)&;~CtQFQa{oJ{8@vi~G}+z_w_w?;sOh+s6Bt z4U1{&EN%R7FtRHv#nZhj3*@ka-O6fNVeb(f zaG*#i6AFY#Vi26yO>b1aWwL5+MR8l}HJtTVRiDTkgy^1i?0i@F{NHcE`AU)HeOy`A zo2RoWb70}O_Pi2yV!L#Cy%*!JsW)@Z?D_Ji&9*p;Z`Zm_vdWqfH`DJtt>BYoL|EkX z_I@G+wHgh8ACS3Gq@6{(3(oTUyBp!TC#m+%vaWM_SJRf~!_bXPY&?zE&yq^ZD(-V{ ztU60O?%-LH<>@_H!_}*+bzXSG)kq!+-SWtfNWIKin>bCE>se@3jN-r z&OL9^wx7eKIDYr~znh1j_Vn!AMmK9w?O)oT=&<9*$LW^4?D5r~S9hlG9#oD$J>F&R zkiW?^RjZLP@x{CPx3#ikxSsBOZ!X-7yaq+Wn5TU4shK4#zF!&IzpZkaKQCbbyV2Ak zC7lBa3i3a)Z=5G)nJPHG(=Sf-eh70U-r)~TBamg*=v3f^($#(-$$FR)gl82RHJ9mf zaK_`!L~%uY3e!V9CmRMG&&6qd@8CfZVWGh2Fd7UAg8^kASSS_>2!- zpL?zodW!SRrPRDyT$Psq-c!{RK6mp~TsHQ&dfTWk^cUfX(c*l(e2!-8I_pw6&UEDz-3W06-DI0UQ({G#eBV zjR9gHSZEdsg$Q9Fs6?s}3)O11oo25!c_U8!nY}XQYsXcrspJR$vtP5e>L5?SN&C^g z(}%)Gz4!F@?e$;p@ULf@d$-q-(I4Y5A64;6bIXEV-IgwO-(+!_zhaO2O<^pYv~ZF0 zd8?i-<~6~$P677tFFh2Ign4ze?PX5B-u-+hnUt2kHT8*McRWQ zAF=**rjH3=;L>R*M6(l}8RBJEc#%Xlsl(=D!wu79=i8 z2FhN7CI~O|S|ybTi+Tp5w4yCeH@U7MNF*aji{BLM z;WFSA!%#`sXmBPh1(Jbapjap+3Iv2

    BpG5eu8ou62&8^;K6~Uu{)tZ>_J#wraV5 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≺Z%UB%~c3v!?WNSd=V~f+J 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%0AFT^8L!eUy3U~9wCzol)TeSkyq;3n?H7gz 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%0D} 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�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 aqC1mbWg8X7}4&L3aS2?=Ch^ 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â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 literal 0 HcmV?d00001 diff --git a/test_scripts/MobileProjection/Phase1/001_Start_video_audio_service.lua b/test_scripts/MobileProjection/Phase1/001_Start_video_audio_service.lua new file mode 100644 index 0000000000..0f4971af2c --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/001_Start_video_audio_service.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with PROJECTION appHMIType +-- 2) and starts video and audio services +-- SDL must: +-- 1) Start services successful +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase1/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = "PROJECTION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Start video service", common.startService, { 11 }) +runner.Step("Start audio service", common.startService, { 10 }) + +runner.Title("Postconditions") +runner.Step("Stop service", common.StopService, { 10 }) +runner.Step("Stop service", common.StopService, { 11 }) +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/MobileProjection/Phase1/002_Start_video_streaming.lua b/test_scripts/MobileProjection/Phase1/002_Start_video_streaming.lua new file mode 100644 index 0000000000..70415d5db2 --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/002_Start_video_streaming.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with PROJECTION appHMIType +-- 2) and starts video streaming +-- SDL must: +-- 1) Start service successful +-- 2) Process streaming from mobile +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase1/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = "PROJECTION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) +runner.Step("Start video service", common.startService, { 11 }) + +runner.Title("Test") +runner.Step("Start video streaming", common.StartStreaming, { 11, "files/SampleVideo_5mb.mp4" }) + +runner.Title("Postconditions") +runner.Step("Stop video streaming", common.StopStreaming, { 11, "files/SampleVideo_5mb.mp4" }) +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/MobileProjection/Phase1/003_Start_audio_streaming.lua b/test_scripts/MobileProjection/Phase1/003_Start_audio_streaming.lua new file mode 100644 index 0000000000..4bb9302703 --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/003_Start_audio_streaming.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with PROJECTION appHMIType +-- 2) and starts audio streaming +-- SDL must: +-- 1) Start service successful +-- 2) Process streaming from mobile +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase1/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = "PROJECTION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) +runner.Step("Start audio service", common.startService, { 10 }) + +runner.Title("Test") +runner.Step("Start audio streaming", common.StartStreaming, { 10, "files/MP3_4555kb.mp3" }) + +runner.Title("Postconditions") +runner.Step("Stop audio streaming", common.StopStreaming, { 10, "files/MP3_4555kb.mp3" }) +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/MobileProjection/Phase1/004_OnTouchEvent_while_streamings.lua b/test_scripts/MobileProjection/Phase1/004_OnTouchEvent_while_streamings.lua new file mode 100644 index 0000000000..9ecee2ccd3 --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/004_OnTouchEvent_while_streamings.lua @@ -0,0 +1,75 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with PROJECTION appHMIType +-- 2) and starts video and audio streaming +-- 3) HMI sends OnTouchEvent +-- SDL must: +-- 1) successful transfer notifications to mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase1/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = "PROJECTION" +local OnTouchEventType = { + "BEGIN", + "MOVE", + "END", + "CANCEL", +} +local NotifParams = { + type = "BEGIN", + event = { {c = {{x = 1, y = 1}}, id = 1, ts = {1} } } +} + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].groups = { "Base-4", "OnTouchEventOnlyGroup" } +end + +local function OnTouchEvent(parameters) + common.getHMIConnection():SendNotification("UI.OnTouchEvent", parameters) + common.getMobileSession():ExpectNotification("OnTouchEvent", parameters) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) +runner.Step("Start video service", common.startService, { 11 }) +runner.Step("Start audio service", common.startService, { 10 }) +runner.Step("Start video streaming", common.StartStreaming, { 11, "files/SampleVideo_5mb.mp4" }) +runner.Step("Start audio streaming", common.StartStreaming, { 10, "files/MP3_4555kb.mp3" }) + +runner.Title("Test") +for key, value in pairs(OnTouchEventType) do + local parameters = common.cloneTable(NotifParams) + parameters.type = value + parameters.event[1].c[1].x = parameters.event[1].c[1].x + key + parameters.event[1].c[1].y = parameters.event[1].c[1].y + key + parameters.event[1].ts[1] = parameters.event[1].ts[1] + key + runner.Step("OnTouchEvent with type " .. value, OnTouchEvent, { parameters }) +end + +runner.Title("Postconditions") +runner.Step("Stop video streaming", common.StopStreaming, { 11, "files/SampleVideo_5mb.mp4" }) +runner.Step("Stop audio streaming", common.StopStreaming, { 10, "files/MP3_4555kb.mp3" }) +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/MobileProjection/Phase1/005_Start_video_service_streaming_in_LIMITED.lua b/test_scripts/MobileProjection/Phase1/005_Start_video_service_streaming_in_LIMITED.lua new file mode 100644 index 0000000000..fcececa077 --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/005_Start_video_service_streaming_in_LIMITED.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with PROJECTION appHMIType +-- 2) app is deactivated to limited HMI level +-- 3) and starts video streaming +-- SDL must: +-- 1) Start service successful +-- 2) Process streaming from mobile +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase1/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = "PROJECTION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } +end + +local function bringAppToLimited() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { appID = common.getHMIAppId() }) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) +runner.Step("Bring app to limited HMI level", bringAppToLimited) + +runner.Title("Test") +runner.Step("Start video service", common.startService, { 11 }) +runner.Step("Start video streaming", common.StartStreaming, { 11, "files/SampleVideo_5mb.mp4" }) + +runner.Title("Postconditions") +runner.Step("Stop video streaming", common.StopStreaming, { 11, "files/SampleVideo_5mb.mp4" }) +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/MobileProjection/Phase1/006_Start_audio_service_streaming_in_LIMITED.lua b/test_scripts/MobileProjection/Phase1/006_Start_audio_service_streaming_in_LIMITED.lua new file mode 100644 index 0000000000..17d6f5184a --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/006_Start_audio_service_streaming_in_LIMITED.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with PROJECTION appHMIType +-- 2) app is deactivated to limited HMI level +-- 3) and starts audio streaming +-- SDL must: +-- 1) Start service successful +-- 2) Process streaming from mobile +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase1/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = "PROJECTION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } +end + +local function bringAppToLimited() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { appID = common.getHMIAppId() }) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) +runner.Step("Bring app to limited HMI level", bringAppToLimited) + +runner.Title("Test") +runner.Step("Start audio service", common.startService, { 10 }) +runner.Step("Start audio streaming", common.StartStreaming, { 10, "files/MP3_4555kb.mp3" }) + +runner.Title("Postconditions") +runner.Step("Stop audio streaming", common.StopStreaming, { 10, "files/MP3_4555kb.mp3" }) +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/MobileProjection/Phase1/007_Rejecting_audio_video_service_in_NONE.lua b/test_scripts/MobileProjection/Phase1/007_Rejecting_audio_video_service_in_NONE.lua new file mode 100644 index 0000000000..9ed3605a67 --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/007_Rejecting_audio_video_service_in_NONE.lua @@ -0,0 +1,47 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with PROJECTION appHMIType +-- 2) set in NONE HMI level +-- 3) and starts audio/video service +-- SDL must: +-- 1) reject audio/video service in NONE HMI level +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase1/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = "PROJECTION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) + +runner.Title("Test") +runner.Step("Reject video service in NONE", common.RejectingServiceStart, { 11 }) +runner.Step("Reject audio service in NONE", common.RejectingServiceStart, { 10 }) + + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/MobileProjection/Phase1/008_Rejecting_audio_video_service_in_BACKGROUND.lua b/test_scripts/MobileProjection/Phase1/008_Rejecting_audio_video_service_in_BACKGROUND.lua new file mode 100644 index 0000000000..b302af208e --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/008_Rejecting_audio_video_service_in_BACKGROUND.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with PROJECTION appHMIType +-- 2) set in BACKGROUND HMI level +-- 3) and starts audio/video service +-- SDL must: +-- 1) reject audio/video service in BACKGROUND HMI level +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase1/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = "PROJECTION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } +config.application2.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } +end + +local function BringAppToBackground() + common.activateApp(2) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) +runner.Step("Register second projection application", common.registerApp, { 2 }) +runner.Step("Bring first app to BACKGROUND", BringAppToBackground) + +runner.Title("Test") +runner.Step("Reject video service in BACKGROUND", common.RejectingServiceStart, { 11 }) +runner.Step("Reject audio service in BACKGROUND", common.RejectingServiceStart, { 10 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/MobileProjection/Phase1/009_Rejecting_audio_video_service_in_FULL_2_protocol.lua b/test_scripts/MobileProjection/Phase1/009_Rejecting_audio_video_service_in_FULL_2_protocol.lua new file mode 100644 index 0000000000..cf57d8ce32 --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/009_Rejecting_audio_video_service_in_FULL_2_protocol.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with PROJECTION appHMIType via 2 protocol +-- 2) set in FULL HMI level +-- 3) and starts audio/video service +-- SDL must: +-- 1) reject video audio/video service via 2 protocol in FULL HMI level +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase1/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = "PROJECTION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } +config.defaultProtocolVersion = 2 + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Reject video service in FULL via 2 protocol", common.RejectingServiceStart, { 11 }) +runner.Step("Reject audio service in FULL via 2 protocol", common.RejectingServiceStart, { 10 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/MobileProjection/Phase1/010_Rejecting_audio_video_service_in_LIMITED_2_protocol.lua b/test_scripts/MobileProjection/Phase1/010_Rejecting_audio_video_service_in_LIMITED_2_protocol.lua new file mode 100644 index 0000000000..3296e8f104 --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/010_Rejecting_audio_video_service_in_LIMITED_2_protocol.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with PROJECTION appHMIType via 2 protocol +-- 4) set in LIMITED HMI level +-- 5) and starts audio/video service +-- SDL must: +-- 1) reject audio/video service via 2 protocol in LIMITED HMI level +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase1/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = "PROJECTION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } +config.defaultProtocolVersion = 2 + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } +end + +local function bringAppToLimited() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { appID = common.getHMIAppId() }) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) +runner.Step("Bring app to LIMITED", bringAppToLimited) + +runner.Title("Test") +runner.Step("Reject video service in LIMITED via 2 protocol", common.RejectingServiceStart, { 11 }) +runner.Step("Reject audio service in LIMITED via 2 protocol", common.RejectingServiceStart, { 10 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/MobileProjection/Phase1/011_Retry_sequence_of_StartAudioStream_during_audio_service_start.lua b/test_scripts/MobileProjection/Phase1/011_Retry_sequence_of_StartAudioStream_during_audio_service_start.lua new file mode 100644 index 0000000000..1f2940d2d2 --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/011_Retry_sequence_of_StartAudioStream_during_audio_service_start.lua @@ -0,0 +1,59 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with PROJECTION appHMIType +-- 2) and starts audio services +-- 3) HMI does not respond on first StartAudioStream +-- SDL must: +-- 1) start retry sequence for StartAudioStream +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase1/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = "PROJECTION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } +end + +local function startService() + common.getMobileSession():StartService(10) + common.getHMIConnection():ExpectRequest("Navigation.StartAudioStream") + :Do(function(exp,data) + if 4 == exp.occurences then + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { }) + end + end) + :Times(4) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set StartStreamRetry value to 5,50", common.setSDLIniParameter, { "StartStreamRetry", "5,50" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Start audio service with retry sequence for StartAudioStream", startService) + +runner.Title("Postconditions") +runner.Step("Stop service", common.StopService, { 10 }) +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/MobileProjection/Phase1/012_Retry_sequence_of_StartStream_during_video_service_start.lua b/test_scripts/MobileProjection/Phase1/012_Retry_sequence_of_StartStream_during_video_service_start.lua new file mode 100644 index 0000000000..4e8a4bb04a --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/012_Retry_sequence_of_StartStream_during_video_service_start.lua @@ -0,0 +1,59 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with PROJECTION appHMIType +-- 2) and starts video services +-- 3) HMI does not respond on first StartStream +-- SDL must: +-- 1) start retry sequence for StartStream +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase1/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = "PROJECTION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } +end + +local function startService() + common.getMobileSession():StartService(11) + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(exp,data) + if 4 == exp.occurences then + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { }) + end + end) + :Times(4) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set StartStreamRetry value to 5,50", common.setSDLIniParameter, { "StartStreamRetry", "5,50" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Start video service with retry sequence for StartStream", startService) + +runner.Title("Postconditions") +runner.Step("Stop service", common.StopService, { 11 }) +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/MobileProjection/Phase1/013_Rejecting_StartAudioStream_during_audio_service_start.lua b/test_scripts/MobileProjection/Phase1/013_Rejecting_StartAudioStream_during_audio_service_start.lua new file mode 100644 index 0000000000..c414cd1b3f --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/013_Rejecting_StartAudioStream_during_audio_service_start.lua @@ -0,0 +1,80 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with PROJECTION appHMIType +-- 2) and starts audio services +-- 3) HMI rejects StartAudioStream +-- SDL must: +-- 1) end service +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase1/common') +local runner = require('user_modules/script_runner') +local events = require('events') +local constants = require('protocol_handler/ford_protocol_constants') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = "PROJECTION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } +end + +local function startService() + common.getMobileSession():StartService(10) + local EndServiceEvent = events.Event() + EndServiceEvent.matches = + function(_, data) + return data.frameType == constants.FRAME_TYPE.CONTROL_FRAME and + data.serviceType == constants.SERVICE_TYPE.PCM and + data.sessionId == common.getMobileSession().sessionId and + data.frameInfo == constants.FRAME_INFO.END_SERVICE + end + common.getMobileSession():ExpectEvent(EndServiceEvent, "Expect EndServiceEvent") + :Do(function() + common.getMobileSession():Send({ + frameType = constants.FRAME_TYPE.CONTROL_FRAME, + serviceType = constants.SERVICE_TYPE.PCM, + frameInfo = constants.FRAME_INFO.END_SERVICE_ACK + }) + end) + common.getHMIConnection():ExpectRequest("Navigation.StartAudioStream") + :Do(function(_, data) + local function response() + common.getHMIConnection():SendError(data.id, data.method, "REJECTED", "Request is rejected") + end + RUN_AFTER(response, 100) + end) + :Times(4) + common.getHMIConnection():ExpectRequest("Navigation.StopAudioStream") + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { }) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Stop audio service by rejecting StartAudioStream", startService) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/MobileProjection/Phase1/014_Rejecting_StartStream_during_video_service_start.lua b/test_scripts/MobileProjection/Phase1/014_Rejecting_StartStream_during_video_service_start.lua new file mode 100644 index 0000000000..a5e0093648 --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/014_Rejecting_StartStream_during_video_service_start.lua @@ -0,0 +1,80 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with PROJECTION appHMIType +-- 2) and starts audio services +-- 3) HMI rejects StartStream +-- SDL must: +-- 1) end service +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase1/common') +local runner = require('user_modules/script_runner') +local events = require('events') +local constants = require('protocol_handler/ford_protocol_constants') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = "PROJECTION" + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } +end + +local function startService() + common.getMobileSession():StartService(11) + local EndServiceEvent = events.Event() + EndServiceEvent.matches = + function(_, data) + return data.frameType == constants.FRAME_TYPE.CONTROL_FRAME and + data.serviceType == constants.SERVICE_TYPE.VIDEO and + data.sessionId == common.getMobileSession().sessionId and + data.frameInfo == constants.FRAME_INFO.END_SERVICE + end + common.getMobileSession():ExpectEvent(EndServiceEvent, "Expect EndServiceEvent") + :Do(function() + common.getMobileSession():Send({ + frameType = constants.FRAME_TYPE.CONTROL_FRAME, + serviceType = constants.SERVICE_TYPE.VIDEO, + frameInfo = constants.FRAME_INFO.END_SERVICE_ACK + }) + end) + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_, data) + local function response() + common.getHMIConnection():SendError(data.id, data.method, "REJECTED", "Request is rejected") + end + RUN_AFTER(response, 100) + end) + :Times(4) + common.getHMIConnection():ExpectRequest("Navigation.StopStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Stop video service by rejecting StartStream", startService) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/MobileProjection/Phase1/015_Restore_video_streaming_from_NONE.lua b/test_scripts/MobileProjection/Phase1/015_Restore_video_streaming_from_NONE.lua new file mode 100644 index 0000000000..bd36dc023a --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/015_Restore_video_streaming_from_NONE.lua @@ -0,0 +1,94 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with PROJECTION appHMIType +-- 2) and starts video streaming +-- 3)user performs 'user exit' +-- SDL must: +-- 1) stop service +-- 2) after activation start service successfully +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase1/common') +local runner = require('user_modules/script_runner') +local events = require('events') +local constants = require('protocol_handler/ford_protocol_constants') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = "NAVIGATION" +local FileForStreaming = "files/SampleVideo_5mb.mp4" +local Service = 11 + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } +end + +local function EndServiceByUserExit() + local EndServiceEvent = events.Event() + EndServiceEvent.matches = function(_, data) + return data.frameType == constants.FRAME_TYPE.CONTROL_FRAME + and data.serviceType == constants.SERVICE_TYPE.VIDEO + and data.sessionId == common.getMobileSession().sessionId + and data.frameInfo == constants.FRAME_INFO.END_SERVICE + end + common.getMobileSession():ExpectEvent(EndServiceEvent, "Expect EndServiceEvent") + :Do(function() + common.getMobileSession():StopStreaming(FileForStreaming) + common.getMobileSession():Send({ + frameType = constants.FRAME_TYPE.CONTROL_FRAME, + serviceType = constants.SERVICE_TYPE.VIDEO, + frameInfo = constants.FRAME_INFO.END_SERVICE_ACK + }) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus", { + systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE" }) + common.getHMIConnection():ExpectRequest("Navigation.StopStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = false }) + :Times(AtLeast(1)) + common.getHMIConnection():SendNotification("BasicCommunication.OnExitApplication", { + appID = common.getHMIAppId(), reason = "USER_EXIT" }) + common.wait(1000) +end + +local function RestoreService() + common.getMobileSession():StartService(Service) + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) +runner.Step("Start video service", common.startService, { Service }) +runner.Step("Start video streaming", common.StartStreaming, { Service, FileForStreaming }) + +runner.Title("Test") +runner.Step("EndService by USER_EXIT", EndServiceByUserExit) +runner.Step("Activate App after user exit", common.activateApp) +runner.Step("Restoring service", RestoreService) + +runner.Title("Postconditions") +runner.Step("Stop service", common.StopService, { Service }) +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/MobileProjection/Phase1/016_Restore_audio_streaming_from_NONE.lua b/test_scripts/MobileProjection/Phase1/016_Restore_audio_streaming_from_NONE.lua new file mode 100644 index 0000000000..b8f4e6adf0 --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/016_Restore_audio_streaming_from_NONE.lua @@ -0,0 +1,94 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with PROJECTION appHMIType +-- 2) and starts audio streaming +-- 3)user performs 'user exit' +-- SDL must: +-- 1) stop service +-- 2) after activation start service successfully +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase1/common') +local runner = require('user_modules/script_runner') +local events = require('events') +local constants = require('protocol_handler/ford_protocol_constants') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = "PROJECTION" +local FileForStreaming = "files/MP3_4555kb.mp3" +local Service = 10 + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } +end + +local function EndServiceByUserExit() + local EndServiceEvent = events.Event() + EndServiceEvent.matches = function(_, data) + return data.frameType == constants.FRAME_TYPE.CONTROL_FRAME + and data.serviceType == constants.SERVICE_TYPE.PCM + and data.sessionId == common.getMobileSession().sessionId + and data.frameInfo == constants.FRAME_INFO.END_SERVICE + end + common.getMobileSession():ExpectEvent(EndServiceEvent, "Expect EndServiceEvent") + :Do(function() + common.getMobileSession():StopStreaming(FileForStreaming) + common.getMobileSession():Send({ + frameType = constants.FRAME_TYPE.CONTROL_FRAME, + serviceType = constants.SERVICE_TYPE.PCM, + frameInfo = constants.FRAME_INFO.END_SERVICE_ACK + }) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus", { + systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE" }) + common.getHMIConnection():ExpectRequest("Navigation.StopAudioStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { }) + end) + common.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = false }) + :Times(AtLeast(1)) + common.getHMIConnection():SendNotification("BasicCommunication.OnExitApplication", { + appID = common.getHMIAppId(), reason = "USER_EXIT" }) + common.wait(1000) +end + +local function RestoreService() + common.getMobileSession():StartService(Service) + common.getHMIConnection():ExpectRequest("Navigation.StartAudioStream") + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) +runner.Step("Start audio service", common.startService, { Service }) +runner.Step("Start audio streaming", common.StartStreaming, { Service, FileForStreaming }) + +runner.Title("Test") +runner.Step("EndService by USER_EXIT", EndServiceByUserExit) +runner.Step("Activate App after user exit", common.activateApp) +runner.Step("Restoring audio service", RestoreService) + +runner.Title("Postconditions") +runner.Step("Stop service", common.StopService, { Service }) +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/MobileProjection/Phase1/017_HappyPath_flow_with_audio_video_streamings.lua b/test_scripts/MobileProjection/Phase1/017_HappyPath_flow_with_audio_video_streamings.lua new file mode 100644 index 0000000000..dc691ce6df --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/017_HappyPath_flow_with_audio_video_streamings.lua @@ -0,0 +1,85 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with PROJECTION appHMIType +-- 2) and starts video streaming +-- 3) HMI sends OnTouchEvent +-- 4) video streaming is stopped +-- 5) audio streaming is started +-- 5) audio streaming is stoped +-- 5) video and audio streamings are started +-- SDL must: +-- 1) successful perforfm all steps +----------------------------------- +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase1/common') +local runner = require('user_modules/script_runner') +local commonFunctions = require('user_modules/shared_testcases/commonFunctions') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = "PROJECTION" +local OnTochEventType = { + "BEGIN", + "MOVE", + "END", + "CANCEL", +} +local NotifParams = { + type = "BEGIN", + event = { {c = {{x = 1, y = 1}}, id = 1, ts = {1} } } +} + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } + +--[[ Local Functions ]] +local function ptUpdate(pTbl) + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].groups = { "Base-4", "OnTouchEventOnlyGroup" } +end + +local function OnTouchEvent(parameters) + common.getHMIConnection():SendNotification("UI.OnTouchEvent", parameters) + common.getMobileSession():ExpectNotification("OnTouchEvent", parameters) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Start video service after activation", common.startService, { 11 }) +runner.Step("Start audio service after activation", common.startService, { 10 }) +runner.Step("Start video streaming first time", common.StartStreaming, { 11, "files/SampleVideo_5mb.mp4" }) +for key, value in pairs(OnTochEventType) do + local parameters = commonFunctions:cloneTable(NotifParams) + parameters.type = value + parameters.event[1].c[1].x = parameters.event[1].c[1].x + key + parameters.event[1].c[1].y = parameters.event[1].c[1].y + key + parameters.event[1].ts[1] = parameters.event[1].ts[1] + key + runner.Step("OnTouchEvent with type " .. value, OnTouchEvent, { parameters }) +end +runner.Step("Stop video streamingfirst time", common.StopStreaming, { 11, "files/SampleVideo_5mb.mp4" }) +runner.Step("Start audio streaming first time", common.StartStreaming, { 10, "files/MP3_4555kb.mp3" }) +runner.Step("Stop audio streaming first time", common.StopStreaming, { 10, "files/MP3_4555kb.mp3" }) +runner.Step("Start video streaming second time", common.StartStreaming, { 11, "files/SampleVideo_5mb.mp4" }) +runner.Step("Start audio streaming second time", common.StartStreaming, { 10, "files/MP3_4555kb.mp3" }) + +runner.Title("Postconditions") +runner.Step("Stop video streamingsecond time", common.StopStreaming, { 11, "files/SampleVideo_5mb.mp4" }) +runner.Step("Stop audio streamingsecond time", common.StopStreaming, { 10, "files/MP3_4555kb.mp3" }) +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/MobileProjection/Phase1/common.lua b/test_scripts/MobileProjection/Phase1/common.lua new file mode 100644 index 0000000000..01dc1bead4 --- /dev/null +++ b/test_scripts/MobileProjection/Phase1/common.lua @@ -0,0 +1,123 @@ +--------------------------------------------------------------------------------------------------- +-- Common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 3 + +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") +local utils = require("user_modules/utils") +local events = require("events") +local constants = require("protocol_handler/ford_protocol_constants") + +--[[ Module ]] +local m = actions + +m.wait = utils.wait +m.cloneTable = utils.cloneTable + +--[[ @startService: start audio/video service +--! @parameters: +--! pService - service value +--! pAppId - app id value for session +--! @return: none +--]] +function m.startService(pService, pAppId) + if not pAppId then pAppId = 1 end + m.getMobileSession(pAppId):StartService(pService) + if pService == 10 then + m.getHMIConnection():ExpectRequest("Navigation.StartAudioStream") + :Do(function(_, data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { }) + end) + elseif pService == 11 then + m.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_, data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { }) + end) + else + utils.cprint( 31, "Service for opening is not set") + end +end + +--[[ @StartStreaming: Start streaming +--! @parameters: +--! pService - service value +--! pFile -file for streaming +--! pAppId - app id value for session +--! @return: none +--]] +function m.StartStreaming(pService, pFile, pAppId) + if not pAppId then pAppId = 1 end + m.getMobileSession(pAppId):StartStreaming(pService, pFile, 160*1024) + if pService == 11 then + m.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = true }) + else + m.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = true }) + end + utils.cprint(33, "Streaming...") + m.wait(1000) +end + +--[[ @StopStreaming: Stop streaming +--! @parameters: +--! pService - service value +--! pFile -file for streaming +--! pAppId - app id value for session +--! @return: none +--]] +function m.StopStreaming(pService, pFile, pAppId) + if not pAppId then pAppId = 1 end + m.getMobileSession(pAppId):StopStreaming(pFile) + if pService == 11 then + m.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = false }) + else + m.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = false }) + end +end + +--[[ @RejectingServiceStart: Rejecting audio/video service start +--! @parameters: +--! pService - service value +--! pAppId - app id value for session +--! @return: none +--]] +function m.RejectingServiceStart(pService, pAppId) + if not pAppId then pAppId = 1 end + local serviceType + if 11 == pService then + serviceType = constants.SERVICE_TYPE.VIDEO + elseif 10 == pService then + serviceType = constants.SERVICE_TYPE.PCM + end + local StartServiceResponseEvent = events.Event() + StartServiceResponseEvent.matches = + function(_, data) + return data.frameType == constants.FRAME_TYPE.CONTROL_FRAME and + data.serviceType == serviceType and + data.sessionId == m.getMobileSession(pAppId).sessionId and + (data.frameInfo == constants.FRAME_INFO.START_SERVICE_NACK or + data.frameInfo == constants.FRAME_INFO.START_SERVICE_ACK) + end + m.getMobileSession(pAppId):Send({ + frameType = constants.FRAME_TYPE.CONTROL_FRAME, + serviceType = serviceType, + frameInfo = constants.FRAME_INFO.START_SERVICE + }) + -- Expect StartServiceNACK on mobile app from SDL, it means service is not started + m.getMobileSession(pAppId):ExpectEvent(StartServiceResponseEvent, "Expect StartServiceNACK") + :ValidIf(function(_, data) + if data.frameInfo == constants.FRAME_INFO.START_SERVICE_NACK then + return true + else + return false, "StartService ACK received" + end + end) +end + +function m.StopService(pServiceId, pAppId) + if not pAppId then pAppId = 1 end + m.getMobileSession(pAppId):StopService(pServiceId) +end + +return m diff --git a/test_sets/mobile_projection.txt b/test_sets/mobile_projection.txt new file mode 100644 index 0000000000..824f42174e --- /dev/null +++ b/test_sets/mobile_projection.txt @@ -0,0 +1,17 @@ +./test_scripts/MobileProjection/Phase1/001_Start_video_audio_service.lua +./test_scripts/MobileProjection/Phase1/002_Start_video_streaming.lua +./test_scripts/MobileProjection/Phase1/003_Start_audio_streaming.lua +./test_scripts/MobileProjection/Phase1/004_OnTouchEvent_while_streamings.lua +./test_scripts/MobileProjection/Phase1/005_Start_video_service_streaming_in_LIMITED.lua +./test_scripts/MobileProjection/Phase1/006_Start_audio_service_streaming_in_LIMITED.lua +./test_scripts/MobileProjection/Phase1/007_Rejecting_audio_video_service_in_NONE.lua +./test_scripts/MobileProjection/Phase1/008_Rejecting_audio_video_service_in_BACKGROUND.lua +./test_scripts/MobileProjection/Phase1/009_Rejecting_audio_video_service_in_FULL_2_protocol.lua +./test_scripts/MobileProjection/Phase1/010_Rejecting_audio_video_service_in_LIMITED_2_protocol.lua +./test_scripts/MobileProjection/Phase1/011_Retry_sequence_of_StartAudioStream_during_audio_service_start.lua +./test_scripts/MobileProjection/Phase1/012_Retry_sequence_of_StartStream_during_video_service_start.lua +./test_scripts/MobileProjection/Phase1/013_Rejecting_StartAudioStream_during_audio_service_start.lua +./test_scripts/MobileProjection/Phase1/014_Rejecting_StartStream_during_video_service_start.lua +./test_scripts/MobileProjection/Phase1/015_Restore_video_streaming_from_NONE.lua +./test_scripts/MobileProjection/Phase1/016_Restore_audio_streaming_from_NONE.lua +./test_scripts/MobileProjection/Phase1/017_HappyPath_flow_with_audio_video_streamings.lua From 6c23fdcf73e15ffa5be352d6442476ea157f9294 Mon Sep 17 00:00:00 2001 From: Conlain Kelly Date: Thu, 21 Jun 2018 16:45:24 -0400 Subject: [PATCH 451/681] add turn signal data --- .../GetVehicleData/001_Success_flow.lua | 6 ++++-- ...2_RPC_parameter_DISALLOWED_by_policies_flow.lua | 8 +++++--- .../VehicleData/OnVehicleData/001_Success_flow.lua | 10 ++++++++-- ...icationForUnsubsribedParameter_Ignored_flow.lua | 13 ++++++++++--- ...nParameterDisallowedByPolicies_Ignored_flow.lua | 12 +++++++++--- .../SubscribeVehicleData/001_Success_flow.lua | 7 ++++++- ...2_RPC_parameter_DISALLOWED_by_policies_flow.lua | 9 +++++++-- ...eter_already_subscribed_Result_IGNORED_flow.lua | 11 ++++++++++- .../UnsubscribeVehicleData/001_Success_flow.lua | 10 ++++++++-- ...C_parameter_not_yet_subscribed_IGNORED_flow.lua | 7 ++++++- ...er_already_unsubscribed_Result_IGNORED_flow.lua | 14 ++++++++++++-- ...sallowed_by_policies_Result_DISALLOWED_flow.lua | 9 +++++++-- test_scripts/API/VehicleData/commonVehicleData.lua | 1 + ...4_SubscribeVehicleData_PositiveCase_SUCCESS.lua | 1 + .../026_GetVehicleData_PositiveCase_SUCCESS.lua | 1 + 15 files changed, 95 insertions(+), 24 deletions(-) diff --git a/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua index ee90d4c76f..dfd752d167 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua @@ -25,7 +25,8 @@ local rpc = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + turnSignal = true } } @@ -48,7 +49,8 @@ local vehicleDataValues = { tpms = "SYSTEM_ACTIVE", pressure = 35.00 } - } + }, + turnSignal = "LEFT" } --[[ Local Functions ]] diff --git a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index 694b41001b..6da68b8e26 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -26,7 +26,8 @@ local rpc = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + turnSignal = true } } @@ -49,7 +50,8 @@ local vehicleDataValues = { tpms = "SYSTEM_ACTIVE", pressure = 35.00 } - } + }, + turnSignal = "OFF" } --[[ Local Functions ]] @@ -57,7 +59,7 @@ local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["GetVehicleData"].parameters local newParams = {} for index, value in pairs(params) do - if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value)) then table.insert(newParams, value) end + if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value or ("turnSignal" == value))) then table.insert(newParams, value) end end tbl.policy_table.functional_groupings["Emergency-1"].rpcs["GetVehicleData"].parameters = newParams end diff --git a/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua index fa577bd8d2..ddf5ebb7d2 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua @@ -25,7 +25,8 @@ local rpc1 = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + turnSignal = true } } @@ -51,7 +52,8 @@ local rpc2 = { pressure = 35.00 } } - } + }, + turnSignal = "OFF" } local vehicleDataResults = { @@ -66,6 +68,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "SUCCESS" + }, + turnSignal = { + dataType = "VEHICLEDATA_TURNSIGNAL", + resultCode = "SUCCESS" } } diff --git a/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua index 198e447a03..5be8250747 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua @@ -27,7 +27,8 @@ local rpc1 = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + turnSignal = true } } @@ -53,7 +54,8 @@ local rpc2 = { pressure = 35.00 } } - } + }, + turnSignal = "OFF" } local rpc3 = { @@ -61,7 +63,8 @@ local rpc3 = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + turnSignal = true } } @@ -77,6 +80,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "SUCCESS" + }, + turnSignal = { + dataType = "VEHICLEDATA_TURNSIGNAL", + resultCode = "SUCCESS" } } diff --git a/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua b/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua index 5017412636..2d5469e104 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua @@ -27,7 +27,8 @@ local rpc1 = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + turnSignal = true } } @@ -53,7 +54,8 @@ local rpc2 = { pressure = 35.00 } } - } + }, + turnSignal = "OFF" } local vehicleDataResults = { @@ -68,6 +70,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "SUCCESS" + }, + turnSignal = { + dataType = "VEHICLEDATA_TURNSIGNAL", + resultCode = "SUCCESS" } } @@ -76,7 +82,7 @@ local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["OnVehicleData"].parameters local newParams = {} for index, value in pairs(params) do - if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value)) then table.insert(newParams, value) end + if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value) or ("turnSignal" == value)) then table.insert(newParams, value) end end tbl.policy_table.functional_groupings["Emergency-1"].rpcs["OnVehicleData"].parameters = newParams end diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua index 519fc629b6..c952bf7730 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua @@ -24,7 +24,8 @@ local rpc = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + turnSignal = true } } @@ -40,6 +41,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "SUCCESS" + }, + turnSignal = { + dataType = "VEHICLEDATA_TURNSIGNAL", + resultCode = "SUCCESS" } } diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index d111e36b24..8e7689bc72 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -25,7 +25,8 @@ local rpc = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + turnSignal = true } } @@ -41,6 +42,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "DISALLOWED" + }, + turnSignal = { + dataType = "VEHICLEDATA_TURNSIGNAL", + resultCode = "DISALLOWED" } } @@ -49,7 +54,7 @@ local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["SubscribeVehicleData"].parameters local newParams = {} for index, value in pairs(params) do - if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value)) then table.insert(newParams, value) end + if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value) or ("turnSignal" == value)) then table.insert(newParams, value) end end tbl.policy_table.functional_groupings["Emergency-1"].rpcs["SubscribeVehicleData"].parameters = newParams end diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua index 8a0991c33b..d038b21a9e 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua @@ -24,7 +24,8 @@ local rpc = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + turnSignal = true } } @@ -40,6 +41,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "SUCCESS" + }, + turnSignal = { + dataType = "VEHICLEDATA_TURNSIGNAL", + resultCode = "SUCCESS" } } @@ -55,6 +60,10 @@ local vehicleDataResults2 = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "DATA_ALREADY_SUBSCRIBED" + }, + turnSignal = { + dataType = "VEHICLEDATA_TURNSIGNAL", + resultCode = "DATA_ALREADY_SUBSCRIBED" } } diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua index 184745f351..c9cbae9939 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua @@ -25,7 +25,8 @@ local rpc_subscribe = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + turnSignal = true } } @@ -34,7 +35,8 @@ local rpc_unsubscribe = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + turnSignal = true } } @@ -50,6 +52,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "SUCCESS" + }, + turnSignal = { + dataType = "turnSignal", + resultCode = "SUCCESS" } } diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua index 368c604206..478465f060 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua @@ -26,7 +26,8 @@ local rpc = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + turnSignal = true } } @@ -42,6 +43,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "DATA_NOT_SUBSCRIBED" + }, + turnSignal = { + dataType = "turnSignal", + resultCode = "DATA_NOT_SUBSCRIBED" } } diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua index 4b550f319b..008f4e8d03 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua @@ -27,7 +27,8 @@ local rpc_subscribe = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + turnSignal = true } } @@ -36,7 +37,8 @@ local rpc_unsubscribe = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + turnSignal = true } } @@ -52,6 +54,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "SUCCESS" + }, + turnSignal = { + dataType = "VEHICLEDATA_TURNSIGNAL", + resultCode = "SUCCESS" } } @@ -67,6 +73,10 @@ local vehicleDataResults2 = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "DATA_NOT_SUBSCRIBED" + }, + turnSignal = { + dataType = "VEHICLEDATA_TURNSIGNAL", + resultCode = "DATA_NOT_SUBSCRIBED" } } diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua index 3144254c7c..e0d77b7532 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua @@ -25,7 +25,8 @@ local rpc = { params = { engineOilLife = true, fuelRange = true, - tirePressure = true + tirePressure = true, + turnSignal = true } } @@ -41,6 +42,10 @@ local vehicleDataResults = { tirePressure = { dataType = "VEHICLEDATA_TIREPRESSURE", resultCode = "DISALLOWED" + }, + turnSignal = { + dataType = "VEHICLEDATA_TURNSIGNAL", + resultCode = "DISALLOWED" } } @@ -49,7 +54,7 @@ local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["UnsubscribeVehicleData"].parameters local newParams = {} for index, value in pairs(params) do - if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value)) then table.insert(newParams, value) end + if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value) or ("turnSignal" == value)) then table.insert(newParams, value) end end tbl.policy_table.functional_groupings["Emergency-1"].rpcs["UnsubscribeVehicleData"].parameters = newParams end diff --git a/test_scripts/API/VehicleData/commonVehicleData.lua b/test_scripts/API/VehicleData/commonVehicleData.lua index 72e1e4221c..8fe9235f03 100644 --- a/test_scripts/API/VehicleData/commonVehicleData.lua +++ b/test_scripts/API/VehicleData/commonVehicleData.lua @@ -92,6 +92,7 @@ local function ptu(self, app_id, ptu_update_func) addParamToRPC(tbl, "Emergency-1", rpc, "engineOilLife") addParamToRPC(tbl, "Emergency-1", rpc, "fuelRange") addParamToRPC(tbl, "Emergency-1", rpc, "tirePressure") + addParamToRPC(tbl, "Emergency-1", rpc, "turnSignal") end tbl.policy_table.app_policies[commonVehicleData.getMobileAppId(app_id)] = commonVehicleData.getGetVehicleDataConfig() end diff --git a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua index a31911a983..5b7016dad8 100644 --- a/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/024_SubscribeVehicleData_PositiveCase_SUCCESS.lua @@ -42,6 +42,7 @@ local VDValues = { fuelRange = "VEHICLEDATA_FUELRANGE", instantFuelConsumption = "VEHICLEDATA_FUELCONSUMPTION", externalTemperature = "VEHICLEDATA_EXTERNTEMP", + turnSignal = "VEHICLEDATA_TURNSIGNAL", prndl = "VEHICLEDATA_PRNDL", tirePressure = "VEHICLEDATA_TIREPRESSURE", odometer = "VEHICLEDATA_ODOMETER", diff --git a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua index 085fd32155..131378635f 100644 --- a/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/026_GetVehicleData_PositiveCase_SUCCESS.lua @@ -66,6 +66,7 @@ local vehicleDataValues = { }, instantFuelConsumption = 1000.5, externalTemperature = 55.5, + turnSignal = "OFF", vin = "123456", prndl = "DRIVE", tirePressure = { From 8e83679b9263ead09454f4c16dede3a557044bb0 Mon Sep 17 00:00:00 2001 From: HSavynetska Date: Fri, 22 Jun 2018 12:45:09 +0300 Subject: [PATCH 452/681] Scripts for reproduce issues_964 --- ...once_if_HMI_responds_with_INVALID_DATA.lua | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 test_scripts/Defects/4_6/964_SDL_sends_to_mobile_APPLICATION_NOT_REGISTRED_in_setAppIcon_responce_if_HMI_responds_with_INVALID_DATA.lua diff --git a/test_scripts/Defects/4_6/964_SDL_sends_to_mobile_APPLICATION_NOT_REGISTRED_in_setAppIcon_responce_if_HMI_responds_with_INVALID_DATA.lua b/test_scripts/Defects/4_6/964_SDL_sends_to_mobile_APPLICATION_NOT_REGISTRED_in_setAppIcon_responce_if_HMI_responds_with_INVALID_DATA.lua new file mode 100644 index 0000000000..00d1334eca --- /dev/null +++ b/test_scripts/Defects/4_6/964_SDL_sends_to_mobile_APPLICATION_NOT_REGISTRED_in_setAppIcon_responce_if_HMI_responds_with_INVALID_DATA.lua @@ -0,0 +1,73 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/SmartDeviceLink/sdl_core/issues/964 +-- +-- Precondition: +-- SDL Core and HMI are started. App is registered, HMI level = FULL +-- Description: +-- Steps to reproduce: +-- 1) Send PutFile with file name =\syncFileName +-- SDL returns SUCCESS result, success:true +-- 2) Send SetAppIcon with file name =\syncFileName +-- 3) Send from HMI INVALID_DATA to SDL. +-- Expected: +-- 1) SDL should send to mobile result code which was sent to SDL by HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/commonDefects') +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local utils = require("user_modules/utils") +local actions = require("user_modules/sequences/actions") + +--[[ Local Functions ]] +local function getPathToFileInStorage(pFileName, pAppId) + if not pAppId then pAppId = 1 end + return commonPreconditions:GetPathToSDL() .. "storage/" + .. actions.getConfigAppParams(pAppId).appID .. "_" + .. utils.getDeviceMAC() .. "/" .. pFileName +end + +local function putFile(self) + local paramsSend = { + syncFileName = "icon.png", + fileType = "GRAPHIC_PNG" + } + local cid = self.mobileSession1:SendRPC( "PutFile", paramsSend, "files/icon.png") + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +local function setAppIcon_INVALID_DATA(pParams, self) + local cid = self.mobileSession1:SendRPC("SetAppIcon", pParams.requestParams) + pParams.requestUiParams.appID = common.getHMIAppId() + EXPECT_HMICALL("UI.SetAppIcon") + :Do(function(_, data) + self.hmiConnection:SendError(data.id, data.method, "INVALID_DATA", "Image does not exist!") + end) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA", info = "Image does not exist!" }) +end + +--[[ Local Variables ]] +local requestParams = { syncFileName = "icon.png" } + +local requestUiParams = { + syncFileName = { + imageType = "DYNAMIC", + value = getPathToFileInStorage(requestParams.syncFileName) + } +} + +local allParams = {requestParams = requestParams, requestUiParams = requestUiParams } + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.rai_ptu_n) +runner.Step("Activate App", common.activate_app) +runner.Step("Upload icon file", putFile) + +runner.Title("Test") +runner.Step("SetAppIcon with INVALID_DATA response from HMI", setAppIcon_INVALID_DATA, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From c289e6091b35a786a05b8e0ea9d793e3ba233bc0 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 22 Jun 2018 13:27:42 +0300 Subject: [PATCH 453/681] Stabilize scripts by changing timings --- ...3_Rejecting_StartAudioStream_during_audio_service_start.lua | 3 ++- .../014_Rejecting_StartStream_during_video_service_start.lua | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/test_scripts/MobileProjection/Phase1/013_Rejecting_StartAudioStream_during_audio_service_start.lua b/test_scripts/MobileProjection/Phase1/013_Rejecting_StartAudioStream_during_audio_service_start.lua index c414cd1b3f..54a8da463a 100644 --- a/test_scripts/MobileProjection/Phase1/013_Rejecting_StartAudioStream_during_audio_service_start.lua +++ b/test_scripts/MobileProjection/Phase1/013_Rejecting_StartAudioStream_during_audio_service_start.lua @@ -56,7 +56,7 @@ local function startService() local function response() common.getHMIConnection():SendError(data.id, data.method, "REJECTED", "Request is rejected") end - RUN_AFTER(response, 100) + RUN_AFTER(response, 550) end) :Times(4) common.getHMIConnection():ExpectRequest("Navigation.StopAudioStream") @@ -68,6 +68,7 @@ end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) +runner.Step("Set StartStreamRetry value to 3,500", common.setSDLIniParameter, { "StartStreamRetry", "3,500" }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register App", common.registerApp) runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) diff --git a/test_scripts/MobileProjection/Phase1/014_Rejecting_StartStream_during_video_service_start.lua b/test_scripts/MobileProjection/Phase1/014_Rejecting_StartStream_during_video_service_start.lua index a5e0093648..fc236a73cd 100644 --- a/test_scripts/MobileProjection/Phase1/014_Rejecting_StartStream_during_video_service_start.lua +++ b/test_scripts/MobileProjection/Phase1/014_Rejecting_StartStream_during_video_service_start.lua @@ -56,7 +56,7 @@ local function startService() local function response() common.getHMIConnection():SendError(data.id, data.method, "REJECTED", "Request is rejected") end - RUN_AFTER(response, 100) + RUN_AFTER(response, 550) end) :Times(4) common.getHMIConnection():ExpectRequest("Navigation.StopStream") @@ -68,6 +68,7 @@ end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) +runner.Step("Set StartStreamRetry value to 3,500", common.setSDLIniParameter, { "StartStreamRetry", "3,500" }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register App", common.registerApp) runner.Step("PolicyTableUpdate with HMI types", common.policyTableUpdate, { ptUpdate }) From 8bdfba3dd3faec9c8da96b6c594c9893f6852aa4 Mon Sep 17 00:00:00 2001 From: Conlain Kelly Date: Fri, 22 Jun 2018 11:38:05 -0400 Subject: [PATCH 454/681] fix bad entry, update another test --- .../API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua | 2 +- .../002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua | 2 +- .../API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua index c9cbae9939..d6fd5c9ef5 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua @@ -54,7 +54,7 @@ local vehicleDataResults = { resultCode = "SUCCESS" }, turnSignal = { - dataType = "turnSignal", + dataType = "VEHICLEDATA_TURNSIGNAL", resultCode = "SUCCESS" } } diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua index 478465f060..0638833010 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua @@ -45,7 +45,7 @@ local vehicleDataResults = { resultCode = "DATA_NOT_SUBSCRIBED" }, turnSignal = { - dataType = "turnSignal", + dataType = "VEHICLEDATA_TURNSIGNAL", resultCode = "DATA_NOT_SUBSCRIBED" } } diff --git a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua index 96924ec0d3..98413915bc 100644 --- a/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/025_UnsubscribeVehicleData_PositiveCase_SUCCESS.lua @@ -43,6 +43,7 @@ local VDValues = { instantFuelConsumption = "VEHICLEDATA_FUELCONSUMPTION", externalTemperature = "VEHICLEDATA_EXTERNTEMP", prndl = "VEHICLEDATA_PRNDL", + turnSignal = "VEHICLEDATA_TURNSIGNAL", tirePressure = "VEHICLEDATA_TIREPRESSURE", odometer = "VEHICLEDATA_ODOMETER", beltStatus = "VEHICLEDATA_BELTSTATUS", From f1014bde6ef3bb1e4b4f357baea2ad3f27edc206 Mon Sep 17 00:00:00 2001 From: Conlain Kelly Date: Fri, 22 Jun 2018 13:38:53 -0400 Subject: [PATCH 455/681] Fix parenthesis mismatch --- .../002_RPC_parameter_DISALLOWED_by_policies_flow.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index 6da68b8e26..eea85ad0c0 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -59,7 +59,7 @@ local function ptu_update_func(tbl) local params = tbl.policy_table.functional_groupings["Emergency-1"].rpcs["GetVehicleData"].parameters local newParams = {} for index, value in pairs(params) do - if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value or ("turnSignal" == value))) then table.insert(newParams, value) end + if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value) or ("turnSignal" == value)) then table.insert(newParams, value) end end tbl.policy_table.functional_groupings["Emergency-1"].rpcs["GetVehicleData"].parameters = newParams end From f374396524db2ade66b219bcd0587d1df597972a Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 25 Jun 2018 08:34:09 +0300 Subject: [PATCH 456/681] Add RequestType and RequestSubType attributes --- .../PolicyTables/DefaultPolicyTableWith_group1.json | 6 ++++-- .../PolicyTables/DefaultPolicyTableWith_group1_2.json | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/user_modules/shared_testcases/PolicyTables/DefaultPolicyTableWith_group1.json b/user_modules/shared_testcases/PolicyTables/DefaultPolicyTableWith_group1.json index 94f5830d72..d9d21db76d 100644 --- a/user_modules/shared_testcases/PolicyTables/DefaultPolicyTableWith_group1.json +++ b/user_modules/shared_testcases/PolicyTables/DefaultPolicyTableWith_group1.json @@ -1553,7 +1553,7 @@ } } }, - + "group1" : { "languages" : { "de-de" : { @@ -2326,7 +2326,9 @@ "steal_focus" : false, "priority" : "NONE", "default_hmi" : "NONE", - "groups" : ["Base-4"] + "groups" : ["Base-4"], + "RequestType": [], + "RequestSubType": [] }, "0000001" : { "keep_context" : false, diff --git a/user_modules/shared_testcases/PolicyTables/DefaultPolicyTableWith_group1_2.json b/user_modules/shared_testcases/PolicyTables/DefaultPolicyTableWith_group1_2.json index 9f776238ae..3f4b134f45 100644 --- a/user_modules/shared_testcases/PolicyTables/DefaultPolicyTableWith_group1_2.json +++ b/user_modules/shared_testcases/PolicyTables/DefaultPolicyTableWith_group1_2.json @@ -1553,7 +1553,7 @@ } } }, - + "group1" : { "languages" : { "de-de" : { @@ -2326,7 +2326,9 @@ "steal_focus" : false, "priority" : "NONE", "default_hmi" : "NONE", - "groups" : ["Base-4"] + "groups" : ["Base-4"], + "RequestType": [], + "RequestSubType": [] }, "device" : { "keep_context" : false, From b4e325e28dea2341fbdaa4bfada5e44964e9d1a5 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 26 Jun 2018 10:28:40 +0300 Subject: [PATCH 457/681] Revert "Merge pull request #1904 from LitvinenkoIra/fix/rc_disabling" This reverts commit 1a6e64055ceeac4051ad721e7f7318d4a10f60b8, reversing changes made to e97ee559f1afa8d3a524fb450c0decf17d1e8d44. Commit is reverted because was decided to include these changes to sdl code by separate proposal. So functionality will be removed from sdl code and also removed from scripts. --- .../008_Allowed_false.lua | 35 ++++++++++--------- .../024_Allowed_false_no_PTU.lua | 15 ++++---- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua index c1f0faa4fc..f272226a97 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 -- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md --- Item: Use Case 1: Main Flow (updates https://github.com/smartdevicelink/sdl_core/issues/2173) +-- Item: Use Case 1: Main Flow -- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode @@ -12,8 +12,9 @@ -- -- SDL must: -- 1) store RC state allowed:false internally --- 2) keep all applications with appHMIType REMOTE_CONTROL registered and in current HMI levels --- 3) unsubscribe all REMOTE_CONTROL applications from OnInteriorVehicleData notifications for all HMI modules internally +-- 2) assign HMILevel none to all registered applications with appHMIType REMOTE_CONTROL and send OnHMIStatus (NONE) to such apps +-- 3) keep all applications with appHMIType REMOTE_CONTROL registered +-- 4) unsubscribe all REMOTE_CONTROL applications from OnInteriorVehicleData notifications for all HMI modules internally --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -28,29 +29,29 @@ local rcRpcs = {"GetInteriorVehicleData", "SetInteriorVehicleData", "ButtonPress --[[ Local Functions ]] local function ptu_update_func(tbl) - local notRcAppConfig = { - keep_context = false, - steal_focus = false, + local notRcAppConfig = { + keep_context = false, + steal_focus = false, priority = "NONE", default_hmi = "NONE", groups = { "Base-4" }, groups_primaryRC = { "Base-4"}, AppHMIType = { "NAVIGATION" } - } + } tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() tbl.policy_table.app_policies[config.application3.registerAppInterfaceParams.appID] = notRcAppConfig end local function disableRcFromHmi(self) - local mobileSession1 = commonRC.getMobileSession(self, 1) - local mobileSession2 = commonRC.getMobileSession(self, 2) + local mobileSession1 = commonRC.getMobileSession(self, 1) + local mobileSession2 = commonRC.getMobileSession(self, 2) local mobileSession3 = commonRC.getMobileSession(self, 3) - commonRC.defineRAMode(false, nil, self) + commonRC.defineRAMode(false, nil, self) - mobileSession1:ExpectNotification("OnHMIStatus"):Times(0) - mobileSession2:ExpectNotification("OnHMIStatus"):Times(0) + mobileSession1:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE"}):Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + mobileSession2:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE"}):Times(AtLeast(1)) -- issue with SDL --> notification is sent twice mobileSession3:ExpectNotification("OnHMIStatus"):Times(0) -- NAVIGATION app commonTestCases:DelayedExp(commonRC.timeout) @@ -76,11 +77,11 @@ for _, mod in pairs(modules) do -- Apps are not subscribed from RC modules runner.Step("Check App1 is not subscribed on " .. mod, commonRC.isUnsubscribed, { mod, 1 }) runner.Step("Check App2 is not subscribed on " .. mod, commonRC.isUnsubscribed, { mod, 2 }) - -- All RC RPCs rejected - for _, rpc in pairs(rcRpcs) do - runner.Step("Check module " .. mod .." App1 " .. rpc .. " rejected", commonRC.rpcDenied, { mod, 1, rpc, "USER_DISALLOWED" }) - runner.Step("Check module " .. mod .." App2 " .. rpc .. " rejected", commonRC.rpcDenied, { mod, 2, rpc, "USER_DISALLOWED" }) - end + -- -- All RC RPCs denied - need clarification + -- for _, rpc in pairs(rcRpcs) do + -- runner.Step("Check module " .. mod .." App1 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 1, rpc, "DISALLOWED" }) + -- runner.Step("Check module " .. mod .." App2 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 2, rpc, "DISALLOWED" }) + -- end end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua index f9c77cf3fc..f3e8812b5c 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 -- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md --- Item: Use Case 1: Main Flow (updates https://github.com/smartdevicelink/sdl_core/issues/2173) +-- Item: Use Case 1: Main Flow -- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode @@ -13,7 +13,8 @@ -- SDL must: -- 1) store RC state allowed:false internally -- 2) assign HMILevel none to all registered applications with appHMIType REMOTE_CONTROL --- 3) keep all applications with appHMIType REMOTE_CONTROL registered and in current HMI levels +-- and send OnHMIStatus (NONE) to such apps +-- 3) keep all applications with appHMIType REMOTE_CONTROL registered --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -62,12 +63,12 @@ local function activate_app(pAppId, self) end local function disableRCFromHMI(self) - commonRC.defineRAMode(false, nil, self) + commonRC.defineRAMode(false, nil, self) - self.mobileSession1:ExpectNotification("OnHMIStatus") - :Times(0) - self.mobileSession2:ExpectNotification("OnHMIStatus") - :Times(0) + self.mobileSession1:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE" }) + :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + self.mobileSession2:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE" }) + :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice self.mobileSession3:ExpectNotification("OnHMIStatus") :Times(0) From a6c432262abf9ca73e5d36965fe7ddb79a9ed2d2 Mon Sep 17 00:00:00 2001 From: "Ira Lytvynenko (GitHub)" Date: Fri, 18 May 2018 12:48:32 +0300 Subject: [PATCH 458/681] Scripts for SEAT module --- .../001_SEAT_all_params_SUCCESS.lua | 37 ++ ...2_SEAT_all_params_UNSUPPORTED_RESOURCE.lua | 36 ++ .../003_Resend_only_supported_parameters.lua | 61 +++ ...supported_and_not_supported_parameters.lua | 54 +++ ...snt_respond_to_RC_GetCapabilities_SEAT.lua | 74 ++++ ...snt_respond_to_RC_GetCapabilities_SEAT.lua | 74 ++++ .../001_Success_flow.lua | 32 ++ ...ransfering_of_HMI_resultCode_to_mobile.lua | 89 ++++ .../003_RPC_parameters_values.lua | 98 +++++ ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 52 +++ ..._in_case_HMI_respond_with_invalid_data.lua | 85 ++++ ...se_moduleType_is_an_empty_array_in_LPT.lua | 63 +++ ...ow_in_case_moduleType_is_absent_in_LPT.lua | 50 +++ ...bscribing_without_isSubscribe_from_HMI.lua | 66 +++ ...ROR_in_case_HMI_respond_with_READ_ONLY.lua | 51 +++ ...response_from_HMI_without_isSubscribed.lua | 75 ++++ ...ut_response_from_HMI_with_isSubscribed.lua | 72 ++++ ...ase_of_2nd_Subscription_UnSubscription.lua | 89 ++++ .../001_Success_flow.lua | 49 +++ ...ribing_with_isSubscribe_false_from_HMI.lua | 61 +++ ...bscribing_without_isSubscribe_from_HMI.lua | 64 +++ ..._Radio_and_without_one_for_module_Seat.lua | 35 ++ ..._after_unsubscribe_from_module_Climate.lua | 40 ++ .../006_RPC_parameters_values.lua | 70 ++++ .../001_Success_flow.lua | 53 +++ .../002_Disallow_flow_by_policy_RADIO.lua | 47 +++ ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 51 +++ .../004_RPC_parameters_values.lua | 92 +++++ ...ow_in_case_moduleType_is_absent_in_LPT.lua | 47 +++ ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 53 +++ ..._in_case_HMI_respond_with_invalid_data.lua | 79 ++++ ...ransfering_of_HMI_resultCode_to_mobile.lua | 81 ++++ test_scripts/RC/SEAT/commonRC.lua | 381 ++++++++++++++++++ test_scripts/RC/commonRC.lua | 25 +- test_sets/rc_SEAT.txt | 32 ++ user_modules/hmi_values.lua | 20 + 36 files changed, 2430 insertions(+), 8 deletions(-) create mode 100644 test_scripts/RC/SEAT/Capabilities/001_SEAT_all_params_SUCCESS.lua create mode 100644 test_scripts/RC/SEAT/Capabilities/002_SEAT_all_params_UNSUPPORTED_RESOURCE.lua create mode 100644 test_scripts/RC/SEAT/Capabilities/003_Resend_only_supported_parameters.lua create mode 100644 test_scripts/RC/SEAT/Capabilities/004_Reject_request_with_both_supported_and_not_supported_parameters.lua create mode 100644 test_scripts/RC/SEAT/Capabilities/005_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua create mode 100644 test_scripts/RC/SEAT/Capabilities/006_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua create mode 100644 test_scripts/RC/SEAT/GetInteriorVehicleData/001_Success_flow.lua create mode 100644 test_scripts/RC/SEAT/GetInteriorVehicleData/002_Transfering_of_HMI_resultCode_to_mobile.lua create mode 100644 test_scripts/RC/SEAT/GetInteriorVehicleData/003_RPC_parameters_values.lua create mode 100644 test_scripts/RC/SEAT/GetInteriorVehicleData/004_GENERIC_ERROR_in_case_HMI_did_not_respond.lua create mode 100644 test_scripts/RC/SEAT/GetInteriorVehicleData/005_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua create mode 100644 test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua create mode 100644 test_scripts/RC/SEAT/GetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua create mode 100644 test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua create mode 100644 test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua create mode 100644 test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua create mode 100644 test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua create mode 100644 test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua create mode 100644 test_scripts/RC/SEAT/OnInteriorVehicleData/001_Success_flow.lua create mode 100644 test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua create mode 100644 test_scripts/RC/SEAT/OnInteriorVehicleData/003_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua create mode 100644 test_scripts/RC/SEAT/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Seat.lua create mode 100644 test_scripts/RC/SEAT/OnInteriorVehicleData/005_Existence_of_OnIVD_for_module_Seat_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Climate.lua create mode 100644 test_scripts/RC/SEAT/OnInteriorVehicleData/006_RPC_parameters_values.lua create mode 100644 test_scripts/RC/SEAT/SetInteriorVehicleData/001_Success_flow.lua create mode 100644 test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_RADIO.lua create mode 100644 test_scripts/RC/SEAT/SetInteriorVehicleData/003_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua create mode 100644 test_scripts/RC/SEAT/SetInteriorVehicleData/004_RPC_parameters_values.lua create mode 100644 test_scripts/RC/SEAT/SetInteriorVehicleData/005_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua create mode 100644 test_scripts/RC/SEAT/SetInteriorVehicleData/006_GENERIC_ERROR_in_case_HMI_did_not_respond.lua create mode 100644 test_scripts/RC/SEAT/SetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua create mode 100644 test_scripts/RC/SEAT/SetInteriorVehicleData/008_Transfering_of_HMI_resultCode_to_mobile.lua create mode 100644 test_scripts/RC/SEAT/commonRC.lua create mode 100644 test_sets/rc_SEAT.txt diff --git a/test_scripts/RC/SEAT/Capabilities/001_SEAT_all_params_SUCCESS.lua b/test_scripts/RC/SEAT/Capabilities/001_SEAT_all_params_SUCCESS.lua new file mode 100644 index 0000000000..db05cd3e4c --- /dev/null +++ b/test_scripts/RC/SEAT/Capabilities/001_SEAT_all_params_SUCCESS.lua @@ -0,0 +1,37 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: +-- In case: +-- SDL gets all RC capabilities for SEAT modules through RC.GetCapabilities +-- SDL must: +-- Send RPC request to HMI and resend HMI answer to Mobile app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { "SEAT" } }) +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI (HMI has all posible RC capabilities), connect Mobile, start Session", commonRC.start, + {commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, commonRC.DEFAULT, commonRC.DEFAULT, commonRC.DEFAULT)}) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App1", commonRC.activate_app) + +runner.Title("Test") + +runner.Step("GetInteriorVehicleData SEAT", commonRC.subscribeToModule, { "SEAT", 1 }) +runner.Step("SetInteriorVehicleData SEAT", commonRC.rpcAllowed, { "SEAT", 1, "SetInteriorVehicleData" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) +runner.Step("Restore HMI capabilities file", commonRC.restoreHMICapabilities) diff --git a/test_scripts/RC/SEAT/Capabilities/002_SEAT_all_params_UNSUPPORTED_RESOURCE.lua b/test_scripts/RC/SEAT/Capabilities/002_SEAT_all_params_UNSUPPORTED_RESOURCE.lua new file mode 100644 index 0000000000..157ab5d0ab --- /dev/null +++ b/test_scripts/RC/SEAT/Capabilities/002_SEAT_all_params_UNSUPPORTED_RESOURCE.lua @@ -0,0 +1,36 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: +-- In case: +-- 1) SDL does not get RC capabilities for SEAT module through RC.GetCapabilities +-- SDL must: +-- 1) Response with success = false and resultCode = UNSUPPORTED_RESOURCE on all valid RPC with module SEAT +-- 2) Does not send RPC request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI (HMI has not SEAT RC capabilities), connect Mobile, start Session", commonRC.start, + {commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, commonRC.DEFAULT, nil, commonRC.DEFAULT)}) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App1", commonRC.activate_app) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData SEAT(UNSUPPORTED_RESOURCE)", commonRC.rpcDenied, + { "SEAT", 1, "GetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) +runner.Step("SetInteriorVehicleData SEAT(UNSUPPORTED_RESOURCE)", commonRC.rpcDenied, + { "SEAT", 1, "SetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/Capabilities/003_Resend_only_supported_parameters.lua b/test_scripts/RC/SEAT/Capabilities/003_Resend_only_supported_parameters.lua new file mode 100644 index 0000000000..7bed41e538 --- /dev/null +++ b/test_scripts/RC/SEAT/Capabilities/003_Resend_only_supported_parameters.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item +-- +-- Description: +-- In case: +-- 1) SDL receive several supported SEAT parameters in GetCapabilites response +-- SDL must: +-- 1) Transfer to HMI remote control RPCs only with supported parameters and +-- 2) Reject any request for SEAT with unsupported parameters with UNSUPPORTED_RESOURCE result code, success: false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local seat_capabilities = {{moduleName = "Seat", horizontalPositionAvailable = true, verticalPositionAvailable = false}} +local rc_capabilities = commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, commonRC.DEFAULT, seat_capabilities, commonRC.DEFAULT) +local available_params = {moduleType = "SEAT", seatControlData = {id = "DRIVER", horizontalPosition = 75}} +local absent_params = {moduleType = "SEAT", seatControlData = {id = "DRIVER", frontVerticalPosition = 55}} +local unavailable_params = {moduleType = "SEAT", seatControlData = {id = "DRIVER", verticalPosition = 65}} + +--[[ Local Functions ]] +local function setVehicleData(params) + local mobSession = commonRC.getMobileSession() + local cid = mobSession:SendRPC("SetInteriorVehicleData", {moduleData = params}) + + if params.seatControlData.horizontalPosition then + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = commonRC.getHMIAppId(1), + moduleData = params}) + :Do(function(_, data) + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = params}) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + else + EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) + end +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, {rc_capabilities}) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate_App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData rejected with unavailable parameter", setVehicleData, { unavailable_params }) +runner.Step("SetInteriorVehicleData processed with available params", setVehicleData, { available_params }) +runner.Step("SetInteriorVehicleData rejected with absent parameter", setVehicleData, { absent_params }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/Capabilities/004_Reject_request_with_both_supported_and_not_supported_parameters.lua b/test_scripts/RC/SEAT/Capabilities/004_Reject_request_with_both_supported_and_not_supported_parameters.lua new file mode 100644 index 0000000000..f744f9a9d6 --- /dev/null +++ b/test_scripts/RC/SEAT/Capabilities/004_Reject_request_with_both_supported_and_not_supported_parameters.lua @@ -0,0 +1,54 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) SDL receive several supported Radio parameters in GetCapabilites response and +-- 2) App sends RC RPC request with several supported by HMI parameters and some unssuported +-- SDL must: +-- 1) Reject such request with UNSUPPORTED_RESOURCE result code, success: false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local seat_capabilities = {{moduleName = "Seat", horizontalPositionAvailable = true, verticalPositionAvailable = false}} +local rc_capabilities = commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, commonRC.DEFAULT, seat_capabilities, commonRC.DEFAULT) +local seat_params = { + moduleType = "SEAT", + seatControlData = { + id = "DRIVER", + horizontalPosition = 72, + verticalPosition = 83 + } +} + +--[[ Local Functions ]] +local function setVehicleData(params) + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", {moduleData = params}) + EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, {rc_capabilities}) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate_App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData rejected if at least one prameter unsuported", setVehicleData, { seat_params }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/Capabilities/005_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua b/test_scripts/RC/SEAT/Capabilities/005_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua new file mode 100644 index 0000000000..0e15e0fc00 --- /dev/null +++ b/test_scripts/RC/SEAT/Capabilities/005_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua @@ -0,0 +1,74 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item +-- +-- Description: +-- In case: +-- HMI didn't respond on RC.IsReady request from SDL +-- and HMI didn't respond on capabilities request from SDL +-- +-- SDL must: +-- Use default capabiltites during ignition cycle stored in HMI_capabilities.json file +-- Process RC-related RPCs +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') +local hmi_values = require('user_modules/hmi_values') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local disabledModule = "RADIO" +local enabledModule = "SEAT" + +--[[ Local Functions ]] +local function getHMIParams() + local params = hmi_values.getDefaultHMITable() + params.RC.IsReady = nil + params.RC.GetCapabilities = nil + return params +end + +local function rpcUnsupportedResource(pModuleType, pRPC) + local pAppId = 1 + local mobSession = commonRC.getMobileSession(pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) +end + +local function rpcSuccess(pModuleType, pRPC) + local pAppId = 1 + local mobSession = commonRC.getMobileSession(pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) + :Do(function(_, data) + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) + end) + mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { disabledModule } }) +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test - Module enabled: " .. enabledModule .. ", disabled: " .. disabledModule) +runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, + { disabledModule, "GetInteriorVehicleData" }) +runner.Step("GetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, + { disabledModule, "SetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "SetInteriorVehicleData" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) +runner.Step("Restore HMI capabilities file", commonRC.restoreHMICapabilities) diff --git a/test_scripts/RC/SEAT/Capabilities/006_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua b/test_scripts/RC/SEAT/Capabilities/006_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua new file mode 100644 index 0000000000..b145a37d7f --- /dev/null +++ b/test_scripts/RC/SEAT/Capabilities/006_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua @@ -0,0 +1,74 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: +-- In case: +-- HMI respond with available = true on RC.IsReady request from SDL +-- and HMI didn't respond on capabilities request from SDL +-- +-- SDL must: +-- Use default capabiltites during ignition cycle stored in HMI_capabilities.json file +-- Process RC-related RPCs +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') +local hmi_values = require('user_modules/hmi_values') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local disabledModule = "CLIMATE" +local enabledModule = "SEAT" + +--[[ Local Functions ]] +local function getHMIParams() + local params = hmi_values.getDefaultHMITable() + params.RC.IsReady.params.available = true + params.RC.GetCapabilities = nil + return params +end + +local function rpcUnsupportedResource(pModuleType, pRPC) + local pAppId = 1 + local mobSession = commonRC.getMobileSession(pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) +end + +local function rpcSuccess(pModuleType, pRPC) + local pAppId = 1 + local mobSession = commonRC.getMobileSession(pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) + :Do(function(_, data) + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) + end) + mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { disabledModule } }) +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test - Module enabled: " .. enabledModule .. ", disabled: " .. disabledModule) +runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, + { disabledModule, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, + { disabledModule, "SetInteriorVehicleData" }) +runner.Step("GetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "SetInteriorVehicleData" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) +runner.Step("Restore HMI capabilities file", commonRC.restoreHMICapabilities) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/001_Success_flow.lua new file mode 100644 index 0000000000..183e0e3935 --- /dev/null +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/001_Success_flow.lua @@ -0,0 +1,32 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: TRS: GetInteriorVehicleData, #3 +-- In case: +-- 1) RC app sends valid and allowed by policies GetInteriorvehicleData_request +-- 2) and SDL received GetInteriorVehicledata_response with successful result code and current module data from HMI +-- SDL must: +-- 1) transfer GetInteriorVehicleData_response with provided from HMI current module data for allowed module and control items +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData SEAT", commonRC.subscribeToModule, { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/002_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/002_Transfering_of_HMI_resultCode_to_mobile.lua new file mode 100644 index 0000000000..d35bcaef74 --- /dev/null +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/002_Transfering_of_HMI_resultCode_to_mobile.lua @@ -0,0 +1,89 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) RC app sends valid and allowed by policies GetInteriorvehicleData request +-- 2) and SDL received GetInteriorVehicledata response with successful result code and current module data from HMI +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with provided from HMI current module data for allowed module and control items +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local success_codes = { "WARNINGS" } +local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } + +--[[ Local Functions ]] +local function stepSuccessfull(pModuleType, pResultCode) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + commonRC.getHMIconnection():SendResponse(data.id, data.method, pResultCode, { + moduleData = commonRC.getModuleControlData(pModuleType) + -- isSubscribed = true + }) + end) + + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = pResultCode, + isSubscribed = false, + moduleData = commonRC.getModuleControlData(pModuleType) + }) +end + +local function stepUnsuccessfull(pModuleType, pResultCode) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + commonRC.getHMIconnection():SendError(data.id, data.method, pResultCode, "Error error") + end) + + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = pResultCode}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") + +for _, code in pairs(success_codes) do + runner.Step("GetInteriorVehicleData SEAT with " .. code .. " resultCode", stepSuccessfull, { "SEAT", code }) +end + +for _, code in pairs(error_codes) do + runner.Step("GetInteriorVehicleData SEAT with " .. code .. " resultCode", stepUnsuccessfull, { "SEAT", code }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/003_RPC_parameters_values.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/003_RPC_parameters_values.lua new file mode 100644 index 0000000000..b8e3d4b97e --- /dev/null +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/003_RPC_parameters_values.lua @@ -0,0 +1,98 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with invalid parameters +-- - invalid parameter name +-- - invalid parameter type +-- - missing mandatory parameter +-- SDL must: +-- 1) Do not transfer request to HMI +-- 2) Respond with success:false, "INVALID_DATA" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function invalidParamName(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { + modduleType = pModuleType, -- invalid name of parameter + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}):Times(0) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function invalidParamType(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = 17 -- invalid type of parameter + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}):Times(0) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function missingMandatoryParam() + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { + -- moduleType = "CLIMATE", -- mandatory parameter absent + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}):Times(0) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function fakeParam(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + fakeParam = "value", + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = true + }) + end) + + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + isSubscribed = true, + moduleData = commonRC.getModuleControlData(pModuleType) + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") + +runner.Step("GetInteriorVehicleData SEAT invalid name of parameter", invalidParamName, { "SEAT" }) +runner.Step("GetInteriorVehicleData SEAT invalid type of parameter", invalidParamType, { "SEAT" }) +runner.Step("GetInteriorVehicleData SEAT fake parameter", fakeParam, { "SEAT" }) +runner.Step("GetInteriorVehicleData mandatory parameter absent", missingMandatoryParam) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/004_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/004_GENERIC_ERROR_in_case_HMI_did_not_respond.lua new file mode 100644 index 0000000000..ea93f90f43 --- /dev/null +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/004_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -0,0 +1,52 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with valid parameters +-- 2) and HMI didn't respond within default timeout +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function getDataForModule(pModuleType) + local mobSession = commonRC.getMobileSession() + local cid = mobSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, _) + -- HMI does not respond + end) + + mobSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData SEAT HMI does not respond", getDataForModule, { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/005_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/005_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua new file mode 100644 index 0000000000..41ad6fd4a9 --- /dev/null +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/005_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -0,0 +1,85 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with valid parameters +-- 2) and HMI responds with invalid data: +-- - invalid type of parameter +-- - missing mandatory parameter +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function invalidParamType(pModuleType) + local mobSession = commonRC.getMobileSession() + local cid = mobSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = "yes" -- invalid type of parameter + }) + end) + + mobSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +local function missingMandatoryParam(pModuleType) + local mobSession = commonRC.getMobileSession() + local cid = mobSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + + :Do(function(_, data) + local moduleData = commonRC.getModuleControlData(pModuleType) + moduleData.moduleType = nil -- missing mandatory parameter + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = moduleData, + isSubscribed = true + }) + end) + + mobSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData SEAT Invalid response from HMI-Invalid type of parameter", invalidParamType, + { "SEAT" }) +runner.Step("GetInteriorVehicleData SEAT Invalid response from HMI-Missing mandatory parameter", missingMandatoryParam, + { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua new file mode 100644 index 0000000000..69e486cb04 --- /dev/null +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -0,0 +1,63 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has an empty array +-- 2) and RC app sends GetInteriorVehicleData request with valid parameters +-- SDL must: +-- 1) Allow this RPC to be processed +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') +local json = require('modules/json') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function getDataForModule(pModuleType) + local mobSession = commonRC.getMobileSession() + local cid = mobSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = true + }) + end) + + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + isSubscribed = true, + moduleData = commonRC.getModuleControlData(pModuleType) + }) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData SEAT", getDataForModule, { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua new file mode 100644 index 0000000000..75d229e2ca --- /dev/null +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -0,0 +1,50 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: +-- In case: +-- 1) "moduleType" does not exist in app's assigned policies +-- 2) and RC app sends GetInteriorVehicleData request with valid parameters +-- SDL must: +-- 1) Disallow this RPC to be processed (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function getDataForModule(module_type) + local mobSession = commonRC.getMobileSession() + local cid = mobSession:SendRPC("GetInteriorVehicleData", { + moduleType = module_type, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + mobSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData SEAT", getDataForModule, { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua new file mode 100644 index 0000000000..a0e93168d2 --- /dev/null +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -0,0 +1,66 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: TRS: GetInteriorVehicleData, #10 +-- In case: +-- 1) RC app is subscribed to "" +-- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response without "isSubscribed" parameter, "resultCode: SUCCESS" from HMI +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS", "success:true" to the related app +-- 2) Re-send OnInteriorVehicleData notification to the app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function unSubscriptionToModule(pModuleType) + local mobSession = commonRC.getMobileSession() + local cid = mobSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = false + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleType = pModuleType, + subscribe = false + }) + :Do(function(_, data) + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + -- no isSubscribed parameter + }) + end) + + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = true + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) +runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) +runner.Step("Send notification OnInteriorVehicleData SEAT. App is subscribed", commonRC.isSubscribed, + { "SEAT" }) + +runner.Title("Test") +runner.Step("Subscribe app to SEAT", unSubscriptionToModule, { "SEAT" }) +runner.Step("Send notification OnInteriorVehicleData SEAT. App still subscribed", commonRC.isSubscribed, + { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua new file mode 100644 index 0000000000..5166f69a06 --- /dev/null +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -0,0 +1,51 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with valid parameters +-- 2) and SDL gets response (resultCode: READ_ONLY) from HMI +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function getDataForModule(module_type) + local mobSession = commonRC.getMobileSession() + local cid = mobSession:SendRPC("GetInteriorVehicleData", { + moduleType = module_type, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleType = module_type, + subscribe = true + }) + :Do(function(_, data) + commonRC.getHMIconnection():SendError(data.id, data.method, "READ_ONLY", "Info message") + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Info message" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData SEAT", getDataForModule, { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua new file mode 100644 index 0000000000..57bcc124ba --- /dev/null +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -0,0 +1,75 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: TRS: GetInteriorVehicleData, #1 +-- In case: +-- 1) RC app sends valid and allowed by policies GetInteriorvehicleData_request with "subscribe" parameter +-- 2) and SDL received GetInteriorVehicledata_response with resultCode: <"any_not_erroneous_result"> +-- 3) and without "isSubscribed" parameter from HMI +-- SDL must: +-- 1) transfer GetInteriorVehicleData_response with resultCode:<"any_not_erroneous_result"> +-- and with added isSubscribed: <"current_subscription_status"> to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe) + local mobSession = commonRC.getMobileSession() + local cid = mobSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = pSubscribe + }) + + local pSubscribeHMI = pSubscribe + if isSubscriptionActive == pSubscribe then + pSubscribeHMI = nil + end + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleType = pModuleType + }) + :Do(function(_, data) + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + -- no isSubscribed parameter + }) + end) + :ValidIf(function(_, data) + if data.params.subscribe == pSubscribeHMI then + return true + end + return false, 'Parameter "subscribe" is transfered to HMI with value: ' .. tostring(data.params.subscribe) + end) + + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + isSubscribed = isSubscriptionActive, -- return current value of subscription + moduleData = commonRC.getModuleControlData(pModuleType) + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData SEAT NoSubscription_subscribe", getDataForModule, { "SEAT", false, true }) +runner.Step("GetInteriorVehicleData SEAT NoSubscription_unsubscribe", getDataForModule, { "SEAT", false, false }) + +runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) +runner.Step("GetInteriorVehicleData SEAT ActiveSubscription_subscribe", getDataForModule, { "SEAT", true, true }) +runner.Step("GetInteriorVehicleData SEAT ActiveSubscription_unsubscribe", getDataForModule, { "SEAT", true, false }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua new file mode 100644 index 0000000000..722ce863fd --- /dev/null +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -0,0 +1,72 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: TRS: GetInteriorVehicleData, #2 +-- In case: +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData_request without "subscribe" parameter +-- 2) and SDL gets GetInteriorVehicleData_response with resultCode: <"any-result"> +-- 3) and with "isSubscribed" parameter from HMI +-- SDL must: +-- 1) transfer GetInteriorVehicleData_response with resultCode: <"any-result"> +-- and without "isSubscribed" param to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, isSubscriptionActive) + local mobSession = commonRC.getMobileSession() + local cid = mobSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType + -- no subscribe parameter + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleType = pModuleType + }) + :Do(function(_, data) + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = isSubscriptionActive -- return current value of subscription + }) + end) + :ValidIf(function(_, data) -- no subscribe parameter + if data.params.subscribe == nil then + return true + end + return false, 'Parameter "subscribe" is transfered with to HMI value: ' .. tostring(data.params.subscribe) + end) + + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = commonRC.getModuleControlData(pModuleType) + }) + :ValidIf(function(_, data) -- no isSubscribed parameter + if data.payload.isSubscribed == nil then + return true + end + return false, 'Parameter "isSubscribed" is transfered to App with value: ' .. tostring(data.payload.isSubscribed) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData SEAT NoSubscription", getDataForModule, { "SEAT", false }) +runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) +runner.Step("GetInteriorVehicleData SEAT ActiveSubscription_subscribe", getDataForModule, { "SEAT", true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua new file mode 100644 index 0000000000..9d801cac0a --- /dev/null +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua @@ -0,0 +1,89 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: TRS: GetInteriorVehicleData, #12 +-- In case: +-- 1) RC app is subscribed to "" +-- 2) and sends valid and allowed-by-policies GetInteriorVehicleData request +-- 3) with "subscribe:true" parameter for the same "" +-- SDL must: +-- 1) Forward request to HMI without "subscribe:true" parameter +-- 2) not change the subscription status of the app +-- 3) transfer HMI's response with added "isSubscribed: true" to the app +-- +-- Description: TRS: GetInteriorVehicleData, #13 +-- In case: +-- 1) RC app is not subscribed to "" +-- 2) and sends valid and allowed-by-policies GetInteriorVehicleData request +-- 3) with "subscribe:false" parameter for the same "" +-- SDL must: +-- 1) Forward request to HMI without "subscribe:false" parameter +-- 2) not change the subscription status of the app +-- 3) transfer HMI's response with added "isSubscribed: false" to the app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function subscriptionToModule(pModuleType, pSubscribe) + local mobSession = commonRC.getMobileSession() + local cid = mobSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = pSubscribe + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleType = pModuleType + }) + :Do(function(_, data) + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = pSubscribe + }) + end) + :ValidIf(function(_, data) + if data.params.subscribe == nil then + return true + end + return false, 'Parameter "subscribe" is transfered to HMI with value: ' .. tostring(data.params.subscribe) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = pSubscribe + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +-- app has not subscribed yet +runner.Step("Unsubscribe app to SEAT", subscriptionToModule, { "SEAT", false }) +runner.Step("Send notification OnInteriorVehicleData SEAT. App is not subscribed", commonRC.isUnsubscribed, { "SEAT" }) +-- subscribe to module 1st time +runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) +runner.Step("Send notification OnInteriorVehicleData SEAT. App is subscribed", commonRC.isSubscribed, { "SEAT" }) +-- subscribe to module 2nd time +runner.Step("Subscribe 2nd time app to SEAT", subscriptionToModule, { "SEAT", true }) +runner.Step("Send notification OnInteriorVehicleData SEAT. App is subscribed", commonRC.isSubscribed, { "SEAT" }) +-- unsubscribe to module 1st time +runner.Step("Unsubscribe app to SEAT", commonRC.unSubscribeToModule, { "SEAT" }) +runner.Step("Send notification OnInteriorVehicleData SEAT. App is not subscribed", commonRC.isUnsubscribed, { "SEAT" }) +-- unsubscribe to module 2nd time +runner.Step("Unsubscribe 2nd time app to SEAT", subscriptionToModule, { "SEAT", false }) +runner.Step("Send notification OnInteriorVehicleData SEAT. App is not subscribed", commonRC.isUnsubscribed, { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/OnInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/SEAT/OnInteriorVehicleData/001_Success_flow.lua new file mode 100644 index 0000000000..ffb23dbeb5 --- /dev/null +++ b/test_scripts/RC/SEAT/OnInteriorVehicleData/001_Success_flow.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: +-- In case: +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter +-- 2) and SDL received GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS" from HMI +-- 3) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Internally subscribe this application for requested +-- 2) Transfer GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS", "success:true" to the related app +-- 3) Re-send OnInteriorVehicleData notification to the related app +-- +-- Description: +-- In case: +-- 1) RC app is subscribed to "" +-- 2) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS" from HMI +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Internally un-subscribe this application for requested +-- 2) Transfer GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS", "success:true" to the related app +-- 3) Does not re-send OnInteriorVehicleData notification to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) +runner.Step("Send notification OnInteriorVehicleData SEAT. App is subscribed", commonRC.isSubscribed, { "SEAT" }) +runner.Step("Unsubscribe app from SEAT", commonRC.unSubscribeToModule, { "SEAT" }) +runner.Step("Send notification OnInteriorVehicleData SEAT. App is not subscribed", commonRC.isUnsubscribed, { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua new file mode 100644 index 0000000000..947163d432 --- /dev/null +++ b/test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: +-- In case: +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter +-- 2) and SDL received GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS" from HMI +-- 3) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS", "success:true" to the related app +-- 2) Does not re-send OnInteriorVehicleData notification to the app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function subscriptionToModule(pModuleType) + local mobSession = commonRC.getMobileSession() + local cid = mobSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = false -- not subscribe + }) + end) + + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = false + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("Subscribe app to SEAT", subscriptionToModule, { "SEAT" }) +runner.Step("Send notification OnInteriorVehicleData SEAT. App is not subscribed", commonRC.isUnsubscribed, { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/OnInteriorVehicleData/003_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/SEAT/OnInteriorVehicleData/003_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua new file mode 100644 index 0000000000..bcfecc4b26 --- /dev/null +++ b/test_scripts/RC/SEAT/OnInteriorVehicleData/003_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -0,0 +1,64 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: +-- In case: +-- 1) RC app is subscribed to "" +-- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response without "isSubscribed" parameter, "resultCode: SUCCESS" from HMI +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS", "success:true" to the related app +-- 2) Re-send OnInteriorVehicleData notification to the app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function unSubscriptionToModule(pModuleType) + local mobileSession = commonRC.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = false + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleType = pModuleType, + subscribe = false + }) + :Do(function(_, data) + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), + -- no isSubscribed parameter + }) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = true + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) +runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) +runner.Step("Send notification OnInteriorVehicleData SEAT. App is subscribed", commonRC.isSubscribed, { "SEAT" }) + +runner.Title("Test") +runner.Step("Subscribe app to SEAT", unSubscriptionToModule, { "SEAT" }) +runner.Step("Send notification OnInteriorVehicleData SEAT. App still subscribed", commonRC.isSubscribed, { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Seat.lua b/test_scripts/RC/SEAT/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Seat.lua new file mode 100644 index 0000000000..96faab8837 --- /dev/null +++ b/test_scripts/RC/SEAT/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Seat.lua @@ -0,0 +1,35 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item +-- +-- Description: +-- In case: +-- 1) RC app is subscribed to one of the RC module +-- 2) and then SDL received OnInteriorVehicleData notification for another module +-- SDL must: +-- 1) Does not re-send OnInteriorVehicleData notification to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") + +runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) +runner.Step("Send notification OnInteriorVehicleData SEAT. App is subscribed", commonRC.isSubscribed, { "SEAT" }) +runner.Step("Send notification OnInteriorVehicleData RADIO. App is not subscribed", commonRC.isUnsubscribed, { "RADIO" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/OnInteriorVehicleData/005_Existence_of_OnIVD_for_module_Seat_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Climate.lua b/test_scripts/RC/SEAT/OnInteriorVehicleData/005_Existence_of_OnIVD_for_module_Seat_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Climate.lua new file mode 100644 index 0000000000..dc51ff6f36 --- /dev/null +++ b/test_scripts/RC/SEAT/OnInteriorVehicleData/005_Existence_of_OnIVD_for_module_Seat_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Climate.lua @@ -0,0 +1,40 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item +-- +-- Description: +-- In case: +-- 1) RC app is subscribed to a few RC modules +-- 2) and then RC app is unsubscribed to one of the module +-- 3) and then SDL received OnInteriorVehicleData notification for another module +-- SDL must: +-- 1) Does not re-send OnInteriorVehicleData notification to the related app for unsubscribed module +-- 2) Re-send OnInteriorVehicleData notification to the related app for subscribed module +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) +runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) +runner.Step("Send notification OnInteriorVehicleData SEAT. App is subscribed", commonRC.isSubscribed, { "SEAT" }) +runner.Step("Subscribe app to CLIMATE", commonRC.subscribeToModule, { "CLIMATE" }) +runner.Step("Send notification OnInteriorVehicleData CLIMATE. App is subscribed", commonRC.isSubscribed, { "CLIMATE" }) + +runner.Title("Test") +runner.Step("Unsubscribe app from CLIMATE", commonRC.unSubscribeToModule, { "CLIMATE" }) +runner.Step("Send notification OnInteriorVehicleData CLIMATE. App is unsubscribed", commonRC.isUnsubscribed, { "CLIMATE" }) +runner.Step("Send notification OnInteriorVehicleData SEAT. App is still subscribed", commonRC.isSubscribed, { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/OnInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/SEAT/OnInteriorVehicleData/006_RPC_parameters_values.lua new file mode 100644 index 0000000000..08ee3fb339 --- /dev/null +++ b/test_scripts/RC/SEAT/OnInteriorVehicleData/006_RPC_parameters_values.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: +-- In case: +-- 1) RC app is subscribed to a RC module +-- 2) and then SDL received OnInteriorVehicleData notification for this module with invalid data +-- - invalid parameter name +-- - invalid parameter type +-- - missing mandatory parameter +-- SDL must: +-- 1) Does not re-send OnInteriorVehicleData notification to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function invalidParamName(pModuleType) + commonRC.getHMIconnection():SendNotification("RC.OnInteriorVehicleData", { + modduleData = commonRC.getAnotherModuleControlData(pModuleType) -- invalid name of parameter + }) + + commonRC.getMobileSession():ExpectNotification("OnInteriorVehicleData"):Times(0) +end + +local function invalidParamType(pModuleType) + local moduleData = commonRC.getAnotherModuleControlData(pModuleType) + moduleData.moduleType = {} -- invalid type of parameter + + commonRC.getHMIconnection():SendNotification("RC.OnInteriorVehicleData", { + moduleData = moduleData + }) + + commonRC.getMobileSession():ExpectNotification("OnInteriorVehicleData"):Times(0) +end + +local function missingMandatoryParam(pModuleType) + local moduleData = commonRC.getAnotherModuleControlData(pModuleType) + moduleData.moduleType = nil -- mandatory parameter missing + + commonRC.getHMIconnection():SendNotification("RC.OnInteriorVehicleData", { + moduleData = moduleData + }) + + commonRC.getMobileSession():ExpectNotification("OnInteriorVehicleData"):Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) +runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) +runner.Step("Send notification OnInteriorVehicleData SEAT. App is subscribed", commonRC.isSubscribed, { "SEAT" }) + +runner.Title("Test") +runner.Step("OnInteriorVehicleData SEAT invalid name of parameter", invalidParamName, { "SEAT" }) +runner.Step("OnInteriorVehicleData SEAT invalid type of parameter", invalidParamType, { "SEAT" }) +runner.Step("OnInteriorVehicleData SEAT mandatory parameter missing", missingMandatoryParam, { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/001_Success_flow.lua new file mode 100644 index 0000000000..e1465f2d09 --- /dev/null +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/001_Success_flow.lua @@ -0,0 +1,53 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) and sends valid SetInteriorVehicleData RPC with valid parameters +-- SDL must: +-- 1) Transfer this request to HMI +-- 2) Respond with received from HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local mobileSession = commonRC.getMobileSession() + local cid = mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, data) + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData SEAT", setVehicleData, { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_RADIO.lua new file mode 100644 index 0000000000..1d51794776 --- /dev/null +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_RADIO.lua @@ -0,0 +1,47 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received SetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local mobileSession = commonRC.getMobileSession() + local cid = mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) + mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData SEAT", setVehicleData, { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/003_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/003_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua new file mode 100644 index 0000000000..9ee3e1ca6f --- /dev/null +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/003_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -0,0 +1,51 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item +-- +-- Description: +-- In case: +-- 1) Non remote-control application is registered on SDL +-- 2) and SDL received SetInteriorVehicleData request from this App +-- SDL must: +-- 1) Disallow remote-control RPCs for this app (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local mobileSession = commonRC.getMobileSession() + local cid = mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) + mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function ptu_update_func(tbl) + local appId = config.application1.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData SEAT", setVehicleData, { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/004_RPC_parameters_values.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/004_RPC_parameters_values.lua new file mode 100644 index 0000000000..9167d0e4b1 --- /dev/null +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/004_RPC_parameters_values.lua @@ -0,0 +1,92 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item +-- +-- Description: +-- In case: +-- 1) RC app sends SetInteriorVehicleData request with invalid parameters +-- - invalid parameter name +-- - invalid parameter type +-- - missing mandatory parameter +-- SDL must: +-- 1) Do not transfer request to HMI +-- 2) Respond with success:false, "INVALID_DATA" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function invalidParamName(pModuleType) + local mobileSession = commonRC.getMobileSession() + local cid = mobileSession:SendRPC("SetInteriorVehicleData", { + moduleDData = commonRC.getSettableModuleControlData(pModuleType) -- invalid name of parameter + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", {}):Times(0) + mobileSession:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function invalidParamType(pModuleType) + local mobileSession = commonRC.getMobileSession() + local moduleData = commonRC.getSettableModuleControlData(pModuleType) + moduleData.moduleType = {} -- invalid type of parameter + local cid = mobileSession:SendRPC("SetInteriorVehicleData", { + modduleData = moduleData + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", {}):Times(0) + mobileSession:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function missingMandatoryParam(pModuleType) + local mobileSession = commonRC.getMobileSession() + local moduleData = commonRC.getSettableModuleControlData(pModuleType) + moduleData.moduleType = nil -- mandatory parameter missing + local cid = mobileSession:SendRPC("SetInteriorVehicleData", { + modduleData = moduleData + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", {}):Times(0) + mobileSession:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function fakeParam(pModuleType) + local mobileSession = commonRC.getMobileSession() + local cid = mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType), + fakeParam = false + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, data) + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + end) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData SEAT invalid name of parameter", invalidParamName, { "SEAT" }) +runner.Step("SetInteriorVehicleData SEAT invalid type of parameter", invalidParamType, { "SEAT" }) +runner.Step("SetInteriorVehicleData SEAT fake parameter", fakeParam, { "SEAT" }) +runner.Step("SetInteriorVehicleData SEAT missing mandatory parameter", missingMandatoryParam, { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/005_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/005_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua new file mode 100644 index 0000000000..17076cb644 --- /dev/null +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/005_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -0,0 +1,47 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item +-- +-- Description: +-- In case: +-- 1) "moduleType" does not exist in app's assigned policies +-- 2) and RC app sends SetInteriorVehicleData request with valid parameters +-- SDL must: +-- 1) Disallow this RPC to be processed (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local mobileSession = commonRC.getMobileSession() + local cid = mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) + mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData SEAT", setVehicleData, { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/006_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/006_GENERIC_ERROR_in_case_HMI_did_not_respond.lua new file mode 100644 index 0000000000..5c0a498356 --- /dev/null +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/006_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -0,0 +1,53 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item +-- +-- Description: +-- In case: +-- 1) RC app sends SetInteriorVehicleData request with valid parameters +-- 2) and HMI didn't respond within default timeout +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local mobileSession = commonRC.getMobileSession() + local cid = mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, _) + -- HMI does not respond + end) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR"}) + commonTestCases:DelayedExp(11000) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") + + runner.Step("SetInteriorVehicleData SEAT HMI does not respond", setVehicleData, { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua new file mode 100644 index 0000000000..e562c7a511 --- /dev/null +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -0,0 +1,79 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item +-- +-- Description: +-- In case: +-- 1) RC app sends SetInteriorVehicleData request with valid parameters +-- 2) and HMI response is invalid +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function invalidParamType(pModuleType) + local mobileSession = commonRC.getMobileSession() + local cid = mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, data) + local modData = commonRC.getSettableModuleControlData(pModuleType) + modData.moduleType = "MODULE" -- invalid value of parameter + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = modData, + isSubscribed = "yes" -- fake parameter + }) + end) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +local function missingMandatoryParam(pModuleType) + local mobileSession = commonRC.getMobileSession() + local cid = mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, data) + local moduleData = commonRC.getModuleControlData(pModuleType) + moduleData.moduleType = nil -- missing mandatory parameter + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = moduleData + }) + end) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData SEAT Invalid response from HMI-Invalid type of parameter", invalidParamType, + { "SEAT" }) +runner.Step("SetInteriorVehicleData SEAT Invalid response from HMI-Missing mandatory parameter", missingMandatoryParam, + { "SEAT" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/008_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/008_Transfering_of_HMI_resultCode_to_mobile.lua new file mode 100644 index 0000000000..a12f61daa7 --- /dev/null +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/008_Transfering_of_HMI_resultCode_to_mobile.lua @@ -0,0 +1,81 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0105-remote-control-seat.md +-- User story: +-- Use case: +-- Item: +-- +-- Description: +-- In case: +-- 1) RC app sends valid and allowed by policies SetInteriorvehicleData request +-- 2) and SDL received SetInteriorVehicleData response with successful result code and current module data from HMI +-- SDL must: +-- 1) Transfer SetInteriorVehicleData response with provided from HMI current module data +-- for allowed module and control items +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/SEAT/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local success_codes = { "WARNINGS" } +local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } + +--[[ Local Functions ]] +local function stepSuccessfull(pModuleType, pResultCode) + local mobileSession = commonRC.getMobileSession() + local cid = mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, data) + commonRC.getHMIconnection():SendResponse(data.id, data.method, pResultCode, { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + end) + + mobileSession:ExpectResponse(cid, + { success = true, resultCode = pResultCode, moduleData = commonRC.getSettableModuleControlData(pModuleType) }) +end + +local function stepUnsuccessfull(pModuleType, pResultCode) + local mobileSession = commonRC.getMobileSession() + local cid = mobileSession:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, data) + commonRC.getHMIconnection():SendError(data.id, data.method, pResultCode, "Error error") + end) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = pResultCode }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +for _, code in pairs(success_codes) do + runner.Step("SetInteriorVehicleData with SEAT resultCode", stepSuccessfull, { "SEAT", code }) +end + +for _, code in pairs(error_codes) do + runner.Step("SetInteriorVehicleData with SEAT resultCode", stepUnsuccessfull, { "SEAT", code }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/commonRC.lua b/test_scripts/RC/SEAT/commonRC.lua new file mode 100644 index 0000000000..91d96be2d6 --- /dev/null +++ b/test_scripts/RC/SEAT/commonRC.lua @@ -0,0 +1,381 @@ +--------------------------------------------------------------------------------------------------- +-- RC common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.mobileHost = "127.0.0.1" +config.defaultProtocolVersion = 2 +config.ValidateSchema = false +config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } + +--[[ Required Shared libraries ]] +local initialCommon = require('test_scripts/RC/commonRC') +local test = require("user_modules/dummy_connecttest") +--[[ Local Variables ]] +local commonRC = {} + +commonRC.timeout = 2000 +commonRC.minTimeout = 500 +commonRC.DEFAULT = initialCommon.DEFAULT + +function initialCommon.getRCAppConfig() + return { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + moduleType = { "RADIO", "CLIMATE", "SEAT" }, + groups = { "Base-4", "RemoteControl" }, + AppHMIType = { "REMOTE_CONTROL" } + } +end + +function commonRC.getMobileSession(pAppId) + if not pAppId then pAppId = 1 end + return test["mobileSession" .. pAppId] +end + +function commonRC.getHMIconnection() + return test.hmiConnection +end + +local origGetModuleControlData = initialCommon.getModuleControlData +function initialCommon.getModuleControlData(module_type) + local out = { } + if module_type == "SEAT" then + out.moduleType = module_type + out.seatControlData = { + id = "DRIVER", + heatingEnabled = true, + coolingEnabled = true, + heatingLevel = 50, + coolingLevel = 50, + horizontalPosition = 50, + verticalPosition = 50, + frontVerticalPosition = 50, + backVerticalPosition = 50, + backTiltAngle = 50, + headSupportHorizontalPosition = 50, + headSupportVerticalPosition = 50, + massageEnabled = true, + massageMode = { + { + massageZone = "LUMBAR", + massageMode = "HIGH" + }, + { + massageZone = "SEAT_CUSHION", + massageMode = "LOW" + } + }, + massageCushionFirmness = { + { + cushion = "TOP_LUMBAR", + firmness = 30 + }, + { + cushion = "BACK_BOLSTERS", + firmness = 60 + } + }, + memory = { + id = 1, + label = "Label value", + action = "SAVE" + } + } + else + out = origGetModuleControlData(module_type) + end + return out +end + +function commonRC.getModuleControlData(module_type) + return initialCommon.getModuleControlData(module_type) +end + +local origGetAnotherModuleControlData = initialCommon.getAnotherModuleControlData +function commonRC.getAnotherModuleControlData(module_type) + local out = { } + if module_type == "SEAT" then + out.moduleType = module_type + out.seatControlData ={ + id = "FRONT_PASSENGER", + heatingEnabled = true, + coolingEnabled = false, + heatingLevel = 75, + coolingLevel = 0, + horizontalPosition = 75, + verticalPosition = 75, + frontVerticalPosition = 75, + backVerticalPosition = 75, + backTiltAngle = 75, + headSupportHorizontalPosition = 75, + headSupportVerticalPosition = 75, + massageEnabled = true, + massageMode = { + { + massageZone = "LUMBAR", + massageMode = "OFF" + }, + { + massageZone = "SEAT_CUSHION", + massageMode = "HIGH" + } + }, + massageCushionFirmness = { + { + cushion = "MIDDLE_LUMBAR", + firmness = 65 + }, + { + cushion = "SEAT_BOLSTERS", + firmness = 30 + } + }, + memory = { + id = 2, + label = "Another label value", + action = "RESTORE" + } + } + else + out = origGetAnotherModuleControlData(module_type) + end + return out +end + +local origGetModuleParams = initialCommon.getModuleParams +function initialCommon.getModuleParams(pModuleData) + if pModuleData.moduleType == "SEAT" then + if not pModuleData.seatControlData then + pModuleData.seatControlData = { } + end + return pModuleData.seatControlData + end + return origGetModuleParams(pModuleData) +end + +function commonRC.getModuleParams(pModuleData) + return initialCommon.getModuleParams(pModuleData) +end + +function commonRC.buildHmiRcCapabilities(pClimateCapabilities, pRadioCapabilities, pSeatCapabilities, pButtonCapabilities) + local hmiParams = initialCommon.buildHmiRcCapabilities(pClimateCapabilities, pRadioCapabilities, pButtonCapabilities) + local capParams = hmiParams.RC.GetCapabilities.params.remoteControlCapability + + if pSeatCapabilities then + if pSeatCapabilities ~= commonRC.DEFAULT then + capParams.seatControlCapabilities = pSeatCapabilities + end + else + capParams.seatControlCapabilities = nil + end + + return hmiParams +end + +function commonRC.getReadOnlyParamsByModule(pModuleType) + return initialCommon.getReadOnlyParamsByModule(pModuleType) +end + +function commonRC.getSettableModuleControlData(pModuleType) + return initialCommon.getSettableModuleControlData(pModuleType) +end + +function commonRC.preconditions() + initialCommon.preconditions() +end + +function commonRC.start(pHMIParams) + initialCommon.start(pHMIParams, test) +end + +function commonRC.rai_ptu(ptu_update_func) + initialCommon.rai_ptu(ptu_update_func, test) +end + +function commonRC.rai_ptu_n(id, ptu_update_func) + initialCommon.rai_ptu_n(id, ptu_update_func, test) +end + +function commonRC.rai_n(id) + initialCommon.rai_n(id, test) +end + +function commonRC.unregisterApp(pAppId) + initialCommon.unregisterApp(pAppId, test) +end + +function commonRC.activate_app(pAppId) + initialCommon.activate_app(pAppId, test) +end + +function commonRC.postconditions() + initialCommon.postconditions() +end + +function commonRC.subscribeToModule(pModuleType, pAppId) + return initialCommon.subscribeToModule(pModuleType, pAppId, test) +end + +function commonRC.unSubscribeToModule(pModuleType, pAppId) + return initialCommon.unSubscribeToModule(pModuleType, pAppId, test) +end + +function commonRC.isSubscribed(pModuleType, pAppId) + return initialCommon.isSubscribed(pModuleType, pAppId, test) +end + +function commonRC.isUnsubscribed(pModuleType, pAppId) + return initialCommon.isUnsubscribed(pModuleType, pAppId, test) +end + +function commonRC.getHMIAppId(pAppId) + return initialCommon.getHMIAppId(pAppId) +end + +function commonRC.rpcDenied(pModuleType, pAppId, pRPC, pResultCode) + return initialCommon.rpcDenied(pModuleType, pAppId, pRPC, pResultCode, test) +end + +function commonRC.rpcAllowed(pModuleType, pAppId, pRPC) + return initialCommon.rpcAllowed(pModuleType, pAppId, pRPC, test) +end + +function commonRC.backupHMICapabilities() + return initialCommon.backupHMICapabilities() +end + +function commonRC.restoreHMICapabilities() + return initialCommon.restoreHMICapabilities() +end + +function commonRC.updateDefaultCapabilities(pDisabledModuleTypes) + return initialCommon.updateDefaultCapabilities(pDisabledModuleTypes) +end + +-- RC RPCs structure +local rcRPCs = { + GetInteriorVehicleData = { + appEventName = "GetInteriorVehicleData", + hmiEventName = "RC.GetInteriorVehicleData", + requestParams = function(pModuleType, pSubscribe) + return { + moduleType = pModuleType, + subscribe = pSubscribe + } + end, + hmiRequestParams = function(pModuleType, pAppId, pSubscribe) + return { + appID = commonRC.getHMIAppId(pAppId), + moduleType = pModuleType, + subscribe = pSubscribe + } + end, + hmiResponseParams = function(pModuleType, pSubscribe) + return { + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = pSubscribe + } + end, + responseParams = function(success, resultCode, pModuleType, pSubscribe) + return { + success = success, + resultCode = resultCode, + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = pSubscribe + } + end + }, + SetInteriorVehicleData = { + appEventName = "SetInteriorVehicleData", + hmiEventName = "RC.SetInteriorVehicleData", + requestParams = function(pModuleType) + return { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + } + end, + hmiRequestParams = function(pModuleType, pAppId) + return { + appID = commonRC.getHMIAppId(pAppId), + moduleData = commonRC.getSettableModuleControlData(pModuleType) + } + end, + hmiResponseParams = function(pModuleType) + return { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + } + end, + responseParams = function(success, resultCode, pModuleType) + return { + success = success, + resultCode = resultCode, + moduleData = commonRC.getSettableModuleControlData(pModuleType) + } + end + }, + GetInteriorVehicleDataConsent = { + hmiEventName = "RC.GetInteriorVehicleDataConsent", + hmiRequestParams = function(pModuleType, pAppId) + return { + appID = commonRC.getHMIAppId(pAppId), + moduleType = pModuleType + } + end, + hmiResponseParams = function(pAllowed) + return { + allowed = pAllowed + } + end, + }, + OnInteriorVehicleData = { + appEventName = "OnInteriorVehicleData", + hmiEventName = "RC.OnInteriorVehicleData", + hmiResponseParams = function(pModuleType) + return { + moduleData = commonRC.getAnotherModuleControlData(pModuleType) + } + end, + responseParams = function(pModuleType) + return { + moduleData = commonRC.getAnotherModuleControlData(pModuleType) + } + end + }, + OnRemoteControlSettings = { + hmiEventName = "RC.OnRemoteControlSettings", + hmiResponseParams = function(pAllowed, pAccessMode) + return { + allowed = pAllowed, + accessMode = pAccessMode + } + end + } +} + +function commonRC.getAppEventName(pRPC) + return rcRPCs[pRPC].appEventName +end + +function commonRC.getHMIEventName(pRPC) + return rcRPCs[pRPC].hmiEventName +end + +function commonRC.getAppRequestParams(pRPC, ...) + return rcRPCs[pRPC].requestParams(...) +end + +function commonRC.getAppResponseParams(pRPC, ...) + return rcRPCs[pRPC].responseParams(...) +end + +function commonRC.getHMIRequestParams(pRPC, ...) + return rcRPCs[pRPC].hmiRequestParams(...) +end + +function commonRC.getHMIResponseParams(pRPC, ...) + return rcRPCs[pRPC].hmiResponseParams(...) +end + +return commonRC diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 6eca7fd689..e0e8b2863c 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -55,14 +55,14 @@ local function updatePTU(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() end -local function jsonFileToTable(file_name) +function commonRC.jsonFileToTable(file_name) local f = io.open(file_name, "r") local content = f:read("*all") f:close() return json.decode(content) end -local function tableToJsonFile(tbl, file_name) +function commonRC.tableToJsonFile(tbl, file_name) local f = io.open(file_name, "w") f:write(json.encode(tbl)) f:close() @@ -96,7 +96,7 @@ local function ptu(self, ptu_update_func) if ptu_update_func then ptu_update_func(ptu_table) end - tableToJsonFile(ptu_table, ptu_file_name) + commonRC.tableToJsonFile(ptu_table, ptu_file_name) local event = events.Event() event.matches = function(self, e) return self == e end @@ -106,7 +106,7 @@ local function ptu(self, ptu_update_func) for id = 1, getAppsCount() do local mobileSession = commonRC.getMobileSession(self, id) mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) - :Do(function(_, d2) + :DoOnce(function(_, d2) print("App ".. id .. " was used for PTU") RAISE_EVENT(event, event, "PTU event") checkIfPTSIsSentAsBinary(d2.binaryData) @@ -194,7 +194,7 @@ function commonRC.rai_ptu_n(id, ptu_update_func, self) EXPECT_HMICALL("BasicCommunication.PolicyUpdate") :Do(function(_, d2) self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) - ptu_table = jsonFileToTable(d2.params.file) + ptu_table = commonRC.jsonFileToTable(d2.params.file) ptu(self, ptu_update_func) end) end) @@ -746,15 +746,24 @@ end function commonRC.updateDefaultCapabilities(pDisabledModuleTypes) local hmiCapabilitiesFile = commonPreconditions:GetPathToSDL() - .. commonFunctions:read_parameter_from_smart_device_link_ini("HMICapabilities") - local hmiCapTbl = jsonFileToTable(hmiCapabilitiesFile) + .. commonFunctions:read_parameter_from_smart_device_link_ini("HMICapabilities") + local hmiCapTbl = commonRC.jsonFileToTable(hmiCapabilitiesFile) local rcCapTbl = hmiCapTbl.UI.systemCapabilities.remoteControlCapability for _, pDisabledModuleType in pairs(pDisabledModuleTypes) do local buttonId = commonRC.getButtonIdByName(rcCapTbl.buttonCapabilities, commonRC.getButtonNameByModule(pDisabledModuleType)) table.remove(rcCapTbl.buttonCapabilities, buttonId) rcCapTbl[string.lower(pDisabledModuleType) .. "ControlCapabilities"] = nil end - tableToJsonFile(hmiCapTbl, hmiCapabilitiesFile) + commonRC.tableToJsonFile(hmiCapTbl, hmiCapabilitiesFile) end +function commonRC.getHMIAppIds() + return hmiAppIds +end + +function commonRC.deleteHMIAppId(pAppId) + hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = nil +end + + return commonRC diff --git a/test_sets/rc_SEAT.txt b/test_sets/rc_SEAT.txt new file mode 100644 index 0000000000..8f3c3554b6 --- /dev/null +++ b/test_sets/rc_SEAT.txt @@ -0,0 +1,32 @@ +./test_scripts/RC/SEAT/Capabilities/001_SEAT_all_params_SUCCESS.lua +./test_scripts/RC/SEAT/Capabilities/002_SEAT_all_params_UNSUPPORTED_RESOURCE.lua +./test_scripts/RC/SEAT/Capabilities/003_Resend_only_supported_parameters.lua +./test_scripts/RC/SEAT/Capabilities/004_Reject_request_with_both_supported_and_not_supported_parameters.lua +./test_scripts/RC/SEAT/Capabilities/005_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua +./test_scripts/RC/SEAT/Capabilities/006_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/002_Transfering_of_HMI_resultCode_to_mobile.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/003_RPC_parameters_values.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/004_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/005_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/003_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Seat.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/005_Existence_of_OnIVD_for_module_Seat_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Climate.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/006_RPC_parameters_values.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_RADIO.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/003_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/004_RPC_parameters_values.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/005_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/006_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/008_Transfering_of_HMI_resultCode_to_mobile.lua diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index 35eda6d132..163c2ad830 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -363,6 +363,26 @@ function module.getDefaultHMITable() signalChangeThresholdAvailable = true } }, + seatControlCapabilities = { + { + moduleName = "Seat", + heatingEnabledAvailable = true, + coolingEnabledAvailable = true, + heatingLevelAvailable = true, + coolingLevelAvailable = true, + horizontalPositionAvailable = true, + verticalPositionAvailable = true, + frontVerticalPositionAvailable = true, + backVerticalPositionAvailable = true, + backTiltAngleAvailable = true, + headSupportHorizontalPositionAvailable = true, + headSupportVerticalPositionAvailable = true, + massageEnabledAvailable = true, + massageModeAvailable = true, + massageCushionFirmnessAvailable = true, + memoryAvailable = true + } + }, buttonCapabilities = (function() local buttons = { -- climate From 3dfa88b3c624ef485b812f623eaaffdc0869f01d Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 31 May 2018 11:00:02 +0300 Subject: [PATCH 459/681] Update according to review: mistakes with Radio name --- ...request_with_both_supported_and_not_supported_parameters.lua | 2 +- ...by_policy_RADIO.lua => 002_Disallow_flow_by_policy_SEAT.lua} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename test_scripts/RC/SEAT/SetInteriorVehicleData/{002_Disallow_flow_by_policy_RADIO.lua => 002_Disallow_flow_by_policy_SEAT.lua} (100%) diff --git a/test_scripts/RC/SEAT/Capabilities/004_Reject_request_with_both_supported_and_not_supported_parameters.lua b/test_scripts/RC/SEAT/Capabilities/004_Reject_request_with_both_supported_and_not_supported_parameters.lua index f744f9a9d6..c1e250247f 100644 --- a/test_scripts/RC/SEAT/Capabilities/004_Reject_request_with_both_supported_and_not_supported_parameters.lua +++ b/test_scripts/RC/SEAT/Capabilities/004_Reject_request_with_both_supported_and_not_supported_parameters.lua @@ -9,7 +9,7 @@ -- -- Description: -- In case: --- 1) SDL receive several supported Radio parameters in GetCapabilites response and +-- 1) SDL receive several supported Seat parameters in GetCapabilites response and -- 2) App sends RC RPC request with several supported by HMI parameters and some unssuported -- SDL must: -- 1) Reject such request with UNSUPPORTED_RESOURCE result code, success: false diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_SEAT.lua similarity index 100% rename from test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_RADIO.lua rename to test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_SEAT.lua From c5cf89e1be7a264fddbf24e6de607d5857970ac7 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 12 Jun 2018 15:43:04 +0300 Subject: [PATCH 460/681] Updated wrong script name in test set --- test_sets/rc_SEAT.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_sets/rc_SEAT.txt b/test_sets/rc_SEAT.txt index 8f3c3554b6..91c5bf122c 100644 --- a/test_sets/rc_SEAT.txt +++ b/test_sets/rc_SEAT.txt @@ -23,7 +23,7 @@ ./test_scripts/RC/SEAT/OnInteriorVehicleData/005_Existence_of_OnIVD_for_module_Seat_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Climate.lua ./test_scripts/RC/SEAT/OnInteriorVehicleData/006_RPC_parameters_values.lua ./test_scripts/RC/SEAT/SetInteriorVehicleData/001_Success_flow.lua -./test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_RADIO.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_SEAT.lua ./test_scripts/RC/SEAT/SetInteriorVehicleData/003_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua ./test_scripts/RC/SEAT/SetInteriorVehicleData/004_RPC_parameters_values.lua ./test_scripts/RC/SEAT/SetInteriorVehicleData/005_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua From 28474bb2f745f5eaab0e1b0dc62dd3cf97912b45 Mon Sep 17 00:00:00 2001 From: "Ira Lytvynenko (GitHub)" Date: Tue, 22 May 2018 15:03:16 +0300 Subject: [PATCH 461/681] Scripts for OnRCStatus notification --- .../001_notification_by_apps_registration.lua | 27 ++ ..._by_rc_functionality_disallowed_on_hmi.lua | 42 +++ .../003_registration_not_rc_app.lua | 38 +++ ...le_subscription_GetInteriorVehicleData.lua | 40 +++ ...ation_by_module_allocation_ButtonPress.lua | 45 +++ ...dule_allocation_SetInteriorVehicleData.lua | 45 +++ ...iption_GetInteriorVehicleData_two_apps.lua | 43 +++ ...module_allocation_ButtonPress_two_apps.lua | 48 +++ ...cation_SetInteriorVehicleData_two_apps.lua | 48 +++ ...ule_allocation_two_apps_one_app_not_rc.lua | 51 +++ ...011_notification_by_app_unregistration.lua | 58 ++++ ...ification_by_revoking_module_by_policy.lua | 59 ++++ ...by_reallocation_module_by_the_same_app.lua | 46 +++ ...n_by_reallocation_module_by_second_app.lua | 56 ++++ .../015_notification_by_user_exit.lua | 52 +++ ...cation_by_DRIVER_DISTRACTION_VIOLATION.lua | 52 +++ ...ication_by_rejecting_consent_by_driver.lua | 58 ++++ .../018_notification_by_driver_consent.lua | 57 ++++ .../019_notification_by_app_disconnect.lua | 56 ++++ ..._in_case_of_policy_permissions_absence.lua | 70 ++++ ...21_notification_in_case_AUTO_DENY_mode.lua | 63 ++++ .../RC/OnRCStatus/commonOnRCStatus.lua | 308 ++++++++++++++++++ test_scripts/RC/commonRC.lua | 25 +- test_sets/rc_OnRCStatus.txt | 21 ++ user_modules/dummy_connecttest.lua | 5 +- 25 files changed, 1404 insertions(+), 9 deletions(-) create mode 100644 test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua create mode 100644 test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua create mode 100644 test_scripts/RC/OnRCStatus/003_registration_not_rc_app.lua create mode 100644 test_scripts/RC/OnRCStatus/004_notification_by_module_subscription_GetInteriorVehicleData.lua create mode 100644 test_scripts/RC/OnRCStatus/005_notification_by_module_allocation_ButtonPress.lua create mode 100644 test_scripts/RC/OnRCStatus/006_notification_by_module_allocation_SetInteriorVehicleData.lua create mode 100644 test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua create mode 100644 test_scripts/RC/OnRCStatus/008_notification_by_module_allocation_ButtonPress_two_apps.lua create mode 100644 test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua create mode 100644 test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua create mode 100644 test_scripts/RC/OnRCStatus/011_notification_by_app_unregistration.lua create mode 100644 test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua create mode 100644 test_scripts/RC/OnRCStatus/013_notification_by_reallocation_module_by_the_same_app.lua create mode 100644 test_scripts/RC/OnRCStatus/014_notification_by_reallocation_module_by_second_app.lua create mode 100644 test_scripts/RC/OnRCStatus/015_notification_by_user_exit.lua create mode 100644 test_scripts/RC/OnRCStatus/016_notification_by_DRIVER_DISTRACTION_VIOLATION.lua create mode 100644 test_scripts/RC/OnRCStatus/017_notification_by_rejecting_consent_by_driver.lua create mode 100644 test_scripts/RC/OnRCStatus/018_notification_by_driver_consent.lua create mode 100644 test_scripts/RC/OnRCStatus/019_notification_by_app_disconnect.lua create mode 100644 test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua create mode 100644 test_scripts/RC/OnRCStatus/021_notification_in_case_AUTO_DENY_mode.lua create mode 100644 test_scripts/RC/OnRCStatus/commonOnRCStatus.lua create mode 100644 test_sets/rc_OnRCStatus.txt diff --git a/test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua b/test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua new file mode 100644 index 0000000000..5a5c78cbbe --- /dev/null +++ b/test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua @@ -0,0 +1,27 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall send OnRCStatus notifications to all registered mobile applications and the HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("OnRCStatus notification by app registration", common.registerRCApplication, { 1 }) +runner.Step("OnRCStatus notification by registration 2nd app", common.registerRCApplication, { 2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua b/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua new file mode 100644 index 0000000000..5f5aba4d15 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua @@ -0,0 +1,42 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall not send OnRCStatus notifications to all registered mobile applications and the HMI +-- in case RC functionality is disallowed on HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function disableRCFromHMI() + common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) + common.wait(2000) +end + +local function registerAppWithoutRCNotification() + common.rai_n() + common.getMobileSession():ExpectNotification("OnRCStatus") + :Times(0) + EXPECT_HMINOTIFICATION("RC.OnRCStatus") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RC functionality is disallowed from HMI", disableRCFromHMI) + +runner.Title("Test") +runner.Step("Register RC application without OnRCStatus notification", registerAppWithoutRCNotification) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/003_registration_not_rc_app.lua b/test_scripts/RC/OnRCStatus/003_registration_not_rc_app.lua new file mode 100644 index 0000000000..65a63d7824 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/003_registration_not_rc_app.lua @@ -0,0 +1,38 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall not send OnRCStatus notifications to not rc registered app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Functions ]] +local function registerNonRCApp() + common.rai_n() + common.getMobileSession():ExpectNotification("OnRCStatus") + :Times(0) + EXPECT_HMINOTIFICATION("RC.OnRCStatus") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Registration non-RC application", registerNonRCApp) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/004_notification_by_module_subscription_GetInteriorVehicleData.lua b/test_scripts/RC/OnRCStatus/004_notification_by_module_subscription_GetInteriorVehicleData.lua new file mode 100644 index 0000000000..2aa2713033 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/004_notification_by_module_subscription_GetInteriorVehicleData.lua @@ -0,0 +1,40 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall not send OnRCStatus notifications to rc registered app +-- by allocation module via GetInteriorVehicleData +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function subscribeToModuleWOOnRCStatus(pModuleType) + common.subscribeToModule(pModuleType) + common.getMobileSession():ExpectNotification("OnRCStatus") + :Times(0) + EXPECT_HMINOTIFICATION("RC.OnRCStatus") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register RC application", common.registerRCApplication) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, mod in pairs(common.getModules()) do + runner.Step("GetInteriorVehicleData " .. mod, subscribeToModuleWOOnRCStatus, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/005_notification_by_module_allocation_ButtonPress.lua b/test_scripts/RC/OnRCStatus/005_notification_by_module_allocation_ButtonPress.lua new file mode 100644 index 0000000000..2e230f2c9f --- /dev/null +++ b/test_scripts/RC/OnRCStatus/005_notification_by_module_allocation_ButtonPress.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall send OnRCStatus notifications to rc registered app +-- by allocation module via ButtonPress +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local freeModules = common.getAllModules() +local allocatedModules = { + [1] = { } +} + +--[[ Local Functions ]] +local function buttonPress(pModuleType) + local pModuleStatus = common.setModuleStatus(freeModules, allocatedModules, pModuleType) + common.rpcAllowed(pModuleType, 1, "ButtonPress") + common.validateOnRCStatusForApp(1, pModuleStatus) + common.validateOnRCStatusForHMI(1, { pModuleStatus }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register RC application", common.registerRCApplication) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, mod in pairs(common.getModules()) do + runner.Step("ButtonPress " .. mod, buttonPress, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/006_notification_by_module_allocation_SetInteriorVehicleData.lua b/test_scripts/RC/OnRCStatus/006_notification_by_module_allocation_SetInteriorVehicleData.lua new file mode 100644 index 0000000000..71592d1f1d --- /dev/null +++ b/test_scripts/RC/OnRCStatus/006_notification_by_module_allocation_SetInteriorVehicleData.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall send OnRCStatus notifications to rc registered app +-- by allocation module via SetInteriorVehicleData +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local freeModules = common.getAllModules() +local allocatedModules = { + [1] = {} +} + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local pModuleStatus = common.setModuleStatus(freeModules, allocatedModules, pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatus) + common.validateOnRCStatusForHMI(1, { pModuleStatus }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register RC application", common.registerRCApplication) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, mod in pairs(common.getModules()) do + runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua b/test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua new file mode 100644 index 0000000000..e9deb70952 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall not send OnRCStatus notifications to rc registered apps +-- by allocation module via GetInteriorVehicleData +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function subscribeToModuleWOOnRCStatus(pModuleType) + common.subscribeToModule(pModuleType) + common.getMobileSession(1):ExpectNotification("OnRCStatus") + :Times(0) + common.getMobileSession(2):ExpectNotification("OnRCStatus") + :Times(0) + EXPECT_HMINOTIFICATION("RC.OnRCStatus") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register RC application 1", common.registerRCApplication, { 1 }) +runner.Step("Activate App 1", common.activateApp, { 1 }) +runner.Step("Register RC application 2", common.registerRCApplication, { 2 }) + +runner.Title("Test") +for _, mod in pairs(common.getModules()) do + runner.Step("GetInteriorVehicleData " .. mod, subscribeToModuleWOOnRCStatus, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/008_notification_by_module_allocation_ButtonPress_two_apps.lua b/test_scripts/RC/OnRCStatus/008_notification_by_module_allocation_ButtonPress_two_apps.lua new file mode 100644 index 0000000000..f6b59cfb37 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/008_notification_by_module_allocation_ButtonPress_two_apps.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall send OnRCStatus notifications to rc registered apps +-- by allocation module via ButtonPress +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local freeModules = common.getAllModules() +local allocatedModules = { + [1] = {}, + [2] = {} +} + +--[[ Local Functions ]] +local function buttonPress(pModuleType) + local pModuleStatusAllocatedApp, pModuleStatusAnotherApp = common.setModuleStatus(freeModules, allocatedModules, pModuleType) + common.rpcAllowed(pModuleType, 1, "ButtonPress") + common.validateOnRCStatusForApp(1, pModuleStatusAllocatedApp) + common.validateOnRCStatusForApp(2, pModuleStatusAnotherApp) + common.validateOnRCStatusForHMI(2, { pModuleStatusAllocatedApp, pModuleStatusAnotherApp }, 1) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register RC application 1", common.registerRCApplication, { 1 }) +runner.Step("Activate App 1", common.activateApp, { 1 }) +runner.Step("Register RC application 2", common.registerRCApplication, { 2 }) + +runner.Title("Test") +for _, mod in pairs(common.getModules()) do + runner.Step("ButtonPress " .. mod, buttonPress, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua b/test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua new file mode 100644 index 0000000000..fe1f206dc8 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall send OnRCStatus notifications to rc registered apps +-- by allocation module via SetInteriorVehicleData +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local freeModules = common.getAllModules() +local allocatedModules = { + [1] = {}, + [2] = {} +} + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local pModuleStatusAllocatedApp, pModuleStatusAnotherApp = common.setModuleStatus(freeModules, allocatedModules, pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatusAllocatedApp) + common.validateOnRCStatusForApp(2, pModuleStatusAnotherApp) + common.validateOnRCStatusForHMI(2, { pModuleStatusAllocatedApp, pModuleStatusAnotherApp }, 1) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register RC application 1", common.registerRCApplication, { 1 }) +runner.Step("Activate App 1", common.activateApp, { 1 }) +runner.Step("Register RC application 2", common.registerRCApplication, { 2 }) + +runner.Title("Test") +for _, mod in pairs(common.getModules()) do + runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua b/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua new file mode 100644 index 0000000000..3f0eaec45d --- /dev/null +++ b/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua @@ -0,0 +1,51 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall send OnRCStatus notifications to rc registered apps +-- by allocation module via SetInteriorVehicleData +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local freeModules = common.getAllModules() +local allocatedModules = { + [1] = {} +} + +--[[ General configuration parameters ]] +config.application2.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Functions ]] +local function alocateModule(pModuleType) + local pModuleStatus = common.setModuleStatus(freeModules, allocatedModules, pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatus) + common.validateOnRCStatusForHMI(1, { pModuleStatus }) + common.getMobileSession(2):ExpectNotification("OnRCStatus") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register RC application 1", common.registerRCApplication) +runner.Step("Activate App 1", common.activateApp) +runner.Step("Register non-RC application 2", common.rai_n, { 2 }) + +runner.Title("Test") +for _, mod in pairs(common.getModules()) do + runner.Step("Allocation of module " .. mod, alocateModule, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/011_notification_by_app_unregistration.lua b/test_scripts/RC/OnRCStatus/011_notification_by_app_unregistration.lua new file mode 100644 index 0000000000..9001038ee8 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/011_notification_by_app_unregistration.lua @@ -0,0 +1,58 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall send OnRCStatus notifications to registered mobile application and to the HMI by +-- app unregistration with allocated module. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local allocatedModules = { + [1] = {}, + [2] = {} +} + +--[[ Local Functions ]] +local function alocateModule(pModuleType) + local pModuleStatusAllocatedApp, pModuleStatusAnotherApp = common.setModuleStatus(common.getAllModules(), allocatedModules, pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatusAllocatedApp) + common.validateOnRCStatusForApp(2, pModuleStatusAnotherApp) + common.validateOnRCStatusForHMI(2, { pModuleStatusAllocatedApp, pModuleStatusAnotherApp }, 1) +end + +local function unregistration() + local pModuleStatus = { + freeModules = common.getModulesArray(common.getAllModules()), + allocatedModules = { } + } + common.unregisterApp() + common.getMobileSession(1):ExpectNotification("OnRCStatus") + :Times(0) + common.validateOnRCStatusForApp(2, pModuleStatus) + common.validateOnRCStatusForHMI(1, { pModuleStatus }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register RC application 1", common.registerRCApplication, { 1 }) +runner.Step("Register RC application 2", common.registerRCApplication, { 2 }) +runner.Step("Activate App 1", common.activateApp) +runner.Step("Allocating module CLIMATE", alocateModule, { "CLIMATE" }) + +runner.Title("Test") +runner.Step("OnRCStatus by app unregistration", unregistration) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua b/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua new file mode 100644 index 0000000000..8f3e6966c5 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua @@ -0,0 +1,59 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall send OnRCStatus notifications to registered mobile application and to the HMI by +-- policy update, allocated module is revoked in update +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application2.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Functions ]] +local function pTUfunc(tbl) + local appId1 = config.application1.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId1] = common.getRCAppConfig() + tbl.policy_table.app_policies[appId1].moduleType = { "RADIO" } + local appId2 = config.application2.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId2] = common.getRCAppConfig() +end + +local function alocateModule(pModuleType) + local pModuleStatus = common.setModuleStatus(common.getAllModules(), {{}}, pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatus) + common.validateOnRCStatusForHMI(1, { pModuleStatus }) +end + +local function registrationAppWithRevokingModule() + common.raiPTU_n(pTUfunc, 2) + local pModuleStatus = { + freeModules = common.getModulesArray(common.getAllModules()), + allocatedModules = { } + } + common.validateOnRCStatusForApp(1, pModuleStatus) + common.validateOnRCStatusForHMI(1, { pModuleStatus }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions, { 1 }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register RC application 1", common.registerRCApplication) +runner.Step("Activate App 1", common.activateApp) +runner.Step("Allocating module CLIMATE", alocateModule, { "CLIMATE" }) + +runner.Title("Test") +runner.Step("OnRCStatus by PTU with revoking of allocated module", registrationAppWithRevokingModule) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/013_notification_by_reallocation_module_by_the_same_app.lua b/test_scripts/RC/OnRCStatus/013_notification_by_reallocation_module_by_the_same_app.lua new file mode 100644 index 0000000000..45d1557836 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/013_notification_by_reallocation_module_by_the_same_app.lua @@ -0,0 +1,46 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall not send OnRCStatus notifications to rc registered app and HMI +-- in case application tries allocate already allocated module +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function alocateModuleWithoutNot(pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.getMobileSession(1):ExpectNotification("OnRCStatus") + :Times(0) + EXPECT_HMINOTIFICATION("RC.OnRCStatus") + :Times(0) +end + +local function alocateModule(pModuleType) + local pModuleStatus = common.setModuleStatus(common.getAllModules(), {{}}, pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatus) + common.validateOnRCStatusForHMI(1, { pModuleStatus }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register RC application", common.registerRCApplication) +runner.Step("Activate App", common.activateApp) +runner.Step("Allocate module CLIMATE", alocateModule, { "CLIMATE" }) + +runner.Title("Test") +runner.Step("App allocates module CLIMATE one more time", alocateModuleWithoutNot, { "CLIMATE" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/014_notification_by_reallocation_module_by_second_app.lua b/test_scripts/RC/OnRCStatus/014_notification_by_reallocation_module_by_second_app.lua new file mode 100644 index 0000000000..dd5a087d1d --- /dev/null +++ b/test_scripts/RC/OnRCStatus/014_notification_by_reallocation_module_by_second_app.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall send OnRCStatus notifications to rc registered apps and to HMI +-- in case app2 tries allocate allocated module by app1 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local freeModules = common.getAllModules() +local allocatedModules = { + [1] = {}, + [2] = {} +} + +--[[ Local Functions ]] +local function alocateModuleFirstApp(pModuleType) + local pModuleStatusAllocatedApp, pModuleStatusAnotherApp = common.setModuleStatus(freeModules, allocatedModules, "CLIMATE") + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatusAllocatedApp) + common.validateOnRCStatusForApp(2, pModuleStatusAnotherApp) + common.validateOnRCStatusForHMI(2, { pModuleStatusAllocatedApp, pModuleStatusAnotherApp }, 1) +end + +local function alocateModuleSecondApp(pModuleType) + local pModuleStatusAllocatedApp, pModuleStatusAnotherApp = common.setModuleStatus(freeModules, allocatedModules, "CLIMATE", 2) + common.rpcAllowed(pModuleType, 2, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(2, pModuleStatusAllocatedApp) + common.validateOnRCStatusForApp(1, pModuleStatusAnotherApp) + common.validateOnRCStatusForHMI(2, { pModuleStatusAnotherApp, pModuleStatusAllocatedApp }, 2) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register RC application 1", common.registerRCApplication, { 1 }) +runner.Step("Register RC application 2", common.registerRCApplication, { 2 }) +runner.Step("Activate App 1", common.activateApp) + +runner.Title("Test") +runner.Step("App1 allocates module CLIMATE", alocateModuleFirstApp, { "CLIMATE"}) +runner.Step("Activate App 2", common.activateApp, { 2 }) +runner.Step("App2 allocates module CLIMATE", alocateModuleSecondApp, { "CLIMATE"}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/015_notification_by_user_exit.lua b/test_scripts/RC/OnRCStatus/015_notification_by_user_exit.lua new file mode 100644 index 0000000000..a592793fc7 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/015_notification_by_user_exit.lua @@ -0,0 +1,52 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall send OnRCStatus notifications to rc registered app +-- by allocation module via SetInteriorVehicleData +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function alocateModule(pModuleType) + local pModuleStatus = common.setModuleStatus(common.getAllModules(), {{ }}, pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatus) + common.validateOnRCStatusForHMI(1, { pModuleStatus }) +end + +local function userExit() + local hmiAppId = common.getHMIAppId() + common.getHMIconnection():SendNotification("BasicCommunication.OnExitApplication", + { appID = hmiAppId, reason = "USER_EXIT" }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE" }) + local pModuleStatus = { + freeModules = common.getModulesArray(common.getAllModules()), + allocatedModules = { } + } + common.validateOnRCStatusForApp(1, pModuleStatus) + common.validateOnRCStatusForHMI(1, { pModuleStatus }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register RC application", common.registerRCApplication) +runner.Step("Activate App", common.activateApp) +runner.Step("App allocates module CLIMATE", alocateModule, { "CLIMATE" }) + +runner.Title("Test") +runner.Step("OnRCStatus notification by user exit", userExit) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/016_notification_by_DRIVER_DISTRACTION_VIOLATION.lua b/test_scripts/RC/OnRCStatus/016_notification_by_DRIVER_DISTRACTION_VIOLATION.lua new file mode 100644 index 0000000000..59cbed5c9b --- /dev/null +++ b/test_scripts/RC/OnRCStatus/016_notification_by_DRIVER_DISTRACTION_VIOLATION.lua @@ -0,0 +1,52 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall send OnRCStatus notifications to rc registered app and to HMI +-- in case app deallocates module by performing DRIVER_DISTRACTION_VIOLATION form HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function alocateModule(pModuleType) + local pModuleStatus = common.setModuleStatus(common.getAllModules(), {{}}, pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatus) + common.validateOnRCStatusForHMI(1, { pModuleStatus }) +end + +local function driverDistractionViolation() + local hmiAppId = common.getHMIAppId() + common.getHMIconnection():SendNotification("BasicCommunication.OnExitApplication", + { appID = hmiAppId, reason = "DRIVER_DISTRACTION_VIOLATION" }) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE" }) + local pModuleStatus = { + freeModules = common.getModulesArray(common.getAllModules()), + allocatedModules = { } + } + common.validateOnRCStatusForApp(1, pModuleStatus) + common.validateOnRCStatusForHMI(1, { pModuleStatus }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register RC application", common.registerRCApplication) +runner.Step("Activate App", common.activateApp) +runner.Step("App allocates module CLIMATE" , alocateModule, { "CLIMATE" }) + +runner.Title("Test") +runner.Step("OnRCStatus notification by DRIVER_DISTRACTION_VIOLATION", driverDistractionViolation) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/017_notification_by_rejecting_consent_by_driver.lua b/test_scripts/RC/OnRCStatus/017_notification_by_rejecting_consent_by_driver.lua new file mode 100644 index 0000000000..8096dd11de --- /dev/null +++ b/test_scripts/RC/OnRCStatus/017_notification_by_rejecting_consent_by_driver.lua @@ -0,0 +1,58 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall not send OnRCStatus notifications to rc registered app and to HMI +-- in case HMI sends REJECTED resultCode to RC.GetInteriorVehicleDataConsent +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local allocatedModules = { + [1] = {}, + [2] = {} +} + +--[[ Local Functions ]] +local function consentRejecting() + common.rpcRejectWithConsent("CLIMATE", 2, "SetInteriorVehicleData") + common.getMobileSession(1):ExpectNotification("OnRCStatus") + :Times(0) + common.getMobileSession(2):ExpectNotification("OnRCStatus") + :Times(0) + EXPECT_HMINOTIFICATION("RC.OnRCStatus") + :Times(0) +end + +local function alocateModule(pModuleType) + local pModuleStatusAllocatedApp, pModuleStatusAnotherApp = common.setModuleStatus(common.getAllModules(), allocatedModules, pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatusAllocatedApp) + common.validateOnRCStatusForApp(2, pModuleStatusAnotherApp) + common.validateOnRCStatusForHMI(2, { pModuleStatusAllocatedApp, pModuleStatusAnotherApp }, 1) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Set AccessMode ASK_DRIVER", common.defineRAMode, { true, "ASK_DRIVER" }) +runner.Step("Register RC application 1", common.registerRCApplication, { 1 }) +runner.Step("Activate App 1", common.activateApp, { 1 }) +runner.Step("Register RC application 2", common.registerRCApplication, { 2 }) +runner.Step("Activate App 2", common.activateApp, { 2 }) + +runner.Title("Test") +runner.Step("Allocation of module by App 1", alocateModule, { "CLIMATE" }) +runner.Step("Allocation of module by App 2 and rejecting consent by driver", consentRejecting) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/018_notification_by_driver_consent.lua b/test_scripts/RC/OnRCStatus/018_notification_by_driver_consent.lua new file mode 100644 index 0000000000..f512a42542 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/018_notification_by_driver_consent.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall send OnRCStatus notifications to rc registered apps and to HMI +-- in case HMI sends SUCCESS resultCode to RC.GetInteriorVehicleDataConsent +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local freeModules = common.getAllModules() +local allocatedModules = { + [1] = {}, + [2] = {} +} + +--[[ Local Functions ]] +local function alocateModule(pModuleType) + local pModuleStatusAllocatedApp, pModuleStatusAnotherApp = common.setModuleStatus(freeModules, allocatedModules, pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatusAllocatedApp) + common.validateOnRCStatusForApp(2, pModuleStatusAnotherApp) + common.validateOnRCStatusForHMI(2, { pModuleStatusAllocatedApp, pModuleStatusAnotherApp }, 1) +end + +local function subscribeToModuleWithDriverConsent(pModuleType) + local pModuleStatusAllocatedApp, pModuleStatusAnotherApp = common.setModuleStatus(freeModules, allocatedModules, pModuleType, 2) + common.rpcAllowedWithConsent(pModuleType, 2, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatusAnotherApp) + common.validateOnRCStatusForApp(2, pModuleStatusAllocatedApp) + common.validateOnRCStatusForHMI(2, { pModuleStatusAnotherApp, pModuleStatusAllocatedApp }, 2) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Set AccessMode ASK_DRIVER", common.defineRAMode, { true, "ASK_DRIVER" }) +runner.Step("Register RC application 1", common.registerRCApplication, { 1 }) +runner.Step("Activate App 1", common.activateApp, { 1 }) +runner.Step("Register RC application 1", common.registerRCApplication, { 2 }) +runner.Step("Activate App 2", common.activateApp, { 2 }) + +runner.Title("Test") +runner.Step("Allocation of module by App 1", alocateModule, { "CLIMATE" }) +runner.Step("Allocation of module by App 2 with driver consent", subscribeToModuleWithDriverConsent, { "CLIMATE" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/019_notification_by_app_disconnect.lua b/test_scripts/RC/OnRCStatus/019_notification_by_app_disconnect.lua new file mode 100644 index 0000000000..bf44dada2a --- /dev/null +++ b/test_scripts/RC/OnRCStatus/019_notification_by_app_disconnect.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall send OnRCStatus notifications to rc registered app +-- in case application deallocates module by unexpected disconnect +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local freeModules = common.getAllModules() +local allocatedModules = { + [1] = {}, + [2] = {} +} + +--[[ Local Functions ]] +local function alocateModule(pModuleType) + local pModuleStatusAllocatedApp, pModuleStatusAnotherApp = common.setModuleStatus(freeModules, allocatedModules, pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatusAllocatedApp) + common.validateOnRCStatusForApp(2, pModuleStatusAnotherApp) + common.validateOnRCStatusForHMI(2, { pModuleStatusAllocatedApp, pModuleStatusAnotherApp }, 1) +end + +local function closeSession() + local pModuleStatus = common.setModuleStatusByDeallocation(freeModules, allocatedModules, "CLIMATE", 1) + common.closeSession(1) + common.validateOnRCStatusForApp(2, pModuleStatus) + common.validateOnRCStatusForHMI(1, { pModuleStatus }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", + { appID = common.getHMIAppId(), unexpectedDisconnect = true }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register RC application 1", common.registerRCApplication, { 1 }) +runner.Step("Activate App 1", common.activateApp, { 1 }) +runner.Step("Register RC application 2", common.registerRCApplication, { 2 }) +runner.Step("Allocation of module CLIMATE", alocateModule, { "CLIMATE" }) + +runner.Title("Test") +runner.Step("OnRCStatus by application disconnect", closeSession) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua b/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua new file mode 100644 index 0000000000..ec3805f7c1 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall not send OnRCStatus notifications to rc registered app +-- in case application has not permissions for OnRCStatus +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local freeModules = common.getAllModules() +local allocatedModules = {{}} + +--[[ Local Functions ]] +local function pTUfunc(tbl) + local appId = config.application1.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId] = common.getRCAppConfig() + local HMILevels = { "NONE", "BACKGROUND", "FULL", "LIMITED" } + local RCgroup = { + rpcs = { + ButtonPress = { hmi_levels = HMILevels }, + GetInteriorVehicleData = { hmi_levels = HMILevels }, + SetInteriorVehicleData = { hmi_levels = HMILevels }, + OnInteriorVehicleData = { hmi_levels = HMILevels }, + SystemRequest = { hmi_levels = HMILevels } + } + } + tbl.policy_table.functional_groupings.NewTestCaseGroup1 = RCgroup + tbl.policy_table.app_policies[appId].groups = { "Base-4", "NewTestCaseGroup1" } +end + +local function alocateModule(pModuleType) + local pModuleStatus = common.setModuleStatus(freeModules, allocatedModules, pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.getMobileSession(1):ExpectNotification("OnRCStatus") + :Times(0) + common.validateOnRCStatusForHMI(1, { pModuleStatus }) +end + +local function registerApp() + common.raiPTU_n(pTUfunc, 1) + common.getMobileSession(1):ExpectNotification("OnRCStatus") + :Times(0) + local pModuleStatus = { + freeModules = common.getModulesArray(freeModules), + allocatedModules = common.getModulesArray(allocatedModules[1]) + } + common.validateOnRCStatusForHMI(1, { pModuleStatus }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions, { 0 }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register RC application", registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("Allocation of module CLIMATE", alocateModule, { "CLIMATE" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/021_notification_in_case_AUTO_DENY_mode.lua b/test_scripts/RC/OnRCStatus/021_notification_in_case_AUTO_DENY_mode.lua new file mode 100644 index 0000000000..4c0e7874a7 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/021_notification_in_case_AUTO_DENY_mode.lua @@ -0,0 +1,63 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: SDL shall not send OnRCStatus notifications to rc registered apps and to HMI +-- in case HMI responds with IN_USE result code to allocation request from second app +-- because of HMI access mode is AUTO_DENY +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local allocatedModules = { + [1] = {}, + [2] = {} +} + +--[[ Local Functions ]] +local function alocateModule(pModuleType) + local pModuleStatusAllocatedApp, pModuleStatusAnotherApp = common.setModuleStatus(common.getAllModules(), allocatedModules, pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatusAllocatedApp) + common.validateOnRCStatusForApp(2, pModuleStatusAnotherApp) + common.validateOnRCStatusForHMI(2, { pModuleStatusAllocatedApp, pModuleStatusAnotherApp }, 1) +end + +local function allocateModuleFromSecondApp(pModuleType) + local cid = common.getMobileSession(2):SendRPC("SetInteriorVehicleData", + { moduleData = common.getSettableModuleControlData(pModuleType) }) + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + common.getMobileSession(2):ExpectResponse(cid, { success = false, resultCode = "IN_USE" }) + common.getMobileSession(2):ExpectNotification("OnRCStatus") + :Times(0) + common.getMobileSession(1):ExpectNotification("OnRCStatus") + :Times(0) + EXPECT_HMINOTIFICATION("RC.OnRCStatus") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Set AccessMode AUTO_DENY", common.defineRAMode, { true, "AUTO_DENY" }) +runner.Step("Register RC application 1", common.registerRCApplication, { 1 }) +runner.Step("Register RC application 2", common.registerRCApplication, { 2 }) +runner.Step("Activate App 1", common.activateApp, { 1 }) + +runner.Title("Test") +runner.Step("Allocation of module by App 1", alocateModule, { "CLIMATE" }) +runner.Step("Activate App 2", common.activateApp, { 2 }) +runner.Step("Rejected allocation of module by App2", allocateModuleFromSecondApp, { "CLIMATE" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua new file mode 100644 index 0000000000..e14cd6c169 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua @@ -0,0 +1,308 @@ +--------------------------------------------------------------------------------------------------- +-- OnRCStatus common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 2 +config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.checkAllValidations = true + +--[[ Required Shared libraries ]] +local commonRC = require('test_scripts/RC/commonRC') +local test = require("user_modules/dummy_connecttest") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local json = require("modules/json") +local utils = require("user_modules/utils") + +--[[ Module ]] +local m = {} + +--[[ Functions ]] +local function backupPreloadedPT() + local preloadedFile = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + commonPreconditions:BackupFile(preloadedFile) +end + +local function updatePreloadedPT(pCountOfRCApps) + if not pCountOfRCApps then pCountOfRCApps = 2 end + local preloadedFile = commonPreconditions:GetPathToSDL() + .. commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + local preloadedTable = commonRC.jsonFileToTable(preloadedFile) + preloadedTable.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + preloadedTable.policy_table.functional_groupings["RemoteControl"].rpcs.OnRCStatus = { + hmi_levels = { "FULL", "BACKGROUND", "LIMITED", "NONE" } + } + for i = 1, pCountOfRCApps do + local appId = config["application" .. i].registerAppInterfaceParams.appID + preloadedTable.policy_table.app_policies[appId] = commonRC.getRCAppConfig() + preloadedTable.policy_table.app_policies[appId].AppHMIType = nil + end + commonRC.tableToJsonFile(preloadedTable, preloadedFile) +end + +local function restorePreloadedPT() + local preloadedFile = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + commonPreconditions:RestoreFile(preloadedFile) +end + +function m.getModules() + return commonFunctions:cloneTable({ "RADIO", "CLIMATE" }) +end + +function m.getAllModules() + return commonFunctions:cloneTable({ "RADIO", "CLIMATE" }) +end + +function m.getRCAppConfig() + return commonRC.getRCAppConfig() +end + +function m.getMobileSession(pAppId) + return commonRC.getMobileSession(test, pAppId) +end + +function m.getHMIconnection() + return test.hmiConnection +end + +function m.preconditions(pCountOfRCApps) + commonRC.preconditions() + backupPreloadedPT() + updatePreloadedPT(pCountOfRCApps) +end + +function m.start() + commonRC.start(nil, test) +end + +function m.getModulesArray(pModules) + local out = {} + for _, mod in pairs(pModules) do + table.insert(out, { moduleType = mod }) + end + return out +end + +function m.getHMIAppIdsRC() + local out = {} + for appID, hmiAppId in pairs(commonRC.getHMIAppIds()) do + for i = 1, 5 do + local params = config["application" .. i].registerAppInterfaceParams + if params.appID == appID and params.appHMIType[1] == "REMOTE_CONTROL" then + table.insert(out, hmiAppId) + end + end + end + return out +end + +function m.registerRCApplication(pAppId) + if not pAppId then pAppId = 1 end + local pModuleStatus = { + freeModules = m.getModulesArray(m.getAllModules()), + allocatedModules = { } + } + commonRC.rai_n(pAppId, test) + for i = 1, pAppId do + m.validateOnRCStatusForApp(i, pModuleStatus) + end + m.validateOnRCStatusForHMI(pAppId, { pModuleStatus }) +end + +function m.raiPTU_n(ptu_update_func, pAppId) + if not pAppId then pAppId = 1 end + commonRC.rai_ptu_n(pAppId, ptu_update_func, test) +end + +function m.rai_n(pAppId) + commonRC.rai_n(pAppId, test) +end + +function m.subscribeToModule(pModule, pAppId) + if not pAppId then pAppId = 1 end + commonRC.subscribeToModule(pModule, pAppId, test) +end + +function m.activateApp(pAppId) + commonRC.activate_app(pAppId, test) +end + +function m.getHMIAppId(pAppId) + return commonRC.getHMIAppId(pAppId) +end + +function m.getSettableModuleControlData(pModuleType) + return commonRC.getSettableModuleControlData(pModuleType) +end + +function m.postconditions() + commonRC.postconditions() + restorePreloadedPT() +end + +local function setAllocationState(pAllocArrays, pAllocApp, pModule) + for i=1,#pAllocArrays do + for key, value in pairs(pAllocArrays[i]) do + if pModule == value then + table.remove(pAllocArrays[i], key) + end + end + end + table.insert(pAllocArrays[pAllocApp], pModule) +end + +function m.setModuleStatus(pFreeMod, pAllocatedMod, pModule, pAllocApp) + if not pAllocApp then pAllocApp = 1 end + local modulesStatusAllocatedApp = { } + local modulesStatusAnotherApp = { } + setAllocationState(pAllocatedMod, pAllocApp, pModule) + for key, value in pairs(pFreeMod) do + if pModule == value then + table.remove(pFreeMod, key) + end + end + modulesStatusAllocatedApp.freeModules = m.getModulesArray(pFreeMod) + modulesStatusAnotherApp.freeModules = m.getModulesArray(pFreeMod) + modulesStatusAllocatedApp.allocatedModules = m.getModulesArray(pAllocatedMod[pAllocApp]) + if 1 == pAllocApp then + modulesStatusAnotherApp.allocatedModules = pAllocatedMod[2] + else + modulesStatusAnotherApp.allocatedModules = pAllocatedMod[1] + end + return modulesStatusAllocatedApp, modulesStatusAnotherApp +end + +function m.setModuleStatusByDeallocation(pFreeMod, pAllocatedMod, pModule, pRemoveAllocFromApp) + if not pRemoveAllocFromApp then pRemoveAllocFromApp = 1 end + local modulesStatusAllocatedApp = { } + local modulesStatusAnotherApp = { } + table.insert(pFreeMod, pModule) + for key, value in pairs(pAllocatedMod[pRemoveAllocFromApp]) do + if pModule == value then + table.remove(pAllocatedMod[pRemoveAllocFromApp], key) + end + end + modulesStatusAllocatedApp.freeModules = m.getModulesArray(pFreeMod) + modulesStatusAnotherApp.freeModules = m.getModulesArray(pFreeMod) + modulesStatusAllocatedApp.allocatedModules = m.getModulesArray(pAllocatedMod[pRemoveAllocFromApp]) + if 1 == pRemoveAllocFromApp then + modulesStatusAnotherApp.allocatedModules = pAllocatedMod[2] + else + modulesStatusAnotherApp.allocatedModules = pAllocatedMod[1] + end + return modulesStatusAllocatedApp, modulesStatusAnotherApp +end + +function m.unregisterApp(pAppId) + if not pAppId then pAppId = 1 end + commonRC.deleteHMIAppId(pAppId) + commonRC.unregisterApp(pAppId, test) +end + +function m.closeSession(pAppId) + if not pAppId then pAppId = 1 end + commonRC.deleteHMIAppId(pAppId) + m.getMobileSession(pAppId):Stop() +end + +function m.defineRAMode(pAllowed, pAccessMode) + commonRC.defineRAMode(pAllowed, pAccessMode, test) +end + +function m.rpcRejectWithConsent(pModuleType, pAppId, pRPC) + commonRC.rpcRejectWithConsent(pModuleType, pAppId, pRPC, test) +end + +function m.rpcAllowedWithConsent(pModuleType, pAppId, pRPC) + commonRC.rpcAllowedWithConsent(pModuleType, pAppId, pRPC, test) +end + +m.getAppEventName = commonRC.getAppEventName +m.getHMIEventName = commonRC.getHMIEventName +m.getAppRequestParams = commonRC.getAppRequestParams +m.getAppResponseParams = commonRC.getAppResponseParams +m.getHMIRequestParams = commonRC.getHMIRequestParams +m.getHMIResponseParams = commonRC.getHMIResponseParams + +function m.rpcAllowed(pModuleType, pAppId, pRPC) + commonRC.rpcAllowed(pModuleType, pAppId, pRPC, test) +end + +function m.cloneTable(...) + commonFunctions:cloneTable(...) +end + +function m.sortModules(pModulesArray) + local function f(a, b) + if a.moduleType and b.moduleType then + return a.moduleType < b.moduleType + elseif a and b then + return a < b + end + return 0 + end + table.sort(pModulesArray, f) +end + +function m.validateOnRCStatusForApp(pAppId, pExpData) + m.getMobileSession(pAppId):ExpectNotification("OnRCStatus") + :ValidIf(function(_, d) + m.sortModules(pExpData.freeModules) + m.sortModules(pExpData.allocatedModules) + m.sortModules(d.payload.freeModules) + m.sortModules(d.payload.allocatedModules) + return compareValues(pExpData, d.payload, "payload") + end) +end + +function m.validateOnRCStatusForHMI(pCountOfRCApps, pExpData, pAllocApp) + local usedHmiAppIds = { } + EXPECT_HMINOTIFICATION("RC.OnRCStatus") + :ValidIf(function(_, d) + m.sortModules(d.params.freeModules) + m.sortModules(d.params.allocatedModules) + for i=1,#pExpData do + m.sortModules(pExpData[i].freeModules) + m.sortModules(pExpData[i].allocatedModules) + end + local AnotherApp + if pAllocApp and pAllocApp == 1 then + AnotherApp = 2 + else + AnotherApp = 1 + end + if d.params.appID == commonRC.getHMIAppId(pAllocApp) and pAllocApp then + return compareValues(pExpData[pAllocApp], d.params, "params") + else + return compareValues(pExpData[AnotherApp], d.params, "params") + end + end) + :ValidIf(function(e, d) + if e.occurences == 1 then + usedHmiAppIds = {} + end + local avlHmiAppIds = {} + for _, appId in pairs(m.getHMIAppIdsRC()) do + avlHmiAppIds[appId] = true + end + local actAppId = d.params.appID + if avlHmiAppIds[actAppId] and not usedHmiAppIds[actAppId] then + usedHmiAppIds[actAppId] = true + return true + end + local expAppIds = {} + for appId in pairs(avlHmiAppIds) do + if not usedHmiAppIds[appId] then + table.insert(expAppIds, appId) + end + end + return false, " Occurence: " .. e.occurences .. ", " + .. "expected appID: [" .. table.concat(expAppIds, ", ") .. "], " .. "actual: " .. tostring(actAppId) + end) + :Times(pCountOfRCApps) +end + +m.wait = utils.wait + +return m diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 6eca7fd689..e0e8b2863c 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -55,14 +55,14 @@ local function updatePTU(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() end -local function jsonFileToTable(file_name) +function commonRC.jsonFileToTable(file_name) local f = io.open(file_name, "r") local content = f:read("*all") f:close() return json.decode(content) end -local function tableToJsonFile(tbl, file_name) +function commonRC.tableToJsonFile(tbl, file_name) local f = io.open(file_name, "w") f:write(json.encode(tbl)) f:close() @@ -96,7 +96,7 @@ local function ptu(self, ptu_update_func) if ptu_update_func then ptu_update_func(ptu_table) end - tableToJsonFile(ptu_table, ptu_file_name) + commonRC.tableToJsonFile(ptu_table, ptu_file_name) local event = events.Event() event.matches = function(self, e) return self == e end @@ -106,7 +106,7 @@ local function ptu(self, ptu_update_func) for id = 1, getAppsCount() do local mobileSession = commonRC.getMobileSession(self, id) mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) - :Do(function(_, d2) + :DoOnce(function(_, d2) print("App ".. id .. " was used for PTU") RAISE_EVENT(event, event, "PTU event") checkIfPTSIsSentAsBinary(d2.binaryData) @@ -194,7 +194,7 @@ function commonRC.rai_ptu_n(id, ptu_update_func, self) EXPECT_HMICALL("BasicCommunication.PolicyUpdate") :Do(function(_, d2) self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) - ptu_table = jsonFileToTable(d2.params.file) + ptu_table = commonRC.jsonFileToTable(d2.params.file) ptu(self, ptu_update_func) end) end) @@ -746,15 +746,24 @@ end function commonRC.updateDefaultCapabilities(pDisabledModuleTypes) local hmiCapabilitiesFile = commonPreconditions:GetPathToSDL() - .. commonFunctions:read_parameter_from_smart_device_link_ini("HMICapabilities") - local hmiCapTbl = jsonFileToTable(hmiCapabilitiesFile) + .. commonFunctions:read_parameter_from_smart_device_link_ini("HMICapabilities") + local hmiCapTbl = commonRC.jsonFileToTable(hmiCapabilitiesFile) local rcCapTbl = hmiCapTbl.UI.systemCapabilities.remoteControlCapability for _, pDisabledModuleType in pairs(pDisabledModuleTypes) do local buttonId = commonRC.getButtonIdByName(rcCapTbl.buttonCapabilities, commonRC.getButtonNameByModule(pDisabledModuleType)) table.remove(rcCapTbl.buttonCapabilities, buttonId) rcCapTbl[string.lower(pDisabledModuleType) .. "ControlCapabilities"] = nil end - tableToJsonFile(hmiCapTbl, hmiCapabilitiesFile) + commonRC.tableToJsonFile(hmiCapTbl, hmiCapabilitiesFile) end +function commonRC.getHMIAppIds() + return hmiAppIds +end + +function commonRC.deleteHMIAppId(pAppId) + hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = nil +end + + return commonRC diff --git a/test_sets/rc_OnRCStatus.txt b/test_sets/rc_OnRCStatus.txt new file mode 100644 index 0000000000..c76a40ad52 --- /dev/null +++ b/test_sets/rc_OnRCStatus.txt @@ -0,0 +1,21 @@ +./test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua +./test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua +./test_scripts/RC/OnRCStatus/003_registration_not_rc_app.lua +./test_scripts/RC/OnRCStatus/004_notification_by_module_subscription_GetInteriorVehicleData.lua +./test_scripts/RC/OnRCStatus/005_notification_by_module_allocation_ButtonPress.lua +./test_scripts/RC/OnRCStatus/006_notification_by_module_allocation_SetInteriorVehicleData.lua +./test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua +./test_scripts/RC/OnRCStatus/008_notification_by_module_allocation_ButtonPress_two_apps.lua +./test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua +./test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua +./test_scripts/RC/OnRCStatus/011_notification_by_app_unregistration.lua +./test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua +./test_scripts/RC/OnRCStatus/013_notification_by_reallocation_module_by_the_same_app.lua +./test_scripts/RC/OnRCStatus/014_notification_by_reallocation_module_by_second_app.lua +./test_scripts/RC/OnRCStatus/015_notification_by_user_exit.lua +./test_scripts/RC/OnRCStatus/016_notification_by_DRIVER_DISTRACTION_VIOLATION.lua +./test_scripts/RC/OnRCStatus/017_notification_by_rejecting_consent_by_driver.lua +./test_scripts/RC/OnRCStatus/018_notification_by_driver_consent.lua +./test_scripts/RC/OnRCStatus/019_notification_by_app_disconnect.lua +./test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua +./test_scripts/RC/OnRCStatus/021_notification_in_case_AUTO_DENY_mode.lua diff --git a/user_modules/dummy_connecttest.lua b/user_modules/dummy_connecttest.lua index 5d19454be4..8dfeba68d8 100644 --- a/user_modules/dummy_connecttest.lua +++ b/user_modules/dummy_connecttest.lua @@ -339,7 +339,10 @@ function module:initHMI() "UI.OnRecordStart" }) registerComponent("VehicleInfo") - registerComponent("RC") + registerComponent("RC", + { + "RC.OnRCStatus" + }) registerComponent("Navigation", { "Navigation.OnAudioDataStreaming", From 1b07ee9bb543ce5534243015c9d6311912a5b4ec Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 31 May 2018 12:42:44 +0300 Subject: [PATCH 462/681] Update according to review: description update --- .../001_notification_by_apps_registration.lua | 6 +++++- ...ication_by_rc_functionality_disallowed_on_hmi.lua | 8 ++++++-- .../RC/OnRCStatus/003_registration_not_rc_app.lua | 6 +++++- ...by_module_subscription_GetInteriorVehicleData.lua | 8 ++++++-- ...notification_by_module_allocation_ButtonPress.lua | 8 ++++++-- ...n_by_module_allocation_SetInteriorVehicleData.lua | 8 ++++++-- ..._subscription_GetInteriorVehicleData_two_apps.lua | 6 ++++++ ...ion_by_module_allocation_ButtonPress_two_apps.lua | 9 +++++++-- ...le_allocation_SetInteriorVehicleData_two_apps.lua | 9 +++++++-- ..._by_module_allocation_two_apps_one_app_not_rc.lua | 6 ++++++ .../011_notification_by_app_unregistration.lua | 9 +++++++-- ...012_notification_by_revoking_module_by_policy.lua | 9 +++++++-- ...cation_by_reallocation_module_by_the_same_app.lua | 9 +++++++-- ...fication_by_reallocation_module_by_second_app.lua | 9 +++++++-- .../RC/OnRCStatus/015_notification_by_user_exit.lua | 9 +++++++-- ..._notification_by_DRIVER_DISTRACTION_VIOLATION.lua | 9 +++++++-- ...7_notification_by_rejecting_consent_by_driver.lua | 11 +++++++++-- .../018_notification_by_driver_consent.lua | 10 ++++++++-- .../019_notification_by_app_disconnect.lua | 9 +++++++-- ...ication_in_case_of_policy_permissions_absence.lua | 9 +++++++-- .../021_notification_in_case_AUTO_DENY_mode.lua | 12 +++++++++--- 21 files changed, 142 insertions(+), 37 deletions(-) diff --git a/test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua b/test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua index 5a5c78cbbe..fec33c345f 100644 --- a/test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua +++ b/test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua @@ -5,7 +5,11 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall send OnRCStatus notifications to all registered mobile applications and the HMI +-- Description: +-- In case: +-- 1) RC app1 and RC app2 are registered +-- SDL must: +-- 1) Send OnRCStatus notifications to all registered mobile applications and the HMI --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua b/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua index 5f5aba4d15..ada406bd2c 100644 --- a/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua +++ b/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua @@ -5,8 +5,12 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall not send OnRCStatus notifications to all registered mobile applications and the HMI --- in case RC functionality is disallowed on HMI +-- Description: +-- In case: +-- 1) RC functionality is disallowed on HMI +-- 2) RC application is registered +-- SDL must: +-- 1) Not send OnRCStatus notification to registered mobile application and the HMI --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/003_registration_not_rc_app.lua b/test_scripts/RC/OnRCStatus/003_registration_not_rc_app.lua index 65a63d7824..24d15f34a2 100644 --- a/test_scripts/RC/OnRCStatus/003_registration_not_rc_app.lua +++ b/test_scripts/RC/OnRCStatus/003_registration_not_rc_app.lua @@ -5,7 +5,11 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall not send OnRCStatus notifications to not rc registered app +-- Description: +-- In case: +-- 1) Not RC application is registered +-- SDL must: +-- 1) Not send OnRCStatus notification to not RC registered application --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/004_notification_by_module_subscription_GetInteriorVehicleData.lua b/test_scripts/RC/OnRCStatus/004_notification_by_module_subscription_GetInteriorVehicleData.lua index 2aa2713033..31ee9c1f52 100644 --- a/test_scripts/RC/OnRCStatus/004_notification_by_module_subscription_GetInteriorVehicleData.lua +++ b/test_scripts/RC/OnRCStatus/004_notification_by_module_subscription_GetInteriorVehicleData.lua @@ -5,8 +5,12 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall not send OnRCStatus notifications to rc registered app --- by allocation module via GetInteriorVehicleData +-- Description: +-- In case: +-- 1) RC application is registered +-- 2) Mobile application subscribes to module via GetInteriorVehicleData +-- SDL must: +-- 1) Not send OnRCStatus notification to RC application by module subscribing --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/005_notification_by_module_allocation_ButtonPress.lua b/test_scripts/RC/OnRCStatus/005_notification_by_module_allocation_ButtonPress.lua index 2e230f2c9f..53c5a7a0fc 100644 --- a/test_scripts/RC/OnRCStatus/005_notification_by_module_allocation_ButtonPress.lua +++ b/test_scripts/RC/OnRCStatus/005_notification_by_module_allocation_ButtonPress.lua @@ -5,8 +5,12 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall send OnRCStatus notifications to rc registered app --- by allocation module via ButtonPress +-- Description: +-- In case: +-- 1) RC applications is registered +-- 2) Mobile application allocates module via ButtonPress +-- SDL must: +-- 1) send OnRCStatus notification to RC application by module allocation via ButtonPress --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/006_notification_by_module_allocation_SetInteriorVehicleData.lua b/test_scripts/RC/OnRCStatus/006_notification_by_module_allocation_SetInteriorVehicleData.lua index 71592d1f1d..7c5235b397 100644 --- a/test_scripts/RC/OnRCStatus/006_notification_by_module_allocation_SetInteriorVehicleData.lua +++ b/test_scripts/RC/OnRCStatus/006_notification_by_module_allocation_SetInteriorVehicleData.lua @@ -5,8 +5,12 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall send OnRCStatus notifications to rc registered app --- by allocation module via SetInteriorVehicleData +-- Description: +-- In case: +-- 1) RC applications is registered +-- 2) Mobile application allocates module via SetInteriorVehicleData +-- SDL must: +-- 1) send OnRCStatus notification to RC application by module allocation via SetInteriorVehicleData --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua b/test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua index e9deb70952..af4baac2ad 100644 --- a/test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua +++ b/test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua @@ -7,6 +7,12 @@ -- -- Description: SDL shall not send OnRCStatus notifications to rc registered apps -- by allocation module via GetInteriorVehicleData +-- In case: +-- 1) RC app1 is registered +-- 2) RC app2 is registered +-- 3) Mobile applications subscribe to module via GetInteriorVehicleData one by one +-- SDL must: +-- 1) Not send OnRCStatus notification to RC applications by module subscribing --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/008_notification_by_module_allocation_ButtonPress_two_apps.lua b/test_scripts/RC/OnRCStatus/008_notification_by_module_allocation_ButtonPress_two_apps.lua index f6b59cfb37..86289f6292 100644 --- a/test_scripts/RC/OnRCStatus/008_notification_by_module_allocation_ButtonPress_two_apps.lua +++ b/test_scripts/RC/OnRCStatus/008_notification_by_module_allocation_ButtonPress_two_apps.lua @@ -5,8 +5,13 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall send OnRCStatus notifications to rc registered apps --- by allocation module via ButtonPress +-- Description: +-- In case: +-- 1) RC app1 is registered +-- 2) RC app2 is registered +-- 3) Mobile applications allocate module via ButtonPress one by one +-- SDL must: +-- 1) Send OnRCStatus notification to RC applications by module allocation via ButtonPress --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua b/test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua index fe1f206dc8..a9f27e11b6 100644 --- a/test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua +++ b/test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua @@ -5,8 +5,13 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall send OnRCStatus notifications to rc registered apps --- by allocation module via SetInteriorVehicleData +-- Description: +-- In case: +-- 1) RC app1 is registered +-- 2) RC app2 is registered +-- 3) Mobile applications allocate module via SetInteriorVehicleData one by one +-- SDL must: +-- 1) Send OnRCStatus notification to RC applications by module allocation via SetInteriorVehicleData --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua b/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua index 3f0eaec45d..8bee18d8b4 100644 --- a/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua +++ b/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua @@ -7,6 +7,12 @@ -- -- Description: SDL shall send OnRCStatus notifications to rc registered apps -- by allocation module via SetInteriorVehicleData +-- In case: +-- 1) RC app1 is registered +-- 2) Non-RC app2 is registered +-- 3) App1 allocates module via SetInteriorVehicleData +-- SDL must: +-- 1) Send OnRCStatus notification to RC app1 only by module allocation via SetInteriorVehicleData --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/011_notification_by_app_unregistration.lua b/test_scripts/RC/OnRCStatus/011_notification_by_app_unregistration.lua index 9001038ee8..f8033a0a32 100644 --- a/test_scripts/RC/OnRCStatus/011_notification_by_app_unregistration.lua +++ b/test_scripts/RC/OnRCStatus/011_notification_by_app_unregistration.lua @@ -5,8 +5,13 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall send OnRCStatus notifications to registered mobile application and to the HMI by --- app unregistration with allocated module. +-- Description: +-- In case: +-- 1) RC app1 and app2 are registered +-- 2) App1 allocates module +-- 3) App1 is unregistered +-- SDL must: +-- 1) send OnRCStatus notification to registered app2 and to the HMI by app1 unregistration with allocated module. --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua b/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua index 8f3e6966c5..8ab4860775 100644 --- a/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua +++ b/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua @@ -5,8 +5,13 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall send OnRCStatus notifications to registered mobile application and to the HMI by --- policy update, allocated module is revoked in update +-- Description: +-- In case: +-- 1) RC app is registered +-- 2) App allocates module +-- 3) PTU for app is performed with revoking of allocated module +-- SDL must: +-- 1) send OnRCStatus notifications to mobile app and to the HMI by PTU with revoking of allocated module --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/013_notification_by_reallocation_module_by_the_same_app.lua b/test_scripts/RC/OnRCStatus/013_notification_by_reallocation_module_by_the_same_app.lua index 45d1557836..609c87578d 100644 --- a/test_scripts/RC/OnRCStatus/013_notification_by_reallocation_module_by_the_same_app.lua +++ b/test_scripts/RC/OnRCStatus/013_notification_by_reallocation_module_by_the_same_app.lua @@ -5,8 +5,13 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall not send OnRCStatus notifications to rc registered app and HMI --- in case application tries allocate already allocated module +-- Description: +-- In case: +-- 1) RC app is registered +-- 2) Module_1 is allocated by app +-- 3) App tries allocate already allocated module_1 +-- SDL must: +-- 1) Not send OnRCStatus notifications to RC app and HMI by second allocation attempt --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/014_notification_by_reallocation_module_by_second_app.lua b/test_scripts/RC/OnRCStatus/014_notification_by_reallocation_module_by_second_app.lua index dd5a087d1d..ba3c444734 100644 --- a/test_scripts/RC/OnRCStatus/014_notification_by_reallocation_module_by_second_app.lua +++ b/test_scripts/RC/OnRCStatus/014_notification_by_reallocation_module_by_second_app.lua @@ -5,8 +5,13 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall send OnRCStatus notifications to rc registered apps and to HMI --- in case app2 tries allocate allocated module by app1 +-- Description: +-- In case: +-- 1) RC app1 and RC app2 are registered +-- 2) Module_1 is allocated by app1 +-- 3) App2 allocates the allocated module_1 by app1 +-- SDL must: +-- 1) Send OnRCStatus notifications to RC apps and to HMI by app2 tries allocate the allocated module by app1 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/015_notification_by_user_exit.lua b/test_scripts/RC/OnRCStatus/015_notification_by_user_exit.lua index a592793fc7..17824ad788 100644 --- a/test_scripts/RC/OnRCStatus/015_notification_by_user_exit.lua +++ b/test_scripts/RC/OnRCStatus/015_notification_by_user_exit.lua @@ -5,8 +5,13 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall send OnRCStatus notifications to rc registered app --- by allocation module via SetInteriorVehicleData +-- Description: +-- In case: +-- 1) RC app is registered +-- 2) App allocates module +-- 3) USER_EXIT is performed from HMI +-- SDL must: +-- 1) Send OnRCStatus notifications to RC app and to HMI by app deallocates module by performing USER_EXIT form HMI --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/016_notification_by_DRIVER_DISTRACTION_VIOLATION.lua b/test_scripts/RC/OnRCStatus/016_notification_by_DRIVER_DISTRACTION_VIOLATION.lua index 59cbed5c9b..94bbc25d14 100644 --- a/test_scripts/RC/OnRCStatus/016_notification_by_DRIVER_DISTRACTION_VIOLATION.lua +++ b/test_scripts/RC/OnRCStatus/016_notification_by_DRIVER_DISTRACTION_VIOLATION.lua @@ -5,8 +5,13 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall send OnRCStatus notifications to rc registered app and to HMI --- in case app deallocates module by performing DRIVER_DISTRACTION_VIOLATION form HMI +-- Description: +-- In case: +-- 1) RC app is registered +-- 2) App allocates module +-- 3) DRIVER_DISTRACTION_VIOLATION is performed from HMI +-- SDL must: +-- 1) Send OnRCStatus notifications to RC app and to HMI by app deallocates module by performing DRIVER_DISTRACTION_VIOLATION form HMI --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/017_notification_by_rejecting_consent_by_driver.lua b/test_scripts/RC/OnRCStatus/017_notification_by_rejecting_consent_by_driver.lua index 8096dd11de..f9b875cab4 100644 --- a/test_scripts/RC/OnRCStatus/017_notification_by_rejecting_consent_by_driver.lua +++ b/test_scripts/RC/OnRCStatus/017_notification_by_rejecting_consent_by_driver.lua @@ -5,8 +5,15 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall not send OnRCStatus notifications to rc registered app and to HMI --- in case HMI sends REJECTED resultCode to RC.GetInteriorVehicleDataConsent +-- Description: +-- In case: +-- 1) RC app1 and app2 are registered +-- 2) AccessMode is ASK_DRIVER on HMI +-- 3) Module_1 is allocated by app1 +-- 4) App2 tries to allocate module_1 +-- 5) SDL requests RC.GetInteriorVehicleDataConsent and HMI sends REJECTED resultCode to RC.GetInteriorVehicleDataConsent +-- SDL must: +-- 1) Not send OnRCStatus notification to RC applications by rejecting RC.GetInteriorVehicleDataConsent --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/018_notification_by_driver_consent.lua b/test_scripts/RC/OnRCStatus/018_notification_by_driver_consent.lua index f512a42542..0ce135e75e 100644 --- a/test_scripts/RC/OnRCStatus/018_notification_by_driver_consent.lua +++ b/test_scripts/RC/OnRCStatus/018_notification_by_driver_consent.lua @@ -5,8 +5,14 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall send OnRCStatus notifications to rc registered apps and to HMI --- in case HMI sends SUCCESS resultCode to RC.GetInteriorVehicleDataConsent +-- Description: +-- 1) RC app1 and app2 are registered +-- 2) AccessMode is ASK_DRIVER on HMI +-- 3) Module_1 is allocated by app1 +-- 4) App2 tries to allocate module_1 +-- 5) SDL requests RC.GetInteriorVehicleDataConsent and HMI sends SUCCESS resultCode to RC.GetInteriorVehicleDataConsent +-- SDL must: +-- 1) Send OnRCStatus notification to RC applications by accepting RC.GetInteriorVehicleDataConsent --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/019_notification_by_app_disconnect.lua b/test_scripts/RC/OnRCStatus/019_notification_by_app_disconnect.lua index bf44dada2a..f0bd405217 100644 --- a/test_scripts/RC/OnRCStatus/019_notification_by_app_disconnect.lua +++ b/test_scripts/RC/OnRCStatus/019_notification_by_app_disconnect.lua @@ -5,8 +5,13 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall send OnRCStatus notifications to rc registered app --- in case application deallocates module by unexpected disconnect +-- Description: +-- In case: +-- 1) RC app1 and app2 are registered +-- 2) App1 allocates module +-- 3) App1 is disconnected +-- SDL must: +-- 1) Send OnRCStatus notification to registered app2 and to the HMI by app1 unexpected disconnect --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua b/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua index ec3805f7c1..bb9cbe3dee 100644 --- a/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua +++ b/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua @@ -5,8 +5,13 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall not send OnRCStatus notifications to rc registered app --- in case application has not permissions for OnRCStatus +-- Description: +-- In case: +-- 1) RC app is registered +-- 2) App has not permissions for OnRCStatus +-- 3) App allocates module +-- SDL must: +-- 1) Not send OnRCStatus notifications to app and the HMI --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/021_notification_in_case_AUTO_DENY_mode.lua b/test_scripts/RC/OnRCStatus/021_notification_in_case_AUTO_DENY_mode.lua index 4c0e7874a7..21cf5f379d 100644 --- a/test_scripts/RC/OnRCStatus/021_notification_in_case_AUTO_DENY_mode.lua +++ b/test_scripts/RC/OnRCStatus/021_notification_in_case_AUTO_DENY_mode.lua @@ -5,9 +5,15 @@ -- Requirement summary: -- [SDL_RC] TBD -- --- Description: SDL shall not send OnRCStatus notifications to rc registered apps and to HMI --- in case HMI responds with IN_USE result code to allocation request from second app --- because of HMI access mode is AUTO_DENY +-- Description: +-- In case: +-- 1) HMI access mode is AUTO_DENY +-- 2) RC app1 and RC app2 are regisered +-- 3) App1 allocates module_1 +-- 4) App2 tries allocate the module_1 +-- SDL must: +-- 1) Respond with IN_USE result code to app2 +-- 2) Not send OnRCStatus notifications to RC registered apps and to HMI --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') From 0fc3e92252e7011a613f01ef470b8c607f631dc0 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 1 Jun 2018 15:52:59 +0300 Subject: [PATCH 463/681] Updated description, script name to non-RC --- ...tration_not_rc_app.lua => 003_registration_non_rc_app.lua} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename test_scripts/RC/OnRCStatus/{003_registration_not_rc_app.lua => 003_registration_non_rc_app.lua} (92%) diff --git a/test_scripts/RC/OnRCStatus/003_registration_not_rc_app.lua b/test_scripts/RC/OnRCStatus/003_registration_non_rc_app.lua similarity index 92% rename from test_scripts/RC/OnRCStatus/003_registration_not_rc_app.lua rename to test_scripts/RC/OnRCStatus/003_registration_non_rc_app.lua index 24d15f34a2..26d1c54549 100644 --- a/test_scripts/RC/OnRCStatus/003_registration_not_rc_app.lua +++ b/test_scripts/RC/OnRCStatus/003_registration_non_rc_app.lua @@ -7,9 +7,9 @@ -- -- Description: -- In case: --- 1) Not RC application is registered +-- 1) Non-RC application is registered -- SDL must: --- 1) Not send OnRCStatus notification to not RC registered application +-- 1) Not send OnRCStatus notification to non-RC registered application --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') From 19936eaaf079d15f9541dcb8ef10f1be3506a69b Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 12 Jun 2018 14:58:17 +0300 Subject: [PATCH 464/681] Updated error script name in test set --- test_sets/rc_OnRCStatus.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_sets/rc_OnRCStatus.txt b/test_sets/rc_OnRCStatus.txt index c76a40ad52..fe7ffc1f2e 100644 --- a/test_sets/rc_OnRCStatus.txt +++ b/test_sets/rc_OnRCStatus.txt @@ -1,6 +1,6 @@ ./test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua ./test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua -./test_scripts/RC/OnRCStatus/003_registration_not_rc_app.lua +./test_scripts/RC/OnRCStatus/003_registration_non_rc_app.lua ./test_scripts/RC/OnRCStatus/004_notification_by_module_subscription_GetInteriorVehicleData.lua ./test_scripts/RC/OnRCStatus/005_notification_by_module_allocation_ButtonPress.lua ./test_scripts/RC/OnRCStatus/006_notification_by_module_allocation_SetInteriorVehicleData.lua From f9065037881fc7c94931f7c6c48e8d9b3cb337da Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 12 Jun 2018 15:05:28 +0300 Subject: [PATCH 465/681] Generating app permissions based on default permissions --- ...ification_by_revoking_module_by_policy.lua | 4 +-- .../RC/OnRCStatus/commonOnRCStatus.lua | 2 +- test_scripts/RC/commonRC.lua | 31 ++++++++++++------- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua b/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua index 8ab4860775..ff3a0aabdc 100644 --- a/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua +++ b/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua @@ -26,10 +26,10 @@ config.application2.registerAppInterfaceParams.appHMIType = { "DEFAULT" } --[[ Local Functions ]] local function pTUfunc(tbl) local appId1 = config.application1.registerAppInterfaceParams.appID - tbl.policy_table.app_policies[appId1] = common.getRCAppConfig() + tbl.policy_table.app_policies[appId1] = common.getRCAppConfig(tbl) tbl.policy_table.app_policies[appId1].moduleType = { "RADIO" } local appId2 = config.application2.registerAppInterfaceParams.appID - tbl.policy_table.app_policies[appId2] = common.getRCAppConfig() + tbl.policy_table.app_policies[appId2] = common.getRCAppConfig(tbl) end local function alocateModule(pModuleType) diff --git a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua index e14cd6c169..6a32f82142 100644 --- a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua +++ b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua @@ -35,7 +35,7 @@ local function updatePreloadedPT(pCountOfRCApps) } for i = 1, pCountOfRCApps do local appId = config["application" .. i].registerAppInterfaceParams.appID - preloadedTable.policy_table.app_policies[appId] = commonRC.getRCAppConfig() + preloadedTable.policy_table.app_policies[appId] = commonRC.getRCAppConfig(preloadedTable) preloadedTable.policy_table.app_policies[appId].AppHMIType = nil end commonRC.tableToJsonFile(preloadedTable, preloadedFile) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index e0e8b2863c..55edd4157c 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -17,6 +17,7 @@ local mobile_session = require("mobile_session") local json = require("modules/json") local hmi_values = require("user_modules/hmi_values") local events = require("events") +local utils = require('user_modules/utils') --[[ Local Variables ]] local ptu_table = {} @@ -39,20 +40,28 @@ local function getPTUFromPTS(tbl) tbl.policy_table.module_config.preloaded_date = nil end -function commonRC.getRCAppConfig() - return { - keep_context = false, - steal_focus = false, - priority = "NONE", - default_hmi = "NONE", - moduleType = { "RADIO", "CLIMATE" }, - groups = { "Base-4", "RemoteControl" }, - AppHMIType = { "REMOTE_CONTROL" } - } +function commonRC.getRCAppConfig(tbl) + if tbl then + local out = utils.cloneTable(tbl.policy_table.app_policies.default) + out.moduleType = { "RADIO", "CLIMATE" } + out.groups = { "Base-4", "RemoteControl" } + out.AppHMIType = { "REMOTE_CONTROL" } + return out + else + return { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + moduleType = { "RADIO", "CLIMATE" }, + groups = { "Base-4", "RemoteControl" }, + AppHMIType = { "REMOTE_CONTROL" } + } + end end local function updatePTU(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig(tbl) end function commonRC.jsonFileToTable(file_name) From cb350b594d527e73245f834efb6e71b13f7c9819 Mon Sep 17 00:00:00 2001 From: ZhdanovP Date: Fri, 6 Jul 2018 11:22:00 +0300 Subject: [PATCH 466/681] Adding script for defect 1915 --- ...g_state_when_navi_app_starts_streaming.lua | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 test_scripts/MobileProjection/Phase2/025_Media_app_must_get_ATTENUATED_streaming_state_when_navi_app_starts_streaming.lua diff --git a/test_scripts/MobileProjection/Phase2/025_Media_app_must_get_ATTENUATED_streaming_state_when_navi_app_starts_streaming.lua b/test_scripts/MobileProjection/Phase2/025_Media_app_must_get_ATTENUATED_streaming_state_when_navi_app_starts_streaming.lua new file mode 100644 index 0000000000..3653aa5c14 --- /dev/null +++ b/test_scripts/MobileProjection/Phase2/025_Media_app_must_get_ATTENUATED_streaming_state_when_navi_app_starts_streaming.lua @@ -0,0 +1,81 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/SmartDeviceLink/sdl_core/issues/1915 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/MobileProjection/Phase2/common') +local runner = require('user_modules/script_runner') +local hmi_values = require('user_modules/hmi_values') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local appHMIType = { + [1] = "MEDIA", + [2] = "NAVIGATION" +} +local isMixingAudioSupported = true + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { appHMIType[1] } +config.application2.registerAppInterfaceParams.appHMIType = { appHMIType[2] } + +--[[ Local Functions ]] +local function getHMIParams(pIsMixingSupported) + local hmiParams = hmi_values.getDefaultHMITable() + hmiParams.BasicCommunication.MixingAudioSupported.params.attenuatedSupported = pIsMixingSupported + return hmiParams +end + +local function activateApp(pAppId, pTC, pAudioSS, pAppName) + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId(pAppId) }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession(pAppId):ExpectNotification("OnHMIStatus") + :ValidIf(function(_, data) + return common.checkAudioSS(pTC, pAppName, pAudioSS, data.payload.audioStreamingState) + end) +end + +local function appStartAudioStreaming(pApp1Id, pApp2Id) + common.getMobileSession(pApp2Id):StartService(10) + :Do(function() + common.getHMIConnection():ExpectRequest("Navigation.StartAudioStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession(pApp2Id):StartStreaming(10,"files/MP3_1140kb.mp3") + common.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = true }) + end) + end) + common.getMobileSession(pApp1Id):ExpectNotification("OnHMIStatus", { + hmiLevel = "FULL", + audioStreamingState = "ATTENUATED" + }) + :Times(1) +end + +local function appStopStreaming() + common.getMobileSession():StopStreaming("files/MP3_1140kb.mp3") + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session, isMixingSupported:" .. tostring(isMixingAudioSupported), + common.start, { getHMIParams(isMixingAudioSupported) }) + +runner.Step("Set App Config", common.setAppConfig, { 2, "NAVIGATION", true }) +runner.Step("Register App", common.registerApp, { 2 }) +runner.Step("Activate App2, audioState:" .. "AUDIBLE", activateApp, { 2, 001, "AUDIBLE", "App2" }) + +runner.Step("Set App Config", common.setAppConfig, { 1, "MEDIA", true }) +runner.Step("Register " .. appHMIType[1] .. " App", common.registerApp, { 1 }) +runner.Step("Activate App1, audioState:" .. "AUDIBLE", activateApp, { 1, 001, "AUDIBLE", "App1" }) + +runner.Step("App starts Audio streaming", appStartAudioStreaming, {1, 2}) + +runner.Step("App stops streaming", appStopStreaming) + +runner.Step("Clean sessions", common.cleanSessions) +runner.Step("Stop SDL", common.postconditions) From eaa8d9ddc122a55c1c83f148abbb3325b29596f1 Mon Sep 17 00:00:00 2001 From: Jacob Keeler Date: Thu, 12 Jul 2018 14:28:16 -0400 Subject: [PATCH 467/681] Add expectation for OnDriverDistraction on app registration --- ...ction_After_changing_HMIlevel_from_NONE.lua | 18 +++++++++++++++--- test_scripts/Defects/4_5/commonDefects.lua | 10 ++++++++-- test_scripts/Defects/commonDefects.lua | 1 + test_scripts/RC/commonRC.lua | 1 + test_scripts/Smoke/commonSmoke.lua | 1 + 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua b/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua index 9535a3ba2f..9e576df6cd 100644 --- a/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua +++ b/test_scripts/Defects/4_5/1881_OnDriverDistraction_After_changing_HMIlevel_from_NONE.lua @@ -13,6 +13,18 @@ config.application2.registerAppInterfaceParams.isMediaApplication = false config.application2.registerAppInterfaceParams.appHMIType = {"DEFAULT"} --[[ Local Functions ]] +-- Prepare policy table for policy table update +-- @tparam table tbl table to update +local function ptUpdateFunc(pTbl) + -- make sure that OnDriverDistraction is disallowed in HMILevel NONE + pTbl.policy_table.functional_groupings["Base-4"].rpcs["OnDriverDistraction"].hmi_levels = { + "FULL", + "LIMITED", + "BACKGROUND" + } +end + + --! @OnDDinNONE: Processing OnDriverDistraction notification with expectations 0 times --! @parameters: --! id - id of session, @@ -157,7 +169,7 @@ runner.Step("Clean environment", commonDefects.preconditions) -- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP and create mobile session runner.Step("Start SDL, HMI, connect Mobile, start Session", commonDefects.start) -- Register application, perform PTU -runner.Step("RAI, PTU", commonDefects.rai_ptu) +runner.Step("RAI, PTU", commonDefects.rai_ptu, {ptUpdateFunc}) runner.Title("Test") -- Absence of OnDriverDistraction notification on mobile app in NONE HMI level @@ -167,9 +179,9 @@ runner.Step("OnDriverDistraction_in_FULL", ActivationAppWithOnDD, {{state = "DD_ runner.Step("UnregisterRegisterApp", commonDefects.unregisterApp, {1}) -- Register first application -runner.Step("RAI_first_app", commonDefects.rai_n, {1}) +runner.Step("RAI_first_app", commonDefects.rai_n, {1, false}) -- Register second application -runner.Step("RAI_second_app", commonDefects.rai_ptu_n, {2}) +runner.Step("RAI_second_app", commonDefects.rai_ptu_n, {2, ptUpdateFunc}) -- Activate first application runner.Step("Activate_first_app", commonDefects.activate_app) -- Receiving OnDriverDistraction notification on mobile app with FULL HMI level diff --git a/test_scripts/Defects/4_5/commonDefects.lua b/test_scripts/Defects/4_5/commonDefects.lua index 9b106fd952..85223e7dfc 100644 --- a/test_scripts/Defects/4_5/commonDefects.lua +++ b/test_scripts/Defects/4_5/commonDefects.lua @@ -410,9 +410,10 @@ end --! self - test object --! @return: none --]] -function commonDefect.rai_n(id, self) - self, id = commonDefect.getSelfAndParams(id, self) +function commonDefect.rai_n(id, expect_dd, self) + self, id, expect_dd = commonDefect.getSelfAndParams(id, expect_dd, self) if not id then id = 1 end + if expect_dd == nil then expect_dd = true end self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) self["mobileSession" .. id]:StartService(7) :Do(function() @@ -429,6 +430,11 @@ function commonDefect.rai_n(id, self) { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) :Times(AtLeast(1)) self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + if expect_dd then + self["mobileSession" .. id]:ExpectNotification("OnDriverDistraction", { state = "DD_OFF" }) + else + self["mobileSession" .. id]:ExpectNotification("OnDriverDistraction"):Times(0) + end end) end) end diff --git a/test_scripts/Defects/commonDefects.lua b/test_scripts/Defects/commonDefects.lua index 6962abe0bf..5a28bec51d 100644 --- a/test_scripts/Defects/commonDefects.lua +++ b/test_scripts/Defects/commonDefects.lua @@ -430,6 +430,7 @@ function commonDefect.rai_n(id, self) { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) :Times(AtLeast(1)) self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + self["mobileSession" .. id]:ExpectNotification("OnDriverDistraction", { state = "DD_OFF" }) end) end) end diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 55edd4157c..3526622f57 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -233,6 +233,7 @@ function commonRC.rai_n(id, self) self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + self["mobileSession" .. id]:ExpectNotification("OnDriverDistraction", { state = "DD_OFF" }) end) end) end diff --git a/test_scripts/Smoke/commonSmoke.lua b/test_scripts/Smoke/commonSmoke.lua index fcfa798b48..b8b690ef58 100644 --- a/test_scripts/Smoke/commonSmoke.lua +++ b/test_scripts/Smoke/commonSmoke.lua @@ -280,6 +280,7 @@ function commonSmoke.registerApp(pAppId, self) mobSession:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) mobSession:ExpectNotification("OnPermissionsChange") + mobSession:ExpectNotification("OnDriverDistraction", { state = "DD_OFF" }) end) end) end From c9a8fc8d902397306cf0424c1ebbfada675fc486 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 22 Jun 2018 12:43:15 +0300 Subject: [PATCH 468/681] Initial scripts for 'Update OnRCStatus with a new allowed parameter' --- .../001_notification_by_apps_registration.lua | 2 +- ..._by_rc_functionality_disallowed_on_hmi.lua | 20 +++--- .../003_registration_non_rc_app.lua | 10 +-- ...iption_GetInteriorVehicleData_two_apps.lua | 14 ++-- ...cation_SetInteriorVehicleData_two_apps.lua | 12 ++-- ...ule_allocation_two_apps_one_app_not_rc.lua | 16 ++--- .../018_notification_by_driver_consent.lua | 2 +- ..._disallowed_on_hmi_with_registered_app.lua | 43 ++++++++++++ ...ity_allowed_on_hmi_with_registered_app.lua | 68 +++++++++++++++++++ .../RC/OnRCStatus/commonOnRCStatus.lua | 36 ++++++++-- test_sets/rc_OnRCStatus.txt | 2 + 11 files changed, 181 insertions(+), 44 deletions(-) create mode 100644 test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua create mode 100644 test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua diff --git a/test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua b/test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua index fec33c345f..c6bf693ebd 100644 --- a/test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua +++ b/test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua @@ -9,7 +9,7 @@ -- In case: -- 1) RC app1 and RC app2 are registered -- SDL must: --- 1) Send OnRCStatus notifications to all registered mobile applications and the HMI +-- 1) Send OnRCStatus notifications to all registered mobile applications and the HMI with allowed = true --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua b/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua index ada406bd2c..6a6745746f 100644 --- a/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua +++ b/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua @@ -10,7 +10,7 @@ -- 1) RC functionality is disallowed on HMI -- 2) RC application is registered -- SDL must: --- 1) Not send OnRCStatus notification to registered mobile application and the HMI +-- 1) Send OnRCStatus(allowed = false, freeModules = {}, allocatedModules = {}) notification to registered mobile application and the HMI --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -21,16 +21,16 @@ runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] local function disableRCFromHMI() - common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) - common.wait(2000) + common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) + common.wait(2000) end -local function registerAppWithoutRCNotification() - common.rai_n() - common.getMobileSession():ExpectNotification("OnRCStatus") - :Times(0) - EXPECT_HMINOTIFICATION("RC.OnRCStatus") - :Times(0) +local function registerAppOnRCStatusAllowFalse() + common.rai_n() + common.getMobileSession():ExpectNotification("OnRCStatus", + { allowed = false, freeModules = {}, allocatedModules = {} }) + EXPECT_HMINOTIFICATION("RC.OnRCStatus") + :Times(0) end --[[ Scenario ]] @@ -40,7 +40,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("RC functionality is disallowed from HMI", disableRCFromHMI) runner.Title("Test") -runner.Step("Register RC application without OnRCStatus notification", registerAppWithoutRCNotification) +runner.Step("Register RC application with OnRCStatus(allowed=false)", registerAppOnRCStatusAllowFalse) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/003_registration_non_rc_app.lua b/test_scripts/RC/OnRCStatus/003_registration_non_rc_app.lua index 26d1c54549..4c69ebd2b9 100644 --- a/test_scripts/RC/OnRCStatus/003_registration_non_rc_app.lua +++ b/test_scripts/RC/OnRCStatus/003_registration_non_rc_app.lua @@ -23,11 +23,11 @@ config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } --[[ Local Functions ]] local function registerNonRCApp() - common.rai_n() - common.getMobileSession():ExpectNotification("OnRCStatus") - :Times(0) - EXPECT_HMINOTIFICATION("RC.OnRCStatus") - :Times(0) + common.rai_n() + common.getMobileSession():ExpectNotification("OnRCStatus") + :Times(0) + EXPECT_HMINOTIFICATION("RC.OnRCStatus") + :Times(0) end --[[ Scenario ]] diff --git a/test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua b/test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua index af4baac2ad..1c26801cef 100644 --- a/test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua +++ b/test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua @@ -23,12 +23,12 @@ runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] local function subscribeToModuleWOOnRCStatus(pModuleType) - common.subscribeToModule(pModuleType) - common.getMobileSession(1):ExpectNotification("OnRCStatus") - :Times(0) - common.getMobileSession(2):ExpectNotification("OnRCStatus") - :Times(0) - EXPECT_HMINOTIFICATION("RC.OnRCStatus") + common.subscribeToModule(pModuleType) + common.getMobileSession(1):ExpectNotification("OnRCStatus") + :Times(0) + common.getMobileSession(2):ExpectNotification("OnRCStatus") + :Times(0) + EXPECT_HMINOTIFICATION("RC.OnRCStatus") :Times(0) end @@ -42,7 +42,7 @@ runner.Step("Register RC application 2", common.registerRCApplication, { 2 }) runner.Title("Test") for _, mod in pairs(common.getModules()) do - runner.Step("GetInteriorVehicleData " .. mod, subscribeToModuleWOOnRCStatus, { mod }) + runner.Step("GetInteriorVehicleData " .. mod, subscribeToModuleWOOnRCStatus, { mod }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua b/test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua index a9f27e11b6..e7a0a4507c 100644 --- a/test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua +++ b/test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua @@ -29,11 +29,11 @@ local allocatedModules = { --[[ Local Functions ]] local function setVehicleData(pModuleType) - local pModuleStatusAllocatedApp, pModuleStatusAnotherApp = common.setModuleStatus(freeModules, allocatedModules, pModuleType) - common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") - common.validateOnRCStatusForApp(1, pModuleStatusAllocatedApp) - common.validateOnRCStatusForApp(2, pModuleStatusAnotherApp) - common.validateOnRCStatusForHMI(2, { pModuleStatusAllocatedApp, pModuleStatusAnotherApp }, 1) + local pModuleStatusAllocatedApp, pModuleStatusAnotherApp = common.setModuleStatus(freeModules, allocatedModules, pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatusAllocatedApp) + common.validateOnRCStatusForApp(2, pModuleStatusAnotherApp) + common.validateOnRCStatusForHMI(2, { pModuleStatusAllocatedApp, pModuleStatusAnotherApp }, 1) end --[[ Scenario ]] @@ -46,7 +46,7 @@ runner.Step("Register RC application 2", common.registerRCApplication, { 2 }) runner.Title("Test") for _, mod in pairs(common.getModules()) do - runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) + runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua b/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua index 8bee18d8b4..4badbb1fb0 100644 --- a/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua +++ b/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua @@ -24,7 +24,7 @@ runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local freeModules = common.getAllModules() local allocatedModules = { - [1] = {} + [1] = {} } --[[ General configuration parameters ]] @@ -32,12 +32,12 @@ config.application2.registerAppInterfaceParams.appHMIType = { "DEFAULT" } --[[ Local Functions ]] local function alocateModule(pModuleType) - local pModuleStatus = common.setModuleStatus(freeModules, allocatedModules, pModuleType) - common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") - common.validateOnRCStatusForApp(1, pModuleStatus) - common.validateOnRCStatusForHMI(1, { pModuleStatus }) - common.getMobileSession(2):ExpectNotification("OnRCStatus") - :Times(0) + local pModuleStatus = common.setModuleStatus(freeModules, allocatedModules, pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatus) + common.validateOnRCStatusForHMI(1, { pModuleStatus }) + common.getMobileSession(2):ExpectNotification("OnRCStatus") + :Times(0) end --[[ Scenario ]] @@ -50,7 +50,7 @@ runner.Step("Register non-RC application 2", common.rai_n, { 2 }) runner.Title("Test") for _, mod in pairs(common.getModules()) do - runner.Step("Allocation of module " .. mod, alocateModule, { mod }) + runner.Step("Allocation of module " .. mod, alocateModule, { mod }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/OnRCStatus/018_notification_by_driver_consent.lua b/test_scripts/RC/OnRCStatus/018_notification_by_driver_consent.lua index 0ce135e75e..4c420187a7 100644 --- a/test_scripts/RC/OnRCStatus/018_notification_by_driver_consent.lua +++ b/test_scripts/RC/OnRCStatus/018_notification_by_driver_consent.lua @@ -52,7 +52,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Set AccessMode ASK_DRIVER", common.defineRAMode, { true, "ASK_DRIVER" }) runner.Step("Register RC application 1", common.registerRCApplication, { 1 }) runner.Step("Activate App 1", common.activateApp, { 1 }) -runner.Step("Register RC application 1", common.registerRCApplication, { 2 }) +runner.Step("Register RC application 2", common.registerRCApplication, { 2 }) runner.Step("Activate App 2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua b/test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua new file mode 100644 index 0000000000..2c9be876e0 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: +-- In case: +-- 1) RC functionality is allowed on HMI +-- 2) RC application is registered +-- 3) RC functionality is disallowed on HMI +-- SDL must: +-- 1) Send OnRCStatus notification with allowed = false to registered mobile application and +-- not send to the HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function disableRCFromHMI() + common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) + common.getMobileSession():ExpectNotification("OnRCStatus", + { allowed = false, freeModules = {}, allocatedModules = {} }) + EXPECT_HMINOTIFICATION("RC.OnRCStatus") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("OnRCStatus notification by app registration", common.registerRCApplication, { 1 , true }) + +runner.Title("Test") +runner.Step("RC functionality is disallowed from HMI", disableRCFromHMI) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua b/test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua new file mode 100644 index 0000000000..41cb86b755 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua @@ -0,0 +1,68 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: +-- In case: +-- 1) RC functionality is disallowed on HMI +-- 2) RC application is registered +-- 3) RC functionality is allowed on HMI +-- SDL must: +-- 1) Send OnRCStatus notification with allowed = true to registered mobile application and +-- not send to the HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') +local commonRC = require('test_scripts/RC/commonRC') +local test = require("user_modules/dummy_connecttest") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function disableRCFromHMI() + common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) + common.wait(2000) +end + +local function registerRCAppRCDisallowed() + local pModuleStatusForApp = { + freeModules = {}, + allocatedModules = { }, + allowed = false + } + + commonRC.rai_n(1, test) + common.validateOnRCStatusForApp(1, pModuleStatusForApp, true) + EXPECT_HMINOTIFICATION("RC.OnRCStatus") + :Times(0) +end + +local function enableRCFromHMI() + local pModuleStatus = { + freeModules = common.getModulesArray(common.getAllModules()), + allocatedModules = { }, + allowed = true + } + common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = true }) + common.validateOnRCStatusForApp(1, pModuleStatus, true) + EXPECT_HMINOTIFICATION("RC.OnRCStatus") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RC functionality is disallowed from HMI", disableRCFromHMI) +runner.Step("RC app registration", registerRCAppRCDisallowed) + +runner.Title("Test") +runner.Step("RC functionality is allowed from HMI", enableRCFromHMI) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua index 6a32f82142..659ef8c065 100644 --- a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua +++ b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua @@ -97,17 +97,27 @@ function m.getHMIAppIdsRC() return out end -function m.registerRCApplication(pAppId) +function m.registerRCApplication(pAppId, pAllowed) if not pAppId then pAppId = 1 end - local pModuleStatus = { - freeModules = m.getModulesArray(m.getAllModules()), + if pAllowed == nil then pAllowed = true end + local freeModulesArray = {} + if true == pAllowed then + freeModulesArray = m.getModulesArray(m.getAllModules()) + end + local pModuleStatusForApp = { + freeModules = freeModulesArray, + allocatedModules = { }, + allowed = pAllowed + } + local pModuleStatusForHMI = { + freeModules = freeModulesArray, allocatedModules = { } } commonRC.rai_n(pAppId, test) for i = 1, pAppId do - m.validateOnRCStatusForApp(i, pModuleStatus) + m.validateOnRCStatusForApp(i, pModuleStatusForApp, pAllowed) end - m.validateOnRCStatusForHMI(pAppId, { pModuleStatus }) + m.validateOnRCStatusForHMI(pAppId, { pModuleStatusForHMI }) end function m.raiPTU_n(ptu_update_func, pAppId) @@ -245,7 +255,8 @@ function m.sortModules(pModulesArray) table.sort(pModulesArray, f) end -function m.validateOnRCStatusForApp(pAppId, pExpData) +function m.validateOnRCStatusForApp(pAppId, pExpData, isAllowedExpected) + if isAllowedExpected == nil then isAllowedExpected = false end m.getMobileSession(pAppId):ExpectNotification("OnRCStatus") :ValidIf(function(_, d) m.sortModules(pExpData.freeModules) @@ -254,6 +265,13 @@ function m.validateOnRCStatusForApp(pAppId, pExpData) m.sortModules(d.payload.allocatedModules) return compareValues(pExpData, d.payload, "payload") end) + :ValidIf(function(_, d) + if d.payload.allowed ~= nil and + isAllowedExpected == false then + return false, "RC.OnRCStatus notification contains unexpected 'allowed' parameter" + end + return true + end) end function m.validateOnRCStatusForHMI(pCountOfRCApps, pExpData, pAllocApp) @@ -278,6 +296,12 @@ function m.validateOnRCStatusForHMI(pCountOfRCApps, pExpData, pAllocApp) return compareValues(pExpData[AnotherApp], d.params, "params") end end) + :ValidIf(function(_, d) + if d.params.allowed ~= nil then + return false, "RC.OnRCStatus notification contains unexpected 'allowed' parameter" + end + return true + end) :ValidIf(function(e, d) if e.occurences == 1 then usedHmiAppIds = {} diff --git a/test_sets/rc_OnRCStatus.txt b/test_sets/rc_OnRCStatus.txt index fe7ffc1f2e..d133ea6673 100644 --- a/test_sets/rc_OnRCStatus.txt +++ b/test_sets/rc_OnRCStatus.txt @@ -19,3 +19,5 @@ ./test_scripts/RC/OnRCStatus/019_notification_by_app_disconnect.lua ./test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua ./test_scripts/RC/OnRCStatus/021_notification_in_case_AUTO_DENY_mode.lua +./test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua +./test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua From b88ffc31f928e722b38937f85b37fbecb1ee403e Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 28 Jun 2018 16:42:10 +0300 Subject: [PATCH 469/681] Update according to requirements update --- ..._disallowed_on_hmi_with_registered_app.lua | 20 ++++-- ...ity_allowed_on_hmi_with_registered_app.lua | 16 +++-- ...tion_by_apps_registration_several_apps.lua | 50 ++++++++++++++ ...onality_disallowed_on_hmi_sevaral_apps.lua | 64 ++++++++++++++++++ ...6_registration_non_rc_app_several_apps.lua | 53 +++++++++++++++ ..._non_rc_app_several_apps_rc_disallowed.lua | 66 +++++++++++++++++++ .../RC/OnRCStatus/commonOnRCStatus.lua | 13 +++- 7 files changed, 268 insertions(+), 14 deletions(-) create mode 100644 test_scripts/RC/OnRCStatus/024_notification_by_apps_registration_several_apps.lua create mode 100644 test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_sevaral_apps.lua create mode 100644 test_scripts/RC/OnRCStatus/026_registration_non_rc_app_several_apps.lua create mode 100644 test_scripts/RC/OnRCStatus/027_registration_non_rc_app_several_apps_rc_disallowed.lua diff --git a/test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua b/test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua index 2c9be876e0..10590191a1 100644 --- a/test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua +++ b/test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua @@ -8,11 +8,13 @@ -- Description: -- In case: -- 1) RC functionality is allowed on HMI --- 2) RC application is registered --- 3) RC functionality is disallowed on HMI +-- 2) RC app1 is registered +-- 3) Non-RC app2 is registered +-- 4) RC functionality is disallowed on HMI -- SDL must: --- 1) Send OnRCStatus notification with allowed = false to registered mobile application and --- not send to the HMI +-- 1) SDL sends an OnRCStatus notification to the HMI (allocatedModules=[], freeModules=[x,y,z], due to resource freed) +-- 2) SDL sends OnRCStatus notifications to the already registered RC apps (allowed=false, allocatedModules=[], freeModules=[]) +-- 3) SDL does not send OnRCStatus notifications to the already registered non-RC apps --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -20,13 +22,16 @@ local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application2.registerAppInterfaceParams.appHMIType = { "DEFAULT" } --[[ Local Functions ]] local function disableRCFromHMI() common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) - common.getMobileSession():ExpectNotification("OnRCStatus", + common.getMobileSession(1):ExpectNotification("OnRCStatus", { allowed = false, freeModules = {}, allocatedModules = {} }) - EXPECT_HMINOTIFICATION("RC.OnRCStatus") + EXPECT_HMINOTIFICATION("RC.OnRCStatus", {allocatedModules = {}, freeModules = common.getAllModules()}) + common.getMobileSession(2):ExpectNotification("OnRCStatus") :Times(0) end @@ -34,7 +39,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("OnRCStatus notification by app registration", common.registerRCApplication, { 1 , true }) +runner.Step("RC app1 registration", common.registerRCApplication, { 1 }) +runner.Step("Non-RC app2 registration", common.registerNonRCApp, { 2 }) runner.Title("Test") runner.Step("RC functionality is disallowed from HMI", disableRCFromHMI) diff --git a/test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua b/test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua index 41cb86b755..526e25e1ee 100644 --- a/test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua +++ b/test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua @@ -8,11 +8,13 @@ -- Description: -- In case: -- 1) RC functionality is disallowed on HMI --- 2) RC application is registered --- 3) RC functionality is allowed on HMI +-- 2) RC app1 is registered +-- 3) Non-RC app2 is registered +-- 4) RC functionality is allowed on HMI -- SDL must: --- 1) Send OnRCStatus notification with allowed = true to registered mobile application and --- not send to the HMI +-- 1) send an OnRCStatus notification to the HMI (allocatedModules=[], freeModules=[x,y,z]) +-- 2) send OnRCStatus notifications to the already registered RC apps (allowed=true, allocatedModules=[], freeModules=[x,y,z]) +-- 3) not send OnRCStatus notifications to the already registered non-RC apps --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -22,6 +24,8 @@ local test = require("user_modules/dummy_connecttest") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application2.registerAppInterfaceParams.appHMIType = { "DEFAULT" } --[[ Local Functions ]] local function disableRCFromHMI() @@ -50,7 +54,8 @@ local function enableRCFromHMI() } common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = true }) common.validateOnRCStatusForApp(1, pModuleStatus, true) - EXPECT_HMINOTIFICATION("RC.OnRCStatus") + EXPECT_HMINOTIFICATION("RC.OnRCStatus", {allocatedModules = {}, freeModules = common.getAllModules()}) + common.getMobileSession(2):ExpectNotification("OnRCStatus") :Times(0) end @@ -60,6 +65,7 @@ runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("RC functionality is disallowed from HMI", disableRCFromHMI) runner.Step("RC app registration", registerRCAppRCDisallowed) +runner.Step("Non-RC app1 registration", common.registerNonRCApp, { 2 }) runner.Title("Test") runner.Step("RC functionality is allowed from HMI", enableRCFromHMI) diff --git a/test_scripts/RC/OnRCStatus/024_notification_by_apps_registration_several_apps.lua b/test_scripts/RC/OnRCStatus/024_notification_by_apps_registration_several_apps.lua new file mode 100644 index 0000000000..fa28a3a653 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/024_notification_by_apps_registration_several_apps.lua @@ -0,0 +1,50 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: +-- In case: +-- 1) RC functionality is allowed on HMI +-- 2) RC app1 is registered +-- 3) Non-RC app2 is registered +-- 4) RC app registers +-- SDL must: +-- 1) send an OnRCStatus notification to the newly registered RC app (allowed=true, allocatedModules=[], freeModules=[x,y,z]) +-- 2) not send an OnRCStatus notification to the HMI +-- 3) not send OnRCStatus notifications to the already registered RC apps +-- 4) not send OnRCStatus notifications to the already registered non-RC apps +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application2.registerAppInterfaceParams.appHMIType = { "DEFAULT" } +config.application3.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } + +-- [[ Local Functions]] +local function registerRCapp() + common.registerRCApplication(3, true, 2) + common.getMobileSession(1):ExpectNotification("OnRCStatus") + :Times(0) + common.getMobileSession(2):ExpectNotification("OnRCStatus") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("RC app1 registration", common.registerRCApplication, { 1 }) +runner.Step("Non-RC app2 registration", common.registerNonRCApp, { 2 }) +runner.Step("RC app3 registration", registerRCapp) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_sevaral_apps.lua b/test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_sevaral_apps.lua new file mode 100644 index 0000000000..d66f9ce2e5 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_sevaral_apps.lua @@ -0,0 +1,64 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: +-- In case: +-- 1) RC functionality is disallowed on HMI +-- 2) RC app1 is registered +-- 3) Non-RC app2 is registered +-- 4) RC app3 starts registration +-- SDL must: +-- 1) Send an OnRCStatus notification to the newly registered RC app (allowed=false, allocatedModules=[], freeModules=[]) +-- 2) not send an OnRCStatus notification to the HMI +-- 3) not send OnRCStatus notifications to the already registered RC apps +-- 4) not send OnRCStatus notifications to the already registered non-RC apps +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application2.registerAppInterfaceParams.appHMIType = { "DEFAULT" } +config.application3.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } + +-- [[ Local Functions]] +local function registerAppOnRCStatusAllowFalse(pAppId) + common.rai_n(pAppId) + common.getMobileSession(pAppId):ExpectNotification("OnRCStatus", + { allowed = false, freeModules = {}, allocatedModules = {} }) + EXPECT_HMINOTIFICATION("RC.OnRCStatus") + :Times(0) +end + +local function registerRCapp() + registerAppOnRCStatusAllowFalse(3) + common.getMobileSession(1):ExpectNotification("OnRCStatus") + :Times(0) + common.getMobileSession(2):ExpectNotification("OnRCStatus") + :Times(0) +end + +local function disableRCFromHMI() + common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) + common.wait(2000) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RC functionality is disallowed from HMI", disableRCFromHMI) +runner.Step("RC app1 registration", registerAppOnRCStatusAllowFalse, { 1 }) +runner.Step("Non-RC app2 registration", common.registerNonRCApp, { 2 }) + +runner.Title("Test") +runner.Step("Register RC app3 with OnRCStatus(allowed=false)", registerRCapp) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/026_registration_non_rc_app_several_apps.lua b/test_scripts/RC/OnRCStatus/026_registration_non_rc_app_several_apps.lua new file mode 100644 index 0000000000..ac8ea4ee43 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/026_registration_non_rc_app_several_apps.lua @@ -0,0 +1,53 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: +-- In case: +-- In case: +-- 1) RC functionality is allowed on HMI +-- 2) RC app1 is registered +-- 3) Non-RC app2 is registered +-- 4) Non-RC app3 starts registration +-- SDL must: +-- 1) not send an OnRCStatus notification to the newly registered non-RC app +-- 2) not send an OnRCStatus notification to the HMI +-- 3) not send OnRCStatus notifications to the already registered RC apps +-- 4) not send OnRCStatus notifications to the already registered non-RC apps +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application2.registerAppInterfaceParams.appHMIType = { "DEFAULT" } +config.application3.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Functions ]] +local function registerNonRCAppSeveralApps() + common.registerNonRCApp(3) + common.getMobileSession(1):ExpectNotification("OnRCStatus") + :Times(0) + common.getMobileSession(2):ExpectNotification("OnRCStatus") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RC app1 registration", common.registerRCApplication, { 1 }) +runner.Step("Non-RC app2 registration", common.registerNonRCApp, { 2 }) + +runner.Title("Test") +runner.Step("Registration non-RC app3", registerNonRCAppSeveralApps) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/027_registration_non_rc_app_several_apps_rc_disallowed.lua b/test_scripts/RC/OnRCStatus/027_registration_non_rc_app_several_apps_rc_disallowed.lua new file mode 100644 index 0000000000..9806f3787d --- /dev/null +++ b/test_scripts/RC/OnRCStatus/027_registration_non_rc_app_several_apps_rc_disallowed.lua @@ -0,0 +1,66 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: +-- In case: +-- 1) RC functionality is disallowed on HMI +-- 2) RC app1 is registered +-- 3) Non-RC app2 is registered +-- 4) Non-RC app3 starts registration +-- SDL must: +-- 1) not send an OnRCStatus notification to the newly registered non-RC app +-- 2) not send an OnRCStatus notification to the HMI +-- 3) not send OnRCStatus notifications to the already registered RC apps +-- 4) not send OnRCStatus notifications to the already registered non-RC apps +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application2.registerAppInterfaceParams.appHMIType = { "DEFAULT" } +config.application3.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Functions ]] +local function disableRCFromHMI() + common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) + common.wait(2000) +end + +local function registerAppOnRCStatusAllowFalse(pAppId) + common.rai_n(pAppId) + common.getMobileSession(pAppId):ExpectNotification("OnRCStatus", + { allowed = false, freeModules = {}, allocatedModules = {} }) + EXPECT_HMINOTIFICATION("RC.OnRCStatus") + :Times(0) +end + +local function registerNonRCAppSeveralApps() + common.registerNonRCApp(3) + common.getMobileSession(1):ExpectNotification("OnRCStatus") + :Times(0) + common.getMobileSession(2):ExpectNotification("OnRCStatus") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RC functionality is disallowed from HMI", disableRCFromHMI) +runner.Step("RC app1 registration", registerAppOnRCStatusAllowFalse, { 1 }) +runner.Step("Non-RC app2 registration", common.registerNonRCApp, { 2 }) + +runner.Title("Test") +runner.Step("Registration non-RC app3", registerNonRCAppSeveralApps) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua index 659ef8c065..fea0bf5369 100644 --- a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua +++ b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua @@ -97,9 +97,10 @@ function m.getHMIAppIdsRC() return out end -function m.registerRCApplication(pAppId, pAllowed) +function m.registerRCApplication(pAppId, pAllowed, pCountOfRCApps) if not pAppId then pAppId = 1 end if pAllowed == nil then pAllowed = true end + if not pCountOfRCApps then pCountOfRCApps = pAppId end local freeModulesArray = {} if true == pAllowed then freeModulesArray = m.getModulesArray(m.getAllModules()) @@ -117,7 +118,7 @@ function m.registerRCApplication(pAppId, pAllowed) for i = 1, pAppId do m.validateOnRCStatusForApp(i, pModuleStatusForApp, pAllowed) end - m.validateOnRCStatusForHMI(pAppId, { pModuleStatusForHMI }) + m.validateOnRCStatusForHMI(pCountOfRCApps, { pModuleStatusForHMI }) end function m.raiPTU_n(ptu_update_func, pAppId) @@ -329,4 +330,12 @@ end m.wait = utils.wait +function m.registerNonRCApp(pAppId) + m.rai_n(pAppId) + m.getMobileSession(pAppId):ExpectNotification("OnRCStatus") + :Times(0) + EXPECT_HMINOTIFICATION("RC.OnRCStatus") + :Times(0) +end + return m From 4cc7e3f950e25c9f1c6115f1027b1b17ed0ace12 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 28 Jun 2018 18:02:20 +0300 Subject: [PATCH 470/681] Absence OnRCStatus on HMI by registration --- ...ation_in_case_of_policy_permissions_absence.lua | 7 ++----- ...ality_disallowed_on_hmi_with_registered_app.lua | 6 +++++- ...ionality_allowed_on_hmi_with_registered_app.lua | 6 +++++- ...ification_by_apps_registration_several_apps.lua | 10 +++++----- ...nctionality_disallowed_on_hmi_several_apps.lua} | 10 +++++----- test_scripts/RC/OnRCStatus/commonOnRCStatus.lua | 14 ++++---------- test_sets/rc_OnRCStatus.txt | 4 ++++ 7 files changed, 30 insertions(+), 27 deletions(-) rename test_scripts/RC/OnRCStatus/{025_notification_by_rc_functionality_disallowed_on_hmi_sevaral_apps.lua => 025_notification_by_rc_functionality_disallowed_on_hmi_several_apps.lua} (90%) diff --git a/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua b/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua index bb9cbe3dee..bb18f7c5ed 100644 --- a/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua +++ b/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua @@ -54,11 +54,8 @@ local function registerApp() common.raiPTU_n(pTUfunc, 1) common.getMobileSession(1):ExpectNotification("OnRCStatus") :Times(0) - local pModuleStatus = { - freeModules = common.getModulesArray(freeModules), - allocatedModules = common.getModulesArray(allocatedModules[1]) - } - common.validateOnRCStatusForHMI(1, { pModuleStatus }) + EXPECT_HMICALL("RC.OnRCStatus") + :Times(0) end --[[ Scenario ]] diff --git a/test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua b/test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua index 10590191a1..deb8652963 100644 --- a/test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua +++ b/test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua @@ -30,7 +30,11 @@ local function disableRCFromHMI() common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) common.getMobileSession(1):ExpectNotification("OnRCStatus", { allowed = false, freeModules = {}, allocatedModules = {} }) - EXPECT_HMINOTIFICATION("RC.OnRCStatus", {allocatedModules = {}, freeModules = common.getAllModules()}) + local pModuleStatusHMI = { + freeModules = common.getModulesArray(common.getAllModules()), + allocatedModules = { } + } + common.validateOnRCStatusForHMI(1, { pModuleStatusHMI }) common.getMobileSession(2):ExpectNotification("OnRCStatus") :Times(0) end diff --git a/test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua b/test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua index 526e25e1ee..c1fb1f2e2d 100644 --- a/test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua +++ b/test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua @@ -52,9 +52,13 @@ local function enableRCFromHMI() allocatedModules = { }, allowed = true } + local pModuleStatusHMI = { + freeModules = common.getModulesArray(common.getAllModules()), + allocatedModules = { } + } common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = true }) common.validateOnRCStatusForApp(1, pModuleStatus, true) - EXPECT_HMINOTIFICATION("RC.OnRCStatus", {allocatedModules = {}, freeModules = common.getAllModules()}) + common.validateOnRCStatusForHMI(1, { pModuleStatusHMI }) common.getMobileSession(2):ExpectNotification("OnRCStatus") :Times(0) end diff --git a/test_scripts/RC/OnRCStatus/024_notification_by_apps_registration_several_apps.lua b/test_scripts/RC/OnRCStatus/024_notification_by_apps_registration_several_apps.lua index fa28a3a653..2fb7a4af18 100644 --- a/test_scripts/RC/OnRCStatus/024_notification_by_apps_registration_several_apps.lua +++ b/test_scripts/RC/OnRCStatus/024_notification_by_apps_registration_several_apps.lua @@ -24,15 +24,15 @@ local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } -config.application2.registerAppInterfaceParams.appHMIType = { "DEFAULT" } -config.application3.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application3.registerAppInterfaceParams.appHMIType = { "DEFAULT" } -- [[ Local Functions]] local function registerRCapp() - common.registerRCApplication(3, true, 2) + common.registerRCApplication(2) common.getMobileSession(1):ExpectNotification("OnRCStatus") :Times(0) - common.getMobileSession(2):ExpectNotification("OnRCStatus") + common.getMobileSession(3):ExpectNotification("OnRCStatus") :Times(0) end @@ -43,7 +43,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("RC app1 registration", common.registerRCApplication, { 1 }) -runner.Step("Non-RC app2 registration", common.registerNonRCApp, { 2 }) +runner.Step("Non-RC app2 registration", common.registerNonRCApp, { 3 }) runner.Step("RC app3 registration", registerRCapp) runner.Title("Postconditions") diff --git a/test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_sevaral_apps.lua b/test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_several_apps.lua similarity index 90% rename from test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_sevaral_apps.lua rename to test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_several_apps.lua index d66f9ce2e5..3adea5bff6 100644 --- a/test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_sevaral_apps.lua +++ b/test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_several_apps.lua @@ -24,8 +24,8 @@ local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } -config.application2.registerAppInterfaceParams.appHMIType = { "DEFAULT" } -config.application3.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application3.registerAppInterfaceParams.appHMIType = { "DEFAULT" } -- [[ Local Functions]] local function registerAppOnRCStatusAllowFalse(pAppId) @@ -37,10 +37,10 @@ local function registerAppOnRCStatusAllowFalse(pAppId) end local function registerRCapp() - registerAppOnRCStatusAllowFalse(3) + registerAppOnRCStatusAllowFalse(2) common.getMobileSession(1):ExpectNotification("OnRCStatus") :Times(0) - common.getMobileSession(2):ExpectNotification("OnRCStatus") + common.getMobileSession(3):ExpectNotification("OnRCStatus") :Times(0) end @@ -55,7 +55,7 @@ runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("RC functionality is disallowed from HMI", disableRCFromHMI) runner.Step("RC app1 registration", registerAppOnRCStatusAllowFalse, { 1 }) -runner.Step("Non-RC app2 registration", common.registerNonRCApp, { 2 }) +runner.Step("Non-RC app2 registration", common.registerNonRCApp, { 3 }) runner.Title("Test") runner.Step("Register RC app3 with OnRCStatus(allowed=false)", registerRCapp) diff --git a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua index fea0bf5369..245c9efbf2 100644 --- a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua +++ b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua @@ -97,10 +97,9 @@ function m.getHMIAppIdsRC() return out end -function m.registerRCApplication(pAppId, pAllowed, pCountOfRCApps) +function m.registerRCApplication(pAppId, pAllowed) if not pAppId then pAppId = 1 end if pAllowed == nil then pAllowed = true end - if not pCountOfRCApps then pCountOfRCApps = pAppId end local freeModulesArray = {} if true == pAllowed then freeModulesArray = m.getModulesArray(m.getAllModules()) @@ -110,15 +109,10 @@ function m.registerRCApplication(pAppId, pAllowed, pCountOfRCApps) allocatedModules = { }, allowed = pAllowed } - local pModuleStatusForHMI = { - freeModules = freeModulesArray, - allocatedModules = { } - } commonRC.rai_n(pAppId, test) - for i = 1, pAppId do - m.validateOnRCStatusForApp(i, pModuleStatusForApp, pAllowed) - end - m.validateOnRCStatusForHMI(pCountOfRCApps, { pModuleStatusForHMI }) + m.validateOnRCStatusForApp(pAppId, pModuleStatusForApp, pAllowed) + EXPECT_HMICALL("RC.OnRCStatus") + :Times(0) end function m.raiPTU_n(ptu_update_func, pAppId) diff --git a/test_sets/rc_OnRCStatus.txt b/test_sets/rc_OnRCStatus.txt index d133ea6673..182cff870f 100644 --- a/test_sets/rc_OnRCStatus.txt +++ b/test_sets/rc_OnRCStatus.txt @@ -21,3 +21,7 @@ ./test_scripts/RC/OnRCStatus/021_notification_in_case_AUTO_DENY_mode.lua ./test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua ./test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua +./test_scripts/RC/OnRCStatus/024_notification_by_apps_registration_several_apps.lua +./test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_sevaral_apps.lua +./test_scripts/RC/OnRCStatus/026_registration_non_rc_app_several_apps.lua +./test_scripts/RC/OnRCStatus/027_registration_non_rc_app_several_apps_rc_disallowed.lua From 212f6c6970dfd04ea371a7539c4e607783baa3c4 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 28 Jun 2018 18:55:50 +0300 Subject: [PATCH 471/681] Update in scripts description --- .../RC/OnRCStatus/001_notification_by_apps_registration.lua | 2 +- .../002_notification_by_rc_functionality_disallowed_on_hmi.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua b/test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua index c6bf693ebd..cadf8e0bc3 100644 --- a/test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua +++ b/test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua @@ -9,7 +9,7 @@ -- In case: -- 1) RC app1 and RC app2 are registered -- SDL must: --- 1) Send OnRCStatus notifications to all registered mobile applications and the HMI with allowed = true +-- 1) Send OnRCStatus notifications to registered mobile application with allowed = true --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua b/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua index 6a6745746f..ec8de2ea3d 100644 --- a/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua +++ b/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua @@ -10,7 +10,7 @@ -- 1) RC functionality is disallowed on HMI -- 2) RC application is registered -- SDL must: --- 1) Send OnRCStatus(allowed = false, freeModules = {}, allocatedModules = {}) notification to registered mobile application and the HMI +-- 1) Send OnRCStatus(allowed = false, freeModules = {}, allocatedModules = {}) notification to registered mobile application --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') From 00efb526de7156cc50f4534a961a46e13f09ddf3 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 28 Jun 2018 19:46:19 +0300 Subject: [PATCH 472/681] Fix test set --- test_sets/rc_OnRCStatus.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_sets/rc_OnRCStatus.txt b/test_sets/rc_OnRCStatus.txt index 182cff870f..8ef0281ab1 100644 --- a/test_sets/rc_OnRCStatus.txt +++ b/test_sets/rc_OnRCStatus.txt @@ -22,6 +22,6 @@ ./test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua ./test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua ./test_scripts/RC/OnRCStatus/024_notification_by_apps_registration_several_apps.lua -./test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_sevaral_apps.lua +./test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_several_apps.lua ./test_scripts/RC/OnRCStatus/026_registration_non_rc_app_several_apps.lua ./test_scripts/RC/OnRCStatus/027_registration_non_rc_app_several_apps_rc_disallowed.lua From d35886504b6f4823cecc4056ed1af6666482b627 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 29 Jun 2018 10:40:19 +0300 Subject: [PATCH 473/681] Add additional script --- ...allowed_on_hmi_with_allocated_resource.lua | 63 +++++++++++++++++++ test_sets/rc_OnRCStatus.txt | 1 + 2 files changed, 64 insertions(+) create mode 100644 test_scripts/RC/OnRCStatus/028_notification_by_rc_functionality_disallowed_on_hmi_with_allocated_resource.lua diff --git a/test_scripts/RC/OnRCStatus/028_notification_by_rc_functionality_disallowed_on_hmi_with_allocated_resource.lua b/test_scripts/RC/OnRCStatus/028_notification_by_rc_functionality_disallowed_on_hmi_with_allocated_resource.lua new file mode 100644 index 0000000000..da22089435 --- /dev/null +++ b/test_scripts/RC/OnRCStatus/028_notification_by_rc_functionality_disallowed_on_hmi_with_allocated_resource.lua @@ -0,0 +1,63 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: +-- In case: +-- 1) RC functionality is allowed on HMI +-- 2) RC app is registered +-- 3) RC app allocates module via SetInteriorVehicleData +-- 4) RC functionality is disallowed on HMI +-- SDL must: +-- 1) SDL sends an OnRCStatus notification to the HMI (allocatedModules=[], freeModules=[x,y,z], due to resource freed) +-- 2) SDL sends OnRCStatus notifications to the already registered RC apps (allowed=false, allocatedModules=[], freeModules=[]) +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } + +--[[ Local Variables ]] +local freeModules = common.getAllModules() +local allocatedModules = { + [1] = {} +} + +--[[ Local Functions ]] +local function disableRCFromHMI() + common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) + common.getMobileSession():ExpectNotification("OnRCStatus", + { allowed = false, freeModules = {}, allocatedModules = {} }) + local pModuleStatusHMI = { + freeModules = common.getModulesArray(common.getAllModules()), + allocatedModules = { } + } + common.validateOnRCStatusForHMI(1, { pModuleStatusHMI }) +end + +local function setVehicleData(pModuleType) + local pModuleStatus = common.setModuleStatus(freeModules, allocatedModules, pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatus) + common.validateOnRCStatusForHMI(1, { pModuleStatus }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RC app registration", common.registerRCApplication) +runner.Step("Activate App", common.activateApp) +runner.Step("SetInteriorVehicleData RADIO", setVehicleData, { "RADIO" }) + +runner.Title("Test") +runner.Step("RC functionality is disallowed from HMI", disableRCFromHMI) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_sets/rc_OnRCStatus.txt b/test_sets/rc_OnRCStatus.txt index 8ef0281ab1..bfcc3b24da 100644 --- a/test_sets/rc_OnRCStatus.txt +++ b/test_sets/rc_OnRCStatus.txt @@ -25,3 +25,4 @@ ./test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_several_apps.lua ./test_scripts/RC/OnRCStatus/026_registration_non_rc_app_several_apps.lua ./test_scripts/RC/OnRCStatus/027_registration_non_rc_app_several_apps_rc_disallowed.lua +./test_scripts/RC/OnRCStatus/028_notification_by_rc_functionality_disallowed_on_hmi_with_allocated_resource.lua From 5ad2c5ca964fbe15caed99f8294701f4493c9c1c Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Mon, 2 Jul 2018 12:46:31 +0300 Subject: [PATCH 474/681] Added script with revoking of several modules --- ..._by_revoking_several_modules_by_policy.lua | 72 +++++++++++++++++++ test_sets/rc_OnRCStatus.txt | 1 + 2 files changed, 73 insertions(+) create mode 100644 test_scripts/RC/OnRCStatus/029_notification_by_revoking_several_modules_by_policy.lua diff --git a/test_scripts/RC/OnRCStatus/029_notification_by_revoking_several_modules_by_policy.lua b/test_scripts/RC/OnRCStatus/029_notification_by_revoking_several_modules_by_policy.lua new file mode 100644 index 0000000000..56a3fc1c7c --- /dev/null +++ b/test_scripts/RC/OnRCStatus/029_notification_by_revoking_several_modules_by_policy.lua @@ -0,0 +1,72 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] TBD +-- +-- Description: +-- In case: +-- 1) RC app is registered +-- 2) App allocates module CLIMATE, RADIO +-- 3) PTU for app is performed with revoking of allocated modules +-- SDL must: +-- 1) send OnRCStatus notifications to mobile app and to the HMI with all modules in freeModules by PTU with revoking of allocated modules +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/OnRCStatus/commonOnRCStatus') +local json = require('modules/json') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application2.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Variables ]] +local freeModules = common.getAllModules() +local allocatedModules = { + [1] = { } +} + +--[[ Local Functions ]] +local function pTUfunc(tbl) + local appId1 = config.application1.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId1] = common.getRCAppConfig(tbl) + tbl.policy_table.app_policies[appId1].moduleType = json.EMPTY_ARRAY + local appId2 = config.application2.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId2] = common.getRCAppConfig(tbl) +end + +local function alocateModule(pModuleType) + local pModuleStatus = common.setModuleStatus(freeModules, allocatedModules, pModuleType) + common.rpcAllowed(pModuleType, 1, "SetInteriorVehicleData") + common.validateOnRCStatusForApp(1, pModuleStatus) + common.validateOnRCStatusForHMI(1, { pModuleStatus }) +end + +local function registrationAppWithRevokingModule() + common.raiPTU_n(pTUfunc, 2) + local pModuleStatus = { + freeModules = common.getModulesArray(common.getAllModules()), + allocatedModules = { } + } + common.validateOnRCStatusForApp(1, pModuleStatus) + common.validateOnRCStatusForHMI(1, { pModuleStatus }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions, { 1 }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register RC application 1", common.registerRCApplication) +runner.Step("Activate App 1", common.activateApp) +runner.Step("Allocating module CLIMATE", alocateModule, { "CLIMATE" }) +runner.Step("Allocating module RADIO", alocateModule, { "RADIO" }) + +runner.Title("Test") +runner.Step("OnRCStatus by PTU with revoking of allocated module", registrationAppWithRevokingModule) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_sets/rc_OnRCStatus.txt b/test_sets/rc_OnRCStatus.txt index bfcc3b24da..c4e581fa51 100644 --- a/test_sets/rc_OnRCStatus.txt +++ b/test_sets/rc_OnRCStatus.txt @@ -26,3 +26,4 @@ ./test_scripts/RC/OnRCStatus/026_registration_non_rc_app_several_apps.lua ./test_scripts/RC/OnRCStatus/027_registration_non_rc_app_several_apps_rc_disallowed.lua ./test_scripts/RC/OnRCStatus/028_notification_by_rc_functionality_disallowed_on_hmi_with_allocated_resource.lua +./test_scripts/RC/OnRCStatus/029_notification_by_revoking_several_modules_by_policy.lua From 619c298aea8a1823cc2221770312f8e224c78d50 Mon Sep 17 00:00:00 2001 From: "Ira Lytvynenko (GitHub)" Date: Mon, 16 Jul 2018 12:19:59 +0300 Subject: [PATCH 475/681] Fix validation of parameter allowed --- .../RC/OnRCStatus/commonOnRCStatus.lua | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua index 245c9efbf2..13bdc9acaa 100644 --- a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua +++ b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua @@ -110,7 +110,7 @@ function m.registerRCApplication(pAppId, pAllowed) allowed = pAllowed } commonRC.rai_n(pAppId, test) - m.validateOnRCStatusForApp(pAppId, pModuleStatusForApp, pAllowed) + m.validateOnRCStatusForApp(pAppId, pModuleStatusForApp) EXPECT_HMICALL("RC.OnRCStatus") :Times(0) end @@ -250,23 +250,23 @@ function m.sortModules(pModulesArray) table.sort(pModulesArray, f) end -function m.validateOnRCStatusForApp(pAppId, pExpData, isAllowedExpected) - if isAllowedExpected == nil then isAllowedExpected = false end - m.getMobileSession(pAppId):ExpectNotification("OnRCStatus") - :ValidIf(function(_, d) - m.sortModules(pExpData.freeModules) - m.sortModules(pExpData.allocatedModules) - m.sortModules(d.payload.freeModules) - m.sortModules(d.payload.allocatedModules) - return compareValues(pExpData, d.payload, "payload") - end) - :ValidIf(function(_, d) - if d.payload.allowed ~= nil and - isAllowedExpected == false then - return false, "RC.OnRCStatus notification contains unexpected 'allowed' parameter" - end - return true - end) +function m.validateOnRCStatusForApp(pAppId, pExpData) + local ExpData = utils.cloneTable(pExpData) + if ExpData.allowed == nil then ExpData.allowed = true end + m.getMobileSession(pAppId):ExpectNotification("OnRCStatus") + :ValidIf(function(_, d) + m.sortModules(ExpData.freeModules) + m.sortModules(ExpData.allocatedModules) + m.sortModules(d.payload.freeModules) + m.sortModules(d.payload.allocatedModules) + return compareValues(ExpData, d.payload, "payload") + end) + :ValidIf(function(_, d) + if d.payload.allowed == nil then + return false, "RC.OnRCStatus notification doesn't contains 'allowed' parameter" + end + return true + end) end function m.validateOnRCStatusForHMI(pCountOfRCApps, pExpData, pAllocApp) From 6d8764788c8849a8f098a32af01b9819dd09c6f7 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 10 Jul 2018 13:29:22 +0300 Subject: [PATCH 476/681] Initial scripts for handling vr help --- ...activation_from_default_hmi_background.lua | 65 ++++ ...0_SetGlobalProp_default_hmi_background.lua | 56 +++ ...Prop_with_added_commands_after_timeout.lua | 37 ++ ...op_commands_with_and_without_vrCommand.lua | 51 +++ ...without_deleted_commands_after_timeout.lua | 47 +++ ...p_processing_30_commands_after_timeout.lua | 45 +++ ...tion_after_timeout_only_for_addcommand.lua | 49 +++ ..._SetGlobalProp_procesing_added_choices.lua | 72 ++++ .../007_SetGlobalProp_absence_in_NONE.lua | 32 ++ ...lobalProp_absence_after_custom_request.lua | 39 +++ ...and_after_custom_request_after_timeout.lua | 48 +++ ...and_after_custom_request_after_timeout.lua | 48 +++ ...1_SetGlobalProp_custom_helpPrompt_only.lua | 72 ++++ .../012_SetGlobalProp_custom_vrHelp_only.lua | 71 ++++ ...rompt_and_vrHelp_in_different_requests.lua | 81 +++++ ..._request_without_helpPrompt_and_vrHelp.lua | 50 +++ ...d_commands_after_timeout_by_resumption.lua | 43 +++ ...th_and_without_vrCommand_by_resumption.lua | 83 +++++ ...d_commands_after_timeout_by_resumption.lua | 53 +++ ...0_commands_after_timeout_by_resumption.lua | 48 +++ ..._procesing_added_choices_by_resumption.lua | 104 ++++++ ..._after_custom_request_after_resumption.lua | 43 +++ ...after_custom_request_before_resumption.lua | 61 ++++ ...ed_vrHelp_helpPrompt_before_resumption.lua | 52 +++ ...p_custom_helpPrompt_only_by_resumption.lua | 77 +++++ ...lProp_custom_vrHelp_only_by_resumption.lua | 76 ++++ ...ut_helpPrompt_and_vrHelp_by_resumption.lua | 55 +++ ...l_vrCommands_in_one_addCommand_request.lua | 39 +++ ...n_one_addCommand_request_by_resumption.lua | 44 +++ ...8_SetGlobalProp_invalid_custom_request.lua | 53 +++ ..._SetGlobalProp_rejected_custom_request.lua | 57 +++ ...balProp_only_successful_added_commands.lua | 61 ++++ ...ly_without_successful_deleted_commands.lua | 65 ++++ .../commonVRhelp.lua | 325 ++++++++++++++++++ 34 files changed, 2202 insertions(+) create mode 100644 test_scripts/Handling_VR_help_requests/000_SetGlobalProp_after_activation_from_default_hmi_background.lua create mode 100644 test_scripts/Handling_VR_help_requests/000_SetGlobalProp_default_hmi_background.lua create mode 100644 test_scripts/Handling_VR_help_requests/001_SetGlobalProp_with_added_commands_after_timeout.lua create mode 100644 test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua create mode 100644 test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands_after_timeout.lua create mode 100644 test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua create mode 100644 test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua create mode 100644 test_scripts/Handling_VR_help_requests/006_SetGlobalProp_procesing_added_choices.lua create mode 100644 test_scripts/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua create mode 100644 test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_after_custom_request.lua create mode 100644 test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request_after_timeout.lua create mode 100644 test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request_after_timeout.lua create mode 100644 test_scripts/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua create mode 100644 test_scripts/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua create mode 100644 test_scripts/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua create mode 100644 test_scripts/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua create mode 100644 test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_after_timeout_by_resumption.lua create mode 100644 test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua create mode 100644 test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_after_timeout_by_resumption.lua create mode 100644 test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua create mode 100644 test_scripts/Handling_VR_help_requests/019_SetGlobalProp_procesing_added_choices_by_resumption.lua create mode 100644 test_scripts/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua create mode 100644 test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua create mode 100644 test_scripts/Handling_VR_help_requests/022_SetGlobalProp_absence_after_constructed_vrHelp_helpPrompt_before_resumption.lua create mode 100644 test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua create mode 100644 test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_vrHelp_only_by_resumption.lua create mode 100644 test_scripts/Handling_VR_help_requests/025_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua create mode 100644 test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua create mode 100644 test_scripts/Handling_VR_help_requests/027_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua create mode 100644 test_scripts/Handling_VR_help_requests/028_SetGlobalProp_invalid_custom_request.lua create mode 100644 test_scripts/Handling_VR_help_requests/029_SetGlobalProp_rejected_custom_request.lua create mode 100644 test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_successful_added_commands.lua create mode 100644 test_scripts/Handling_VR_help_requests/031_SetGlobalProp_only_without_successful_deleted_commands.lua create mode 100644 test_scripts/Handling_VR_help_requests/commonVRhelp.lua diff --git a/test_scripts/Handling_VR_help_requests/000_SetGlobalProp_after_activation_from_default_hmi_background.lua b/test_scripts/Handling_VR_help_requests/000_SetGlobalProp_after_activation_from_default_hmi_background.lua new file mode 100644 index 0000000000..3ab0f424ab --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/000_SetGlobalProp_after_activation_from_default_hmi_background.lua @@ -0,0 +1,65 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. default_hmi for app is BACKGROUND +-- 2. App is registered and is set in BACKGROUND hmiLevel +-- 3. App is activated and Command1, Command2, Command3 commands with vrCommands are added +-- 2. 10 seconds timer is expired +-- SDL does: +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function ptuFunc(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.cloneTable(tbl.policy_table.app_policies.default) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID].default_hmi = "BACKGROUND" +end + +local function registerAppWOPTU() + local mobSession = common.getMobileSession(2) + mobSession:StartService(7) + :Do(function() + local corId = mobSession:SendRPC("RegisterAppInterface", common.getConfigAppParams(2)) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", + { application = { appName = common.getConfigAppParams(2).appName } }) + :Do(function(_, data) + common.writeHMIappId(data.params.application.appID, 2) + end) + mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + end) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App1 registration", common.registerApp) +runner.Step("PTU with BACKGROUND default_hmi for App2", common.policyTableUpdate, { ptuFunc }) + +runner.Title("Test") +runner.Step("App2 registration", registerAppWOPTU) +runner.Step("App2 activation", common.activateApp, { 2 }) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i), 2 }) +end +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/000_SetGlobalProp_default_hmi_background.lua b/test_scripts/Handling_VR_help_requests/000_SetGlobalProp_default_hmi_background.lua new file mode 100644 index 0000000000..d2650462ec --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/000_SetGlobalProp_default_hmi_background.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. default_hmi for app is BACKGROUND +-- 2. App is registered and sets in BACKGROUND hmiLevel +-- 3. 10 seconds timer is expired +-- SDL does: +-- not send SetGlobalProperties to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function ptuFunc(tbl) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.cloneTable(tbl.policy_table.app_policies.default) + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID].default_hmi = "BACKGROUND" +end + +local function registerAppWOPTU() + local mobSession = common.getMobileSession(2) + mobSession:StartService(7) + :Do(function() + local corId = mobSession:SendRPC("RegisterAppInterface", common.getConfigAppParams(2)) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", + { application = { appName = common.getConfigAppParams(2).appName } }) + mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + end) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App1 registration", common.registerApp) +runner.Step("PTU with BACKGROUND default_hmi for App2", common.policyTableUpdate, { ptuFunc }) + +runner.Title("Test") +runner.Step("App2 registration", registerAppWOPTU) +runner.Step("Absence of SetGlobalProperties request from SDL", common.setGlobalPropertiesDoesNotExpect) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/001_SetGlobalProp_with_added_commands_after_timeout.lua b/test_scripts/Handling_VR_help_requests/001_SetGlobalProp_with_added_commands_after_timeout.lua new file mode 100644 index 0000000000..1f1f150914 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/001_SetGlobalProp_with_added_commands_after_timeout.lua @@ -0,0 +1,37 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. 10 seconds timer is expired +-- SDL does: +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) + +runner.Title("Test") +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua b/test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua new file mode 100644 index 0000000000..2bd9dafa33 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua @@ -0,0 +1,51 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1 with vrCommand and Command2 without vrCommands are added +-- 2. 10 seconds timer is expired +-- SDL does: +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local commandWithoutVr = { + cmdID = 2, + menuParams = { + menuName = "CommandWithoutVr" + } +} +local commandWithtVr = { + cmdID = 1, + vrCommands = { "vrCommand"}, + menuParams = { + menuName = "commandWithtVr" + } +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) + +runner.Title("Test") +runner.Step("AddCommand with vr command", common.addCommand, { commandWithtVr }) +runner.Step("AddCommand without vr command", common.addCommand, { commandWithoutVr }) +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands_after_timeout.lua b/test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands_after_timeout.lua new file mode 100644 index 0000000000..b72d428937 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands_after_timeout.lua @@ -0,0 +1,47 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Command1 is deleted by app +-- 3. 10 seconds timer is expired +-- SDL does: +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function deleteCommandParams() + local out = { + cmdID = 1 + } + return out +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end + +runner.Title("Test") +runner.Step("Delete Command1", common.deleteCommand, { deleteCommandParams(), true }) +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua b/test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua new file mode 100644 index 0000000000..c76f9083e0 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. 10 seconds timer is expired +-- 3. SDL sends SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand. +-- 4. Mobile application sets 30 command one by one +-- 5. Mobile application sets 31 command +-- SDL does: +-- send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters after each added command +-- not send SetGlobalProperties after added 31 command +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) + +runner.Title("Test") +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) +for i = 4, 34 do + runner.Step("SetGlobalProperties from SDL after added command" ..i, common.addCommandWithSetGP, { i }) +end +runner.Step("Absence SetGlobalProperties from SDL after adding 35 command", common.addCommandWithoutSetGP, { 35 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua b/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua new file mode 100644 index 0000000000..28344510e2 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. 10 seconds timer is expired +-- 3. SDL sends SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand. +-- 4. Mobile application sets 30 command one by one +-- 5.Mobile application deletes 10 command one by one +-- 6. Mobile application sets 31 command +-- SDL does: +-- send SetGlobalProperties with update for vrHelp and helpPrompt parameters after each added and deleted command +-- not send SetGlobalProperties after added 31 command +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) + +runner.Title("Test") +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) +for i = 4, 34 do + runner.Step("SetGlobalProperties from SDL after added command" ..i, common.addCommandWithSetGP, { i }) +end +for i = 1, 10 do + runner.Step("SetGlobalProperties from SDL after deleted command" ..i, common.deleteCommandWithSetGP, { i }) +end +runner.Step("Absence SetGlobalProperties from SDL after adding 35 command", common.addCommandWithoutSetGP, { 35 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/006_SetGlobalProp_procesing_added_choices.lua b/test_scripts/Handling_VR_help_requests/006_SetGlobalProp_procesing_added_choices.lua new file mode 100644 index 0000000000..840bbcfb47 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/006_SetGlobalProp_procesing_added_choices.lua @@ -0,0 +1,72 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. vrCommands Choice1, Choice2 are added via CreateInterationChoiceSet +-- 3. 10 seconds timer is expired +-- SDL does: +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands via AddCommand +-- requests(with type "Command" ). +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +-- [[ Local Variables ]] +local requestParams = { + interactionChoiceSetID = 1001, + choiceSet = { + { + choiceID = 1001, + menuName ="Choice1001", + vrCommands = { + "Choice1001_1", "Choice1001_2" + } + } + } +} + +local responseVrParams = { + cmdID = requestParams.interactionChoiceSetID, + type = "Choice", + vrCommands = requestParams.vrCommands +} + +-- [[ Local Functions ]] +local function createInteractionChoiceSetWithoutSetGP() + local mobSession = common.getMobileSession(1) + local hmiConnection = common.getHMIConnection() + local cid = mobSession:SendRPC("CreateInteractionChoiceSet", requestParams) + EXPECT_HMICALL("VR.AddCommand", responseVrParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) + +runner.Title("Test") +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end +runner.Step("CreateInteractionChoiceSet", createInteractionChoiceSetWithoutSetGP) +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua b/test_scripts/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua new file mode 100644 index 0000000000..ce6ba99056 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua @@ -0,0 +1,32 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. App is registered and in NONE hmiLevel +-- 2. 10 seconds timer is expired +-- SDL does: +-- not send SetGlobalProperties to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Absence of SetGlobalProperties request from SDL", common.setGlobalPropertiesDoesNotExpect) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_after_custom_request.lua b/test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_after_custom_request.lua new file mode 100644 index 0000000000..6bd0b9499c --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_after_custom_request.lua @@ -0,0 +1,39 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Mobile application sets SetGlobalProperties with custom helpPrompt and vrHelp +-- 3. 10 seconds timer is expired +-- SDL does: +-- not send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end + +runner.Title("Test") +runner.Step("Custom SetGlobalProperties from mobile application", common.setGlobalProperties, + { common.customSetGPParams() }) +runner.Step("Absence of SetGlobalProperties request from SDL", common.setGlobalPropertiesDoesNotExpect) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request_after_timeout.lua b/test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request_after_timeout.lua new file mode 100644 index 0000000000..926f6c2aea --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request_after_timeout.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Mobile application sets SetGlobalProperties with custom helpPrompt and vrHelp +-- 3. 10 seconds timer is expired and SDL send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands +-- 4. Mobile application adds Command4 command +-- 5.SDL sends SetGlobalProperties with updated list of commands +-- 6.Mobile application sets SetGlobalProperties with custom helpPrompt and vrHelp +-- 7.Mobile application adds Command5 command +-- SDL does: +-- not send SetGlobalProperties with updated values for the vrHelp and helpPrompt parameters +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) + +runner.Title("Test") +runner.Step("SetGlobalProperties from SDL with updated values after added command4", common.addCommandWithSetGP, + { 4 }) +runner.Step("Custom SetGlobalProperties from mobile application", common.setGlobalProperties, + { common.customSetGPParams() }) +runner.Step("Absence of SetGlobalProperties request from SDL after added command5", common.addCommandWithoutSetGP, + { 5 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request_after_timeout.lua b/test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request_after_timeout.lua new file mode 100644 index 0000000000..5d132481b6 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request_after_timeout.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Mobile application sets SetGlobalProperties with custom helpPrompt and vrHelp +-- 3. 10 seconds timer is expired and SDL send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands +-- 4. Mobile application deletes Command1 command +-- 5.SDL sends SetGlobalProperties with updated list of command +-- 6.Mobile application sets SetGlobalProperties with custom helpPrompt and vrHelp +-- 7.Mobile application deletes Command2 +-- SDL does: +-- not send SetGlobalProperties with updated values for the vrHelp and helpPrompt parameters +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) + +runner.Title("Test") +runner.Step("SetGlobalProperties from SDL with updated values after deleting command1", common.deleteCommandWithSetGP, + { 1 }) +runner.Step("Custom SetGlobalProperties from mobile application", common.setGlobalProperties, + { common.customSetGPParams() }) +runner.Step("Absence of SetGlobalProperties request from SDL after deleting command2", common.deleteCommandWithoutSetGP, + { 2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua b/test_scripts/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua new file mode 100644 index 0000000000..a7800b0496 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua @@ -0,0 +1,72 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Mobile application sets SetGlobalProperties with custom helpPrompt +-- 3. 10 seconds timer is expired +-- 4. Mobile application adds Command4 +-- SDL does: +-- 1. send SetGlobalProperties with constructed the vrHelp parameter using added vrCommand. +-- 2. send SetGlobalProperties with updated value for the vrHelp parameter using added vrCommand +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local SetGPParamsWithHelpPromptOnly = common.customSetGPParams() +SetGPParamsWithHelpPromptOnly.requestParams.vrHelpTitle = nil +SetGPParamsWithHelpPromptOnly.requestParams.vrHelp = nil + +--[[ Local Functions ]] +local function SetGlobalPropertiesFromSDL() + local params = common.setGPParams() + local hmiConnection = common.getHMIConnection() + EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + EXPECT_HMICALL("TTS.SetGlobalProperties") + :Times(0) +end + +local function SetGlobalPropertiesFromSDLbyAddingCommand() + common.addCommand(common.addCommandParams(4)) + local params = common.setGPParams() + local hmiConnection = common.getHMIConnection() + EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + EXPECT_HMICALL("TTS.SetGlobalProperties") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end + +runner.Title("Test") +runner.Step("Custom SetGlobalProperties with helpPrompt only from mobile application", common.setGlobalProperties, + { SetGPParamsWithHelpPromptOnly }) +runner.Step("SetGlobalProperties with constructed the vrHelp", SetGlobalPropertiesFromSDL) +runner.Step("SetGlobalProperties with updated value for vrHelp after added command ", + SetGlobalPropertiesFromSDLbyAddingCommand) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua b/test_scripts/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua new file mode 100644 index 0000000000..dba9fa5323 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua @@ -0,0 +1,71 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Mobile application sets SetGlobalProperties with custom vrHelp +-- 3. 10 seconds timer is expired +-- 4. Mobile application adds Command4 +-- SDL does: +-- 1. send SetGlobalProperties with constructed the helpPrompt parameter using added vrCommand. +-- 2. send SetGlobalProperties with updated value for the helpPrompt parameter using added vrCommands +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local SetGPParamsWithVrHelpOnly = common.customSetGPParams() +SetGPParamsWithVrHelpOnly.requestParams.helpPrompt = nil + +--[[ Local Functions ]] +local function SetGlobalPropertiesFromSDL() + local params = common.setGPParams() + local hmiConnection = common.getHMIConnection() + EXPECT_HMICALL("UI.SetGlobalProperties") + :Times(0) + EXPECT_HMICALL("TTS.SetGlobalProperties", params.requestTtsParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) +end + +local function SetGlobalPropertiesFromSDLbyAddingCommand() + common.addCommand(common.addCommandParams(4)) + local params = common.setGPParams() + local hmiConnection = common.getHMIConnection() + EXPECT_HMICALL("UI.SetGlobalProperties") + :Times(0) + EXPECT_HMICALL("TTS.SetGlobalProperties", params.requestTtsParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end + +runner.Title("Test") +runner.Step("Custom SetGlobalProperties with vrHelp only from mobile application", common.setGlobalProperties, + { SetGPParamsWithVrHelpOnly }) +runner.Step("SetGlobalProperties with constructed the helpPrompt", SetGlobalPropertiesFromSDL) +runner.Step("SetGlobalProperties with updated value for helpPrompt after added command ", + SetGlobalPropertiesFromSDLbyAddingCommand) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua b/test_scripts/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua new file mode 100644 index 0000000000..39164f23a8 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua @@ -0,0 +1,81 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Mobile application sets SetGlobalProperties with only custom helpPrompt +-- 3. 10 seconds timer is expired and SDL sends SetGlobalProperties with constructed the vrHelp parameter using added vrCommands +-- 4. Mobile application adds Command4 +-- 5. SDL sends SetGlobalProperties with updated value for the vrHelp parameter using added vrCommands +-- 6. Mobile application sets SetGlobalProperties with only custom vrHelp +-- 7. Mobile application adds Command5 +-- SDL does: +-- 1. send SetGlobalProperties with constructed the vrHelp parameter using added vrCommand. +-- 2. send SetGlobalProperties with updated value for the vrHelp parameter using added vrCommand +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local SetGPParamsWithHelpPromptOnly = common.cloneTable(common.customSetGPParams()) +SetGPParamsWithHelpPromptOnly.requestParams.vrHelpTitle = nil +SetGPParamsWithHelpPromptOnly.requestParams.vrHelp = nil + +local SetGPParamsWithVrHelpOnly = common.cloneTable(common.customSetGPParams()) +SetGPParamsWithVrHelpOnly.requestParams.helpPrompt = nil + +--[[ Local Functions ]] +local function SetGlobalPropertiesFromSDL() + local params = common.setGPParams() + local hmiConnection = common.getHMIConnection() + EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + EXPECT_HMICALL("TTS.SetGlobalProperties") + :Times(0) +end + +local function SetGlobalPropertiesFromSDLbyAddingCommand() + common.addCommand(common.addCommandParams(4)) + local params = common.setGPParams() + local hmiConnection = common.getHMIConnection() + EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + EXPECT_HMICALL("TTS.SetGlobalProperties") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end + +runner.Title("Test") +runner.Step("Custom SetGlobalProperties with helpPrompt only from mobile application", common.setGlobalProperties, + { SetGPParamsWithHelpPromptOnly }) +runner.Step("SetGlobalProperties with constructed the vrHelp", SetGlobalPropertiesFromSDL) +runner.Step("SetGlobalProperties with updated value for vrHelp after added command ", + SetGlobalPropertiesFromSDLbyAddingCommand) +runner.Step("Custom SetGlobalProperties with vrHrelp only from mobile application", common.setGlobalProperties, + { SetGPParamsWithVrHelpOnly }) +runner.Step("Absence SetGlobalProperties after added command", common.addCommandWithoutSetGP, { 5 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua b/test_scripts/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua new file mode 100644 index 0000000000..1b90fbff8f --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua @@ -0,0 +1,50 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Mobile application sets SetGlobalProperties without helpPrompt and vrHelp +-- 3. 10 seconds timer is expired +-- SDL does: +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local setGPParams = { } +setGPParams.requestParams = { + keyboardProperties = { + keyboardLayout = "QWERTY", + keypressMode = "SINGLE_KEYPRESS" + } +} +setGPParams.requestUiParams = setGPParams.requestParams + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end + +runner.Title("Test") +runner.Step("Custom SetGlobalProperties from mobile application without helpPrompt and vrHelp", + common.setGlobalProperties, { setGPParams }) +runner.Step("SetGlobalProperties request from SDL with constructed the vrHelp and helpPrompt", + common.setGlobalPropertiesFromSDL, { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_after_timeout_by_resumption.lua b/test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_after_timeout_by_resumption.lua new file mode 100644 index 0000000000..ed07c75f2c --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_after_timeout_by_resumption.lua @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Perform reopening session +-- SDL does: +-- 1. resume HMI level and added before reconnection AddCommands +-- 2. send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands +-- when timer times out after resuming HMI level +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, {}) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Pin OnHashChange", common.pinOnHashChange) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end + +runner.Title("Test") +runner.Step("App reconnect", common.reconnect) +runner.Step("App resumption", common.registrationWithResumption, + { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua b/test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua new file mode 100644 index 0000000000..6662fbc997 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua @@ -0,0 +1,83 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1 with vrCommand and Command2 without vrCommands are added +-- 2. Perform reopening session +-- SDL does: +-- 1. resume HMI level and added before reconnection AddCommands +-- 2. send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand. +-- when timer times out after resuming HMI level +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local commandWithoutVr = { + cmdID = 2, + menuParams = { + menuName = "CommandWithoutVr" + } +} +local commandWithtVr = { + cmdID = 1, + vrCommands = { "vrCommand"}, + menuParams = { + menuName = "commandWithtVr" + } +} + +--[[ Local Functions ]] +local function resumptionLevelLimited() + common.getHMIConnection():ExpectNotification("BasicCommunication.OnResumeAudioSource", + { appID = common.getHMIAppId() }) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, + { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + :Do(function(exp) + if exp.occurences == 2 then + common.timeActivation = timestamp() + end + end) + :Times(2) +end + +local function deactivateAppToLimited() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", {appID = common.getHMIAppId()}) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Pin OnHashChange", common.pinOnHashChange) +runner.Step("App activation", common.activateApp) +runner.Step("Bring app to LIMITED HMI level", deactivateAppToLimited) + +runner.Title("Test") +runner.Step("AddCommand with vr command", common.addCommand, { commandWithtVr }) +runner.Step("AddCommand without vr command", common.addCommand, { commandWithoutVr }) +runner.Title("Test") +runner.Step("App reconnect", common.reconnect) +runner.Step("App resumption", common.registrationWithResumption, + { 1, resumptionLevelLimited, common.resumptionDataAddCommands }) +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_after_timeout_by_resumption.lua b/test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_after_timeout_by_resumption.lua new file mode 100644 index 0000000000..effac65d92 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_after_timeout_by_resumption.lua @@ -0,0 +1,53 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Command1 is deleted by app +-- 3. Perform reopening session +-- SDL does: +-- 1. resume HMI level and AddCommands +-- 2. send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand +-- when timer times out after resuming HMI level +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function deleteCommandParams() + local out = { + cmdID = 1 + } + return out +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Pin OnHashChange", common.pinOnHashChange) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end + +runner.Title("Test") +runner.Step("Delete command1", common.deleteCommand, { deleteCommandParams(), true }) +runner.Step("App reconnect", common.reconnect) +runner.Step("App resumption", common.registrationWithResumption, + { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua b/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua new file mode 100644 index 0000000000..a47b7cfa45 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Perform reopening session +-- SDL does: +-- 1. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters after each added +-- command after resumption in 10 seconds after FULL hmi level +-- 2. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters after each added command +-- 3. not send SetGlobalProperties after added 31 command +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Pin OnHashChange", common.pinOnHashChange) +runner.Step("App activation", common.activateApp) + +runner.Title("Test") +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end +runner.Step("App reconnect", common.reconnect) +runner.Step("App resumption", common.registrationWithResumption, + { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) +for i = 4, 34 do + runner.Step("SetGlobalProperties from SDL after added command" ..i, common.addCommandWithSetGP, { i }) +end +runner.Step("Absence SetGlobalProperties from SDL after adding 35 command", common.addCommandWithoutSetGP, { 35 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/019_SetGlobalProp_procesing_added_choices_by_resumption.lua b/test_scripts/Handling_VR_help_requests/019_SetGlobalProp_procesing_added_choices_by_resumption.lua new file mode 100644 index 0000000000..d2fdf27f17 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/019_SetGlobalProp_procesing_added_choices_by_resumption.lua @@ -0,0 +1,104 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. vrCommands Choice1, Choice2 are added via CreateInterationChoiceSet +-- 3. Perform session reconnect +-- SDL does: +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands via AddCommand +-- requests(with type "Command") after resumption in 10 seconds after FULL hmi level +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +-- [[ Local Variables ]] +local requestParams = { + interactionChoiceSetID = 1001, + choiceSet = { + { + choiceID = 1001, + menuName ="Choice1001", + vrCommands = { + "Choice1001_1", "Choice1001_2" + } + } + } +} + +local responseVrParams = { + cmdID = requestParams.interactionChoiceSetID, + type = "Choice", + vrCommands = requestParams.vrCommands +} + +local commandArrayResumption = { } + +-- [[ Local Functions ]] +local function createInteractionChoiceSetWithoutSetGP() + local mobSession = common.getMobileSession(1) + local hmiConnection = common.getHMIConnection() + local cid = mobSession:SendRPC("CreateInteractionChoiceSet", requestParams) + EXPECT_HMICALL("VR.AddCommand", responseVrParams) + :Do(function(_,data) + commandArrayResumption = common.cloneTable(common.commandArray) + table.insert(commandArrayResumption, { cmdID = data.params.cmdID, vrCommand = data.params.vrCommands}) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +local function resumptionDataAddCommands() + EXPECT_HMICALL("VR.AddCommand") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + for _, value in pairs(commandArrayResumption) do + if data.params.cmdID == value.cmdID then + local vrCommandCompareResult = commonFunctions:is_table_equal(data.params.vrCommands, value.vrCommand) + local Msg = "" + if vrCommandCompareResult == false then + Msg = "vrCommands in received VR.AddCommand are not match to expected result.\n" .. + "Actual result:" .. common.tableToString(data.params.vrCommands) .. "\n" .. + "Expected result:" .. common.tableToString(value.vrCommand) .."\n" + end + return vrCommandCompareResult, Msg + end + end + return true + end) + :Times(#commandArrayResumption) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Pin OnHashChange", common.pinOnHashChange) +runner.Step("App activation", common.activateApp) + +runner.Title("Test") +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end +runner.Step("CreateInteractionChoiceSet", createInteractionChoiceSetWithoutSetGP) +runner.Step("App reconnect", common.reconnect) +runner.Step("App resumption", common.registrationWithResumption, + { 1, common.resumptionLevelFull, resumptionDataAddCommands }) +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua b/test_scripts/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua new file mode 100644 index 0000000000..9ce594b641 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Perform session reconnect +-- 3. Mobile application sets SetGlobalProperties with custom helpPrompt and vrHelp after resumption +-- SDL does: +-- not send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Pin OnHashChange", common.pinOnHashChange) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end + +runner.Title("Test") +runner.Step("App reconnect", common.reconnect) +runner.Step("App resumption", common.registrationWithResumption, + { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) +runner.Step("Custom SetGlobalProperties from mobile application", common.setGlobalProperties, + { common.customSetGPParams() }) +runner.Step("Absence of SetGlobalProperties request from SDL", common.setGlobalPropertiesDoesNotExpect) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua b/test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua new file mode 100644 index 0000000000..b5b7bebe6f --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Mobile application sets SetGlobalProperties with custom helpPrompt and vrHelp after resumption +-- 3. Perform session reconnect +-- SDL does: +-- 1. resume custom SetGlobalProperties +-- 2. not send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local SetGPParams = common.customSetGPParams() + +--[[ Local Functions ]] +local function resumptionData() + common.resumptionDataAddCommands() + local hmiConnection = common.getHMIConnection() + EXPECT_HMICALL("UI.SetGlobalProperties", SetGPParams.requestUiParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + EXPECT_HMICALL("TTS.SetGlobalProperties", SetGPParams.requestTtsParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Pin OnHashChange", common.pinOnHashChange) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end +runner.Step("Custom SetGlobalProperties from mobile application", common.setGlobalProperties, + { common.customSetGPParams() }) + +runner.Title("Test") +runner.Step("App reconnect", common.reconnect) +runner.Step("App resumption", common.registrationWithResumption, + { 1, common.resumptionLevelFull, resumptionData }) +runner.Step("Absence of SetGlobalProperties request from SDL", common.setGlobalPropertiesDoesNotExpect) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/022_SetGlobalProp_absence_after_constructed_vrHelp_helpPrompt_before_resumption.lua b/test_scripts/Handling_VR_help_requests/022_SetGlobalProp_absence_after_constructed_vrHelp_helpPrompt_before_resumption.lua new file mode 100644 index 0000000000..61409dd785 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/022_SetGlobalProp_absence_after_constructed_vrHelp_helpPrompt_before_resumption.lua @@ -0,0 +1,52 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. 10 seconds timer is expired +-- 3. send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. +-- 4. Perform session reconnect +-- SDL does: +-- 1. Resume SetGlobalProperties +-- 2. not send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function resumptionData() + common.resumptionDataAddCommands() + common.setGlobalPropertiesFromSDL() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Pin OnHashChange", common.pinOnHashChange) +runner.Step("App activation", common.activateApp) + +runner.Title("Test") +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) +runner.Step("Wait for resumption data saving", common.wait, { 10000 }) +runner.Step("App reconnect", common.reconnect) +runner.Step("App resumption", common.registrationWithResumption, + { 1, common.resumptionLevelFull, resumptionData }) +runner.Step("Absence of SetGlobalProperties request from SDL", common.setGlobalPropertiesDoesNotExpect) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua b/test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua new file mode 100644 index 0000000000..e76d32024e --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua @@ -0,0 +1,77 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Perform reconnect +-- 3. Mobile application sets SetGlobalProperties with custom helpPrompt +-- 4. 10 seconds timer is expired +-- 5. Mobile application adds Command4 +-- SDL does: +-- 1. send SetGlobalProperties with constructed the vrHelp parameter using added vrCommand. +-- 2. send SetGlobalProperties with updated value for the vrHelp parameter using added vrCommand +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local SetGPParamsWithHelpPromptOnly = common.customSetGPParams() +SetGPParamsWithHelpPromptOnly.requestParams.vrHelpTitle = nil +SetGPParamsWithHelpPromptOnly.requestParams.vrHelp = nil + +--[[ Local Functions ]] +local function SetGlobalPropertiesFromSDL() + local params = common.setGPParams() + local hmiConnection = common.getHMIConnection() + EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + EXPECT_HMICALL("TTS.SetGlobalProperties") + :Times(0) +end + +local function SetGlobalPropertiesFromSDLbyAddingCommand() + common.addCommand(common.addCommandParams(4)) + local params = common.setGPParams() + local hmiConnection = common.getHMIConnection() + EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + EXPECT_HMICALL("TTS.SetGlobalProperties") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Pin OnHashChange", common.pinOnHashChange) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end +runner.Step("App reconnect", common.reconnect) +runner.Step("App resumption", common.registrationWithResumption, + { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) + +runner.Title("Test") +runner.Step("Custom SetGlobalProperties with helpPrompt only from mobile application", common.setGlobalProperties, + { SetGPParamsWithHelpPromptOnly }) +runner.Step("SetGlobalProperties with constructed the vrHelp", SetGlobalPropertiesFromSDL) +runner.Step("SetGlobalProperties with updated value for vrHelp after added command ", + SetGlobalPropertiesFromSDLbyAddingCommand) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_vrHelp_only_by_resumption.lua b/test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_vrHelp_only_by_resumption.lua new file mode 100644 index 0000000000..f0745965db --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_vrHelp_only_by_resumption.lua @@ -0,0 +1,76 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 3. Perform reconnect +-- 4. Mobile application sets SetGlobalProperties with custom vrHelp +-- 5. 10 seconds timer is expired +-- 6. Mobile application adds Command4 +-- SDL does: +-- 1. send SetGlobalProperties with constructed the helpPrompt parameter using added vrCommand. +-- 2. send SetGlobalProperties with updated value for the helpPrompt parameter using added vrCommands +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local SetGPParamsWithVrHelpOnly = common.customSetGPParams() +SetGPParamsWithVrHelpOnly.requestParams.helpPrompt = nil + +--[[ Local Functions ]] +local function SetGlobalPropertiesFromSDL() + local params = common.setGPParams() + local hmiConnection = common.getHMIConnection() + EXPECT_HMICALL("UI.SetGlobalProperties") + :Times(0) + EXPECT_HMICALL("TTS.SetGlobalProperties", params.requestTtsParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) +end + +local function SetGlobalPropertiesFromSDLbyAddingCommand() + common.addCommand(common.addCommandParams(4)) + local params = common.setGPParams() + local hmiConnection = common.getHMIConnection() + EXPECT_HMICALL("UI.SetGlobalProperties") + :Times(0) + EXPECT_HMICALL("TTS.SetGlobalProperties", params.requestTtsParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Pin OnHashChange", common.pinOnHashChange) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end +runner.Step("App reconnect", common.reconnect) +runner.Step("App resumption", common.registrationWithResumption, + { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) + +runner.Title("Test") +runner.Step("Custom SetGlobalProperties with vrHelp only from mobile application", common.setGlobalProperties, + { SetGPParamsWithVrHelpOnly }) +runner.Step("SetGlobalProperties with constructed the helpPrompt", SetGlobalPropertiesFromSDL) +runner.Step("SetGlobalProperties with updated value for helpPrompt after added command", + SetGlobalPropertiesFromSDLbyAddingCommand) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/025_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua b/test_scripts/Handling_VR_help_requests/025_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua new file mode 100644 index 0000000000..5879a2ea97 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/025_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Perform reconnect +-- 3. Mobile application sets SetGlobalProperties without helpPrompt and vrHelp +-- 4. 10 seconds timer is expired +-- SDL does: +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand with type=Command. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local setGPParams = { } +setGPParams.requestParams = { + keyboardProperties = { + keyboardLayout = "QWERTY", + keypressMode = "SINGLE_KEYPRESS" + } +} +setGPParams.requestUiParams = setGPParams.requestParams + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Pin OnHashChange", common.pinOnHashChange) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end +runner.Step("App reconnect", common.reconnect) +runner.Step("App resumption", common.registrationWithResumption, + { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) + +runner.Title("Test") +runner.Step("Custom SetGlobalProperties from mobile application without helpPrompt and vrHelp", + common.setGlobalProperties, { setGPParams }) +runner.Step("SetGlobalProperties request from SDL with constructed the vrHelp and helpPrompt", + common.setGlobalPropertiesFromSDL, { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua b/test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua new file mode 100644 index 0000000000..48ef0ba141 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua @@ -0,0 +1,39 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1 commands with vrCommands Command1_1, Command2_1, Command3_1 is added +-- 2. 10 seconds timer is expired +-- SDL does: +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local AddCommandParams = common.addCommandParams(1) +AddCommandParams.vrCommands = { "Command1_1", "Command2_1", "Command3_1" } + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) + +runner.Title("Test") +runner.Step("AddCommand with several vrCommand ", common.addCommand, { AddCommandParams }) +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/027_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua b/test_scripts/Handling_VR_help_requests/027_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua new file mode 100644 index 0000000000..6a08a8e56b --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/027_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1 commands with vrCommands Command1_1, Command2_1, Command3_1 is added +-- 2. Perform reconnect +-- 2. 10 seconds timer is expired +-- SDL does: +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local AddCommandParams = common.addCommandParams(1) +AddCommandParams.vrCommands = { "Command1_1", "Command2_1", "Command3_1" } + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Pin OnHashChange", common.pinOnHashChange) +runner.Step("App activation", common.activateApp) + +runner.Title("Test") +runner.Step("AddCommand with several vrCommand", common.addCommand, { AddCommandParams }) +runner.Step("App reconnect", common.reconnect) +runner.Step("App resumption", common.registrationWithResumption, + { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/028_SetGlobalProp_invalid_custom_request.lua b/test_scripts/Handling_VR_help_requests/028_SetGlobalProp_invalid_custom_request.lua new file mode 100644 index 0000000000..1f4f6bc563 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/028_SetGlobalProp_invalid_custom_request.lua @@ -0,0 +1,53 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Mobile application sends SetGlobalProperties with invalid data( e.g. invalid type ) +-- 3. SDL responds with resultCode INVALID_DATA to mobile application +-- 4. 10 seconds timer is expired +-- SDL does: +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function invalidSetGlobalProperties() + local mobSession = common.getMobileSession() + local Params = common.customSetGPParams() + Params.requestParams.vrHelpTitle = 1234 + local cid = mobSession:SendRPC("SetGlobalProperties", Params.requestParams) + EXPECT_HMICALL("UI.SetGlobalProperties") + :Times(0) + EXPECT_HMICALL("TTS.SetGlobalProperties") + :Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end + +runner.Title("Test") +runner.Step("Invalid custom SetGlobalProperties", invalidSetGlobalProperties) +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/029_SetGlobalProp_rejected_custom_request.lua b/test_scripts/Handling_VR_help_requests/029_SetGlobalProp_rejected_custom_request.lua new file mode 100644 index 0000000000..434d7708c0 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/029_SetGlobalProp_rejected_custom_request.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Mobile application sends valid SetGlobalProperties and HMI rejected request +-- 3. SDL responds with resultCode REJECTED to mobile application +-- 4. 10 seconds timer is expired +-- SDL does: +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function rejectedSetGlobalProperties() + local mobSession = common.getMobileSession() + local hmiConnection = common.getHMIConnection() + local Params = common.customSetGPParams() + local cid = mobSession:SendRPC("SetGlobalProperties", Params.requestParams) + EXPECT_HMICALL("UI.SetGlobalProperties") + :Do(function(_,data) + hmiConnection:SendError(data.id, data.method, "REJECTED", " UI is rejected ") + end) + EXPECT_HMICALL("TTS.SetGlobalProperties") + :Do(function(_,data) + hmiConnection:SendError(data.id, data.method, "REJECTED", " TTS is rejected ") + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end + +runner.Title("Test") +runner.Step("Rejected custom SetGlobalProperties", rejectedSetGlobalProperties) +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_successful_added_commands.lua b/test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_successful_added_commands.lua new file mode 100644 index 0000000000..a3791e654e --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_successful_added_commands.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Mobile app adds Command4 and HMI responds with resultCode = REJECTED, as result command is not added +-- 3. 10 seconds timer is expired +-- SDL does: +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function rejectedAddCommand(pParams) + local mobSession = common.getMobileSession() + local hmiConnection = common.getHMIConnection() + local cid = mobSession:SendRPC("AddCommand", pParams) + EXPECT_HMICALL("UI.AddCommand") + :Do(function(_,data) + hmiConnection:SendError(data.id, data.method, "REJECTED", "Rejected request") + end) + local requestUiParams = { + cmdID = pParams.cmdID, + vrCommands = pParams.vrCommands, + type = "Command", + appID = common.getHMIAppId() + } + EXPECT_HMICALL("VR.AddCommand", requestUiParams) + :Do(function(_,data) + hmiConnection:SendError(data.id, data.method, "REJECTED", "Rejected request") + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end + +runner.Title("Test") +runner.Step("Rejected adding Command4", rejectedAddCommand, { common.addCommandParams(4) }) +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_only_without_successful_deleted_commands.lua b/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_only_without_successful_deleted_commands.lua new file mode 100644 index 0000000000..d41146263a --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_only_without_successful_deleted_commands.lua @@ -0,0 +1,65 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Mobile app deletes Command3 and HMI responds with resultCode = REJECTED, as result command is not deleted +-- 3. 10 seconds timer is expired +-- SDL does: +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local params = { + cmdID = 3 + } + +--[[ Local Functions ]] +local function rejectedDeleteCommand(pParams) + local mobSession = common.getMobileSession() + local hmiConnection = common.getHMIConnection() + local cid = mobSession:SendRPC("DeleteCommand", pParams) + EXPECT_HMICALL("UI.DeleteCommand") + :Do(function(_,data) + hmiConnection:SendError(data.id, data.method, "REJECTED", "Request rejected") + end) + local requestVrParams = { + cmdID = pParams.cmdID, + type = "Command", + appID = common.getHMIAppId() + } + EXPECT_HMICALL("VR.DeleteCommand", requestVrParams) + :Do(function(_,data) + hmiConnection:SendError(data.id, data.method, "REJECTED", "Request rejected") + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) +end + +runner.Title("Test") +runner.Step("Rejected deleting Command3", rejectedDeleteCommand, { params }) +runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, + { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/commonVRhelp.lua b/test_scripts/Handling_VR_help_requests/commonVRhelp.lua new file mode 100644 index 0000000000..4d641a8be3 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/commonVRhelp.lua @@ -0,0 +1,325 @@ +--------------------------------------------------------------------------------------------------- +-- Common module +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") +local utils = require("user_modules/utils") +local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +local mobile_session = require('mobile_session') +local test = require("user_modules/dummy_connecttest") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") + +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 2 + +--[[ Variables ]] +local m = actions +m.commandArray = {} + +m.cloneTable = utils.cloneTable +m.tableToString = utils.tableToString +m.wait = utils.wait + +function m.setGPParams() + local params = { + requestUiParams = m.vrHelp(m.commandArray), + requestTtsParams = m.vrHelpPrompt(m.commandArray) + } + return params +end + +function m.customSetGPParams() + local allParams = { } + allParams.requestParams = { + helpPrompt = { + { text = "helpPrompt", type = "TEXT"} + }, + vrHelpTitle = " Help title ", + vrHelp = { + { text = "vrHelp1", position = 1 }, + { text = "vrHelp2", position = 2 } + } + } + + allParams.requestUiParams = { + vrHelp = allParams.requestParams.vrHelp, + vrHelpTitle = allParams.requestParams.vrHelpTitle + } + + allParams.requestTtsParams = { + helpPrompt = allParams.requestParams.helpPrompt + } + return allParams +end + +function m.addCommandParams(pN) + local out = { + cmdID = pN, + vrCommands = { "vrCommand" .. pN}, + menuParams = { + menuName = "Command" .. pN + } + } + return out +end + +function m.addCommand(pParams, pAppId) + if not pAppId then pAppId = 1 end + local mobSession = m.getMobileSession(pAppId) + local hmiConnection = m.getHMIConnection() + local cid = mobSession:SendRPC("AddCommand", pParams) + EXPECT_HMICALL("UI.AddCommand") + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + if pParams.vrCommands then + table.insert(m.commandArray, { cmdID = pParams.cmdID, vrCommand = pParams.vrCommands}) + local requestUiParams = { + cmdID = pParams.cmdID, + vrCommands = pParams.vrCommands, + type = "Command", + appID = m.getHMIAppId(pAppId) + } + EXPECT_HMICALL("VR.AddCommand", requestUiParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + end + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +function m.deleteCommand(pParams, pVRInterface, pAppId) + if not pAppId then pAppId = 1 end + local mobSession = m.getMobileSession(pAppId) + local hmiConnection = m.getHMIConnection() + local cid = mobSession:SendRPC("DeleteCommand", pParams) + EXPECT_HMICALL("UI.DeleteCommand") + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + if pVRInterface then + for k, v in pairs(m.commandArray) do + if v.cmdID == pParams.cmdID then + table.remove(m.commandArray, k) + end + end + local requestVrParams = { + cmdID = pParams.cmdID, + type = "Command", + appID = m.getHMIAppId(pAppId) + } + EXPECT_HMICALL("VR.DeleteCommand", requestVrParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + end + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +function m.setGlobalProperties(pParams, pAppId) + if not pAppId then pAppId = 1 end + local mobSession = m.getMobileSession(pAppId) + local hmiConnection = m.getHMIConnection() + local cid = mobSession:SendRPC("SetGlobalProperties", pParams.requestParams) + if pParams.requestParams.vrHelp or + pParams.requestParams.keyboardProperties then + EXPECT_HMICALL("UI.SetGlobalProperties", pParams.requestUiParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + end + if pParams.requestParams.helpPrompt or pParams.requestParams.timeoutPrompt then + EXPECT_HMICALL("TTS.SetGlobalProperties", pParams.requestTtsParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + end + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +function m.setGlobalPropertiesFromSDL(pTST) + local params = m.setGPParams() + local hmiConnection = m.getHMIConnection() + EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function() + if pTST then + local timeSetGPReg = timestamp() + local timeToSetGP = timeSetGPReg - m.timeActivation + if timeToSetGP > 10500 or + timeToSetGP < 9500 then + return false, "SetGlobalProperties request with constracted vrHelp and helpPrompt came not in 10 sec " .. + "after activation, actual time -" .. tostring(timeToSetGP) + end + end + return true + end) + EXPECT_HMICALL("TTS.SetGlobalProperties", params.requestTtsParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) +end + +function m.activateApp(pAppId) + if not pAppId then pAppId = 1 end + local requestId = m.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = m.getHMIAppId(pAppId) }) + m.getHMIConnection():ExpectResponse(requestId) + m.getMobileSession(pAppId):ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + :Do(function() + m.timeActivation = timestamp() + end) + m.wait() +end + +function m.vrHelp(pCommandArray) + local out = {} + for k, value in pairs(pCommandArray) do + for _, sub_v in pairs(value.vrCommand) do + local item = { + text = sub_v, + position = k + } + table.insert(out, item) + end + end + return out +end + +function m.vrHelpPrompt(pVrCommandArray) + local out = {} + for _, value in pairs(pVrCommandArray) do + for _, sub_v in pairs(value.vrCommand) do + local item = { + text = sub_v, + type = "TEXT" + } + table.insert(out, item) + end + end + return out +end + +function m.setGlobalPropertiesDoesNotExpect() + EXPECT_HMICALL("UI.SetGlobalProperties") + :Times(0) + EXPECT_HMICALL("TTS.SetGlobalProperties") + :Times(0) + commonTestCases:DelayedExp(11000) +end + +function m.deleteCommandWithSetGP(pN) + local params = { + cmdID = pN + } + m.deleteCommand(params, true) + m.setGlobalPropertiesFromSDL() +end + +function m.deleteCommandWithoutSetGP(pN) + local params = { + cmdID = pN + } + m.deleteCommand(params, true) + m.setGlobalPropertiesDoesNotExpect() +end + +function m.addCommandWithSetGP(pN) + m.addCommand(m.addCommandParams(pN)) + m.setGlobalPropertiesFromSDL() +end + +function m.addCommandWithoutSetGP(pN) + m.addCommand(m.addCommandParams(pN)) + m.setGlobalPropertiesDoesNotExpect() +end + +function m.reconnect(pAppId) + if not pAppId then pAppId = 1 end + m.getMobileSession(pAppId):Stop() + m.getHMIConnection():ExpectNotification("BasicCommunication.OnAppUnregistered", + {appID = m.getHMIAppId(pAppId), unexpectedDisconnect = true}) + :Do(function() + test.mobileSession[pAppId] = mobile_session.MobileSession( + test, + test.mobileConnection, + config["application" .. pAppId].registerAppInterfaceParams) + test.mobileConnection:Connect() + end) +end + +function m.registrationWithResumption(pAppId, pLevelResumpFunc, pDataResump) + if not pAppId then pAppId = 1 end + local mobSession = m.getMobileSession(pAppId) + mobSession:StartService(7) + :Do(function() + local params = m.getConfigAppParams(pAppId) + params.hashID = m.hashId + local corId = mobSession:SendRPC("RegisterAppInterface", m.getConfigAppParams(pAppId)) + test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", + { application = { appName = m.getConfigAppParams(pAppId).appName } }) + :Do(function(_, d1) + m.writeHMIappId(d1.params.application.appID, pAppId) + pDataResump() + end) + mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + pLevelResumpFunc() + end) + end) +end + +function m.pinOnHashChange(pAppId) + if not pAppId then pAppId = 1 end + m.getMobileSession(pAppId):ExpectNotification("OnHashChange") + :Pin() + :Times(AnyNumber()) + :Do(function(_, data) + m.hashId = data.payload.hashID + end) +end + +function m.resumptionDataAddCommands() + EXPECT_HMICALL("VR.AddCommand") + :Do(function(_, data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + for _, value in pairs(m.commandArray) do + if data.params.cmdID == value.cmdID then + local vrCommandCompareResult = commonFunctions:is_table_equal(data.params.vrCommands, value.vrCommand) + local Msg = "" + if vrCommandCompareResult == false then + Msg = "vrCommands in received VR.AddCommand are not match to expected result.\n" .. + "Actual result:" .. m.tableToString(data.params.vrCommands) .. "\n" .. + "Expected result:" .. m.tableToString(value.vrCommand) .."\n" + end + return vrCommandCompareResult, Msg + end + end + return true + end) + :Times(#m.commandArray) +end + +function m.resumptionLevelFull() + m.getHMIConnection():ExpectNotification("BasicCommunication.ActivateApp", { appID = m.getHMIAppId() }) + :Do(function(_,data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + m.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + :Do(function(exp) + if exp.occurences == 2 then + m.timeActivation = timestamp() + end + end) + :Times(2) +end + + + +return m From 9c13ac2440be091db201d65948f7c51589b793b7 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Mon, 7 May 2018 13:02:16 +0300 Subject: [PATCH 477/681] Updated setGPParams func --- .../Handling_VR_help_requests/commonVRhelp.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test_scripts/Handling_VR_help_requests/commonVRhelp.lua b/test_scripts/Handling_VR_help_requests/commonVRhelp.lua index 4d641a8be3..78afa0fd1d 100644 --- a/test_scripts/Handling_VR_help_requests/commonVRhelp.lua +++ b/test_scripts/Handling_VR_help_requests/commonVRhelp.lua @@ -22,8 +22,12 @@ m.wait = utils.wait function m.setGPParams() local params = { - requestUiParams = m.vrHelp(m.commandArray), - requestTtsParams = m.vrHelpPrompt(m.commandArray) + requestUiParams = { + vrHelp = m.vrHelp(m.commandArray) + }, + requestTtsParams = { + helpPrompt = m.vrHelpPrompt(m.commandArray) + } } return params end @@ -151,7 +155,7 @@ function m.setGlobalPropertiesFromSDL(pTST) if timeToSetGP > 10500 or timeToSetGP < 9500 then return false, "SetGlobalProperties request with constracted vrHelp and helpPrompt came not in 10 sec " .. - "after activation, actual time -" .. tostring(timeToSetGP) + "after activation, actual time is" .. tostring(timeToSetGP) end end return true From 40ec6905e0b18c7c40fb52d873fe95b5bee5a10a Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 10 May 2018 08:45:16 +0300 Subject: [PATCH 478/681] Added test set, update of command limitation --- ...p_processing_30_commands_after_timeout.lua | 4 +-- ...tion_after_timeout_only_for_addcommand.lua | 4 +-- ...0_commands_after_timeout_by_resumption.lua | 4 +-- test_sets/handling_VR_help_requests.txt | 31 +++++++++++++++++++ 4 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 test_sets/handling_VR_help_requests.txt diff --git a/test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua b/test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua index c76f9083e0..a17b452a6c 100644 --- a/test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua +++ b/test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua @@ -36,10 +36,10 @@ for i = 1,3 do end runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, { true }) -for i = 4, 34 do +for i = 4, 33 do runner.Step("SetGlobalProperties from SDL after added command" ..i, common.addCommandWithSetGP, { i }) end -runner.Step("Absence SetGlobalProperties from SDL after adding 35 command", common.addCommandWithoutSetGP, { 35 }) +runner.Step("Absence SetGlobalProperties from SDL after adding 35 command", common.addCommandWithoutSetGP, { 34 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua b/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua index 28344510e2..429fa9ab46 100644 --- a/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua +++ b/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua @@ -37,13 +37,13 @@ for i = 1,3 do end runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, { true }) -for i = 4, 34 do +for i = 4, 33 do runner.Step("SetGlobalProperties from SDL after added command" ..i, common.addCommandWithSetGP, { i }) end for i = 1, 10 do runner.Step("SetGlobalProperties from SDL after deleted command" ..i, common.deleteCommandWithSetGP, { i }) end -runner.Step("Absence SetGlobalProperties from SDL after adding 35 command", common.addCommandWithoutSetGP, { 35 }) +runner.Step("Absence SetGlobalProperties from SDL after adding 35 command", common.addCommandWithoutSetGP, { 34 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua b/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua index a47b7cfa45..05e3ce9c51 100644 --- a/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua @@ -39,10 +39,10 @@ runner.Step("App resumption", common.registrationWithResumption, { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, { true }) -for i = 4, 34 do +for i = 4, 33 do runner.Step("SetGlobalProperties from SDL after added command" ..i, common.addCommandWithSetGP, { i }) end -runner.Step("Absence SetGlobalProperties from SDL after adding 35 command", common.addCommandWithoutSetGP, { 35 }) +runner.Step("Absence SetGlobalProperties from SDL after adding 35 command", common.addCommandWithoutSetGP, { 34 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_sets/handling_VR_help_requests.txt b/test_sets/handling_VR_help_requests.txt new file mode 100644 index 0000000000..4fe7243ad9 --- /dev/null +++ b/test_sets/handling_VR_help_requests.txt @@ -0,0 +1,31 @@ +./test_scripts/Handling_VR_help_requests/001_SetGlobalProp_with_added_commands_after_timeout.lua +./test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua +./test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands_after_timeout.lua +./test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua +./test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua +./test_scripts/Handling_VR_help_requests/006_SetGlobalProp_procesing_added_choices.lua +./test_scripts/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua +./test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_after_custom_request.lua +./test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request_after_timeout.lua +./test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request_after_timeout.lua +./test_scripts/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua +./test_scripts/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua +./test_scripts/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua +./test_scripts/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua +./test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_after_timeout_by_resumption.lua +./test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua +./test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_after_timeout_by_resumption.lua +./test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua +./test_scripts/Handling_VR_help_requests/019_SetGlobalProp_procesing_added_choices_by_resumption.lua +./test_scripts/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua +./test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua +./test_scripts/Handling_VR_help_requests/022_SetGlobalProp_absence_after_constructed_vrHelp_helpPrompt_before_resumption.lua +./test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua +./test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_vrHelp_only_by_resumption.lua +./test_scripts/Handling_VR_help_requests/025_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua +./test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua +./test_scripts/Handling_VR_help_requests/027_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua +./test_scripts/Handling_VR_help_requests/028_SetGlobalProp_invalid_custom_request.lua +./test_scripts/Handling_VR_help_requests/029_SetGlobalProp_rejected_custom_request.lua +./test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_successful_added_commands.lua +./test_scripts/Handling_VR_help_requests/031_SetGlobalProp_only_without_successful_deleted_commands.lua From b9cd863cb9ab3b0b899e606f1dba296b51b1c6c5 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 10 Jul 2018 13:31:30 +0300 Subject: [PATCH 479/681] Script stabilization --- ...activation_from_default_hmi_background.lua | 65 ------------------ ...0_SetGlobalProp_default_hmi_background.lua | 56 ---------------- ...Prop_with_added_commands_after_timeout.lua | 2 +- ...without_deleted_commands_after_timeout.lua | 6 +- ...p_processing_30_commands_after_timeout.lua | 4 +- ...tion_after_timeout_only_for_addcommand.lua | 4 +- ..._SetGlobalProp_procesing_added_choices.lua | 2 +- ...lobalProp_absence_after_custom_request.lua | 2 +- ...and_after_custom_request_after_timeout.lua | 2 +- ...and_after_custom_request_after_timeout.lua | 2 +- ...1_SetGlobalProp_custom_helpPrompt_only.lua | 8 +-- .../012_SetGlobalProp_custom_vrHelp_only.lua | 8 +-- ...rompt_and_vrHelp_in_different_requests.lua | 8 +-- ..._request_without_helpPrompt_and_vrHelp.lua | 2 +- ...d_commands_after_timeout_by_resumption.lua | 4 +- ...th_and_without_vrCommand_by_resumption.lua | 43 +++++++++++- ...d_commands_after_timeout_by_resumption.lua | 6 +- ...0_commands_after_timeout_by_resumption.lua | 4 +- ..._procesing_added_choices_by_resumption.lua | 2 +- ..._after_custom_request_after_resumption.lua | 2 +- ...after_custom_request_before_resumption.lua | 2 +- ...ed_vrHelp_helpPrompt_before_resumption.lua | 2 +- ...p_custom_helpPrompt_only_by_resumption.lua | 8 +-- ...lProp_custom_vrHelp_only_by_resumption.lua | 8 +-- ...ut_helpPrompt_and_vrHelp_by_resumption.lua | 2 +- ...l_vrCommands_in_one_addCommand_request.lua | 2 +- ...n_one_addCommand_request_by_resumption.lua | 2 +- ...8_SetGlobalProp_invalid_custom_request.lua | 2 +- ..._SetGlobalProp_rejected_custom_request.lua | 2 +- ...balProp_only_successful_added_commands.lua | 4 +- ...ly_without_successful_deleted_commands.lua | 2 +- .../commonVRhelp.lua | 66 +++++++++++++------ 32 files changed, 139 insertions(+), 195 deletions(-) delete mode 100644 test_scripts/Handling_VR_help_requests/000_SetGlobalProp_after_activation_from_default_hmi_background.lua delete mode 100644 test_scripts/Handling_VR_help_requests/000_SetGlobalProp_default_hmi_background.lua diff --git a/test_scripts/Handling_VR_help_requests/000_SetGlobalProp_after_activation_from_default_hmi_background.lua b/test_scripts/Handling_VR_help_requests/000_SetGlobalProp_after_activation_from_default_hmi_background.lua deleted file mode 100644 index 3ab0f424ab..0000000000 --- a/test_scripts/Handling_VR_help_requests/000_SetGlobalProp_after_activation_from_default_hmi_background.lua +++ /dev/null @@ -1,65 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md --- User story: TBD --- Use case: TBD --- --- Requirement summary: TBD --- --- Description: --- In case: --- 1. default_hmi for app is BACKGROUND --- 2. App is registered and is set in BACKGROUND hmiLevel --- 3. App is activated and Command1, Command2, Command3 commands with vrCommands are added --- 2. 10 seconds timer is expired --- SDL does: --- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ Local Functions ]] -local function ptuFunc(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.cloneTable(tbl.policy_table.app_policies.default) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID].default_hmi = "BACKGROUND" -end - -local function registerAppWOPTU() - local mobSession = common.getMobileSession(2) - mobSession:StartService(7) - :Do(function() - local corId = mobSession:SendRPC("RegisterAppInterface", common.getConfigAppParams(2)) - common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", - { application = { appName = common.getConfigAppParams(2).appName } }) - :Do(function(_, data) - common.writeHMIappId(data.params.application.appID, 2) - end) - mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) - :Do(function() - mobSession:ExpectNotification("OnHMIStatus", - { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - end) - end) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("App1 registration", common.registerApp) -runner.Step("PTU with BACKGROUND default_hmi for App2", common.policyTableUpdate, { ptuFunc }) - -runner.Title("Test") -runner.Step("App2 registration", registerAppWOPTU) -runner.Step("App2 activation", common.activateApp, { 2 }) -for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i), 2 }) -end -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/000_SetGlobalProp_default_hmi_background.lua b/test_scripts/Handling_VR_help_requests/000_SetGlobalProp_default_hmi_background.lua deleted file mode 100644 index d2650462ec..0000000000 --- a/test_scripts/Handling_VR_help_requests/000_SetGlobalProp_default_hmi_background.lua +++ /dev/null @@ -1,56 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md --- User story: TBD --- Use case: TBD --- --- Requirement summary: TBD --- --- Description: --- In case: --- 1. default_hmi for app is BACKGROUND --- 2. App is registered and sets in BACKGROUND hmiLevel --- 3. 10 seconds timer is expired --- SDL does: --- not send SetGlobalProperties to HMI ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ Local Functions ]] -local function ptuFunc(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.cloneTable(tbl.policy_table.app_policies.default) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID].default_hmi = "BACKGROUND" -end - -local function registerAppWOPTU() - local mobSession = common.getMobileSession(2) - mobSession:StartService(7) - :Do(function() - local corId = mobSession:SendRPC("RegisterAppInterface", common.getConfigAppParams(2)) - common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", - { application = { appName = common.getConfigAppParams(2).appName } }) - mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) - :Do(function() - mobSession:ExpectNotification("OnHMIStatus", - { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - end) - end) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("App1 registration", common.registerApp) -runner.Step("PTU with BACKGROUND default_hmi for App2", common.policyTableUpdate, { ptuFunc }) - -runner.Title("Test") -runner.Step("App2 registration", registerAppWOPTU) -runner.Step("Absence of SetGlobalProperties request from SDL", common.setGlobalPropertiesDoesNotExpect) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/001_SetGlobalProp_with_added_commands_after_timeout.lua b/test_scripts/Handling_VR_help_requests/001_SetGlobalProp_with_added_commands_after_timeout.lua index 1f1f150914..83ac3db134 100644 --- a/test_scripts/Handling_VR_help_requests/001_SetGlobalProp_with_added_commands_after_timeout.lua +++ b/test_scripts/Handling_VR_help_requests/001_SetGlobalProp_with_added_commands_after_timeout.lua @@ -28,7 +28,7 @@ runner.Step("App activation", common.activateApp) runner.Title("Test") for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, { true }) diff --git a/test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands_after_timeout.lua b/test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands_after_timeout.lua index b72d428937..66c8eb9124 100644 --- a/test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands_after_timeout.lua +++ b/test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands_after_timeout.lua @@ -21,7 +21,7 @@ local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function deleteCommandParams() +local function getDeleteCommandParams() local out = { cmdID = 1 } @@ -35,11 +35,11 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Title("Test") -runner.Step("Delete Command1", common.deleteCommand, { deleteCommandParams(), true }) +runner.Step("Delete Command1", common.deleteCommand, { getDeleteCommandParams(), true }) runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, { true }) diff --git a/test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua b/test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua index a17b452a6c..f0eac15dce 100644 --- a/test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua +++ b/test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua @@ -32,14 +32,14 @@ runner.Step("App activation", common.activateApp) runner.Title("Test") for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, { true }) for i = 4, 33 do runner.Step("SetGlobalProperties from SDL after added command" ..i, common.addCommandWithSetGP, { i }) end -runner.Step("Absence SetGlobalProperties from SDL after adding 35 command", common.addCommandWithoutSetGP, { 34 }) +runner.Step("Absence SetGlobalProperties from SDL after adding 34 command", common.addCommandWithoutSetGP, { 34 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua b/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua index 429fa9ab46..2bd337ad19 100644 --- a/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua +++ b/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua @@ -33,7 +33,7 @@ runner.Step("App activation", common.activateApp) runner.Title("Test") for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, { true }) @@ -43,7 +43,7 @@ end for i = 1, 10 do runner.Step("SetGlobalProperties from SDL after deleted command" ..i, common.deleteCommandWithSetGP, { i }) end -runner.Step("Absence SetGlobalProperties from SDL after adding 35 command", common.addCommandWithoutSetGP, { 34 }) +runner.Step("Absence SetGlobalProperties from SDL after adding 34 command", common.addCommandWithoutSetGP, { 34 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/006_SetGlobalProp_procesing_added_choices.lua b/test_scripts/Handling_VR_help_requests/006_SetGlobalProp_procesing_added_choices.lua index 840bbcfb47..390d77499f 100644 --- a/test_scripts/Handling_VR_help_requests/006_SetGlobalProp_procesing_added_choices.lua +++ b/test_scripts/Handling_VR_help_requests/006_SetGlobalProp_procesing_added_choices.lua @@ -62,7 +62,7 @@ runner.Step("App activation", common.activateApp) runner.Title("Test") for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Step("CreateInteractionChoiceSet", createInteractionChoiceSetWithoutSetGP) runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, diff --git a/test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_after_custom_request.lua b/test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_after_custom_request.lua index 6bd0b9499c..0b3cb1871f 100644 --- a/test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_after_custom_request.lua +++ b/test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_after_custom_request.lua @@ -27,7 +27,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Title("Test") diff --git a/test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request_after_timeout.lua b/test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request_after_timeout.lua index 926f6c2aea..749e050627 100644 --- a/test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request_after_timeout.lua +++ b/test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request_after_timeout.lua @@ -31,7 +31,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, { true }) diff --git a/test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request_after_timeout.lua b/test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request_after_timeout.lua index 5d132481b6..2f85e59266 100644 --- a/test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request_after_timeout.lua +++ b/test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request_after_timeout.lua @@ -31,7 +31,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, { true }) diff --git a/test_scripts/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua b/test_scripts/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua index a7800b0496..df3ab50073 100644 --- a/test_scripts/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua +++ b/test_scripts/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua @@ -29,7 +29,7 @@ SetGPParamsWithHelpPromptOnly.requestParams.vrHelp = nil --[[ Local Functions ]] local function SetGlobalPropertiesFromSDL() - local params = common.setGPParams() + local params = common.getGPParams() local hmiConnection = common.getHMIConnection() EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) :Do(function(_,data) @@ -40,8 +40,8 @@ local function SetGlobalPropertiesFromSDL() end local function SetGlobalPropertiesFromSDLbyAddingCommand() - common.addCommand(common.addCommandParams(4)) - local params = common.setGPParams() + common.addCommand(common.getAddCommandParams(4)) + local params = common.getGPParams() local hmiConnection = common.getHMIConnection() EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) :Do(function(_,data) @@ -58,7 +58,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Title("Test") diff --git a/test_scripts/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua b/test_scripts/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua index dba9fa5323..27f76343c2 100644 --- a/test_scripts/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua +++ b/test_scripts/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua @@ -28,7 +28,7 @@ SetGPParamsWithVrHelpOnly.requestParams.helpPrompt = nil --[[ Local Functions ]] local function SetGlobalPropertiesFromSDL() - local params = common.setGPParams() + local params = common.getGPParams() local hmiConnection = common.getHMIConnection() EXPECT_HMICALL("UI.SetGlobalProperties") :Times(0) @@ -39,8 +39,8 @@ local function SetGlobalPropertiesFromSDL() end local function SetGlobalPropertiesFromSDLbyAddingCommand() - common.addCommand(common.addCommandParams(4)) - local params = common.setGPParams() + common.addCommand(common.getAddCommandParams(4)) + local params = common.getGPParams() local hmiConnection = common.getHMIConnection() EXPECT_HMICALL("UI.SetGlobalProperties") :Times(0) @@ -57,7 +57,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Title("Test") diff --git a/test_scripts/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua b/test_scripts/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua index 39164f23a8..13444f1b59 100644 --- a/test_scripts/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua +++ b/test_scripts/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua @@ -35,7 +35,7 @@ SetGPParamsWithVrHelpOnly.requestParams.helpPrompt = nil --[[ Local Functions ]] local function SetGlobalPropertiesFromSDL() - local params = common.setGPParams() + local params = common.getGPParams() local hmiConnection = common.getHMIConnection() EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) :Do(function(_,data) @@ -46,8 +46,8 @@ local function SetGlobalPropertiesFromSDL() end local function SetGlobalPropertiesFromSDLbyAddingCommand() - common.addCommand(common.addCommandParams(4)) - local params = common.setGPParams() + common.addCommand(common.getAddCommandParams(4)) + local params = common.getGPParams() local hmiConnection = common.getHMIConnection() EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) :Do(function(_,data) @@ -64,7 +64,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Title("Test") diff --git a/test_scripts/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua b/test_scripts/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua index 1b90fbff8f..abd2b7a57e 100644 --- a/test_scripts/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua +++ b/test_scripts/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua @@ -37,7 +37,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Title("Test") diff --git a/test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_after_timeout_by_resumption.lua b/test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_after_timeout_by_resumption.lua index ed07c75f2c..170c213260 100644 --- a/test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_after_timeout_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_after_timeout_by_resumption.lua @@ -24,12 +24,12 @@ runner.testSettings.isSelfIncluded = false --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, {}) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("Pin OnHashChange", common.pinOnHashChange) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Title("Test") diff --git a/test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua b/test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua index 6662fbc997..ee66964f2c 100644 --- a/test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua @@ -17,6 +17,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -36,6 +37,8 @@ local commandWithtVr = { } } +local uiCommandArray = { { cmdID = commandWithtVr.cmdID }, { cmdID = commandWithoutVr.cmdID } } + --[[ Local Functions ]] local function resumptionLevelLimited() common.getHMIConnection():ExpectNotification("BasicCommunication.OnResumeAudioSource", @@ -54,6 +57,43 @@ local function resumptionLevelLimited() :Times(2) end +local function resumptionDataAddCommands() + EXPECT_HMICALL("VR.AddCommand") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + for _, value in pairs(common.commandArray) do + if data.params.cmdID == value.cmdID then + local vrCommandCompareResult = commonFunctions:is_table_equal(data.params.vrCommands, value.vrCommand) + local Msg = "" + if vrCommandCompareResult == false then + Msg = "vrCommands in received VR.AddCommand are not match to expected result.\n" .. + "Actual result:" .. common.tableToString(data.params.vrCommands) .. "\n" .. + "Expected result:" .. common.tableToString(value.vrCommand) .."\n" + end + return vrCommandCompareResult, Msg + end + end + return true + end) + :Times(#common.commandArray) + EXPECT_HMICALL("UI.AddCommand") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + for k, value in pairs(uiCommandArray) do + if data.params.cmdID == value.cmdID then + return true + elseif data.params.cmdID ~= value.cmdID and k == #uiCommandArray then + return false, "Received cmdID in UI.AddCommand was not added previously before resumption" + end + end + end) + :Times(#uiCommandArray) +end + local function deactivateAppToLimited() common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", {appID = common.getHMIAppId()}) common.getMobileSession():ExpectNotification("OnHMIStatus", @@ -72,10 +112,9 @@ runner.Step("Bring app to LIMITED HMI level", deactivateAppToLimited) runner.Title("Test") runner.Step("AddCommand with vr command", common.addCommand, { commandWithtVr }) runner.Step("AddCommand without vr command", common.addCommand, { commandWithoutVr }) -runner.Title("Test") runner.Step("App reconnect", common.reconnect) runner.Step("App resumption", common.registrationWithResumption, - { 1, resumptionLevelLimited, common.resumptionDataAddCommands }) + { 1, resumptionLevelLimited, resumptionDataAddCommands }) runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, { true }) diff --git a/test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_after_timeout_by_resumption.lua b/test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_after_timeout_by_resumption.lua index effac65d92..d9708aef49 100644 --- a/test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_after_timeout_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_after_timeout_by_resumption.lua @@ -23,7 +23,7 @@ local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function deleteCommandParams() +local function getDeleteCommandParams() local out = { cmdID = 1 } @@ -38,11 +38,11 @@ runner.Step("App registration", common.registerAppWOPTU) runner.Step("Pin OnHashChange", common.pinOnHashChange) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Title("Test") -runner.Step("Delete command1", common.deleteCommand, { deleteCommandParams(), true }) +runner.Step("Delete command1", common.deleteCommand, { getDeleteCommandParams(), true }) runner.Step("App reconnect", common.reconnect) runner.Step("App resumption", common.registrationWithResumption, { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) diff --git a/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua b/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua index 05e3ce9c51..42ec5e4996 100644 --- a/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua @@ -32,7 +32,7 @@ runner.Step("App activation", common.activateApp) runner.Title("Test") for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Step("App reconnect", common.reconnect) runner.Step("App resumption", common.registrationWithResumption, @@ -42,7 +42,7 @@ runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", co for i = 4, 33 do runner.Step("SetGlobalProperties from SDL after added command" ..i, common.addCommandWithSetGP, { i }) end -runner.Step("Absence SetGlobalProperties from SDL after adding 35 command", common.addCommandWithoutSetGP, { 34 }) +runner.Step("Absence SetGlobalProperties from SDL after adding 34 command", common.addCommandWithoutSetGP, { 34 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/019_SetGlobalProp_procesing_added_choices_by_resumption.lua b/test_scripts/Handling_VR_help_requests/019_SetGlobalProp_procesing_added_choices_by_resumption.lua index d2fdf27f17..33ed19994e 100644 --- a/test_scripts/Handling_VR_help_requests/019_SetGlobalProp_procesing_added_choices_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/019_SetGlobalProp_procesing_added_choices_by_resumption.lua @@ -91,7 +91,7 @@ runner.Step("App activation", common.activateApp) runner.Title("Test") for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Step("CreateInteractionChoiceSet", createInteractionChoiceSetWithoutSetGP) runner.Step("App reconnect", common.reconnect) diff --git a/test_scripts/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua b/test_scripts/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua index 9ce594b641..e486b1a7a5 100644 --- a/test_scripts/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua @@ -28,7 +28,7 @@ runner.Step("App registration", common.registerAppWOPTU) runner.Step("Pin OnHashChange", common.pinOnHashChange) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Title("Test") diff --git a/test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua b/test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua index b5b7bebe6f..88aaec9b99 100644 --- a/test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua @@ -46,7 +46,7 @@ runner.Step("App registration", common.registerAppWOPTU) runner.Step("Pin OnHashChange", common.pinOnHashChange) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Step("Custom SetGlobalProperties from mobile application", common.setGlobalProperties, { common.customSetGPParams() }) diff --git a/test_scripts/Handling_VR_help_requests/022_SetGlobalProp_absence_after_constructed_vrHelp_helpPrompt_before_resumption.lua b/test_scripts/Handling_VR_help_requests/022_SetGlobalProp_absence_after_constructed_vrHelp_helpPrompt_before_resumption.lua index 61409dd785..f1d2f1342e 100644 --- a/test_scripts/Handling_VR_help_requests/022_SetGlobalProp_absence_after_constructed_vrHelp_helpPrompt_before_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/022_SetGlobalProp_absence_after_constructed_vrHelp_helpPrompt_before_resumption.lua @@ -38,7 +38,7 @@ runner.Step("App activation", common.activateApp) runner.Title("Test") for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, { true }) diff --git a/test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua b/test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua index e76d32024e..5ac78fafe4 100644 --- a/test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua @@ -30,7 +30,7 @@ SetGPParamsWithHelpPromptOnly.requestParams.vrHelp = nil --[[ Local Functions ]] local function SetGlobalPropertiesFromSDL() - local params = common.setGPParams() + local params = common.getGPParams() local hmiConnection = common.getHMIConnection() EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) :Do(function(_,data) @@ -41,8 +41,8 @@ local function SetGlobalPropertiesFromSDL() end local function SetGlobalPropertiesFromSDLbyAddingCommand() - common.addCommand(common.addCommandParams(4)) - local params = common.setGPParams() + common.addCommand(common.getAddCommandParams(4)) + local params = common.getGPParams() local hmiConnection = common.getHMIConnection() EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) :Do(function(_,data) @@ -60,7 +60,7 @@ runner.Step("App registration", common.registerAppWOPTU) runner.Step("Pin OnHashChange", common.pinOnHashChange) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Step("App reconnect", common.reconnect) runner.Step("App resumption", common.registrationWithResumption, diff --git a/test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_vrHelp_only_by_resumption.lua b/test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_vrHelp_only_by_resumption.lua index f0745965db..daaeec0f20 100644 --- a/test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_vrHelp_only_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_vrHelp_only_by_resumption.lua @@ -29,7 +29,7 @@ SetGPParamsWithVrHelpOnly.requestParams.helpPrompt = nil --[[ Local Functions ]] local function SetGlobalPropertiesFromSDL() - local params = common.setGPParams() + local params = common.getGPParams() local hmiConnection = common.getHMIConnection() EXPECT_HMICALL("UI.SetGlobalProperties") :Times(0) @@ -40,8 +40,8 @@ local function SetGlobalPropertiesFromSDL() end local function SetGlobalPropertiesFromSDLbyAddingCommand() - common.addCommand(common.addCommandParams(4)) - local params = common.setGPParams() + common.addCommand(common.getAddCommandParams(4)) + local params = common.getGPParams() local hmiConnection = common.getHMIConnection() EXPECT_HMICALL("UI.SetGlobalProperties") :Times(0) @@ -59,7 +59,7 @@ runner.Step("App registration", common.registerAppWOPTU) runner.Step("Pin OnHashChange", common.pinOnHashChange) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Step("App reconnect", common.reconnect) runner.Step("App resumption", common.registrationWithResumption, diff --git a/test_scripts/Handling_VR_help_requests/025_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua b/test_scripts/Handling_VR_help_requests/025_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua index 5879a2ea97..bda6d3dff2 100644 --- a/test_scripts/Handling_VR_help_requests/025_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/025_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua @@ -39,7 +39,7 @@ runner.Step("App registration", common.registerAppWOPTU) runner.Step("Pin OnHashChange", common.pinOnHashChange) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Step("App reconnect", common.reconnect) runner.Step("App resumption", common.registrationWithResumption, diff --git a/test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua b/test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua index 48ef0ba141..c0735c5a65 100644 --- a/test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua +++ b/test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua @@ -20,7 +20,7 @@ local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local AddCommandParams = common.addCommandParams(1) +local AddCommandParams = common.getAddCommandParams(1) AddCommandParams.vrCommands = { "Command1_1", "Command2_1", "Command3_1" } --[[ Scenario ]] diff --git a/test_scripts/Handling_VR_help_requests/027_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua b/test_scripts/Handling_VR_help_requests/027_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua index 6a08a8e56b..a7bdc04a32 100644 --- a/test_scripts/Handling_VR_help_requests/027_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/027_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua @@ -21,7 +21,7 @@ local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local AddCommandParams = common.addCommandParams(1) +local AddCommandParams = common.getAddCommandParams(1) AddCommandParams.vrCommands = { "Command1_1", "Command2_1", "Command3_1" } --[[ Scenario ]] diff --git a/test_scripts/Handling_VR_help_requests/028_SetGlobalProp_invalid_custom_request.lua b/test_scripts/Handling_VR_help_requests/028_SetGlobalProp_invalid_custom_request.lua index 1f4f6bc563..f721918f8a 100644 --- a/test_scripts/Handling_VR_help_requests/028_SetGlobalProp_invalid_custom_request.lua +++ b/test_scripts/Handling_VR_help_requests/028_SetGlobalProp_invalid_custom_request.lua @@ -41,7 +41,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Title("Test") diff --git a/test_scripts/Handling_VR_help_requests/029_SetGlobalProp_rejected_custom_request.lua b/test_scripts/Handling_VR_help_requests/029_SetGlobalProp_rejected_custom_request.lua index 434d7708c0..1514c780e8 100644 --- a/test_scripts/Handling_VR_help_requests/029_SetGlobalProp_rejected_custom_request.lua +++ b/test_scripts/Handling_VR_help_requests/029_SetGlobalProp_rejected_custom_request.lua @@ -45,7 +45,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Title("Test") diff --git a/test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_successful_added_commands.lua b/test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_successful_added_commands.lua index a3791e654e..b5435f3e53 100644 --- a/test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_successful_added_commands.lua +++ b/test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_successful_added_commands.lua @@ -49,11 +49,11 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Title("Test") -runner.Step("Rejected adding Command4", rejectedAddCommand, { common.addCommandParams(4) }) +runner.Step("Rejected adding Command4", rejectedAddCommand, { common.getAddCommandParams(4) }) runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, { true }) diff --git a/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_only_without_successful_deleted_commands.lua b/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_only_without_successful_deleted_commands.lua index d41146263a..f6c88b83ab 100644 --- a/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_only_without_successful_deleted_commands.lua +++ b/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_only_without_successful_deleted_commands.lua @@ -53,7 +53,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.addCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end runner.Title("Test") diff --git a/test_scripts/Handling_VR_help_requests/commonVRhelp.lua b/test_scripts/Handling_VR_help_requests/commonVRhelp.lua index 78afa0fd1d..872342ea25 100644 --- a/test_scripts/Handling_VR_help_requests/commonVRhelp.lua +++ b/test_scripts/Handling_VR_help_requests/commonVRhelp.lua @@ -15,12 +15,13 @@ config.defaultProtocolVersion = 2 --[[ Variables ]] local m = actions m.commandArray = {} +m.timeActivation = 0 m.cloneTable = utils.cloneTable m.tableToString = utils.tableToString m.wait = utils.wait -function m.setGPParams() +function m.getGPParams() local params = { requestUiParams = { vrHelp = m.vrHelp(m.commandArray) @@ -56,7 +57,7 @@ function m.customSetGPParams() return allParams end -function m.addCommandParams(pN) +function m.getAddCommandParams(pN) local out = { cmdID = pN, vrCommands = { "vrCommand" .. pN}, @@ -92,16 +93,15 @@ function m.addCommand(pParams, pAppId) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) end -function m.deleteCommand(pParams, pVRInterface, pAppId) - if not pAppId then pAppId = 1 end - local mobSession = m.getMobileSession(pAppId) +function m.deleteCommand(pParams, pIsVRInterfaceEnabled) + local mobSession = m.getMobileSession() local hmiConnection = m.getHMIConnection() local cid = mobSession:SendRPC("DeleteCommand", pParams) EXPECT_HMICALL("UI.DeleteCommand") :Do(function(_,data) hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) - if pVRInterface then + if pIsVRInterfaceEnabled then for k, v in pairs(m.commandArray) do if v.cmdID == pParams.cmdID then table.remove(m.commandArray, k) @@ -110,7 +110,7 @@ function m.deleteCommand(pParams, pVRInterface, pAppId) local requestVrParams = { cmdID = pParams.cmdID, type = "Command", - appID = m.getHMIAppId(pAppId) + appID = m.getHMIAppId() } EXPECT_HMICALL("VR.DeleteCommand", requestVrParams) :Do(function(_,data) @@ -141,20 +141,19 @@ function m.setGlobalProperties(pParams, pAppId) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) end -function m.setGlobalPropertiesFromSDL(pTST) - local params = m.setGPParams() +function m.setGlobalPropertiesFromSDL(pIsCheckOnTimeoutRequied) + local params = m.getGPParams() local hmiConnection = m.getHMIConnection() EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) :Do(function(_,data) hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) :ValidIf(function() - if pTST then + if pIsCheckOnTimeoutRequied then local timeSetGPReg = timestamp() local timeToSetGP = timeSetGPReg - m.timeActivation - if timeToSetGP > 10500 or - timeToSetGP < 9500 then - return false, "SetGlobalProperties request with constracted vrHelp and helpPrompt came not in 10 sec " .. + if timeToSetGP > 10500 or timeToSetGP < 9500 then + return false, "SetGlobalProperties request with constructed vrHelp came not in 10 sec " .. "after activation, actual time is" .. tostring(timeToSetGP) end end @@ -164,6 +163,17 @@ function m.setGlobalPropertiesFromSDL(pTST) :Do(function(_,data) hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) + :ValidIf(function() + if pIsCheckOnTimeoutRequied then + local timeSetGPReg = timestamp() + local timeToSetGP = timeSetGPReg - m.timeActivation + if timeToSetGP > 10500 or timeToSetGP < 9500 then + return false, "SetGlobalProperties request with constructed helpPrompt came not in 10 sec " .. + "after activation, actual time is" .. tostring(timeToSetGP) + end + end + return true + end) end function m.activateApp(pAppId) @@ -180,11 +190,13 @@ end function m.vrHelp(pCommandArray) local out = {} - for k, value in pairs(pCommandArray) do + local positionValue = 0 + for _, value in pairs(pCommandArray) do for _, sub_v in pairs(value.vrCommand) do + positionValue = positionValue + 1 local item = { text = sub_v, - position = k + position = positionValue } table.insert(out, item) end @@ -231,12 +243,12 @@ function m.deleteCommandWithoutSetGP(pN) end function m.addCommandWithSetGP(pN) - m.addCommand(m.addCommandParams(pN)) + m.addCommand(m.getAddCommandParams(pN)) m.setGlobalPropertiesFromSDL() end function m.addCommandWithoutSetGP(pN) - m.addCommand(m.addCommandParams(pN)) + m.addCommand(m.getAddCommandParams(pN)) m.setGlobalPropertiesDoesNotExpect() end @@ -265,7 +277,7 @@ function m.registrationWithResumption(pAppId, pLevelResumpFunc, pDataResump) test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", { application = { appName = m.getConfigAppParams(pAppId).appName } }) :Do(function(_, d1) - m.writeHMIappId(d1.params.application.appID, pAppId) + m.setHMIAppId(d1.params.application.appID, pAppId) pDataResump() end) mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) @@ -300,12 +312,26 @@ function m.resumptionDataAddCommands() "Actual result:" .. m.tableToString(data.params.vrCommands) .. "\n" .. "Expected result:" .. m.tableToString(value.vrCommand) .."\n" end - return vrCommandCompareResult, Msg - end + return vrCommandCompareResult, Msg + end end return true end) :Times(#m.commandArray) + EXPECT_HMICALL("UI.AddCommand") + :Do(function(_, data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + for k, value in pairs(m.commandArray) do + if data.params.cmdID == value.cmdID then + return true + elseif data.params.cmdID ~= value.cmdID and k == #m.commandArray then + return false, "Received cmdID in UI.AddCommand was not added previously before resumption" + end + end + end) + :Times(#m.commandArray) end function m.resumptionLevelFull() From 9bff07bc256e38e29eede8db3a5c1d81f4259d2f Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 10 Jul 2018 18:10:34 +0300 Subject: [PATCH 480/681] Update according to removing 10sec timer --- ... 001_SetGlobalProp_by_adding_commands.lua} | 13 ++-- ...op_commands_with_and_without_vrCommand.lua | 10 ++- ...etGlobalProp_without_deleted_commands.lua} | 12 ++-- ..._SetGlobalProp_processing_30_commands.lua} | 26 +++----- ...p_processing_30_commands_after_timeout.lua | 45 -------------- ..._apply_limitation_only_for_addcommand.lua} | 18 ++---- ...etGlobalProp_processing_added_choices.lua} | 6 +- .../007_SetGlobalProp_absence_in_NONE.lua | 22 +++++-- ...08_SetGlobalProp_absence_in_BACKGROUND.lua | 61 +++++++++++++++++++ ...sence_addCommand_after_custom_request.lua} | 17 ++---- ...ce_deleteCommand_after_custom_request.lua} | 15 ++--- ...1_SetGlobalProp_custom_helpPrompt_only.lua | 22 ++----- .../012_SetGlobalProp_custom_vrHelp_only.lua | 20 +----- ...rompt_and_vrHelp_in_different_requests.lua | 24 ++------ ..._request_without_helpPrompt_and_vrHelp.lua | 7 +-- ...rop_with_added_commands_by_resumption.lua} | 9 ++- ...th_and_without_vrCommand_by_resumption.lua | 35 +++++++++-- ...ithout_deleted_commands_by_resumption.lua} | 16 +---- ..._processing_30_commands_by_resumption.lua} | 15 ++--- ...rocessing_added_choices_by_resumption.lua} | 31 ++++++++-- ..._after_custom_request_after_resumption.lua | 4 +- ...after_custom_request_before_resumption.lua | 38 +++++++++++- ...ed_vrHelp_helpPrompt_before_resumption.lua | 52 ---------------- ..._custom_helpPrompt_only_by_resumption.lua} | 18 +----- ...Prop_custom_vrHelp_only_by_resumption.lua} | 18 +----- ...t_helpPrompt_and_vrHelp_by_resumption.lua} | 5 +- ..._vrCommands_in_one_addCommand_request.lua} | 8 +-- ..._one_addCommand_request_by_resumption.lua} | 9 ++- ..._SetGlobalProp_invalid_custom_request.lua} | 7 +-- ...SetGlobalProp_rejected_custom_request.lua} | 7 +-- ...alProp_only_successful_added_commands.lua} | 15 +++-- ...y_without_successful_deleted_commands.lua} | 15 +++-- .../commonVRhelp.lua | 47 ++++++++++++-- test_sets/handling_VR_help_requests.txt | 43 +++++++------ 34 files changed, 346 insertions(+), 364 deletions(-) rename test_scripts/Handling_VR_help_requests/{008_SetGlobalProp_absence_after_custom_request.lua => 001_SetGlobalProp_by_adding_commands.lua} (74%) rename test_scripts/Handling_VR_help_requests/{001_SetGlobalProp_with_added_commands_after_timeout.lua => 003_SetGlobalProp_without_deleted_commands.lua} (82%) rename test_scripts/Handling_VR_help_requests/{003_SetGlobalProp_without_deleted_commands_after_timeout.lua => 004_SetGlobalProp_processing_30_commands.lua} (61%) delete mode 100644 test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua rename test_scripts/Handling_VR_help_requests/{005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua => 005_SetGlobalProp_apply_limitation_only_for_addcommand.lua} (69%) rename test_scripts/Handling_VR_help_requests/{006_SetGlobalProp_procesing_added_choices.lua => 006_SetGlobalProp_processing_added_choices.lua} (90%) create mode 100644 test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua rename test_scripts/Handling_VR_help_requests/{009_SetGlobalProp_absence_addCommand_after_custom_request_after_timeout.lua => 009_SetGlobalProp_absence_addCommand_after_custom_request.lua} (65%) rename test_scripts/Handling_VR_help_requests/{010_SetGlobalProp_absence_deleteCommand_after_custom_request_after_timeout.lua => 010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua} (68%) rename test_scripts/Handling_VR_help_requests/{015_SetGlobalProp_with_added_commands_after_timeout_by_resumption.lua => 015_SetGlobalProp_with_added_commands_by_resumption.lua} (80%) rename test_scripts/Handling_VR_help_requests/{017_SetGlobalProp_without_deleted_commands_after_timeout_by_resumption.lua => 017_SetGlobalProp_without_deleted_commands_by_resumption.lua} (77%) rename test_scripts/Handling_VR_help_requests/{018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua => 018_SetGlobalProp_processing_30_commands_by_resumption.lua} (77%) rename test_scripts/Handling_VR_help_requests/{019_SetGlobalProp_procesing_added_choices_by_resumption.lua => 019_SetGlobalProp_processing_added_choices_by_resumption.lua} (72%) delete mode 100644 test_scripts/Handling_VR_help_requests/022_SetGlobalProp_absence_after_constructed_vrHelp_helpPrompt_before_resumption.lua rename test_scripts/Handling_VR_help_requests/{023_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua => 022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua} (77%) rename test_scripts/Handling_VR_help_requests/{024_SetGlobalProp_custom_vrHelp_only_by_resumption.lua => 023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua} (78%) rename test_scripts/Handling_VR_help_requests/{025_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua => 024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua} (92%) rename test_scripts/Handling_VR_help_requests/{026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua => 025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua} (78%) rename test_scripts/Handling_VR_help_requests/{027_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua => 026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua} (88%) rename test_scripts/Handling_VR_help_requests/{028_SetGlobalProp_invalid_custom_request.lua => 027_SetGlobalProp_invalid_custom_request.lua} (89%) rename test_scripts/Handling_VR_help_requests/{029_SetGlobalProp_rejected_custom_request.lua => 028_SetGlobalProp_rejected_custom_request.lua} (89%) rename test_scripts/Handling_VR_help_requests/{030_SetGlobalProp_only_successful_added_commands.lua => 029_SetGlobalProp_only_successful_added_commands.lua} (85%) rename test_scripts/Handling_VR_help_requests/{031_SetGlobalProp_only_without_successful_deleted_commands.lua => 030_SetGlobalProp_only_without_successful_deleted_commands.lua} (85%) diff --git a/test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_after_custom_request.lua b/test_scripts/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua similarity index 74% rename from test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_after_custom_request.lua rename to test_scripts/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua index 0b3cb1871f..274f0e7086 100644 --- a/test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_after_custom_request.lua +++ b/test_scripts/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua @@ -8,10 +8,9 @@ -- Description: -- In case: -- 1. Command1, Command2, Command3 commands with vrCommands are added --- 2. Mobile application sets SetGlobalProperties with custom helpPrompt and vrHelp --- 3. 10 seconds timer is expired -- SDL does: --- not send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand. +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands +-- after receiving each command --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -26,13 +25,11 @@ runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) -for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) -end runner.Title("Test") -runner.Step("Custom SetGlobalProperties from mobile application", common.setGlobalProperties, - { common.customSetGPParams() }) +for i = 1,3 do + runner.Step("SetGlobalProperties after AddCommand" .. i, common.addCommandWithSetGP, { i }) +end runner.Step("Absence of SetGlobalProperties request from SDL", common.setGlobalPropertiesDoesNotExpect) runner.Title("Postconditions") diff --git a/test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua b/test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua index 2bd9dafa33..9a86f30606 100644 --- a/test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua +++ b/test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua @@ -8,9 +8,9 @@ -- Description: -- In case: -- 1. Command1 with vrCommand and Command2 without vrCommands are added --- 2. 10 seconds timer is expired -- SDL does: --- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand. +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand +-- only after receiving Command1. --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -42,10 +42,8 @@ runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) runner.Title("Test") -runner.Step("AddCommand with vr command", common.addCommand, { commandWithtVr }) -runner.Step("AddCommand without vr command", common.addCommand, { commandWithoutVr }) -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) +runner.Step("SetGlobalProperties after AddCommand with vr command", common.addCommandWithSetGP, { nil, commandWithtVr }) +runner.Step("Absence of SetGlobalProperties after AddCommand without vr command", common.addCommandWithoutSetGP, { nil, commandWithoutVr }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/001_SetGlobalProp_with_added_commands_after_timeout.lua b/test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua similarity index 82% rename from test_scripts/Handling_VR_help_requests/001_SetGlobalProp_with_added_commands_after_timeout.lua rename to test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua index 83ac3db134..7687a8876f 100644 --- a/test_scripts/Handling_VR_help_requests/001_SetGlobalProp_with_added_commands_after_timeout.lua +++ b/test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua @@ -8,9 +8,10 @@ -- Description: -- In case: -- 1. Command1, Command2, Command3 commands with vrCommands are added --- 2. 10 seconds timer is expired +-- 2. Command1 is deleted by app -- SDL does: --- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand +-- without deleted Command1 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -25,13 +26,12 @@ runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) - -runner.Title("Test") for i = 1,3 do runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) end -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) + +runner.Title("Test") +runner.Step("SetGlobalProperties by deleting Command1", common.deleteCommandWithSetGP, { 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands_after_timeout.lua b/test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua similarity index 61% rename from test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands_after_timeout.lua rename to test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua index 66c8eb9124..7e52a4ade3 100644 --- a/test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands_after_timeout.lua +++ b/test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua @@ -7,11 +7,11 @@ -- -- Description: -- In case: --- 1. Command1, Command2, Command3 commands with vrCommands are added --- 2. Command1 is deleted by app --- 3. 10 seconds timer is expired +-- 1. Mobile application sets 30 command one by one +-- 2. Mobile application sets 31 command -- SDL does: --- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand. +-- 1. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters after each added command +-- 2. not send SetGlobalProperties after added 31 command --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -20,28 +20,18 @@ local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false ---[[ Local Functions ]] -local function getDeleteCommandParams() - local out = { - cmdID = 1 - } - return out -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) -for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) -end runner.Title("Test") -runner.Step("Delete Command1", common.deleteCommand, { getDeleteCommandParams(), true }) -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) +for i = 1, 30 do + runner.Step("SetGlobalProperties from SDL after added command" ..i, common.addCommandWithSetGP, { i }) +end +runner.Step("Absence SetGlobalProperties from SDL after adding 31 command", common.addCommandWithoutSetGP, { 31 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua b/test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua deleted file mode 100644 index f0eac15dce..0000000000 --- a/test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua +++ /dev/null @@ -1,45 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md --- User story: TBD --- Use case: TBD --- --- Requirement summary: TBD --- --- Description: --- In case: --- 1. Command1, Command2, Command3 commands with vrCommands are added --- 2. 10 seconds timer is expired --- 3. SDL sends SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand. --- 4. Mobile application sets 30 command one by one --- 5. Mobile application sets 31 command --- SDL does: --- send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters after each added command --- not send SetGlobalProperties after added 31 command ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("App registration", common.registerAppWOPTU) -runner.Step("App activation", common.activateApp) - -runner.Title("Test") -for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) -end -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) -for i = 4, 33 do - runner.Step("SetGlobalProperties from SDL after added command" ..i, common.addCommandWithSetGP, { i }) -end -runner.Step("Absence SetGlobalProperties from SDL after adding 34 command", common.addCommandWithoutSetGP, { 34 }) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua b/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua similarity index 69% rename from test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua rename to test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua index 2bd337ad19..f12c69cfa0 100644 --- a/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua +++ b/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua @@ -7,12 +7,9 @@ -- -- Description: -- In case: --- 1. Command1, Command2, Command3 commands with vrCommands are added --- 2. 10 seconds timer is expired --- 3. SDL sends SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand. --- 4. Mobile application sets 30 command one by one --- 5.Mobile application deletes 10 command one by one --- 6. Mobile application sets 31 command +-- 1. Mobile application sets 30 command one by one +-- 2.Mobile application deletes 10 command one by one +-- 3. Mobile application sets 31 command -- SDL does: -- send SetGlobalProperties with update for vrHelp and helpPrompt parameters after each added and deleted command -- not send SetGlobalProperties after added 31 command @@ -32,18 +29,13 @@ runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) runner.Title("Test") -for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) -end -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) -for i = 4, 33 do +for i = 1, 30 do runner.Step("SetGlobalProperties from SDL after added command" ..i, common.addCommandWithSetGP, { i }) end for i = 1, 10 do runner.Step("SetGlobalProperties from SDL after deleted command" ..i, common.deleteCommandWithSetGP, { i }) end -runner.Step("Absence SetGlobalProperties from SDL after adding 34 command", common.addCommandWithoutSetGP, { 34 }) +runner.Step("Absence SetGlobalProperties from SDL after adding 34 command", common.addCommandWithoutSetGP, { 31 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/006_SetGlobalProp_procesing_added_choices.lua b/test_scripts/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua similarity index 90% rename from test_scripts/Handling_VR_help_requests/006_SetGlobalProp_procesing_added_choices.lua rename to test_scripts/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua index 390d77499f..8958fa0151 100644 --- a/test_scripts/Handling_VR_help_requests/006_SetGlobalProp_procesing_added_choices.lua +++ b/test_scripts/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua @@ -9,7 +9,6 @@ -- In case: -- 1. Command1, Command2, Command3 commands with vrCommands are added -- 2. vrCommands Choice1, Choice2 are added via CreateInterationChoiceSet --- 3. 10 seconds timer is expired -- SDL does: -- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands via AddCommand -- requests(with type "Command" ). @@ -51,6 +50,7 @@ local function createInteractionChoiceSetWithoutSetGP() hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + common.setGlobalPropertiesDoesNotExpect() end --[[ Scenario ]] @@ -62,11 +62,9 @@ runner.Step("App activation", common.activateApp) runner.Title("Test") for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommandWithSetGP, { i }) end runner.Step("CreateInteractionChoiceSet", createInteractionChoiceSetWithoutSetGP) -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua b/test_scripts/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua index ce6ba99056..9a4bb26678 100644 --- a/test_scripts/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua +++ b/test_scripts/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua @@ -7,10 +7,12 @@ -- -- Description: -- In case: --- 1. App is registered and in NONE hmiLevel --- 2. 10 seconds timer is expired +-- 1. App is registered and set in NONE HMI level. +-- 2. PT is updated with "NONE" for AddCommand RPC +-- 3. Command1, Command2, Command3 commands with vrCommands are added -- SDL does: --- not send SetGlobalProperties to HMI +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands +-- after receiving each command --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -18,15 +20,25 @@ local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } +config.application1.registerAppInterfaceParams.isMediaApplication = false + +--[[ Local Functions ]] +local function ptuFunc(tbl) + tbl.policy_table.functional_groupings["Base-4"].rpcs.AddCommand.hmi_levels = { "BACKGROUND", "FULL", "LIMITED", "NONE" } +end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App1 registration", common.registerApp) +runner.Step("PTU with NONE hmi level for AddCommand", common.policyTableUpdate, { ptuFunc }) runner.Title("Test") -runner.Step("App registration", common.registerAppWOPTU) -runner.Step("Absence of SetGlobalProperties request from SDL", common.setGlobalPropertiesDoesNotExpect) +for i = 1,3 do + runner.Step("SetGlobalProperties after AddCommand" .. i, common.addCommandWithSetGP, { i }) +end runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua b/test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua new file mode 100644 index 0000000000..babbb974d5 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- Description: +-- In case: +-- 1. App is registered and activated. +-- 2. PT is updated with "BACKGROUND" for AddCommand RPC +-- 3. App deactivated to BACKGROUND HMI level +-- 3. Command1, Command2, Command3 commands with vrCommands are added +-- SDL does: +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands +-- after receiving each command +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } +config.application1.registerAppInterfaceParams.isMediaApplication = false + +--[[ Local Functions ]] +local function ptuFunc(tbl) + tbl.policy_table.functional_groupings["Base-4"].rpcs.AddCommand.hmi_levels = { "BACKGROUND", "FULL", "LIMITED", "NONE" } +end + +local function activateApp() + local requestId = common.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId(1) }) + common.getHMIConnection():ExpectResponse(requestId) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +local function deactivateApp() + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", {appID = common.getHMIAppId(1)}) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", + {hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App1 registration", common.registerApp) +runner.Step("App activation", activateApp) +runner.Step("PTU with BACKGROUND hmi level for AddCommand", common.policyTableUpdate, { ptuFunc }) +runner.Step("App deactivation", deactivateApp) + +runner.Title("Test") +for i = 1,3 do + runner.Step("SetGlobalProperties after AddCommand" .. i, common.addCommandWithSetGP, { i }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request_after_timeout.lua b/test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua similarity index 65% rename from test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request_after_timeout.lua rename to test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua index 749e050627..4f136c30cd 100644 --- a/test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request_after_timeout.lua +++ b/test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua @@ -8,12 +8,9 @@ -- Description: -- In case: -- 1. Command1, Command2, Command3 commands with vrCommands are added --- 2. Mobile application sets SetGlobalProperties with custom helpPrompt and vrHelp --- 3. 10 seconds timer is expired and SDL send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands +-- 2. SDL sends SetGlobalProperties with updated list of command +-- 3. Mobile application sets SetGlobalProperties with custom helpPrompt and vrHelp -- 4. Mobile application adds Command4 command --- 5.SDL sends SetGlobalProperties with updated list of commands --- 6.Mobile application sets SetGlobalProperties with custom helpPrompt and vrHelp --- 7.Mobile application adds Command5 command -- SDL does: -- not send SetGlobalProperties with updated values for the vrHelp and helpPrompt parameters --------------------------------------------------------------------------------------------------- @@ -31,18 +28,14 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommandWithSetGP, { i }) end -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) runner.Title("Test") -runner.Step("SetGlobalProperties from SDL with updated values after added command4", common.addCommandWithSetGP, - { 4 }) runner.Step("Custom SetGlobalProperties from mobile application", common.setGlobalProperties, { common.customSetGPParams() }) -runner.Step("Absence of SetGlobalProperties request from SDL after added command5", common.addCommandWithoutSetGP, - { 5 }) +runner.Step("Absence of SetGlobalProperties request from SDL after added command4", common.addCommandWithoutSetGP, + { 4 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request_after_timeout.lua b/test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua similarity index 68% rename from test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request_after_timeout.lua rename to test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua index 2f85e59266..671aa61f31 100644 --- a/test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request_after_timeout.lua +++ b/test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua @@ -7,13 +7,10 @@ -- -- Description: -- In case: --- 1. Command1, Command2, Command3 commands with vrCommands are added --- 2. Mobile application sets SetGlobalProperties with custom helpPrompt and vrHelp --- 3. 10 seconds timer is expired and SDL send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands --- 4. Mobile application deletes Command1 command --- 5.SDL sends SetGlobalProperties with updated list of command --- 6.Mobile application sets SetGlobalProperties with custom helpPrompt and vrHelp --- 7.Mobile application deletes Command2 +-- 1. Mobile application deletes Command1 command +-- 2. SDL sends SetGlobalProperties with updated list of command +-- 3. Mobile application sets SetGlobalProperties with custom helpPrompt and vrHelp +-- 4. Mobile application deletes Command2 -- SDL does: -- not send SetGlobalProperties with updated values for the vrHelp and helpPrompt parameters --------------------------------------------------------------------------------------------------- @@ -31,10 +28,8 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommandWithSetGP, { i }) end -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) runner.Title("Test") runner.Step("SetGlobalProperties from SDL with updated values after deleting command1", common.deleteCommandWithSetGP, diff --git a/test_scripts/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua b/test_scripts/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua index df3ab50073..f68bb1bd49 100644 --- a/test_scripts/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua +++ b/test_scripts/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua @@ -9,11 +9,9 @@ -- In case: -- 1. Command1, Command2, Command3 commands with vrCommands are added -- 2. Mobile application sets SetGlobalProperties with custom helpPrompt --- 3. 10 seconds timer is expired --- 4. Mobile application adds Command4 +-- 3. Mobile application adds Command4 -- SDL does: --- 1. send SetGlobalProperties with constructed the vrHelp parameter using added vrCommand. --- 2. send SetGlobalProperties with updated value for the vrHelp parameter using added vrCommand +-- 1. send SetGlobalProperties with updated value for the vrHelp parameter using added vrCommands --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -28,17 +26,6 @@ SetGPParamsWithHelpPromptOnly.requestParams.vrHelpTitle = nil SetGPParamsWithHelpPromptOnly.requestParams.vrHelp = nil --[[ Local Functions ]] -local function SetGlobalPropertiesFromSDL() - local params = common.getGPParams() - local hmiConnection = common.getHMIConnection() - EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) - :Do(function(_,data) - hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - EXPECT_HMICALL("TTS.SetGlobalProperties") - :Times(0) -end - local function SetGlobalPropertiesFromSDLbyAddingCommand() common.addCommand(common.getAddCommandParams(4)) local params = common.getGPParams() @@ -58,14 +45,13 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommandWithSetGP, { i }) end runner.Title("Test") runner.Step("Custom SetGlobalProperties with helpPrompt only from mobile application", common.setGlobalProperties, { SetGPParamsWithHelpPromptOnly }) -runner.Step("SetGlobalProperties with constructed the vrHelp", SetGlobalPropertiesFromSDL) -runner.Step("SetGlobalProperties with updated value for vrHelp after added command ", +runner.Step("SetGlobalProperties with updated value for vrHelp after added command", SetGlobalPropertiesFromSDLbyAddingCommand) runner.Title("Postconditions") diff --git a/test_scripts/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua b/test_scripts/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua index 27f76343c2..cf2f512578 100644 --- a/test_scripts/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua +++ b/test_scripts/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua @@ -9,11 +9,9 @@ -- In case: -- 1. Command1, Command2, Command3 commands with vrCommands are added -- 2. Mobile application sets SetGlobalProperties with custom vrHelp --- 3. 10 seconds timer is expired --- 4. Mobile application adds Command4 +-- 3. Mobile application adds Command4 -- SDL does: --- 1. send SetGlobalProperties with constructed the helpPrompt parameter using added vrCommand. --- 2. send SetGlobalProperties with updated value for the helpPrompt parameter using added vrCommands +-- 1. send SetGlobalProperties with updated value for the helpPrompt parameter using added vrCommands --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -27,17 +25,6 @@ local SetGPParamsWithVrHelpOnly = common.customSetGPParams() SetGPParamsWithVrHelpOnly.requestParams.helpPrompt = nil --[[ Local Functions ]] -local function SetGlobalPropertiesFromSDL() - local params = common.getGPParams() - local hmiConnection = common.getHMIConnection() - EXPECT_HMICALL("UI.SetGlobalProperties") - :Times(0) - EXPECT_HMICALL("TTS.SetGlobalProperties", params.requestTtsParams) - :Do(function(_,data) - hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) -end - local function SetGlobalPropertiesFromSDLbyAddingCommand() common.addCommand(common.getAddCommandParams(4)) local params = common.getGPParams() @@ -57,13 +44,12 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommandWithSetGP, { i }) end runner.Title("Test") runner.Step("Custom SetGlobalProperties with vrHelp only from mobile application", common.setGlobalProperties, { SetGPParamsWithVrHelpOnly }) -runner.Step("SetGlobalProperties with constructed the helpPrompt", SetGlobalPropertiesFromSDL) runner.Step("SetGlobalProperties with updated value for helpPrompt after added command ", SetGlobalPropertiesFromSDLbyAddingCommand) diff --git a/test_scripts/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua b/test_scripts/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua index 13444f1b59..f5e6353485 100644 --- a/test_scripts/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua +++ b/test_scripts/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua @@ -9,14 +9,12 @@ -- In case: -- 1. Command1, Command2, Command3 commands with vrCommands are added -- 2. Mobile application sets SetGlobalProperties with only custom helpPrompt --- 3. 10 seconds timer is expired and SDL sends SetGlobalProperties with constructed the vrHelp parameter using added vrCommands --- 4. Mobile application adds Command4 --- 5. SDL sends SetGlobalProperties with updated value for the vrHelp parameter using added vrCommands +-- 3. Mobile application adds Command4 +-- 4. SDL sends SetGlobalProperties with updated value for the vrHelp parameter using added vrCommands -- 6. Mobile application sets SetGlobalProperties with only custom vrHelp --- 7. Mobile application adds Command5 +-- 7. Mobile application adds Command5 -- SDL does: --- 1. send SetGlobalProperties with constructed the vrHelp parameter using added vrCommand. --- 2. send SetGlobalProperties with updated value for the vrHelp parameter using added vrCommand +-- 1. not send SetGlobalProperties with updated values for the vrHelp and helpPrompt --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -34,17 +32,6 @@ local SetGPParamsWithVrHelpOnly = common.cloneTable(common.customSetGPParams()) SetGPParamsWithVrHelpOnly.requestParams.helpPrompt = nil --[[ Local Functions ]] -local function SetGlobalPropertiesFromSDL() - local params = common.getGPParams() - local hmiConnection = common.getHMIConnection() - EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) - :Do(function(_,data) - hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - EXPECT_HMICALL("TTS.SetGlobalProperties") - :Times(0) -end - local function SetGlobalPropertiesFromSDLbyAddingCommand() common.addCommand(common.getAddCommandParams(4)) local params = common.getGPParams() @@ -64,13 +51,12 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommandWithSetGP, { i }) end runner.Title("Test") runner.Step("Custom SetGlobalProperties with helpPrompt only from mobile application", common.setGlobalProperties, { SetGPParamsWithHelpPromptOnly }) -runner.Step("SetGlobalProperties with constructed the vrHelp", SetGlobalPropertiesFromSDL) runner.Step("SetGlobalProperties with updated value for vrHelp after added command ", SetGlobalPropertiesFromSDLbyAddingCommand) runner.Step("Custom SetGlobalProperties with vrHrelp only from mobile application", common.setGlobalProperties, diff --git a/test_scripts/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua b/test_scripts/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua index abd2b7a57e..da542bb189 100644 --- a/test_scripts/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua +++ b/test_scripts/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua @@ -9,7 +9,7 @@ -- In case: -- 1. Command1, Command2, Command3 commands with vrCommands are added -- 2. Mobile application sets SetGlobalProperties without helpPrompt and vrHelp --- 3. 10 seconds timer is expired +-- 3. Mobile app adds Command4 -- SDL does: -- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand. --------------------------------------------------------------------------------------------------- @@ -37,14 +37,13 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommandWithSetGP, { i }) end runner.Title("Test") runner.Step("Custom SetGlobalProperties from mobile application without helpPrompt and vrHelp", common.setGlobalProperties, { setGPParams }) -runner.Step("SetGlobalProperties request from SDL with constructed the vrHelp and helpPrompt", - common.setGlobalPropertiesFromSDL, { true }) +runner.Step("SetGlobalProperties by adding AddCommand4", common.addCommandWithSetGP, { 4 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_after_timeout_by_resumption.lua b/test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua similarity index 80% rename from test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_after_timeout_by_resumption.lua rename to test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua index 170c213260..0b9e4fc46e 100644 --- a/test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_after_timeout_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua @@ -11,8 +11,8 @@ -- 2. Perform reopening session -- SDL does: -- 1. resume HMI level and added before reconnection AddCommands --- 2. send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands --- when timer times out after resuming HMI level +-- 2. send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands +-- after each resumed command --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -29,15 +29,14 @@ runner.Step("App registration", common.registerAppWOPTU) runner.Step("Pin OnHashChange", common.pinOnHashChange) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommandWithSetGP, { i }) end runner.Title("Test") runner.Step("App reconnect", common.reconnect) runner.Step("App resumption", common.registrationWithResumption, { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) +runner.Step("Absence of SetGlobalProperties request from SDL", common.setGlobalPropertiesDoesNotExpect) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua b/test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua index ee66964f2c..4453a9dc4a 100644 --- a/test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua @@ -11,8 +11,8 @@ -- 2. Perform reopening session -- SDL does: -- 1. resume HMI level and added before reconnection AddCommands --- 2. send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand. --- when timer times out after resuming HMI level +-- 2. send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands +-- after each resumed command --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -78,6 +78,19 @@ local function resumptionDataAddCommands() return true end) :Times(#common.commandArray) + EXPECT_HMICALL("TTS.SetGlobalProperties") + :ValidIf(function(_, data) + local expectedHelpPrompt = common.vrHelpPrompt(common.commandArray) + local vrCommandCompareResult = commonFunctions:is_table_equal(data.params.helpPrompt, expectedHelpPrompt) + local Msg = "" + if vrCommandCompareResult == false then + Msg = "helpPrompt in received TTS.SetGlobalProperties is not match to expected result.\n" .. + "Actual result:" .. common.tableToString(data.params.helpPrompt) .. "\n" .. + "Expected result:" .. common.tableToString(expectedHelpPrompt) .."\n" + end + return vrCommandCompareResult, Msg + end) + EXPECT_HMICALL("UI.AddCommand") :Do(function(_, data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) @@ -92,6 +105,18 @@ local function resumptionDataAddCommands() end end) :Times(#uiCommandArray) + EXPECT_HMICALL("UI.SetGlobalProperties") + :ValidIf(function(_, data) + local expectedVrHelp = common.vrHelp(common.commandArray) + local vrCommandCompareResult = commonFunctions:is_table_equal(data.params.vrHelp, expectedVrHelp) + local Msg = "" + if vrCommandCompareResult == false then + Msg = "vrHelp in received TTS.SetGlobalProperties is not match to expected result.\n" .. + "Actual result:" .. common.tableToString(data.params.vrHelp) .. "\n" .. + "Expected result:" .. common.tableToString(expectedVrHelp) .."\n" + end + return vrCommandCompareResult, Msg + end) end local function deactivateAppToLimited() @@ -110,13 +135,11 @@ runner.Step("App activation", common.activateApp) runner.Step("Bring app to LIMITED HMI level", deactivateAppToLimited) runner.Title("Test") -runner.Step("AddCommand with vr command", common.addCommand, { commandWithtVr }) -runner.Step("AddCommand without vr command", common.addCommand, { commandWithoutVr }) +runner.Step("AddCommand with vr command", common.addCommandWithSetGP, {nil, commandWithtVr }) +runner.Step("AddCommand without vr command", common.addCommandWithoutSetGP, {nil, commandWithoutVr }) runner.Step("App reconnect", common.reconnect) runner.Step("App resumption", common.registrationWithResumption, { 1, resumptionLevelLimited, resumptionDataAddCommands }) -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_after_timeout_by_resumption.lua b/test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua similarity index 77% rename from test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_after_timeout_by_resumption.lua rename to test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua index d9708aef49..838c06d93b 100644 --- a/test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_after_timeout_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua @@ -13,7 +13,7 @@ -- SDL does: -- 1. resume HMI level and AddCommands -- 2. send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand --- when timer times out after resuming HMI level +-- after each resumed command --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -22,14 +22,6 @@ local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false ---[[ Local Functions ]] -local function getDeleteCommandParams() - local out = { - cmdID = 1 - } - return out -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) @@ -38,16 +30,14 @@ runner.Step("App registration", common.registerAppWOPTU) runner.Step("Pin OnHashChange", common.pinOnHashChange) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommandWithSetGP, { i }) end runner.Title("Test") -runner.Step("Delete command1", common.deleteCommand, { getDeleteCommandParams(), true }) +runner.Step("Delete command1", common.deleteCommandWithSetGP, { 1 }) runner.Step("App reconnect", common.reconnect) runner.Step("App resumption", common.registrationWithResumption, { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua b/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua similarity index 77% rename from test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua rename to test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua index 42ec5e4996..5e1edd4cd8 100644 --- a/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua @@ -9,11 +9,14 @@ -- In case: -- 1. Command1, Command2, Command3 commands with vrCommands are added -- 2. Perform reopening session +-- 3. Mobile app adds 30 commands after resumption +-- 3. Mobile app adds 31 command -- SDL does: --- 1. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters after each added --- command after resumption in 10 seconds after FULL hmi level --- 2. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters after each added command --- 3. not send SetGlobalProperties after added 31 command +-- 1. resume HMI level and AddCommands +-- 2. send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand +-- after each resumed command +-- 3. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters after each added command +-- 4. not send SetGlobalProperties after added 31 command --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -32,13 +35,11 @@ runner.Step("App activation", common.activateApp) runner.Title("Test") for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommandWithSetGP, { i }) end runner.Step("App reconnect", common.reconnect) runner.Step("App resumption", common.registrationWithResumption, { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) for i = 4, 33 do runner.Step("SetGlobalProperties from SDL after added command" ..i, common.addCommandWithSetGP, { i }) end diff --git a/test_scripts/Handling_VR_help_requests/019_SetGlobalProp_procesing_added_choices_by_resumption.lua b/test_scripts/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua similarity index 72% rename from test_scripts/Handling_VR_help_requests/019_SetGlobalProp_procesing_added_choices_by_resumption.lua rename to test_scripts/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua index 33ed19994e..0b65c6407e 100644 --- a/test_scripts/Handling_VR_help_requests/019_SetGlobalProp_procesing_added_choices_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua @@ -12,7 +12,7 @@ -- 3. Perform session reconnect -- SDL does: -- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands via AddCommand --- requests(with type "Command") after resumption in 10 seconds after FULL hmi level +-- requests(with type "Command") after each resumed AddCommad --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -56,6 +56,7 @@ local function createInteractionChoiceSetWithoutSetGP() hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + common.setGlobalPropertiesDoesNotExpect() end local function resumptionDataAddCommands() @@ -79,6 +80,30 @@ local function resumptionDataAddCommands() return true end) :Times(#commandArrayResumption) + EXPECT_HMICALL("TTS.SetGlobalProperties") + :ValidIf(function(_, data) + local expectedHelpPrompt = common.vrHelpPrompt(common.commandArray) + local vrCommandCompareResult = commonFunctions:is_table_equal(data.params.helpPrompt, expectedHelpPrompt) + local Msg = "" + if vrCommandCompareResult == false then + Msg = "helpPrompt in received TTS.SetGlobalProperties is not match to expected result.\n" .. + "Actual result:" .. common.tableToString(data.params.helpPrompt) .. "\n" .. + "Expected result:" .. common.tableToString(expectedHelpPrompt) .."\n" + end + return vrCommandCompareResult, Msg + end) + EXPECT_HMICALL("UI.SetGlobalProperties") + :ValidIf(function(_, data) + local expectedVrHelp = common.vrHelp(common.commandArray) + local vrCommandCompareResult = commonFunctions:is_table_equal(data.params.vrHelp, expectedVrHelp) + local Msg = "" + if vrCommandCompareResult == false then + Msg = "vrHelp in received TTS.SetGlobalProperties is not match to expected result.\n" .. + "Actual result:" .. common.tableToString(data.params.vrHelp) .. "\n" .. + "Expected result:" .. common.tableToString(expectedVrHelp) .."\n" + end + return vrCommandCompareResult, Msg + end) end --[[ Scenario ]] @@ -91,14 +116,12 @@ runner.Step("App activation", common.activateApp) runner.Title("Test") for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommandWithSetGP, { i }) end runner.Step("CreateInteractionChoiceSet", createInteractionChoiceSetWithoutSetGP) runner.Step("App reconnect", common.reconnect) runner.Step("App resumption", common.registrationWithResumption, { 1, common.resumptionLevelFull, resumptionDataAddCommands }) -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua b/test_scripts/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua index e486b1a7a5..364e52cc20 100644 --- a/test_scripts/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua @@ -10,6 +10,7 @@ -- 1. Command1, Command2, Command3 commands with vrCommands are added -- 2. Perform session reconnect -- 3. Mobile application sets SetGlobalProperties with custom helpPrompt and vrHelp after resumption +-- 4. Mobile app adds Command4 -- SDL does: -- not send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters --------------------------------------------------------------------------------------------------- @@ -37,7 +38,8 @@ runner.Step("App resumption", common.registrationWithResumption, { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) runner.Step("Custom SetGlobalProperties from mobile application", common.setGlobalProperties, { common.customSetGPParams() }) -runner.Step("Absence of SetGlobalProperties request from SDL", common.setGlobalPropertiesDoesNotExpect) +runner.Step("Absence of SetGlobalProperties request from SDL after added command4", common.addCommandWithoutSetGP, + { 4 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua b/test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua index 88aaec9b99..cd92473f8f 100644 --- a/test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua @@ -12,11 +12,12 @@ -- 3. Perform session reconnect -- SDL does: -- 1. resume custom SetGlobalProperties --- 2. not send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters +-- 2. not send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters after each resumed command --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -26,7 +27,40 @@ local SetGPParams = common.customSetGPParams() --[[ Local Functions ]] local function resumptionData() - common.resumptionDataAddCommands() + EXPECT_HMICALL("VR.AddCommand") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + for _, value in pairs(common.commandArray) do + if data.params.cmdID == value.cmdID then + local vrCommandCompareResult = commonFunctions:is_table_equal(data.params.vrCommands, value.vrCommand) + local Msg = "" + if vrCommandCompareResult == false then + Msg = "vrCommands in received VR.AddCommand are not match to expected result.\n" .. + "Actual result:" .. common.tableToString(data.params.vrCommands) .. "\n" .. + "Expected result:" .. common.tableToString(value.vrCommand) .."\n" + end + return vrCommandCompareResult, Msg + end + end + return true + end) + :Times(#common.commandArray) +EXPECT_HMICALL("UI.AddCommand") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + for k, value in pairs(common.commandArray) do + if data.params.cmdID == value.cmdID then + return true + elseif data.params.cmdID ~= value.cmdID and k == #common.commandArray then + return false, "Received cmdID in UI.AddCommand was not added previously before resumption" + end + end + end) + :Times(#common.commandArray) local hmiConnection = common.getHMIConnection() EXPECT_HMICALL("UI.SetGlobalProperties", SetGPParams.requestUiParams) :Do(function(_,data) diff --git a/test_scripts/Handling_VR_help_requests/022_SetGlobalProp_absence_after_constructed_vrHelp_helpPrompt_before_resumption.lua b/test_scripts/Handling_VR_help_requests/022_SetGlobalProp_absence_after_constructed_vrHelp_helpPrompt_before_resumption.lua deleted file mode 100644 index f1d2f1342e..0000000000 --- a/test_scripts/Handling_VR_help_requests/022_SetGlobalProp_absence_after_constructed_vrHelp_helpPrompt_before_resumption.lua +++ /dev/null @@ -1,52 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md --- User story: TBD --- Use case: TBD --- --- Requirement summary: TBD --- --- Description: --- In case: --- 1. Command1, Command2, Command3 commands with vrCommands are added --- 2. 10 seconds timer is expired --- 3. send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. --- 4. Perform session reconnect --- SDL does: --- 1. Resume SetGlobalProperties --- 2. not send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ Local Functions ]] -local function resumptionData() - common.resumptionDataAddCommands() - common.setGlobalPropertiesFromSDL() -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("App registration", common.registerAppWOPTU) -runner.Step("Pin OnHashChange", common.pinOnHashChange) -runner.Step("App activation", common.activateApp) - -runner.Title("Test") -for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) -end -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) -runner.Step("Wait for resumption data saving", common.wait, { 10000 }) -runner.Step("App reconnect", common.reconnect) -runner.Step("App resumption", common.registrationWithResumption, - { 1, common.resumptionLevelFull, resumptionData }) -runner.Step("Absence of SetGlobalProperties request from SDL", common.setGlobalPropertiesDoesNotExpect) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua b/test_scripts/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua similarity index 77% rename from test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua rename to test_scripts/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua index 5ac78fafe4..7768ab427f 100644 --- a/test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua @@ -10,11 +10,9 @@ -- 1. Command1, Command2, Command3 commands with vrCommands are added -- 2. Perform reconnect -- 3. Mobile application sets SetGlobalProperties with custom helpPrompt --- 4. 10 seconds timer is expired --- 5. Mobile application adds Command4 +-- 4. Mobile application adds Command4 -- SDL does: --- 1. send SetGlobalProperties with constructed the vrHelp parameter using added vrCommand. --- 2. send SetGlobalProperties with updated value for the vrHelp parameter using added vrCommand +-- 1. send SetGlobalProperties with updated value for the vrHelp parameter using added vrCommand --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -29,17 +27,6 @@ SetGPParamsWithHelpPromptOnly.requestParams.vrHelpTitle = nil SetGPParamsWithHelpPromptOnly.requestParams.vrHelp = nil --[[ Local Functions ]] -local function SetGlobalPropertiesFromSDL() - local params = common.getGPParams() - local hmiConnection = common.getHMIConnection() - EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) - :Do(function(_,data) - hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - EXPECT_HMICALL("TTS.SetGlobalProperties") - :Times(0) -end - local function SetGlobalPropertiesFromSDLbyAddingCommand() common.addCommand(common.getAddCommandParams(4)) local params = common.getGPParams() @@ -69,7 +56,6 @@ runner.Step("App resumption", common.registrationWithResumption, runner.Title("Test") runner.Step("Custom SetGlobalProperties with helpPrompt only from mobile application", common.setGlobalProperties, { SetGPParamsWithHelpPromptOnly }) -runner.Step("SetGlobalProperties with constructed the vrHelp", SetGlobalPropertiesFromSDL) runner.Step("SetGlobalProperties with updated value for vrHelp after added command ", SetGlobalPropertiesFromSDLbyAddingCommand) diff --git a/test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_vrHelp_only_by_resumption.lua b/test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua similarity index 78% rename from test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_vrHelp_only_by_resumption.lua rename to test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua index daaeec0f20..c25baee33a 100644 --- a/test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_vrHelp_only_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua @@ -10,11 +10,9 @@ -- 1. Command1, Command2, Command3 commands with vrCommands are added -- 3. Perform reconnect -- 4. Mobile application sets SetGlobalProperties with custom vrHelp --- 5. 10 seconds timer is expired --- 6. Mobile application adds Command4 +-- 5. Mobile application adds Command4 -- SDL does: --- 1. send SetGlobalProperties with constructed the helpPrompt parameter using added vrCommand. --- 2. send SetGlobalProperties with updated value for the helpPrompt parameter using added vrCommands +-- 1. send SetGlobalProperties with updated value for the helpPrompt parameter using added vrCommands --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -28,17 +26,6 @@ local SetGPParamsWithVrHelpOnly = common.customSetGPParams() SetGPParamsWithVrHelpOnly.requestParams.helpPrompt = nil --[[ Local Functions ]] -local function SetGlobalPropertiesFromSDL() - local params = common.getGPParams() - local hmiConnection = common.getHMIConnection() - EXPECT_HMICALL("UI.SetGlobalProperties") - :Times(0) - EXPECT_HMICALL("TTS.SetGlobalProperties", params.requestTtsParams) - :Do(function(_,data) - hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) -end - local function SetGlobalPropertiesFromSDLbyAddingCommand() common.addCommand(common.getAddCommandParams(4)) local params = common.getGPParams() @@ -68,7 +55,6 @@ runner.Step("App resumption", common.registrationWithResumption, runner.Title("Test") runner.Step("Custom SetGlobalProperties with vrHelp only from mobile application", common.setGlobalProperties, { SetGPParamsWithVrHelpOnly }) -runner.Step("SetGlobalProperties with constructed the helpPrompt", SetGlobalPropertiesFromSDL) runner.Step("SetGlobalProperties with updated value for helpPrompt after added command", SetGlobalPropertiesFromSDLbyAddingCommand) diff --git a/test_scripts/Handling_VR_help_requests/025_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua b/test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua similarity index 92% rename from test_scripts/Handling_VR_help_requests/025_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua rename to test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua index bda6d3dff2..a3dab98cdd 100644 --- a/test_scripts/Handling_VR_help_requests/025_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua @@ -10,7 +10,7 @@ -- 1. Command1, Command2, Command3 commands with vrCommands are added -- 2. Perform reconnect -- 3. Mobile application sets SetGlobalProperties without helpPrompt and vrHelp --- 4. 10 seconds timer is expired +-- 4. Mobile application adds Command4 -- SDL does: -- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand with type=Command. --------------------------------------------------------------------------------------------------- @@ -48,8 +48,7 @@ runner.Step("App resumption", common.registrationWithResumption, runner.Title("Test") runner.Step("Custom SetGlobalProperties from mobile application without helpPrompt and vrHelp", common.setGlobalProperties, { setGPParams }) -runner.Step("SetGlobalProperties request from SDL with constructed the vrHelp and helpPrompt", - common.setGlobalPropertiesFromSDL, { true }) +runner.Step("SetGlobalProperties after adding AddCommand4", common.addCommandWithSetGP, { 4 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua b/test_scripts/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua similarity index 78% rename from test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua rename to test_scripts/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua index c0735c5a65..b429cdecd7 100644 --- a/test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua +++ b/test_scripts/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua @@ -8,9 +8,8 @@ -- Description: -- In case: -- 1. Command1 commands with vrCommands Command1_1, Command2_1, Command3_1 is added --- 2. 10 seconds timer is expired -- SDL does: --- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -31,9 +30,8 @@ runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) runner.Title("Test") -runner.Step("AddCommand with several vrCommand ", common.addCommand, { AddCommandParams }) -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) +runner.Step("SetGlobalProperties after AddCommand with several vrCommand", common.addCommandWithSetGP, + { nil, AddCommandParams }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/027_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua b/test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua similarity index 88% rename from test_scripts/Handling_VR_help_requests/027_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua rename to test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua index a7bdc04a32..7a1af6be24 100644 --- a/test_scripts/Handling_VR_help_requests/027_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua @@ -9,9 +9,10 @@ -- In case: -- 1. Command1 commands with vrCommands Command1_1, Command2_1, Command3_1 is added -- 2. Perform reconnect --- 2. 10 seconds timer is expired +-- 3. SDL resumes commands -- SDL does: --- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands +-- by command resumption --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -33,12 +34,10 @@ runner.Step("Pin OnHashChange", common.pinOnHashChange) runner.Step("App activation", common.activateApp) runner.Title("Test") -runner.Step("AddCommand with several vrCommand", common.addCommand, { AddCommandParams }) +runner.Step("AddCommand with several vrCommand", common.addCommandWithSetGP, { nil, AddCommandParams }) runner.Step("App reconnect", common.reconnect) runner.Step("App resumption", common.registrationWithResumption, { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/028_SetGlobalProp_invalid_custom_request.lua b/test_scripts/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua similarity index 89% rename from test_scripts/Handling_VR_help_requests/028_SetGlobalProp_invalid_custom_request.lua rename to test_scripts/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua index f721918f8a..080461a781 100644 --- a/test_scripts/Handling_VR_help_requests/028_SetGlobalProp_invalid_custom_request.lua +++ b/test_scripts/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua @@ -10,7 +10,7 @@ -- 1. Command1, Command2, Command3 commands with vrCommands are added -- 2. Mobile application sends SetGlobalProperties with invalid data( e.g. invalid type ) -- 3. SDL responds with resultCode INVALID_DATA to mobile application --- 4. 10 seconds timer is expired +-- 4. Mobile application adds Command4 -- SDL does: -- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. --------------------------------------------------------------------------------------------------- @@ -41,13 +41,12 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommandWithSetGP, { i }) end runner.Title("Test") runner.Step("Invalid custom SetGlobalProperties", invalidSetGlobalProperties) -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) +runner.Step("SetGlobalProperties after AddCommand 4", common.addCommandWithSetGP, { 4 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/029_SetGlobalProp_rejected_custom_request.lua b/test_scripts/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua similarity index 89% rename from test_scripts/Handling_VR_help_requests/029_SetGlobalProp_rejected_custom_request.lua rename to test_scripts/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua index 1514c780e8..e047ccb8cc 100644 --- a/test_scripts/Handling_VR_help_requests/029_SetGlobalProp_rejected_custom_request.lua +++ b/test_scripts/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua @@ -10,7 +10,7 @@ -- 1. Command1, Command2, Command3 commands with vrCommands are added -- 2. Mobile application sends valid SetGlobalProperties and HMI rejected request -- 3. SDL responds with resultCode REJECTED to mobile application --- 4. 10 seconds timer is expired +-- 4. Mobile application adds Command4 -- SDL does: -- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. --------------------------------------------------------------------------------------------------- @@ -45,13 +45,12 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommandWithSetGP, { i }) end runner.Title("Test") runner.Step("Rejected custom SetGlobalProperties", rejectedSetGlobalProperties) -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) +runner.Step("SetGlobalProperties after AddCommand 4", common.addCommandWithSetGP, { 4 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_successful_added_commands.lua b/test_scripts/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua similarity index 85% rename from test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_successful_added_commands.lua rename to test_scripts/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua index b5435f3e53..4e3be6bc2d 100644 --- a/test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_successful_added_commands.lua +++ b/test_scripts/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua @@ -9,9 +9,8 @@ -- In case: -- 1. Command1, Command2, Command3 commands with vrCommands are added -- 2. Mobile app adds Command4 and HMI responds with resultCode = REJECTED, as result command is not added --- 3. 10 seconds timer is expired -- SDL does: --- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. +-- not send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands by processing Command4. --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -25,6 +24,13 @@ local function rejectedAddCommand(pParams) local mobSession = common.getMobileSession() local hmiConnection = common.getHMIConnection() local cid = mobSession:SendRPC("AddCommand", pParams) + + EXPECT_HMICALL("UI.SetGlobalProperties") + :Times(0) + + EXPECT_HMICALL("TTS.SetGlobalProperties") + :Times(0) + EXPECT_HMICALL("UI.AddCommand") :Do(function(_,data) hmiConnection:SendError(data.id, data.method, "REJECTED", "Rejected request") @@ -35,6 +41,7 @@ local function rejectedAddCommand(pParams) type = "Command", appID = common.getHMIAppId() } + EXPECT_HMICALL("VR.AddCommand", requestUiParams) :Do(function(_,data) hmiConnection:SendError(data.id, data.method, "REJECTED", "Rejected request") @@ -49,13 +56,11 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommandWithSetGP, { i }) end runner.Title("Test") runner.Step("Rejected adding Command4", rejectedAddCommand, { common.getAddCommandParams(4) }) -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_only_without_successful_deleted_commands.lua b/test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua similarity index 85% rename from test_scripts/Handling_VR_help_requests/031_SetGlobalProp_only_without_successful_deleted_commands.lua rename to test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua index f6c88b83ab..56df8c6269 100644 --- a/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_only_without_successful_deleted_commands.lua +++ b/test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua @@ -9,9 +9,8 @@ -- In case: -- 1. Command1, Command2, Command3 commands with vrCommands are added -- 2. Mobile app deletes Command3 and HMI responds with resultCode = REJECTED, as result command is not deleted --- 3. 10 seconds timer is expired -- SDL does: --- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. +-- not send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands by processing Command4. --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -30,6 +29,13 @@ local function rejectedDeleteCommand(pParams) local mobSession = common.getMobileSession() local hmiConnection = common.getHMIConnection() local cid = mobSession:SendRPC("DeleteCommand", pParams) + + EXPECT_HMICALL("UI.SetGlobalProperties") + :Times(0) + + EXPECT_HMICALL("TTS.SetGlobalProperties") + :Times(0) + EXPECT_HMICALL("UI.DeleteCommand") :Do(function(_,data) hmiConnection:SendError(data.id, data.method, "REJECTED", "Request rejected") @@ -39,6 +45,7 @@ local function rejectedDeleteCommand(pParams) type = "Command", appID = common.getHMIAppId() } + EXPECT_HMICALL("VR.DeleteCommand", requestVrParams) :Do(function(_,data) hmiConnection:SendError(data.id, data.method, "REJECTED", "Request rejected") @@ -53,13 +60,11 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) + runner.Step("AddCommand" .. i, common.addCommandWithSetGP, { i }) end runner.Title("Test") runner.Step("Rejected deleting Command3", rejectedDeleteCommand, { params }) -runner.Step("SetGlobalProperties with constructed the vrHelp and helpPrompt", common.setGlobalPropertiesFromSDL, - { true }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/commonVRhelp.lua b/test_scripts/Handling_VR_help_requests/commonVRhelp.lua index 872342ea25..909b980990 100644 --- a/test_scripts/Handling_VR_help_requests/commonVRhelp.lua +++ b/test_scripts/Handling_VR_help_requests/commonVRhelp.lua @@ -242,13 +242,25 @@ function m.deleteCommandWithoutSetGP(pN) m.setGlobalPropertiesDoesNotExpect() end -function m.addCommandWithSetGP(pN) - m.addCommand(m.getAddCommandParams(pN)) +function m.addCommandWithSetGP(pN, pAddCommandParams) + local AddCommandParams + if not pAddCommandParams then + AddCommandParams = m.getAddCommandParams(pN) + else + AddCommandParams = pAddCommandParams + end + m.addCommand(AddCommandParams) m.setGlobalPropertiesFromSDL() end -function m.addCommandWithoutSetGP(pN) - m.addCommand(m.getAddCommandParams(pN)) +function m.addCommandWithoutSetGP(pN, pAddCommandParams) + local AddCommandParams + if not pAddCommandParams then + AddCommandParams = m.getAddCommandParams(pN) + else + AddCommandParams = pAddCommandParams + end + m.addCommand(AddCommandParams) m.setGlobalPropertiesDoesNotExpect() end @@ -318,6 +330,20 @@ function m.resumptionDataAddCommands() return true end) :Times(#m.commandArray) + + EXPECT_HMICALL("TTS.SetGlobalProperties") + :ValidIf(function(_, data) + local expectedHelpPrompt = m.vrHelpPrompt(m.commandArray) + local vrCommandCompareResult = commonFunctions:is_table_equal(data.params.helpPrompt, expectedHelpPrompt) + local Msg = "" + if vrCommandCompareResult == false then + Msg = "helpPrompt in received TTS.SetGlobalProperties is not match to expected result.\n" .. + "Actual result:" .. m.tableToString(data.params.helpPrompt) .. "\n" .. + "Expected result:" .. m.tableToString(expectedHelpPrompt) .."\n" + end + return vrCommandCompareResult, Msg + end) + EXPECT_HMICALL("UI.AddCommand") :Do(function(_, data) m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) @@ -332,6 +358,19 @@ function m.resumptionDataAddCommands() end end) :Times(#m.commandArray) + + EXPECT_HMICALL("UI.SetGlobalProperties") + :ValidIf(function(_, data) + local expectedVrHelp = m.vrHelp(m.commandArray) + local vrCommandCompareResult = commonFunctions:is_table_equal(data.params.vrHelp, expectedVrHelp) + local Msg = "" + if vrCommandCompareResult == false then + Msg = "vrHelp in received TTS.SetGlobalProperties is not match to expected result.\n" .. + "Actual result:" .. m.tableToString(data.params.vrHelp) .. "\n" .. + "Expected result:" .. m.tableToString(expectedVrHelp) .."\n" + end + return vrCommandCompareResult, Msg + end) end function m.resumptionLevelFull() diff --git a/test_sets/handling_VR_help_requests.txt b/test_sets/handling_VR_help_requests.txt index 4fe7243ad9..58f0eaf3d9 100644 --- a/test_sets/handling_VR_help_requests.txt +++ b/test_sets/handling_VR_help_requests.txt @@ -1,31 +1,30 @@ -./test_scripts/Handling_VR_help_requests/001_SetGlobalProp_with_added_commands_after_timeout.lua +./test_scripts/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua ./test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua -./test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands_after_timeout.lua -./test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands_after_timeout.lua -./test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_after_timeout_only_for_addcommand.lua -./test_scripts/Handling_VR_help_requests/006_SetGlobalProp_procesing_added_choices.lua +./test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua +./test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua +./test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua +./test_scripts/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua ./test_scripts/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua -./test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_after_custom_request.lua -./test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request_after_timeout.lua -./test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request_after_timeout.lua +./test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua +./test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua +./test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua ./test_scripts/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua ./test_scripts/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua ./test_scripts/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua ./test_scripts/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua -./test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_after_timeout_by_resumption.lua +./test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua ./test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua -./test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_after_timeout_by_resumption.lua -./test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_after_timeout_by_resumption.lua -./test_scripts/Handling_VR_help_requests/019_SetGlobalProp_procesing_added_choices_by_resumption.lua +./test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua +./test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua +./test_scripts/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua ./test_scripts/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua ./test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua -./test_scripts/Handling_VR_help_requests/022_SetGlobalProp_absence_after_constructed_vrHelp_helpPrompt_before_resumption.lua -./test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua -./test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_vrHelp_only_by_resumption.lua -./test_scripts/Handling_VR_help_requests/025_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua -./test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua -./test_scripts/Handling_VR_help_requests/027_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua -./test_scripts/Handling_VR_help_requests/028_SetGlobalProp_invalid_custom_request.lua -./test_scripts/Handling_VR_help_requests/029_SetGlobalProp_rejected_custom_request.lua -./test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_successful_added_commands.lua -./test_scripts/Handling_VR_help_requests/031_SetGlobalProp_only_without_successful_deleted_commands.lua +./test_scripts/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua +./test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua +./test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua +./test_scripts/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua +./test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua +./test_scripts/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua +./test_scripts/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua +./test_scripts/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua +./test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua From b01eee9a87e39ea64b18f2f9244ab360593885a2 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 11 Jul 2018 13:18:06 +0300 Subject: [PATCH 481/681] Update according to comments in review --- ...op_commands_with_and_without_vrCommand.lua | 4 +-- ...p_apply_limitation_only_for_addcommand.lua | 19 ++++++++---- ...p_processing_30_commands_by_resumption.lua | 29 ++++++++++++------- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua b/test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua index 9a86f30606..f0cefef999 100644 --- a/test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua +++ b/test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua @@ -26,7 +26,7 @@ local commandWithoutVr = { menuName = "CommandWithoutVr" } } -local commandWithtVr = { +local commandWithVr = { cmdID = 1, vrCommands = { "vrCommand"}, menuParams = { @@ -42,7 +42,7 @@ runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) runner.Title("Test") -runner.Step("SetGlobalProperties after AddCommand with vr command", common.addCommandWithSetGP, { nil, commandWithtVr }) +runner.Step("SetGlobalProperties after AddCommand with vr command", common.addCommandWithSetGP, { nil, commandWithVr }) runner.Step("Absence of SetGlobalProperties after AddCommand without vr command", common.addCommandWithoutSetGP, { nil, commandWithoutVr }) runner.Title("Postconditions") diff --git a/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua b/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua index f12c69cfa0..f75908c099 100644 --- a/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua +++ b/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua @@ -9,10 +9,11 @@ -- In case: -- 1. Mobile application sets 30 command one by one -- 2.Mobile application deletes 10 command one by one --- 3. Mobile application sets 31 command +-- 3. Mobile application sets 10 commands one by one +-- 4. Mobile app adds 31th command -- SDL does: --- send SetGlobalProperties with update for vrHelp and helpPrompt parameters after each added and deleted command --- not send SetGlobalProperties after added 31 command +-- 1. send SetGlobalProperties with update for vrHelp and helpPrompt parameters after each added and deleted command +-- 2. not send SetGlobalProperties after added 31th command --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -29,13 +30,19 @@ runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) runner.Title("Test") +runner.Title("Add 30 commands") for i = 1, 30 do - runner.Step("SetGlobalProperties from SDL after added command" ..i, common.addCommandWithSetGP, { i }) + runner.Step("SetGlobalProperties from SDL after added command " ..i, common.addCommandWithSetGP, { i }) end +runner.Title("Delete 10 commands") for i = 1, 10 do - runner.Step("SetGlobalProperties from SDL after deleted command" ..i, common.deleteCommandWithSetGP, { i }) + runner.Step("SetGlobalProperties from SDL after deleted command " ..i, common.deleteCommandWithSetGP, { i }) end -runner.Step("Absence SetGlobalProperties from SDL after adding 34 command", common.addCommandWithoutSetGP, { 31 }) +runner.Title("Add 10 commands") +for i = 31, 40 do + runner.Step("SetGlobalProperties from SDL after added command " ..i, common.addCommandWithSetGP, { i }) +end +runner.Step("Absence SetGlobalProperties from SDL after adding 31 command", common.addCommandWithoutSetGP, { 41 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua b/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua index 5e1edd4cd8..c4d565c0f0 100644 --- a/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua @@ -7,16 +7,17 @@ -- -- Description: -- In case: --- 1. Command1, Command2, Command3 commands with vrCommands are added --- 2. Perform reopening session --- 3. Mobile app adds 30 commands after resumption --- 3. Mobile app adds 31 command +-- 1. Mobile app adds 20 commands one by one +-- 2. Mobile app deletes 5 commands one by one +-- 3. Perform reopening session +-- 4. Mobile app adds 15 commands after resumption +-- 5. Mobile app adds 31th command -- SDL does: -- 1. resume HMI level and AddCommands -- 2. send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand -- after each resumed command --- 3. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters after each added command --- 4. not send SetGlobalProperties after added 31 command +-- 3. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters after each added command +-- 4. not send SetGlobalProperties after added 31th command --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -34,16 +35,22 @@ runner.Step("Pin OnHashChange", common.pinOnHashChange) runner.Step("App activation", common.activateApp) runner.Title("Test") -for i = 1,3 do - runner.Step("AddCommand" .. i, common.addCommandWithSetGP, { i }) +runner.Title("Add 20 commands") +for i = 1, 20 do + runner.Step("SetGlobalProperties from SDL after added command " ..i, common.addCommandWithSetGP, { i }) +end +runner.Title("Delete 5 commands") +for i = 1, 5 do + runner.Step("SetGlobalProperties from SDL after deleted command " ..i, common.deleteCommandWithSetGP, { i }) end runner.Step("App reconnect", common.reconnect) runner.Step("App resumption", common.registrationWithResumption, { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) -for i = 4, 33 do - runner.Step("SetGlobalProperties from SDL after added command" ..i, common.addCommandWithSetGP, { i }) +runner.Title("Add 15 commands") +for i = 21, 35 do + runner.Step("SetGlobalProperties from SDL after added command " ..i, common.addCommandWithSetGP, { i }) end -runner.Step("Absence SetGlobalProperties from SDL after adding 34 command", common.addCommandWithoutSetGP, { 34 }) +runner.Step("Absence SetGlobalProperties from SDL after adding 31 command", common.addCommandWithoutSetGP, { 36 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) From 903c7f9dc7df92dc372aa5bd9ebe5fb1243ee640 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 11 Jul 2018 20:11:52 +0300 Subject: [PATCH 482/681] Add additional test scripts for specific case --- ...ing_30_commands_several_in_one_command.lua | 63 +++++++++++++++++ ...s_several_in_one_command_by_resumption.lua | 69 +++++++++++++++++++ test_sets/handling_VR_help_requests.txt | 2 + 3 files changed, 134 insertions(+) create mode 100644 test_scripts/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua create mode 100644 test_scripts/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua diff --git a/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua b/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua new file mode 100644 index 0000000000..5f88785175 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua @@ -0,0 +1,63 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Mobile application sets 29 command one by one +-- 2. Mobile application sets 2 commands in one request +-- SDL does: +-- 1. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters for 30 VR commands +-- and exclude 31th VR command from list +-- 2. not send SetGlobalProperties after added 31 command +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function sendAddCommand() + local params = common.getAddCommandParams(30) + params.vrCommands = { "vrCommand_30_1", "vrCommand_30_2" } + local cid = common.getMobileSession():SendRPC("AddCommand", params) + EXPECT_HMICALL("UI.AddCommand") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + local requestHMIParams = { + type = "Command", + cmdID = params.cmdID, + vrCommands = params.vrCommands, + appID = common.getHMIAppId() + } + EXPECT_HMICALL("VR.AddCommand", requestHMIParams) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + table.insert(common.commandArray, { cmdID = params.cmdID, vrCommand = { params.vrCommands[1] } }) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + common.setGlobalPropertiesFromSDL() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) + +runner.Title("Test") +for i = 1, 29 do + runner.Step("SetGlobalProperties from SDL after added command " .. i, common.addCommandWithSetGP, { i }) +end +runner.Step("Set 2 VR commands by 1 request", sendAddCommand) +runner.Step("Absence SetGlobalProperties from SDL after adding 32 VR command", common.addCommandWithoutSetGP, { 31 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua b/test_scripts/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua new file mode 100644 index 0000000000..055e5403bf --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua @@ -0,0 +1,69 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Mobile application sets 29 command one by one +-- 2. Perform reconnect +-- 3. SDL resumes commands +-- 4. Mobile application sets 2 commands in one request +-- SDL does: +-- 1. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters for 30 VR commands +-- and exclude 31th VR command from list +-- 2. not send SetGlobalProperties after added 31 command +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function sendAddCommand() + local params = common.getAddCommandParams(30) + params.vrCommands = { "vrCommand_30_1", "vrCommand_30_2" } + local cid = common.getMobileSession():SendRPC("AddCommand", params) + EXPECT_HMICALL("UI.AddCommand") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + local requestHMIParams = { + type = "Command", + cmdID = params.cmdID, + vrCommands = params.vrCommands, + appID = common.getHMIAppId() + } + EXPECT_HMICALL("VR.AddCommand", requestHMIParams) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + table.insert(common.commandArray, { cmdID = params.cmdID, vrCommand = { params.vrCommands[1] } }) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + common.setGlobalPropertiesFromSDL() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Pin OnHashChange", common.pinOnHashChange) +runner.Step("App activation", common.activateApp) + +runner.Title("Test") +for i = 1, 29 do + runner.Step("SetGlobalProperties from SDL after added command " .. i, common.addCommandWithSetGP, { i }) +end +runner.Step("App reconnect", common.reconnect) +runner.Step("App resumption", common.registrationWithResumption, + { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) +runner.Step("Set 2 VR commands by 1 request", sendAddCommand) +runner.Step("Absence SetGlobalProperties from SDL after adding 32 VR command", common.addCommandWithoutSetGP, { 31 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_sets/handling_VR_help_requests.txt b/test_sets/handling_VR_help_requests.txt index 58f0eaf3d9..25245a3659 100644 --- a/test_sets/handling_VR_help_requests.txt +++ b/test_sets/handling_VR_help_requests.txt @@ -28,3 +28,5 @@ ./test_scripts/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua ./test_scripts/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua ./test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua +./test_scripts/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua +./test_scripts/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua From e6c1dbc737b15369ef7482cbc396be5a66bba34c Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 13 Jul 2018 10:32:23 +0300 Subject: [PATCH 483/681] Correct scripts according to changes in SDL --- ...p_apply_limitation_only_for_addcommand.lua | 23 +++++------ ...p_processing_30_commands_by_resumption.lua | 38 +++++++++---------- ...ing_30_commands_several_in_one_command.lua | 29 +++----------- ...s_several_in_one_command_by_resumption.lua | 29 +++----------- .../commonVRhelp.lua | 11 ++++-- 5 files changed, 44 insertions(+), 86 deletions(-) diff --git a/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua b/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua index f75908c099..9109b55ff0 100644 --- a/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua +++ b/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua @@ -8,12 +8,9 @@ -- Description: -- In case: -- 1. Mobile application sets 30 command one by one --- 2.Mobile application deletes 10 command one by one --- 3. Mobile application sets 10 commands one by one --- 4. Mobile app adds 31th command +-- 2. Mobile application set/delete commands -- SDL does: --- 1. send SetGlobalProperties with update for vrHelp and helpPrompt parameters after each added and deleted command --- 2. not send SetGlobalProperties after added 31th command +-- send SetGlobalProperties with 30 items only in case if first 30 items in list are updated --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -34,15 +31,13 @@ runner.Title("Add 30 commands") for i = 1, 30 do runner.Step("SetGlobalProperties from SDL after added command " ..i, common.addCommandWithSetGP, { i }) end -runner.Title("Delete 10 commands") -for i = 1, 10 do - runner.Step("SetGlobalProperties from SDL after deleted command " ..i, common.deleteCommandWithSetGP, { i }) -end -runner.Title("Add 10 commands") -for i = 31, 40 do - runner.Step("SetGlobalProperties from SDL after added command " ..i, common.addCommandWithSetGP, { i }) -end -runner.Step("Absence SetGlobalProperties from SDL after adding 31 command", common.addCommandWithoutSetGP, { 41 }) +runner.Title("Change list of commands") +runner.Step("No SetGlobalProperties from SDL after added command 31", common.addCommandWithoutSetGP, { 31 }) +runner.Step("No SetGlobalProperties from SDL after deleted command 31", common.deleteCommandWithoutSetGP, { 31 }) +runner.Step("No SetGlobalProperties from SDL after added command 32", common.addCommandWithoutSetGP, { 32 }) +runner.Step("SetGlobalProperties from SDL after deleted command 1", common.deleteCommandWithSetGP, { 1 }) +runner.Step("No SetGlobalProperties from SDL after added command 33", common.addCommandWithoutSetGP, { 33 }) +runner.Step("SetGlobalProperties from SDL after deleted command 2", common.deleteCommandWithSetGP, { 2 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua b/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua index c4d565c0f0..8095faf73b 100644 --- a/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua @@ -7,17 +7,11 @@ -- -- Description: -- In case: --- 1. Mobile app adds 20 commands one by one --- 2. Mobile app deletes 5 commands one by one --- 3. Perform reopening session --- 4. Mobile app adds 15 commands after resumption --- 5. Mobile app adds 31th command +-- 1. Mobile application sets 30 command one by one +-- 2. Perform reopening session +-- 3. Mobile application set/delete commands -- SDL does: --- 1. resume HMI level and AddCommands --- 2. send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommand --- after each resumed command --- 3. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters after each added command --- 4. not send SetGlobalProperties after added 31th command +-- send SetGlobalProperties with 30 items only in case if first 30 items in list are updated --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -35,22 +29,24 @@ runner.Step("Pin OnHashChange", common.pinOnHashChange) runner.Step("App activation", common.activateApp) runner.Title("Test") -runner.Title("Add 20 commands") -for i = 1, 20 do +runner.Title("Add 30 commands") +for i = 1, 30 do runner.Step("SetGlobalProperties from SDL after added command " ..i, common.addCommandWithSetGP, { i }) end -runner.Title("Delete 5 commands") -for i = 1, 5 do - runner.Step("SetGlobalProperties from SDL after deleted command " ..i, common.deleteCommandWithSetGP, { i }) -end +runner.Title("Add 31 command") +runner.Step("No SetGlobalProperties from SDL after added command 31", common.addCommandWithoutSetGP, { 31 }) + +runner.Title("App diconnect") runner.Step("App reconnect", common.reconnect) runner.Step("App resumption", common.registrationWithResumption, { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) -runner.Title("Add 15 commands") -for i = 21, 35 do - runner.Step("SetGlobalProperties from SDL after added command " ..i, common.addCommandWithSetGP, { i }) -end -runner.Step("Absence SetGlobalProperties from SDL after adding 31 command", common.addCommandWithoutSetGP, { 36 }) + +runner.Title("Change list of commands") +runner.Step("No SetGlobalProperties from SDL after deleted command 31", common.deleteCommandWithoutSetGP, { 31 }) +runner.Step("No SetGlobalProperties from SDL after added command 32", common.addCommandWithoutSetGP, { 32 }) +runner.Step("SetGlobalProperties from SDL after deleted command 1", common.deleteCommandWithSetGP, { 1 }) +runner.Step("No SetGlobalProperties from SDL after added command 33", common.addCommandWithoutSetGP, { 33 }) +runner.Step("SetGlobalProperties from SDL after deleted command 2", common.deleteCommandWithSetGP, { 2 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua b/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua index 5f88785175..e470028986 100644 --- a/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua +++ b/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua @@ -21,29 +21,9 @@ local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false ---[[ Local Functions ]] -local function sendAddCommand() - local params = common.getAddCommandParams(30) - params.vrCommands = { "vrCommand_30_1", "vrCommand_30_2" } - local cid = common.getMobileSession():SendRPC("AddCommand", params) - EXPECT_HMICALL("UI.AddCommand") - :Do(function(_, data) - common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) - end) - local requestHMIParams = { - type = "Command", - cmdID = params.cmdID, - vrCommands = params.vrCommands, - appID = common.getHMIAppId() - } - EXPECT_HMICALL("VR.AddCommand", requestHMIParams) - :Do(function(_,data) - common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) - end) - table.insert(common.commandArray, { cmdID = params.cmdID, vrCommand = { params.vrCommands[1] } }) - common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) - common.setGlobalPropertiesFromSDL() -end +--[[ Local Variables ]] +local AddCommandParams = common.getAddCommandParams(30) +AddCommandParams.vrCommands = { "Command_30_1", "Command_30_2" } --[[ Scenario ]] runner.Title("Preconditions") @@ -56,7 +36,8 @@ runner.Title("Test") for i = 1, 29 do runner.Step("SetGlobalProperties from SDL after added command " .. i, common.addCommandWithSetGP, { i }) end -runner.Step("Set 2 VR commands by 1 request", sendAddCommand) +runner.Step("SetGlobalProperties after AddCommand with several vrCommand", common.addCommandWithSetGP, + { nil, AddCommandParams }) runner.Step("Absence SetGlobalProperties from SDL after adding 32 VR command", common.addCommandWithoutSetGP, { 31 }) runner.Title("Postconditions") diff --git a/test_scripts/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua b/test_scripts/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua index 055e5403bf..d47b6094f0 100644 --- a/test_scripts/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua @@ -23,29 +23,9 @@ local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false ---[[ Local Functions ]] -local function sendAddCommand() - local params = common.getAddCommandParams(30) - params.vrCommands = { "vrCommand_30_1", "vrCommand_30_2" } - local cid = common.getMobileSession():SendRPC("AddCommand", params) - EXPECT_HMICALL("UI.AddCommand") - :Do(function(_, data) - common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) - end) - local requestHMIParams = { - type = "Command", - cmdID = params.cmdID, - vrCommands = params.vrCommands, - appID = common.getHMIAppId() - } - EXPECT_HMICALL("VR.AddCommand", requestHMIParams) - :Do(function(_,data) - common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) - end) - table.insert(common.commandArray, { cmdID = params.cmdID, vrCommand = { params.vrCommands[1] } }) - common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) - common.setGlobalPropertiesFromSDL() -end +--[[ Local Variables ]] +local AddCommandParams = common.getAddCommandParams(30) +AddCommandParams.vrCommands = { "Command_30_1", "Command_30_2" } --[[ Scenario ]] runner.Title("Preconditions") @@ -62,7 +42,8 @@ end runner.Step("App reconnect", common.reconnect) runner.Step("App resumption", common.registrationWithResumption, { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) -runner.Step("Set 2 VR commands by 1 request", sendAddCommand) +runner.Step("SetGlobalProperties after AddCommand with several vrCommand", common.addCommandWithSetGP, + { nil, AddCommandParams }) runner.Step("Absence SetGlobalProperties from SDL after adding 32 VR command", common.addCommandWithoutSetGP, { 31 }) runner.Title("Postconditions") diff --git a/test_scripts/Handling_VR_help_requests/commonVRhelp.lua b/test_scripts/Handling_VR_help_requests/commonVRhelp.lua index 909b980990..877acd5384 100644 --- a/test_scripts/Handling_VR_help_requests/commonVRhelp.lua +++ b/test_scripts/Handling_VR_help_requests/commonVRhelp.lua @@ -16,6 +16,7 @@ config.defaultProtocolVersion = 2 local m = actions m.commandArray = {} m.timeActivation = 0 +m.commandsLimit = 30 m.cloneTable = utils.cloneTable m.tableToString = utils.tableToString @@ -190,15 +191,16 @@ end function m.vrHelp(pCommandArray) local out = {} - local positionValue = 0 + local counter = 0 for _, value in pairs(pCommandArray) do for _, sub_v in pairs(value.vrCommand) do - positionValue = positionValue + 1 + counter = counter + 1 local item = { text = sub_v, - position = positionValue + position = counter } table.insert(out, item) + if counter == m.commandsLimit then return out end end end return out @@ -206,13 +208,16 @@ end function m.vrHelpPrompt(pVrCommandArray) local out = {} + local counter = 0 for _, value in pairs(pVrCommandArray) do for _, sub_v in pairs(value.vrCommand) do + counter = counter + 1 local item = { text = sub_v, type = "TEXT" } table.insert(out, item) + if counter == m.commandsLimit then return out end end end return out From 1ebce4c700c51a08a6d6c8a2009afcf91575e088 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 16 Jul 2018 16:24:59 +0300 Subject: [PATCH 484/681] Update according to comments in review --- ...op_commands_with_and_without_vrCommand.lua | 2 +- ...th_and_without_vrCommand_by_resumption.lua | 17 ++---- ...after_custom_request_before_resumption.lua | 2 +- ...balProp_only_successful_added_commands.lua | 13 ++++- .../commonVRhelp.lua | 56 +++++-------------- 5 files changed, 33 insertions(+), 57 deletions(-) diff --git a/test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua b/test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua index f0cefef999..d60a139cc5 100644 --- a/test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua +++ b/test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua @@ -30,7 +30,7 @@ local commandWithVr = { cmdID = 1, vrCommands = { "vrCommand"}, menuParams = { - menuName = "commandWithtVr" + menuName = "commandWithVr" } } diff --git a/test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua b/test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua index 4453a9dc4a..996e7eebad 100644 --- a/test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua @@ -29,15 +29,15 @@ local commandWithoutVr = { menuName = "CommandWithoutVr" } } -local commandWithtVr = { +local commandWithVr = { cmdID = 1, vrCommands = { "vrCommand"}, menuParams = { - menuName = "commandWithtVr" + menuName = "commandWithVr" } } -local uiCommandArray = { { cmdID = commandWithtVr.cmdID }, { cmdID = commandWithoutVr.cmdID } } +local uiCommandArray = { { cmdID = commandWithVr.cmdID }, { cmdID = commandWithoutVr.cmdID } } --[[ Local Functions ]] local function resumptionLevelLimited() @@ -47,13 +47,8 @@ local function resumptionLevelLimited() common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) end) common.getMobileSession():ExpectNotification("OnHMIStatus", - { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, - { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) - :Do(function(exp) - if exp.occurences == 2 then - common.timeActivation = timestamp() - end - end) + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, + { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) :Times(2) end @@ -135,7 +130,7 @@ runner.Step("App activation", common.activateApp) runner.Step("Bring app to LIMITED HMI level", deactivateAppToLimited) runner.Title("Test") -runner.Step("AddCommand with vr command", common.addCommandWithSetGP, {nil, commandWithtVr }) +runner.Step("AddCommand with vr command", common.addCommandWithSetGP, {nil, commandWithVr }) runner.Step("AddCommand without vr command", common.addCommandWithoutSetGP, {nil, commandWithoutVr }) runner.Step("App reconnect", common.reconnect) runner.Step("App resumption", common.registrationWithResumption, diff --git a/test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua b/test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua index cd92473f8f..8d1fee561a 100644 --- a/test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua @@ -47,7 +47,7 @@ local function resumptionData() return true end) :Times(#common.commandArray) -EXPECT_HMICALL("UI.AddCommand") + EXPECT_HMICALL("UI.AddCommand") :Do(function(_, data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) end) diff --git a/test_scripts/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua b/test_scripts/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua index 4e3be6bc2d..d8791ee2d6 100644 --- a/test_scripts/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua +++ b/test_scripts/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua @@ -31,18 +31,25 @@ local function rejectedAddCommand(pParams) EXPECT_HMICALL("TTS.SetGlobalProperties") :Times(0) - EXPECT_HMICALL("UI.AddCommand") + local requestUiParams = { + cmdID = pParams.cmdID, + menuParams = pParams.menuParams, + appID = common.getHMIAppId() + } + + EXPECT_HMICALL("UI.AddCommand", requestUiParams) :Do(function(_,data) hmiConnection:SendError(data.id, data.method, "REJECTED", "Rejected request") end) - local requestUiParams = { + + local requestVrParams = { cmdID = pParams.cmdID, vrCommands = pParams.vrCommands, type = "Command", appID = common.getHMIAppId() } - EXPECT_HMICALL("VR.AddCommand", requestUiParams) + EXPECT_HMICALL("VR.AddCommand", requestVrParams) :Do(function(_,data) hmiConnection:SendError(data.id, data.method, "REJECTED", "Rejected request") end) diff --git a/test_scripts/Handling_VR_help_requests/commonVRhelp.lua b/test_scripts/Handling_VR_help_requests/commonVRhelp.lua index 877acd5384..9bbaa820d7 100644 --- a/test_scripts/Handling_VR_help_requests/commonVRhelp.lua +++ b/test_scripts/Handling_VR_help_requests/commonVRhelp.lua @@ -15,7 +15,6 @@ config.defaultProtocolVersion = 2 --[[ Variables ]] local m = actions m.commandArray = {} -m.timeActivation = 0 m.commandsLimit = 30 m.cloneTable = utils.cloneTable @@ -63,7 +62,7 @@ function m.getAddCommandParams(pN) cmdID = pN, vrCommands = { "vrCommand" .. pN}, menuParams = { - menuName = "Command" .. pN + menuName = "Command" .. pN } } return out @@ -74,19 +73,24 @@ function m.addCommand(pParams, pAppId) local mobSession = m.getMobileSession(pAppId) local hmiConnection = m.getHMIConnection() local cid = mobSession:SendRPC("AddCommand", pParams) - EXPECT_HMICALL("UI.AddCommand") + local requestUiParams = { + cmdID = pParams.cmdID, + menuParams = pParams.menuParams, + appID = m.getHMIAppId() + } + EXPECT_HMICALL("UI.AddCommand", requestUiParams) :Do(function(_,data) hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) if pParams.vrCommands then table.insert(m.commandArray, { cmdID = pParams.cmdID, vrCommand = pParams.vrCommands}) - local requestUiParams = { + local requestVrParams = { cmdID = pParams.cmdID, vrCommands = pParams.vrCommands, type = "Command", appID = m.getHMIAppId(pAppId) } - EXPECT_HMICALL("VR.AddCommand", requestUiParams) + EXPECT_HMICALL("VR.AddCommand", requestVrParams) :Do(function(_,data) hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) @@ -142,39 +146,17 @@ function m.setGlobalProperties(pParams, pAppId) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) end -function m.setGlobalPropertiesFromSDL(pIsCheckOnTimeoutRequied) +function m.setGlobalPropertiesFromSDL() local params = m.getGPParams() local hmiConnection = m.getHMIConnection() EXPECT_HMICALL("UI.SetGlobalProperties", params.requestUiParams) :Do(function(_,data) hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) - :ValidIf(function() - if pIsCheckOnTimeoutRequied then - local timeSetGPReg = timestamp() - local timeToSetGP = timeSetGPReg - m.timeActivation - if timeToSetGP > 10500 or timeToSetGP < 9500 then - return false, "SetGlobalProperties request with constructed vrHelp came not in 10 sec " .. - "after activation, actual time is" .. tostring(timeToSetGP) - end - end - return true - end) EXPECT_HMICALL("TTS.SetGlobalProperties", params.requestTtsParams) :Do(function(_,data) hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) - :ValidIf(function() - if pIsCheckOnTimeoutRequied then - local timeSetGPReg = timestamp() - local timeToSetGP = timeSetGPReg - m.timeActivation - if timeToSetGP > 10500 or timeToSetGP < 9500 then - return false, "SetGlobalProperties request with constructed helpPrompt came not in 10 sec " .. - "after activation, actual time is" .. tostring(timeToSetGP) - end - end - return true - end) end function m.activateApp(pAppId) @@ -183,9 +165,6 @@ function m.activateApp(pAppId) m.getHMIConnection():ExpectResponse(requestId) m.getMobileSession(pAppId):ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) - :Do(function() - m.timeActivation = timestamp() - end) m.wait() end @@ -276,9 +255,9 @@ function m.reconnect(pAppId) {appID = m.getHMIAppId(pAppId), unexpectedDisconnect = true}) :Do(function() test.mobileSession[pAppId] = mobile_session.MobileSession( - test, - test.mobileConnection, - config["application" .. pAppId].registerAppInterfaceParams) + test, + test.mobileConnection, + config["application" .. pAppId].registerAppInterfaceParams) test.mobileConnection:Connect() end) end @@ -384,13 +363,8 @@ function m.resumptionLevelFull() m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) end) m.getMobileSession():ExpectNotification("OnHMIStatus", - { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, - { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) - :Do(function(exp) - if exp.occurences == 2 then - m.timeActivation = timestamp() - end - end) + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) :Times(2) end From f64249fde7fb9a26aecc48825ed92fbc378b8f52 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 16 Jul 2018 19:07:43 +0300 Subject: [PATCH 485/681] Add additional script on removing of last command --- .../033_SetGlobalProp_delete_last_command.lua | 107 ++++++++++++++++++ test_sets/handling_VR_help_requests.txt | 1 + 2 files changed, 108 insertions(+) create mode 100644 test_scripts/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua diff --git a/test_scripts/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua b/test_scripts/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua new file mode 100644 index 0000000000..f118270003 --- /dev/null +++ b/test_scripts/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua @@ -0,0 +1,107 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0122-New_rules_for_providing_VRHelpItems_VRHelpTitle.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Mobile application sets 30 commands in requests #1, #2, #3 +-- 2. Mobile application sets 10 commands in requests #4 and #5 +-- 3. Mobile application removes commands +-- SDL does: +-- 1. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters for 30 VR commands +-- after processing request #1, #2, #3 +-- 2. not send SetGlobalProperties after processing requests #4, #5 +-- 3. not send SetGlobalProperties when commands from request #4 and #5 were removed +-- 4. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters for 30 VR commands +-- after removing commands from requests #1, #2 +-- 5. send SetGlobalProperties with empty array for helpPrompt parameter and omitted vrHelp parameter +-- after removing commands from requests #3 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local function getVRCommandsList(pCmdId, pN) + local out = {} + for _ = 1, pN do + table.insert(out, "Command_" .. pCmdId .. "_" .. pN) + end + return out +end + +local params1 = common.getAddCommandParams(1) +params1.vrCommands = getVRCommandsList(1, 10) + +local params2 = common.getAddCommandParams(2) +params2.vrCommands = getVRCommandsList(2, 10) + +local params3 = common.getAddCommandParams(3) +params3.vrCommands = getVRCommandsList(3, 10) + +local params4 = common.getAddCommandParams(4) +params4.vrCommands = getVRCommandsList(4, 5) + +local params5 = common.getAddCommandParams(5) +params5.vrCommands = getVRCommandsList(5, 5) + + +local function deleteLastCommand(pN) + common.deleteCommand({ cmdID = pN }, true) + local requestUiParams = { + vrHelpTitle = common.getConfigAppParams().appName + } + EXPECT_HMICALL("UI.SetGlobalProperties", requestUiParams) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_, data) + if data.params.vrHelp ~= nil then + return false, "'vrHelp' is not expected" + end + return true + end) + local requestTtsParams = { + helpPrompt = {} + } + EXPECT_HMICALL("TTS.SetGlobalProperties", requestTtsParams) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("App activation", common.activateApp) + +runner.Title("Test") +runner.Step("SetGlobalProperties from SDL after added cmd_id 1 with 10 commands", common.addCommandWithSetGP, + { nil, params1 }) +runner.Step("SetGlobalProperties from SDL after added cmd_id 2 with 10 commands", common.addCommandWithSetGP, + { nil, params2 }) +runner.Step("SetGlobalProperties from SDL after added cmd_id 3 with 10 commands", common.addCommandWithSetGP, + { nil, params3 }) + +runner.Step("Absence SetGlobalProperties from SDL after adding cmd_id 4 with 5 commands", common.addCommandWithoutSetGP, + { nil, params4 }) +runner.Step("Absence SetGlobalProperties from SDL after adding cmd_id 5 with 5 commands", common.addCommandWithoutSetGP, + { nil, params5 }) + +runner.Step("No SetGlobalProperties from SDL after deleted cmd_id 4", common.deleteCommandWithoutSetGP, { 4 }) +runner.Step("No SetGlobalProperties from SDL after deleted cmd_id 5", common.deleteCommandWithoutSetGP, { 5 }) + +runner.Step("SetGlobalProperties from SDL after deleted cmd_id 1", common.deleteCommandWithSetGP, { 1 }) +runner.Step("SetGlobalProperties from SDL after deleted cmd_id 2", common.deleteCommandWithSetGP, { 2 }) +runner.Step("SetGlobalProperties from SDL after deleted cmd_id 3", deleteLastCommand, { 3 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_sets/handling_VR_help_requests.txt b/test_sets/handling_VR_help_requests.txt index 25245a3659..140068cbac 100644 --- a/test_sets/handling_VR_help_requests.txt +++ b/test_sets/handling_VR_help_requests.txt @@ -30,3 +30,4 @@ ./test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua ./test_scripts/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua ./test_scripts/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua +./test_scripts/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua From 417c4cff2bf1b5602cd8abdb0e2c13873a763517 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 17 Jul 2018 13:21:01 +0300 Subject: [PATCH 486/681] Update for SEAT module in OnRCStatus --- ...le_subscription_GetInteriorVehicleData.lua | 2 +- ...dule_allocation_SetInteriorVehicleData.lua | 2 +- ...iption_GetInteriorVehicleData_two_apps.lua | 2 +- ...cation_SetInteriorVehicleData_two_apps.lua | 2 +- ...ule_allocation_two_apps_one_app_not_rc.lua | 2 +- .../RC/OnRCStatus/commonOnRCStatus.lua | 71 ++++++++++++++++++- 6 files changed, 75 insertions(+), 6 deletions(-) diff --git a/test_scripts/RC/OnRCStatus/004_notification_by_module_subscription_GetInteriorVehicleData.lua b/test_scripts/RC/OnRCStatus/004_notification_by_module_subscription_GetInteriorVehicleData.lua index 31ee9c1f52..0e6d4a8e08 100644 --- a/test_scripts/RC/OnRCStatus/004_notification_by_module_subscription_GetInteriorVehicleData.lua +++ b/test_scripts/RC/OnRCStatus/004_notification_by_module_subscription_GetInteriorVehicleData.lua @@ -36,7 +36,7 @@ runner.Step("Register RC application", common.registerRCApplication) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, mod in pairs(common.getModules()) do +for _, mod in pairs(common.getAllModules()) do runner.Step("GetInteriorVehicleData " .. mod, subscribeToModuleWOOnRCStatus, { mod }) end diff --git a/test_scripts/RC/OnRCStatus/006_notification_by_module_allocation_SetInteriorVehicleData.lua b/test_scripts/RC/OnRCStatus/006_notification_by_module_allocation_SetInteriorVehicleData.lua index 7c5235b397..a41d71acf5 100644 --- a/test_scripts/RC/OnRCStatus/006_notification_by_module_allocation_SetInteriorVehicleData.lua +++ b/test_scripts/RC/OnRCStatus/006_notification_by_module_allocation_SetInteriorVehicleData.lua @@ -41,7 +41,7 @@ runner.Step("Register RC application", common.registerRCApplication) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, mod in pairs(common.getModules()) do +for _, mod in pairs(common.getAllModules()) do runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) end diff --git a/test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua b/test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua index 1c26801cef..682b0658da 100644 --- a/test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua +++ b/test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua @@ -41,7 +41,7 @@ runner.Step("Activate App 1", common.activateApp, { 1 }) runner.Step("Register RC application 2", common.registerRCApplication, { 2 }) runner.Title("Test") -for _, mod in pairs(common.getModules()) do +for _, mod in pairs(common.getAllModules()) do runner.Step("GetInteriorVehicleData " .. mod, subscribeToModuleWOOnRCStatus, { mod }) end diff --git a/test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua b/test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua index e7a0a4507c..5775219b62 100644 --- a/test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua +++ b/test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua @@ -45,7 +45,7 @@ runner.Step("Activate App 1", common.activateApp, { 1 }) runner.Step("Register RC application 2", common.registerRCApplication, { 2 }) runner.Title("Test") -for _, mod in pairs(common.getModules()) do +for _, mod in pairs(common.getAllModules()) do runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) end diff --git a/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua b/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua index 4badbb1fb0..c746732259 100644 --- a/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua +++ b/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua @@ -49,7 +49,7 @@ runner.Step("Activate App 1", common.activateApp) runner.Step("Register non-RC application 2", common.rai_n, { 2 }) runner.Title("Test") -for _, mod in pairs(common.getModules()) do +for _, mod in pairs(common.getAllModules()) do runner.Step("Allocation of module " .. mod, alocateModule, { mod }) end diff --git a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua index 13bdc9acaa..a4378561c0 100644 --- a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua +++ b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua @@ -19,6 +19,24 @@ local utils = require("user_modules/utils") local m = {} --[[ Functions ]] +local getRCAppConfigOrigin = commonRC.getRCAppConfig +function commonRC.getRCAppConfig(tbl) + local rcAppConfig = getRCAppConfigOrigin(tbl) + rcAppConfig.moduleType = { "RADIO", "CLIMATE", "SEAT" } + return rcAppConfig +end + +function commonRC.getSettableModuleControlData(pModuleType) + local out = commonRC.getModuleControlData(pModuleType) + local params_read_only = commonRC.getModuleParams(commonRC.getReadOnlyParamsByModule(pModuleType)) + if params_read_only then + for p_read_only in pairs(params_read_only) do + commonRC.getModuleParams(out)[p_read_only] = nil + end + end + return out +end + local function backupPreloadedPT() local preloadedFile = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") commonPreconditions:BackupFile(preloadedFile) @@ -41,6 +59,57 @@ local function updatePreloadedPT(pCountOfRCApps) commonRC.tableToJsonFile(preloadedTable, preloadedFile) end +local origGetModuleControlData = commonRC.getModuleControlData +function commonRC.getModuleControlData(module_type) + local out = { } + if module_type == "SEAT" then + out.moduleType = module_type + out.seatControlData = { + id = "DRIVER", + heatingEnabled = true, + coolingEnabled = true, + heatingLevel = 50, + coolingLevel = 50, + horizontalPosition = 50, + verticalPosition = 50, + frontVerticalPosition = 50, + backVerticalPosition = 50, + backTiltAngle = 50, + headSupportHorizontalPosition = 50, + headSupportVerticalPosition = 50, + massageEnabled = true, + massageMode = { + { + massageZone = "LUMBAR", + massageMode = "HIGH" + }, + { + massageZone = "SEAT_CUSHION", + massageMode = "LOW" + } + }, + massageCushionFirmness = { + { + cushion = "TOP_LUMBAR", + firmness = 30 + }, + { + cushion = "BACK_BOLSTERS", + firmness = 60 + } + }, + memory = { + id = 1, + label = "Label value", + action = "SAVE" + } + } + else + out = origGetModuleControlData(module_type) + end + return out +end + local function restorePreloadedPT() local preloadedFile = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") commonPreconditions:RestoreFile(preloadedFile) @@ -51,7 +120,7 @@ function m.getModules() end function m.getAllModules() - return commonFunctions:cloneTable({ "RADIO", "CLIMATE" }) + return commonFunctions:cloneTable({ "RADIO", "CLIMATE", "SEAT" }) end function m.getRCAppConfig() From 4994793213289039150fd9c4380b155e4ebb67a6 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Thu, 19 Jul 2018 13:16:57 -0400 Subject: [PATCH 487/681] Update smoke tests to include audio streaming indicator --- .../API/014_SetMediaClockTimer_PositiveCase_SUCCESS.lua | 9 +++++++-- ...SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase_SUCCESS.lua index bab8fe3ebf..73c753774d 100644 --- a/test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/014_SetMediaClockTimer_PositiveCase_SUCCESS.lua @@ -48,10 +48,13 @@ local requestParams = { } } +local indicator = {"PLAY_PAUSE", "PLAY", "PAUSE", "STOP"} + --[[ Local Functions ]] -local function SetMediaClockTimer(pParams, pMode, self) +local function SetMediaClockTimer(pParams, pMode, pIndicator, self) local Parameters = commonFunctions:cloneTable(pParams) Parameters.updateMode = pMode + Parameters.audioStreamingIndicator = pIndicator if pMode == "COUNTDOWN" then Parameters.endTime.minutes = Parameters.startTime.minutes - 1 end @@ -73,7 +76,9 @@ runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") for _, value in pairs (updateMode) do - runner.Step("SetMediaClockTimer Positive Case with udate mode " .. value, SetMediaClockTimer, { requestParams,value }) + for _, value2 in pairs (indicator) do + runner.Step("SetMediaClockTimer Positive Case with udate mode " .. value .. " " .. value2 , SetMediaClockTimer, { requestParams,value,value2 }) + end end runner.Title("Postconditions") diff --git a/test_scripts/Smoke/API/040_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/040_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua index 8f704a54fa..8e5b056124 100644 --- a/test_scripts/Smoke/API/040_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/040_SetMediaClockTimer_Non_Media_PositiveCase_SUCCESS.lua @@ -51,10 +51,13 @@ local requestParams = { } } +local indicator = {"PLAY_PAUSE", "PLAY", "PAUSE", "STOP"} + --[[ Local Functions ]] -local function SetMediaClockTimer(pParams, pMode, self) +local function SetMediaClockTimer(pParams, pMode, pIndicator, self) local Parameters = commonFunctions:cloneTable(pParams) Parameters.updateMode = pMode + Parameters.audioStreamingIndicator = pIndicator if pMode == "COUNTDOWN" then Parameters.endTime.minutes = Parameters.startTime.minutes - 1 end @@ -73,7 +76,9 @@ runner.Step("Activate App", commonSmoke.activateApp) runner.Title("Test") for _, value in pairs (updateMode) do - runner.Step("SetMediaClockTimer Positive Case with udate mode " .. value, SetMediaClockTimer, { requestParams,value }) + for _, value2 in pairs (indicator) do + runner.Step("SetMediaClockTimer Non Media Positive Case with udate mode " .. value .. " " .. value2, SetMediaClockTimer, { requestParams,value,value2 }) + end end runner.Title("Postconditions") From c6a114fc0dfc948f48c5876e999d3507d3571d9f Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Sat, 10 Feb 2018 21:19:09 +0200 Subject: [PATCH 488/681] Initial version of the scripts for Low Voltage feature --- .../001_Low_Voltage_and_Wake_Up.lua | 123 ++++ .../002_Low_Voltage_and_Ignition_Off.lua | 82 +++ ...ake_Up_and_Ignition_Off_wo_Low_Voltage.lua | 42 ++ .../004_App_unregister_itself_gracefully.lua | 62 ++ ...ow_Voltage_and_Wake_Up_RPC_in_progress.lua | 74 +++ test_scripts/LowVoltage/common.lua | 553 ++++++++++++++++++ test_sets/low_voltage.txt | 5 + 7 files changed, 941 insertions(+) create mode 100644 test_scripts/LowVoltage/001_Low_Voltage_and_Wake_Up.lua create mode 100644 test_scripts/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua create mode 100644 test_scripts/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua create mode 100644 test_scripts/LowVoltage/004_App_unregister_itself_gracefully.lua create mode 100644 test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua create mode 100644 test_scripts/LowVoltage/common.lua create mode 100644 test_sets/low_voltage.txt diff --git a/test_scripts/LowVoltage/001_Low_Voltage_and_Wake_Up.lua b/test_scripts/LowVoltage/001_Low_Voltage_and_Wake_Up.lua new file mode 100644 index 0000000000..458d42bf7a --- /dev/null +++ b/test_scripts/LowVoltage/001_Low_Voltage_and_Wake_Up.lua @@ -0,0 +1,123 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1) SDL is started (there was no LOW_VOLTAGE signal sent) +-- 2) There are following app’s in HMI levels: +-- App1 is in FULL +-- App2 is in LIMITED +-- App3 is in BACKGROUND +-- App4 is in NONE +-- 3) All apps have some data that can be resumed +-- 4) SDL get LOW_VOLTAGE signal via mqueue +-- 5) And then SDL get WAKE_UP signal via mqueue +-- 6) All apps are registered with the same hashID +-- SDL does: +-- 1) after 4th step: +-- Stop all read write activities +-- Stop Audio/Video streaming +-- Ignore all RPCs from mobile side +-- Ignore all RPCs from HMI side +-- 2) after 5th step: Start it’s work successfully +-- 3) after 6th step: +-- Resume app data for App1, App2, App3 and App4 +-- Resume HMI level for App1, App2, App4 +-- Not resume HMI level for App3 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') +local commonFunctions = require('user_modules/shared_testcases/commonFunctions') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function checkSDLIgnoresRPCFromMobileSide() + common.getMobileSession():SendRPC("AddCommand", { cmdID = 2, vrCommands = { "OnlyVRCommand" }}) + + common.getHMIConnection():ExpectAny():Times(0) + :Do(function(_, data) + print("HMI Event") + commonFunctions:printTable(data) + end) + + common.getMobileSession():ExpectAny():Times(0) + :Do(function(_, data) + print("Mobile Event") + commonFunctions:printTable(data) + end) + common.wait(11000) +end + +local function checkSDLIgnoresRPCFromHMISide() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { + isActive = true, eventName = "EMERGENCY_EVENT" }) + + common.getHMIConnection():ExpectAny():Times(0) + :Do(function(_, data) + print("HMI Event") + commonFunctions:printTable(data) + end) + + common.getMobileSession():ExpectAny():Times(0) + :Do(function(_, data) + print("Mobile Event") + commonFunctions:printTable(data) + end) + common.wait(11000) +end + +local function addResumptionData(pAppId) + local f = {} + f[1] = common.rpcSend.AddCommand + f[2] = common.rpcSend.AddSubMenu + f[3] = common.rpcSend.CreateInteractionChoiceSet + f[4] = common.rpcSend.NoRPC + f[pAppId](pAppId) +end + +local function checkResumptionData(pAppId) + local f = {} + f[1] = common.rpcCheck.AddCommand + f[2] = common.rpcCheck.AddSubMenu + f[3] = common.rpcCheck.CreateInteractionChoiceSet + f[4] = common.rpcCheck.NoRPC + f[pAppId](pAppId) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +local numOfApps = 4 +for i = 1, numOfApps do + runner.Step("Register App " .. i, common.registerApp, { i }) + runner.Step("PolicyTableUpdate", common.policyTableUpdate) +end +runner.Step("Configure HMI levels", common.configureHMILevels, { numOfApps }) +for i = 1, numOfApps do + runner.Step("Add resumption data for App " .. i, addResumptionData, { i }) +end + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Send LOW_VOLTAGE signal", common.sendMQLowVoltageSignal) +runner.Step("Check SDL Ignores RPCs from Mobile side", checkSDLIgnoresRPCFromMobileSide) +runner.Step("Check SDL Ignores RPCs from HMI side", checkSDLIgnoresRPCFromHMISide) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Send WAKE_UP signal", common.sendMQWakeUpSignal) +runner.Step("Re-connect Mobile", common.connectMobile) +for i = 1, numOfApps do + runner.Step("Re-register App " .. i .. ", check resumption data and HMI level", common.reRegisterApp, { + i, checkAppId, checkResumptionData, common.checkResumptionHMILevel, "SUCCESS", 1000 + }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua b/test_scripts/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua new file mode 100644 index 0000000000..5266604712 --- /dev/null +++ b/test_scripts/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua @@ -0,0 +1,82 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1) SDL is started (there was no LOW_VOLTAGE signal sent) +-- 2) There are following app’s in HMI levels: +-- App1 is in FULL +-- App2 is in LIMITED +-- App3 is in BACKGROUND +-- App4 is in NONE +-- 3) All apps have some data that can be resumed +-- 4) SDL get LOW_VOLTAGE signal via mqueue +-- 5) And then SDL get IGNITION_OFF signal via mqueue +-- 6) And then SDL is started +-- 7) All apps are registered with the same hashID +-- SDL does: +-- 1) after 5th step: Finish it’s work successfully (as for Ignition Off) +-- 2) after 6th step: Start it’s work successfully (as for next Ignition Cycle) +-- 3) after 7th step: +-- Resume app data for App1, App2, App3 and App4 +-- Resume HMI level for App1, App2, App4 +-- Not resume HMI level for App3 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function addResumptionData(pAppId) + local f = {} + f[1] = common.rpcSend.AddCommand + f[2] = common.rpcSend.AddSubMenu + f[3] = common.rpcSend.CreateInteractionChoiceSet + f[4] = common.rpcSend.NoRPC + f[pAppId](pAppId) +end + +local function checkResumptionData(pAppId) + local f = {} + f[1] = common.rpcCheck.AddCommand + f[2] = common.rpcCheck.AddSubMenu + f[3] = common.rpcCheck.CreateInteractionChoiceSet + f[4] = common.rpcCheck.NoRPC + f[pAppId](pAppId) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +local numOfApps = 4 +for i = 1, numOfApps do + runner.Step("Register App " .. i, common.registerApp, { i }) + runner.Step("PolicyTableUpdate", common.policyTableUpdate) +end +runner.Step("Configure HMI levels", common.configureHMILevels, { numOfApps }) +for i = 1, numOfApps do + runner.Step("Add resumption data for App " .. i, addResumptionData, { i }) +end + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Send LOW_VOLTAGE signal", common.sendMQLowVoltageSignal) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Send IGNITION_OFF signal", common.sendMQIgnitionOffSignal) +runner.Step("Ignition On", common.start) +for i = 1, numOfApps do + runner.Step("Re-register App " .. i .. ", check resumption data and HMI level", common.reRegisterApp, { + i, checkAppId, checkResumptionData, common.checkResumptionHMILevel, "SUCCESS", 1000 + }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua b/test_scripts/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua new file mode 100644 index 0000000000..19f709b731 --- /dev/null +++ b/test_scripts/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua @@ -0,0 +1,42 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1) SDL is started (there was no LOW_VOLTAGE signal sent) +-- 2) SDL get IGNITION_OFF or WAKE_UP signal via mqueue +-- SDL does: +-- 1) Ignore signal WAKE_UP and continue working as usual +-- 2) Process IGNITION_OFF signal and shut down successfully +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function processAddCommandSuccessfully() + local cid = common.getMobileSession():SendRPC("AddCommand", { cmdID = 1, vrCommands = { "CMD" }}) + common.getHMIConnection():ExpectRequest("VR.AddCommand") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + common.getMobileSession():ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Send WAKE_UP signal", common.sendMQWakeUpSignal) +runner.Step("AddCommand success", processAddCommandSuccessfully) +runner.Step("Send IGNITION_OFF signal", common.sendMQIgnitionOffSignal) +runner.Step("Check SDL stopped", common.isSDLStopped) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/004_App_unregister_itself_gracefully.lua b/test_scripts/LowVoltage/004_App_unregister_itself_gracefully.lua new file mode 100644 index 0000000000..c0561fcf25 --- /dev/null +++ b/test_scripts/LowVoltage/004_App_unregister_itself_gracefully.lua @@ -0,0 +1,62 @@ +--------------------------------------------------------------------------------------------------- +-- Test Case #1: Extension 3 +-- In case: +-- 1) App unregisters itself gracefully before LOW_VOLTAGE +-- 2) App registers again after WAKE_UP +-- SDL does: +-- 1) Not resume app data +-- 2) Not resume app HMI level +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function addResumptionData() + common.rpcSend.AddCommand(1) +end + +local function checkResumptionData() + common.getHMIConnection():ExpectRequest("VR.AddCommand") + :Times(0) +end + +local function checkResumptionHMILevel() + common.getHMIConnection():ExpectRequest("BasicCommunication.ActivateApp", { appID = common.getHMIAppId(1) }) + :Times(0) + common.getMobileSession(1):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID == common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with the same HMI App Id" + end + return true +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate App", common.activateApp) +runner.Step("Add resumption data for App", addResumptionData) + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Unregister App", common.unregisterApp) +runner.Step("Send LOW_VOLTAGE signal", common.sendMQLowVoltageSignal) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Send WAKE_UP signal", common.sendMQWakeUpSignal) +runner.Step("Re-connect Mobile", common.connectMobile) +runner.Step("Re-register App, check no resumption of Data and no resumption of HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "RESUME_FAILED", 5000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua b/test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua new file mode 100644 index 0000000000..a659e69993 --- /dev/null +++ b/test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua @@ -0,0 +1,74 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1) SDL is started (there was no LOW_VOLTAGE signal sent) +-- 2) SDL is in progress of processing some RPC +-- 3) SDL get LOW_VOLTAGE signal via mqueue +-- 4) And then SDL get WAKE_UP signal via mqueue +-- SDL does: +-- 1) Resume it’s work successfully (as for Resumption) +-- 2) Discard processing of RPC +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local cid = nil + +--[[ Local Functions ]] +local function checkResumptionData() + common.getMobileSession():ExpectResponse(cid) -- check absence of response + :Times(0) +end + +local function checkResumptionHMILevel() + common.getHMIConnection():ExpectRequest("BasicCommunication.ActivateApp", { appID = common.getHMIAppId(1) }) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, "BasicCommunication.ActivateApp", "SUCCESS", {}) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, + { hmiLevel = "FULL", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE" }) + :Times(2) +end + +local function processRPCPartially() + local params = { + mainField1 = "Show Line 1", + mainField2 = "Show Line 2", + mainField3 = "Show Line 3" + } + cid = common.getMobileSession():SendRPC("Show", params) + EXPECT_HMICALL("UI.Show") +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("RPC Show partially", processRPCPartially) +runner.Step("Send LOW_VOLTAGE signal", common.sendMQLowVoltageSignal) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Send WAKE_UP signal", common.sendMQWakeUpSignal) +runner.Step("Re-connect Mobile", common.connectMobile) +runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "SUCCESS", 11000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/common.lua b/test_scripts/LowVoltage/common.lua new file mode 100644 index 0000000000..083826cc73 --- /dev/null +++ b/test_scripts/LowVoltage/common.lua @@ -0,0 +1,553 @@ +--------------------------------------------------------------------------------------------------- +-- Common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 2 + +--[[ Required Shared libraries ]] +local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local events = require('events') +local test = require('user_modules/dummy_connecttest') +local expectations = require('expectations') +local Expectation = expectations.Expectation +local SDL = require('SDL') +local mq = require('mq') +local utils = require("user_modules/utils") +local actions = require("user_modules/sequences/actions") + +--[[ Module ]] +local m = actions + +m.cprint = utils.cprint +m.wait = utils.wait + +--[[ Constants ]] +m.appParams = { + [1] = { appHMIType = "MEDIA", isMediaApplication = false }, + [2] = { appHMIType = "DEFAULT", isMediaApplication = true }, + [3] = { appHMIType = "DEFAULT", isMediaApplication = false }, + [4] = { appHMIType = "DEFAULT", isMediaApplication = false } +} +m.sdlMQ = "SDLMQ" +m.rpcSend = {} +m.rpcCheck = {} + +for i = 1, 4 do + config["application" .. i].registerAppInterfaceParams.appHMIType = { m.appParams[i].appHMIType } + config["application" .. i].registerAppInterfaceParams.isMediaApplication = m.appParams[i].isMediaApplication +end + +--[[ Variables ]] +local isMobileConnected = false +local grammarId = {} +local hashId = {} +local origGetMobileSession = actions.getMobileSession + +-- Override functions of Actions module + +--[[ @registerStartSecureServiceFunc: register function to expect Any event on mobile connection +--! @parameters: +--! pMobSession - mobile session +--]] +local function registerCustomExpFunctions(pMobSession) + --[[ @ExpectAny: register expectation for any event on Mobile connection + --! @parameters: none + --]] + function pMobSession:ExpectAny() + local session = self.mobile_session_impl + local event = events.Event() + event.matches = function(_, data) + return data.sessionId == session.sessionId.get() + end + local ret = Expectation("Any Mobile Event", session.connection) + ret.event = event + event_dispatcher:AddEvent(session.connection, event, ret) + test:AddExpectation(ret) + return ret + end +end + +function m.getMobileSession(pAppId) + if not pAppId then pAppId = 1 end + if not test.mobileSession[pAppId] then + local session = origGetMobileSession(pAppId) + registerCustomExpFunctions(session) + end + return origGetMobileSession(pAppId) +end + +function m.activateApp(pAppId) + if not pAppId then pAppId = 1 end + local requestId = test.hmiConnection:SendRequest("SDL.ActivateApp", { appID = m.getHMIAppId(pAppId) }) + test.hmiConnection:ExpectResponse(requestId) + m.getMobileSession(pAppId):ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", systemContext = "MAIN" }) + utils.wait() +end + +--[[ Functions ]] +--[[ @execCMD: execute any linux command and return result +--! @parameters: +--! pCmd - command to execute +--! @return: result +--]] +local function execCMD(pCmd) + local handle = io.popen(pCmd) + local result = handle:read("*a") + handle:close() + return result +end + +--[[ @ExpectAny: register expectation for any event on HMI connection +--! @parameters: none +--]] +function test.hmiConnection:ExpectAny() + local event = events.Event() + event.matches = function() return true end + local ret = Expectation("Any HMI Event", self) + ret.event = event + event_dispatcher:AddEvent(self, event, ret) + test:AddExpectation(ret) + return ret +end + +--[[ @cleanSessions: delete all mobile sessions and close mobile connection +--! @parameters: none +--! @return: none +--]] +function m.cleanSessions() + if isMobileConnected == true then + EXPECT_EVENT(events.disconnectedEvent, "Disconnected") + :Do(function() + isMobileConnected = false + utils.cprint(35, "Mobile disconnected") + end) + end + local function toRun() + for i = 1, m.getAppsCount() do + test.mobileSession[i] = nil + utils.cprint(35, "Mobile session " .. i .. " deleted") + end + test.mobileConnection:Close() + end + RUN_AFTER(toRun, 1000) + utils.wait() +end + +--[[ @unexpectedDisconnect: perform unexpected disconnect sequence +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: none +--]] +function m.unexpectedDisconnect(pAppId) + if not pAppId then pAppId = 1 end + m.getHMIConnection():ExpectNotification("BasicCommunication.OnAppUnregistered", { + unexpectedDisconnect = true, + appID = m.getHMIAppId(pAppId) + }) + m.getMobileSession(pAppId):Stop() +end + +--[[ @unregisterApp: unregister application sequence +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: none +--]] +function m.unregisterApp(pAppId) + if not pAppId then pAppId = 1 end + local cid = m.getMobileSession(pAppId):SendRPC("UnregisterAppInterface", {}) + m.getMobileSession(pAppId):ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + m.getHMIConnection():ExpectNotification("BasicCommunication.OnAppUnregistered", { + unexpectedDisconnect = false, + appID = m.getHMIAppId(pAppId) + }) +end + +--[[ @createMQ: create SDL MQ +--! @parameters: none +--! @return: none +--]] +function m.createMQ() + local queue = mq.create("/" .. m.sdlMQ, "rw", "rw-rw----") + if queue == nil then + utils.cprint(35, "Queue '" .. m.sdlMQ .. "' can't be created") + return + else + utils.cprint(35, "Queue '" .. m.sdlMQ .. "' created successfully") + end +end + +--[[ @sendMQSignal: send MQ signal +--! @parameters: +--! pSignal - signal +--! @return: none +--]] +function m.sendMQSignal(pSignal) + local queue = mq.open("/" .. m.sdlMQ, "rw") + if queue == nil then + utils.cprint(35, "Queue '" .. m.sdlMQ .. "' can't be opened") + return + else + utils.cprint(35, "Queue '" .. m.sdlMQ .. "' opened successfully") + end + local result = mq.send(queue, pSignal) + if result == nil then + utils.cprint(35, "Signal '" .. pSignal .. "' was not sent") + return + else + utils.cprint(35, "Signal '" .. pSignal .. "' was sent successfully") + end + result = mq.close(queue) + if result == nil then + utils.cprint(35, "Queue '" .. m.sdlMQ .. "' can't be closed") + return + else + utils.cprint(35, "Queue '" .. m.sdlMQ .. "' closed successfully") + end +end + +--[[ @deleteMQ: delete SDL MQ +--! @parameters: none +--! @return: none +--]] +function m.deleteMQ() + local result = mq.unlink("/" .. m.sdlMQ) + if result == nil then + utils.cprint(35, "Queue '" .. m.sdlMQ .. "' can't be deleted") + return + else + utils.cprint(35, "Queue '" .. m.sdlMQ .. "' deleted successfully") + end +end + +--[[ @receiveMQSignal: receive MQ signal +--! @parameters: none +--! @return: none +--]] +function m.receiveMQSignal() + local queue = mq.open("/" .. m.sdlMQ, "rw") + if queue == nil then + utils.cprint(35, "Queue '" .. m.sdlMQ .. "' can't be opened") + return + else + utils.cprint(35, "Queue '" .. m.sdlMQ .. "' opened successfully") + end + local msg = mq.receive(queue) + if msg == nil then + utils.cprint(35, "Queue '" .. m.sdlMQ .. "' can't be read") + return + else + utils.cprint(35, "Signal '" .. msg .. "' received successfully") + end + local result = mq.close(queue) + if result == nil then + utils.cprint(35, "Queue '" .. m.sdlMQ .. "' can't be closed") + return + else + utils.cprint(35, "Queue '" .. m.sdlMQ .. "' closed successfully") + end +end + +--[[ @connectMobile: connect mobile device +--! @parameters: none +--! @return: none +--]] +function m.connectMobile() + test.mobileConnection:Connect() + EXPECT_EVENT(events.connectedEvent, "Connected") + :Do(function() + utils.cprint(35, "Mobile connected") + end) +end + +--[[ @reRegisterApp: re-register application +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! pCheckAppId - verification function for HMI Application id +--! pCheckResumptionData - verification function for resumption data +--! pCheckResumptionHMILevel - verification function for resumption HMI level +--! pResultCode - expected result code +--! pDelay - delay +--! @return: none +--]] +function m.reRegisterApp(pAppId, pCheckAppId, pCheckResumptionData, pCheckResumptionHMILevel, pResultCode, pDelay) + local mobSession = m.getMobileSession(pAppId) + mobSession:StartService(7) + :Do(function() + local params = config["application" .. pAppId].registerAppInterfaceParams + params.hashID = hashId[pAppId] + local corId = mobSession:SendRPC("RegisterAppInterface", params) + m.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", { + application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } + }) + :Do(function() + m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate") + :Times(0) + m.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") + :Times(0) + end) + :ValidIf(function(_, data) + return pCheckAppId(pAppId, data) + end) + mobSession:ExpectResponse(corId, { success = true, resultCode = pResultCode }) + :Do(function() + mobSession:ExpectNotification("OnPermissionsChange") + end) + end) + pCheckResumptionData(pAppId) + pCheckResumptionHMILevel(pAppId) + utils.wait(pDelay) +end + +--[[ @waitUntilSocketIsClosed: wait some time until SDL logger is closed +--! @parameters: none +--! @return: none +--]] +local function waitUntilSDLLoggerIsClosed() + utils.cprint(35, "Wait until SDL Logger is closed ...") + local function getNetStat() + local cmd = "netstat" + .. " | grep -E '" .. config.sdl_logs_host .. ":" .. config.sdl_logs_port .. "\\s*FIN_WAIT'" + .. " | wc -l" + return tonumber(execCMD(cmd)) + end + while getNetStat() > 0 do + os.execute("sleep 1") + end + os.execute("sleep 1") +end + +--[[ @sendMQLowVoltageSignal: send 'SDL_LOW_VOLTAGE' signal to SDL MQ +--! @parameters: none +--! @return: none +--]] +function m.sendMQLowVoltageSignal() + m.sendMQSignal("LOW_VOLTAGE") +end + +--[[ @sendMQIgnitionOffSignal: send 'IGNITION_OFF' signal to SDL MQ +--! @parameters: none +--! @return: none +--]] +function m.sendMQIgnitionOffSignal() + SDL:DeleteFile() + m.sendMQSignal("IGNITION_OFF") + local function toRun() + SDL:StopSDL() + waitUntilSDLLoggerIsClosed() + end + RUN_AFTER(toRun, 1000) + utils.wait() +end + +--[[ @sendMQWakeUpSignal: send 'WAKE_UP' signal to SDL MQ +--! @parameters: none +--! @return: none +--]] +function m.sendMQWakeUpSignal() + m.sendMQSignal("WAKE_UP") + utils.wait() +end + +--[[ @waitUntilResumptionDataIsStored: wait some time until SDL saves resumption data +--! @parameters: none +--! @return: none +--]] +function m.waitUntilResumptionDataIsStored() + utils.cprint(35, "Wait ...") + local fileName = commonPreconditions:GetPathToSDL() + .. commonFunctions:read_parameter_from_smart_device_link_ini("AppInfoStorage") + local function isFileExist() + local f = io.open(fileName, "r") + if f ~= nil then + io.close(f) + return true + else + return false + end + end + while not isFileExist() do + os.execute("sleep 1") + end +end + +--[[ @isSDLStopped: verifies if SDL stopped +--! @parameters: none +--! @return: none +--]] +function m.isSDLStopped() + local s = SDL:CheckStatusSDL() + if s ~= SDL.STOPPED then + return test:FailTestCase("SDL is not stopped") + end + utils.cprint(35, "SDL stopped") +end + +m.rpcSend.AddCommand = function(pAppId, pCommandId) + if not pCommandId then pCommandId = 1 end + local cmd = "CMD" .. pCommandId + local cid = m.getMobileSession(pAppId):SendRPC("AddCommand", { cmdID = pCommandId, vrCommands = { cmd }}) + m.getHMIConnection():ExpectRequest("VR.AddCommand") + :Do(function(_, data) + grammarId[pAppId] = data.params.grammarID + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + m.getMobileSession(pAppId):ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + m.getMobileSession(pAppId):ExpectNotification("OnHashChange") + :Do(function(_, data) + hashId[pAppId] = data.payload.hashID + end) + end +m.rpcSend.AddSubMenu = function(pAppId) + local cid = m.getMobileSession(pAppId):SendRPC("AddSubMenu", { menuID = 1, position = 500, menuName = "SubMenu" }) + m.getHMIConnection():ExpectRequest("UI.AddSubMenu") + :Do(function(_, data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + m.getMobileSession(pAppId):ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + m.getMobileSession(pAppId):ExpectNotification("OnHashChange") + :Do(function(_, data) + hashId[pAppId] = data.payload.hashID + end) + end +m.rpcSend.CreateInteractionChoiceSet = function(pAppId) + local cid = m.getMobileSession(pAppId):SendRPC("CreateInteractionChoiceSet", { + interactionChoiceSetID = 1, + choiceSet = { + { choiceID = 1, menuName = "Choice", vrCommands = { "VrChoice" }} + } + }) + m.getHMIConnection():ExpectRequest("VR.AddCommand") + :Do(function(_, data) + grammarId[pAppId] = data.params.grammarID + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + m.getMobileSession(pAppId):ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + m.getMobileSession(pAppId):ExpectNotification("OnHashChange") + :Do(function(_, data) + hashId[pAppId] = data.payload.hashID + end) + end +m.rpcSend.NoRPC = function() end + +m.rpcCheck.AddCommand = function(pAppId, pCommandId) + if not pCommandId then pCommandId = 1 end + local cmd = "CMD" .. pCommandId + m.getHMIConnection():ExpectRequest("VR.AddCommand", { + cmdID = pCommandId, + vrCommands = { cmd }, + type = "Command", + grammarID = grammarId[pAppId], + appID = m.getHMIAppId(pAppId) + }) + :Do(function(_, data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS") + end) + end +m.rpcCheck.AddSubMenu = function(pAppId) + m.getHMIConnection():ExpectRequest("UI.AddSubMenu", { + menuID = 1, + menuParams = { + position = 500, + menuName = "SubMenu" + }, + appID = m.getHMIAppId(pAppId) + }) + :Do(function(_, data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS") + end) + end +m.rpcCheck.CreateInteractionChoiceSet = function(pAppId) + m.getHMIConnection():ExpectRequest("VR.AddCommand", { + cmdID = 1, + vrCommands = { "VrChoice" }, + type = "Choice", + grammarID = grammarId[pAppId], + appID = m.getHMIAppId(pAppId) + }) + :Do(function(_, data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS") + end) + end +m.rpcCheck.NoRPC = function() end + +--[[ @configureHMILevels: configures app's HMI levels: +--! 1 - FULL +--! 2 - LIMITED +--! 3 - BACKGROUND +--! 4 - NONE +--! @parameters: +--! pNumOfApps - number of applications +--! @return: none +--]] +function m.configureHMILevels(pNumOfApps) + local apps = { + [1] = { 1 }, + [2] = { 2, 1 }, + [3] = { 2, 3, 1 }, + [4] = { 2, 3, 1 } + } + for k, i in pairs(apps[pNumOfApps]) do + local function activateApp() + local cid = m.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = m.getHMIAppId(i) }) + m.getHMIConnection():ExpectResponse(cid) + :Do(function() utils.cprint(35, "Activate App: " .. i) end) + end + RUN_AFTER(activateApp, 100 * k) + end + m.getMobileSession(1):ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE" }) + + if pNumOfApps >= 2 then + m.getMobileSession(2):ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", systemContext = "MAIN", audioStreamingState = "AUDIBLE" }, + { hmiLevel = "LIMITED", systemContext = "MAIN", audioStreamingState = "AUDIBLE" }) + :Times(2) + end + if pNumOfApps >= 3 then + m.getMobileSession(3):ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE" }, + { hmiLevel = "BACKGROUND", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE" }) + :Times(2) + end +end + +--[[ @checkResumptionHMILevel: verifies app's HMI levels while resumption +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: none +--]] +function m.checkResumptionHMILevel(pAppId) + local f = {} + f[1] = function() + m.getHMIConnection():ExpectRequest("BasicCommunication.ActivateApp", { appID = m.getHMIAppId(1) }) + :Do(function(_, data) + m.getHMIConnection():SendResponse(data.id, "BasicCommunication.ActivateApp", "SUCCESS", {}) + end) + m.getMobileSession(1):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, + { hmiLevel = "FULL", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE" }) + :Times(2) + end + f[2] = function() + m.getHMIConnection():ExpectNotification("BasicCommunication.OnResumeAudioSource", { + appID = m.getHMIAppId(2) }) + m.getMobileSession(2):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, + { hmiLevel = "LIMITED", systemContext = "MAIN", audioStreamingState = "AUDIBLE" }) + :Times(2) + end + f[3] = function() + m.getMobileSession(3):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(1) + end + f[4] = function() + m.getMobileSession(4):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(1) + end + f[pAppId]() +end + +return m diff --git a/test_sets/low_voltage.txt b/test_sets/low_voltage.txt new file mode 100644 index 0000000000..3aa5170f44 --- /dev/null +++ b/test_sets/low_voltage.txt @@ -0,0 +1,5 @@ +./test_scripts/LowVoltage/001_Low_Voltage_and_Wake_Up.lua +./test_scripts/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua +./test_scripts/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua +./test_scripts/LowVoltage/004_App_unregister_itself_gracefully.lua +./test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua From e424464033059bf1dd2fddb788cb71882aeed4ff Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 20 Jun 2018 17:48:33 +0300 Subject: [PATCH 489/681] Switch to signals instead of MQ --- .../001_Low_Voltage_and_Wake_Up.lua | 8 +- .../002_Low_Voltage_and_Ignition_Off.lua | 15 ++- ...ake_Up_and_Ignition_Off_wo_Low_Voltage.lua | 6 +- .../004_App_unregister_itself_gracefully.lua | 4 +- ...ow_Voltage_and_Wake_Up_RPC_in_progress.lua | 8 +- test_scripts/LowVoltage/common.lua | 117 ++++-------------- 6 files changed, 45 insertions(+), 113 deletions(-) diff --git a/test_scripts/LowVoltage/001_Low_Voltage_and_Wake_Up.lua b/test_scripts/LowVoltage/001_Low_Voltage_and_Wake_Up.lua index 458d42bf7a..1361dbf987 100644 --- a/test_scripts/LowVoltage/001_Low_Voltage_and_Wake_Up.lua +++ b/test_scripts/LowVoltage/001_Low_Voltage_and_Wake_Up.lua @@ -7,8 +7,8 @@ -- App3 is in BACKGROUND -- App4 is in NONE -- 3) All apps have some data that can be resumed --- 4) SDL get LOW_VOLTAGE signal via mqueue --- 5) And then SDL get WAKE_UP signal via mqueue +-- 4) SDL get LOW_VOLTAGE signal +-- 5) And then SDL get WAKE_UP signal -- 6) All apps are registered with the same hashID -- SDL does: -- 1) after 4th step: @@ -107,11 +107,11 @@ end runner.Title("Test") runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) -runner.Step("Send LOW_VOLTAGE signal", common.sendMQLowVoltageSignal) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) runner.Step("Check SDL Ignores RPCs from Mobile side", checkSDLIgnoresRPCFromMobileSide) runner.Step("Check SDL Ignores RPCs from HMI side", checkSDLIgnoresRPCFromHMISide) runner.Step("Close mobile connection", common.cleanSessions) -runner.Step("Send WAKE_UP signal", common.sendMQWakeUpSignal) +runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) runner.Step("Re-connect Mobile", common.connectMobile) for i = 1, numOfApps do runner.Step("Re-register App " .. i .. ", check resumption data and HMI level", common.reRegisterApp, { diff --git a/test_scripts/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua b/test_scripts/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua index 5266604712..34d9372084 100644 --- a/test_scripts/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua +++ b/test_scripts/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua @@ -7,8 +7,8 @@ -- App3 is in BACKGROUND -- App4 is in NONE -- 3) All apps have some data that can be resumed --- 4) SDL get LOW_VOLTAGE signal via mqueue --- 5) And then SDL get IGNITION_OFF signal via mqueue +-- 4) SDL get LOW_VOLTAGE signal +-- 5) And then SDL get IGNITION_OFF signal -- 6) And then SDL is started -- 7) All apps are registered with the same hashID -- SDL does: @@ -52,6 +52,13 @@ local function checkAppId(pAppId, pData) return true end +local function sendIgnitionOffSignal() + common.getMobileSession():ExpectAny():Times(0) + common.getHMIConnection():ExpectAny():Times(0) + common.sendIgnitionOffSignal() + common.wait(2000) +end + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) @@ -68,9 +75,9 @@ end runner.Title("Test") runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) -runner.Step("Send LOW_VOLTAGE signal", common.sendMQLowVoltageSignal) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) runner.Step("Close mobile connection", common.cleanSessions) -runner.Step("Send IGNITION_OFF signal", common.sendMQIgnitionOffSignal) +runner.Step("Send IGNITION_OFF signal", sendIgnitionOffSignal) runner.Step("Ignition On", common.start) for i = 1, numOfApps do runner.Step("Re-register App " .. i .. ", check resumption data and HMI level", common.reRegisterApp, { diff --git a/test_scripts/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua b/test_scripts/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua index 19f709b731..05e337dfd1 100644 --- a/test_scripts/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua +++ b/test_scripts/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- In case: -- 1) SDL is started (there was no LOW_VOLTAGE signal sent) --- 2) SDL get IGNITION_OFF or WAKE_UP signal via mqueue +-- 2) SDL get IGNITION_OFF or WAKE_UP signal -- SDL does: -- 1) Ignore signal WAKE_UP and continue working as usual -- 2) Process IGNITION_OFF signal and shut down successfully @@ -33,9 +33,9 @@ runner.Step("PolicyTableUpdate", common.policyTableUpdate) runner.Step("Activate App", common.activateApp) runner.Title("Test") -runner.Step("Send WAKE_UP signal", common.sendMQWakeUpSignal) +runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) runner.Step("AddCommand success", processAddCommandSuccessfully) -runner.Step("Send IGNITION_OFF signal", common.sendMQIgnitionOffSignal) +runner.Step("Send IGNITION_OFF signal", common.sendIgnitionOffSignal) runner.Step("Check SDL stopped", common.isSDLStopped) runner.Title("Postconditions") diff --git a/test_scripts/LowVoltage/004_App_unregister_itself_gracefully.lua b/test_scripts/LowVoltage/004_App_unregister_itself_gracefully.lua index c0561fcf25..67b1ea46a4 100644 --- a/test_scripts/LowVoltage/004_App_unregister_itself_gracefully.lua +++ b/test_scripts/LowVoltage/004_App_unregister_itself_gracefully.lua @@ -50,9 +50,9 @@ runner.Step("Add resumption data for App", addResumptionData) runner.Title("Test") runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) runner.Step("Unregister App", common.unregisterApp) -runner.Step("Send LOW_VOLTAGE signal", common.sendMQLowVoltageSignal) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) runner.Step("Close mobile connection", common.cleanSessions) -runner.Step("Send WAKE_UP signal", common.sendMQWakeUpSignal) +runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) runner.Step("Re-connect Mobile", common.connectMobile) runner.Step("Re-register App, check no resumption of Data and no resumption of HMI level", common.reRegisterApp, { 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "RESUME_FAILED", 5000 diff --git a/test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua b/test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua index a659e69993..2dc0cad90f 100644 --- a/test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua +++ b/test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua @@ -2,8 +2,8 @@ -- In case: -- 1) SDL is started (there was no LOW_VOLTAGE signal sent) -- 2) SDL is in progress of processing some RPC --- 3) SDL get LOW_VOLTAGE signal via mqueue --- 4) And then SDL get WAKE_UP signal via mqueue +-- 3) SDL get LOW_VOLTAGE signal +-- 4) And then SDL get WAKE_UP signal -- SDL does: -- 1) Resume it’s work successfully (as for Resumption) -- 2) Discard processing of RPC @@ -62,9 +62,9 @@ runner.Step("Activate App", common.activateApp) runner.Title("Test") runner.Step("RPC Show partially", processRPCPartially) -runner.Step("Send LOW_VOLTAGE signal", common.sendMQLowVoltageSignal) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) runner.Step("Close mobile connection", common.cleanSessions) -runner.Step("Send WAKE_UP signal", common.sendMQWakeUpSignal) +runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) runner.Step("Re-connect Mobile", common.connectMobile) runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "SUCCESS", 11000 diff --git a/test_scripts/LowVoltage/common.lua b/test_scripts/LowVoltage/common.lua index 083826cc73..8eb7bf2cfe 100644 --- a/test_scripts/LowVoltage/common.lua +++ b/test_scripts/LowVoltage/common.lua @@ -12,7 +12,6 @@ local test = require('user_modules/dummy_connecttest') local expectations = require('expectations') local Expectation = expectations.Expectation local SDL = require('SDL') -local mq = require('mq') local utils = require("user_modules/utils") local actions = require("user_modules/sequences/actions") @@ -29,10 +28,16 @@ m.appParams = { [3] = { appHMIType = "DEFAULT", isMediaApplication = false }, [4] = { appHMIType = "DEFAULT", isMediaApplication = false } } -m.sdlMQ = "SDLMQ" + m.rpcSend = {} m.rpcCheck = {} +m.signal = { + LOW_VOLTAGE = 35, + WAKE_UP = 36, + IGNITION_OFF = 37 +} + for i = 1, 4 do config["application" .. i].registerAppInterfaceParams.appHMIType = { m.appParams[i].appHMIType } config["application" .. i].registerAppInterfaceParams.isMediaApplication = m.appParams[i].isMediaApplication @@ -163,89 +168,15 @@ function m.unregisterApp(pAppId) }) end ---[[ @createMQ: create SDL MQ ---! @parameters: none ---! @return: none ---]] -function m.createMQ() - local queue = mq.create("/" .. m.sdlMQ, "rw", "rw-rw----") - if queue == nil then - utils.cprint(35, "Queue '" .. m.sdlMQ .. "' can't be created") - return - else - utils.cprint(35, "Queue '" .. m.sdlMQ .. "' created successfully") - end -end - ---[[ @sendMQSignal: send MQ signal +--[[ @sendSignal: send signal --! @parameters: --! pSignal - signal --! @return: none --]] -function m.sendMQSignal(pSignal) - local queue = mq.open("/" .. m.sdlMQ, "rw") - if queue == nil then - utils.cprint(35, "Queue '" .. m.sdlMQ .. "' can't be opened") - return - else - utils.cprint(35, "Queue '" .. m.sdlMQ .. "' opened successfully") - end - local result = mq.send(queue, pSignal) - if result == nil then - utils.cprint(35, "Signal '" .. pSignal .. "' was not sent") - return - else - utils.cprint(35, "Signal '" .. pSignal .. "' was sent successfully") - end - result = mq.close(queue) - if result == nil then - utils.cprint(35, "Queue '" .. m.sdlMQ .. "' can't be closed") - return - else - utils.cprint(35, "Queue '" .. m.sdlMQ .. "' closed successfully") - end -end - ---[[ @deleteMQ: delete SDL MQ ---! @parameters: none ---! @return: none ---]] -function m.deleteMQ() - local result = mq.unlink("/" .. m.sdlMQ) - if result == nil then - utils.cprint(35, "Queue '" .. m.sdlMQ .. "' can't be deleted") - return - else - utils.cprint(35, "Queue '" .. m.sdlMQ .. "' deleted successfully") - end -end - ---[[ @receiveMQSignal: receive MQ signal ---! @parameters: none ---! @return: none ---]] -function m.receiveMQSignal() - local queue = mq.open("/" .. m.sdlMQ, "rw") - if queue == nil then - utils.cprint(35, "Queue '" .. m.sdlMQ .. "' can't be opened") - return - else - utils.cprint(35, "Queue '" .. m.sdlMQ .. "' opened successfully") - end - local msg = mq.receive(queue) - if msg == nil then - utils.cprint(35, "Queue '" .. m.sdlMQ .. "' can't be read") - return - else - utils.cprint(35, "Signal '" .. msg .. "' received successfully") - end - local result = mq.close(queue) - if result == nil then - utils.cprint(35, "Queue '" .. m.sdlMQ .. "' can't be closed") - return - else - utils.cprint(35, "Queue '" .. m.sdlMQ .. "' closed successfully") - end +function m.sendSignal(pSignal) + local cmd = "ps -ef | grep smartDeviceLinkCore | grep -v grep | awk '{print $2}' | xargs kill -" .. m.signal[pSignal] + utils.cprint(35, "Sending signal '" .. pSignal .. "'") + execCMD(cmd) end --[[ @connectMobile: connect mobile device @@ -280,12 +211,6 @@ function m.reRegisterApp(pAppId, pCheckAppId, pCheckResumptionData, pCheckResump m.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) - :Do(function() - m.getHMIConnection():ExpectNotification("SDL.OnStatusUpdate") - :Times(0) - m.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") - :Times(0) - end) :ValidIf(function(_, data) return pCheckAppId(pAppId, data) end) @@ -317,21 +242,21 @@ local function waitUntilSDLLoggerIsClosed() os.execute("sleep 1") end ---[[ @sendMQLowVoltageSignal: send 'SDL_LOW_VOLTAGE' signal to SDL MQ +--[[ @sendLowVoltageSignal: send 'SDL_LOW_VOLTAGE' signal --! @parameters: none --! @return: none --]] -function m.sendMQLowVoltageSignal() - m.sendMQSignal("LOW_VOLTAGE") +function m.sendLowVoltageSignal() + m.sendSignal("LOW_VOLTAGE") end ---[[ @sendMQIgnitionOffSignal: send 'IGNITION_OFF' signal to SDL MQ +--[[ @sendIgnitionOffSignal: send 'IGNITION_OFF' signal --! @parameters: none --! @return: none --]] -function m.sendMQIgnitionOffSignal() +function m.sendIgnitionOffSignal() SDL:DeleteFile() - m.sendMQSignal("IGNITION_OFF") + m.sendSignal("IGNITION_OFF") local function toRun() SDL:StopSDL() waitUntilSDLLoggerIsClosed() @@ -340,12 +265,12 @@ function m.sendMQIgnitionOffSignal() utils.wait() end ---[[ @sendMQWakeUpSignal: send 'WAKE_UP' signal to SDL MQ +--[[ @sendWakeUpSignal: send 'WAKE_UP' signal --! @parameters: none --! @return: none --]] -function m.sendMQWakeUpSignal() - m.sendMQSignal("WAKE_UP") +function m.sendWakeUpSignal() + m.sendSignal("WAKE_UP") utils.wait() end From c801cea3efe563256be796bd9c62de024545edc5 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 25 Jul 2018 11:59:25 +0300 Subject: [PATCH 490/681] Scripts for resumption within low voltage --- ...ow_Voltage_and_Wake_Up_RPC_in_progress.lua | 1 + ..._and_Wake_Up_resumption_FULL_hmi_level.lua | 57 +++++++++++++++ ..._hmi_level_in_case_existed_app_in_full.lua | 66 +++++++++++++++++ ...L_hmi_level_in_case_more_30_sec_before.lua | 64 +++++++++++++++++ ...LL_hmi_level_in_case_more_30_sec_after.lua | 65 +++++++++++++++++ ...i_level_in_case_existed_app_in_limited.lua | 61 ++++++++++++++++ ...d_Wake_Up_resumption_LIMITED_hmi_level.lua | 66 +++++++++++++++++ ..._hmi_level_in_case_existed_app_in_full.lua | 72 +++++++++++++++++++ ...D_hmi_level_in_case_more_30_sec_before.lua | 68 ++++++++++++++++++ ...ED_hmi_level_in_case_more_30_sec_after.lua | 66 +++++++++++++++++ ...i_level_in_case_existed_app_in_limited.lua | 71 ++++++++++++++++++ ...Ignition_Off_resumption_FULL_hmi_level.lua | 58 +++++++++++++++ ...ition_Off_resumption_LIMITED_hmi_level.lua | 67 +++++++++++++++++ ..._without_disconnect_before_low_voltage.lua | 56 +++++++++++++++ ..._without_disconnect_before_low_voltage.lua | 65 +++++++++++++++++ ...level_in_case_more_30_sec_after_ing_on.lua | 66 +++++++++++++++++ ...level_in_case_more_30_sec_after_ing_on.lua | 70 ++++++++++++++++++ ...e_and_Wake_Up_no_timeout_no_resumption.lua | 68 ++++++++++++++++++ ...tage_and_Wake_Up_no_timeout_resumption.lua | 62 ++++++++++++++++ test_scripts/LowVoltage/common.lua | 53 ++++++++------ test_sets/low_voltage.txt | 18 +++++ 21 files changed, 1217 insertions(+), 23 deletions(-) create mode 100644 test_scripts/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua create mode 100644 test_scripts/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua create mode 100644 test_scripts/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua create mode 100644 test_scripts/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua create mode 100644 test_scripts/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua create mode 100644 test_scripts/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua create mode 100644 test_scripts/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua create mode 100644 test_scripts/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua create mode 100644 test_scripts/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua create mode 100644 test_scripts/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua create mode 100644 test_scripts/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua create mode 100644 test_scripts/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua create mode 100644 test_scripts/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua create mode 100644 test_scripts/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua create mode 100644 test_scripts/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua create mode 100644 test_scripts/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua create mode 100644 test_scripts/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua create mode 100644 test_scripts/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua diff --git a/test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua b/test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua index 2dc0cad90f..ae3aed5cff 100644 --- a/test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua +++ b/test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua @@ -61,6 +61,7 @@ runner.Step("PolicyTableUpdate", common.policyTableUpdate) runner.Step("Activate App", common.activateApp) runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) runner.Step("RPC Show partially", processRPCPartially) runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) runner.Step("Close mobile connection", common.cleanSessions) diff --git a/test_scripts/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua b/test_scripts/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua new file mode 100644 index 0000000000..fb85d3a092 --- /dev/null +++ b/test_scripts/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in FULL HMILevel +-- 2. App has some persistent data that can be resumed +-- 3. Mobile app is disconnected during the time frame of 30 sec (inclusive) before "SDL_LOW_VOLTAGE" unix signal from HMI +-- 4. Mobile app registers with the same hashID during 30 sec. after "WAKE_UP" unix signal in the same ignition cycle +-- 5. there is no application currently in FULL +-- SDL does: +-- 1. resume FULL HMILevel for app +-- 2. resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function addResumptionData() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.rpcCheck.AddCommand(1, 1) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App ", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Add resumption data for App ", addResumptionData) + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Wait 10 sec before LOW_VOLTAGE", common.wait, {10000}) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) +runner.Step("Wait 10 sec before registration", common.wait, {10000}) +runner.Step("Re-connect Mobile", common.connectMobile) +runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, common.checkResumptionHMILevel, "SUCCESS", 1000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua b/test_scripts/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua new file mode 100644 index 0000000000..cd40747138 --- /dev/null +++ b/test_scripts/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua @@ -0,0 +1,66 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in FULL HMILevel +-- 2. App has some persistent data that can be resumed +-- 3. Mobile app is disconnected during the time frame of 30 sec (inclusive) before "SDL_LOW_VOLTAGE" unix signal from HMI +-- 4. Mobile app registers with the same hashID during 30 sec. after "WAKE_UP" unix signal in the same ignition cycle +-- 5. there is application currently in FULL +-- SDL does: +-- 1. not resume FULL HMILevel for app +-- 2. resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function addResumptionData() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.rpcCheck.AddCommand(1, 1) +end + +local function checkResumptionHMILevel() + common.getMobileSession(1):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App ", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Add resumption data for App ", addResumptionData) + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Wait 5 sec before LOW_VOLTAGE", common.wait, {5000}) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) +runner.Step("Wait 5 sec before registration", common.wait, {5000}) +runner.Step("Re-connect Mobile", common.connectMobile) +runner.Step("Register app2", common.registerApp, { 2 }) +runner.Step("Activate app2", common.activateApp, { 2 }) +runner.Step("Re-register App , check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "SUCCESS", 10000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua b/test_scripts/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua new file mode 100644 index 0000000000..c988870d77 --- /dev/null +++ b/test_scripts/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua @@ -0,0 +1,64 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in FULL HMILevel +-- 2. App has some persistent data that can be resumed +-- 3. Mobile app is disconnected in 35 sec before "SDL_LOW_VOLTAGE" unix signal from HMI +-- 4. Mobile app registers with the same hashID during 30 sec. after "WAKE_UP" unix signal in the same ignition cycle +-- 5. there is no application currently in FULL +-- SDL does: +-- 1. not resume FULL HMILevel for app +-- 2. resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function addResumptionData() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.rpcCheck.AddCommand(1, 1) +end + +local function checkResumptionHMILevel() + common.getMobileSession(1):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + common.getHMIConnection():ExpectRequest("BasicCommunication.ActivateApp") + :Times(0) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App ", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Add resumption data for App ", addResumptionData) + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Wait 35 sec before LOW_VOLTAGE", common.wait, {35000}) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) +runner.Step("Wait 5 sec before registration", common.wait, {5000}) +runner.Step("Re-connect Mobile", common.connectMobile) +runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "SUCCESS", 5000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua b/test_scripts/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua new file mode 100644 index 0000000000..f551ba69c3 --- /dev/null +++ b/test_scripts/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua @@ -0,0 +1,65 @@ +--------------------------------------------------------------------------------------------------- +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in FULL HMILevel +-- 2. App has some persistent data that can be resumed +-- 3. Mobile app is disconnected during the time frame of 30 sec (inclusive) before "SDL_LOW_VOLTAGE" unix signal from HMI +-- 4. Mobile app registers with the same hashID in 35 sec after "WAKE_UP" unix signal in the same ignition cycle +-- 5. there is no application currently in FULL +-- SDL does: +-- 1. not resume FULL HMILevel for app +-- 2. resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function addResumptionData() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.rpcCheck.AddCommand(1, 1) +end + +local function checkResumptionHMILevel() + common.getMobileSession(1):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + common.getHMIConnection():ExpectRequest("BasicCommunication.ActivateApp") + :Times(0) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App ", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Add resumption data for App ", addResumptionData) + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Wait 5 sec before LOW_VOLTAGE", common.wait, {5000}) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) +runner.Step("Wait 35 sec before registration", common.wait, {35000}) +runner.Step("Re-connect Mobile", common.connectMobile) +runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "SUCCESS", 5000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua b/test_scripts/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua new file mode 100644 index 0000000000..948f4a9920 --- /dev/null +++ b/test_scripts/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in FULL HMILevel +-- 2. App has some persistent data that can be resumed +-- 3. Mobile app is disconnected during the time frame of 30 sec (inclusive) before "SDL_LOW_VOLTAGE" unix signal from HMI +-- 4. Mobile app registers with the same hashID during 30 sec. after "WAKE_UP" unix signal in the same ignition cycle +-- 5. there is no application currently in FULL +-- 6. there is application currently in LIMITED +-- SDL does: +-- 1. resume FULL HMILevel for app +-- 2. resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function addResumptionData() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.rpcCheck.AddCommand(1, 1) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App ", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Add resumption data for App ", addResumptionData) + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Wait 5 sec before LOW_VOLTAGE", common.wait, {5000}) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) +runner.Step("Wait 5 sec before registration", common.wait, {5000}) +runner.Step("Re-connect Mobile", common.connectMobile) +runner.Step("Register app2", common.registerApp, { 2 }) +runner.Step("Activate app2", common.activateApp, { 2 }) +runner.Step("Deactivate app2 to limited", common.deactivateAppToLimited, { 2 }) +runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, common.checkResumptionHMILevel, "SUCCESS", 1000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua b/test_scripts/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua new file mode 100644 index 0000000000..f3ab8d1fd1 --- /dev/null +++ b/test_scripts/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua @@ -0,0 +1,66 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in LIMITED HMILevel +-- 2. App has some persistent data that can be resumed +-- 3. Mobile app is disconnected during the time frame of 30 sec (inclusive) before "SDL_LOW_VOLTAGE" unix signal from HMI +-- 4. Mobile app registers with the same hashID during 30 sec. after "WAKE_UP" unix signal in the same ignition cycle +-- 5. there is no application currently in FULL/LIMITED +-- SDL does: +-- 1. resume LIMITED HMILevel for app +-- 2. resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Functions ]] +local function addResumptionData() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.rpcCheck.AddCommand(1, 1) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +local function checkResumptionHMILevel() + common.getMobileSession(1):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE" }, + { hmiLevel = "LIMITED", systemContext = "MAIN", audioStreamingState = "AUDIBLE" }) + :Times(2) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Deactivate app to limited", common.deactivateAppToLimited, { 1 }) +runner.Step("Add resumption data for App ", addResumptionData) + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Wait 10 sec before LOW_VOLTAGE", common.wait, {10000}) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) +runner.Step("Wait 10 sec before registration", common.wait, {10000}) +runner.Step("Re-connect Mobile", common.connectMobile) +runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "SUCCESS", 1000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua b/test_scripts/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua new file mode 100644 index 0000000000..9e4759ca03 --- /dev/null +++ b/test_scripts/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua @@ -0,0 +1,72 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in LIMITED HMILevel +-- 2. App has some persistent data that can be resumed +-- 3. Mobile app is disconnected during the time frame of 30 sec (inclusive) before "SDL_LOW_VOLTAGE" unix signal from HMI +-- 4. Mobile app registers with the same hashID during 30 sec. after "WAKE_UP" unix signal in the same ignition cycle +-- 5. there is application currently in FULL +-- SDL does: +-- 1. not resume LIMITED HMILevel for app +-- 2. resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Functions ]] +local function addResumptionData() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.rpcCheck.AddCommand(1, 1) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +local function checkResumptionHMILevel() + common.getMobileSession(1):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE" }) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :Times(0) + common.getHMIConnection():ExpectRequest("BasicCommunication.OnResumeAudioSource") + :Times(0) + common.getHMIConnection():ExpectRequest("BasicCommunication.ActivateApp") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App ", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Deactivate app to limited", common.deactivateAppToLimited, { 1 }) +runner.Step("Add resumption data for App ", addResumptionData) + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Wait 5 sec before LOW_VOLTAGE", common.wait, {5000}) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) +runner.Step("Wait 5 sec before registration", common.wait, {5000}) +runner.Step("Re-connect Mobile", common.connectMobile) +runner.Step("Register app2", common.registerApp, { 2 }) +runner.Step("Activate app2", common.activateApp, { 2 }) +runner.Step("Re-register App , check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "SUCCESS", 10000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua b/test_scripts/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua new file mode 100644 index 0000000000..a9291ac3f6 --- /dev/null +++ b/test_scripts/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua @@ -0,0 +1,68 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in LIMITED HMILevel +-- 2. App has some persistent data that can be resumed +-- 3. Mobile app is disconnected in 35 sec before "SDL_LOW_VOLTAGE" unix signal from HMI +-- 4. Mobile app registers with the same hashID during 30 sec. after "WAKE_UP" unix signal in the same ignition cycle +-- 5. there is no application currently in FULL/LIMITED +-- SDL does: +-- 1. not resume LIMITED HMILevel for app +-- 2. resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Functions ]] +local function addResumptionData() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.rpcCheck.AddCommand(1, 1) +end + +local function checkResumptionHMILevel() + common.getMobileSession(1):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + common.getHMIConnection():ExpectRequest("BasicCommunication.OnResumeAudioSource") + :Times(0) + common.getHMIConnection():ExpectRequest("BasicCommunication.ActivateApp") + :Times(0) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App ", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Deactivate app to limited", common.deactivateAppToLimited, { 1 }) +runner.Step("Add resumption data for App ", addResumptionData) + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Wait 35 sec before LOW_VOLTAGE", common.wait, {35000}) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) +runner.Step("Wait 5 sec before registration", common.wait, {5000}) +runner.Step("Re-connect Mobile", common.connectMobile) +runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "SUCCESS", 5000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua b/test_scripts/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua new file mode 100644 index 0000000000..dc1ed0ff06 --- /dev/null +++ b/test_scripts/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua @@ -0,0 +1,66 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in LIMITED HMILevel +-- 2. App has some persistent data that can be resumed +-- 3. Mobile app is disconnected during the time frame of 30 sec (inclusive) before "SDL_LOW_VOLTAGE" unix signal from HMI +-- 4. Mobile app registers with the same hashID in 35 sec after "WAKE_UP" unix signal in the same ignition cycle +-- 5. there is no application currently in FULL/LIMITED +-- SDL does: +-- 1. not resume LIMITED HMILevel for app +-- 2. resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Functions ]] +local function addResumptionData() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.rpcCheck.AddCommand(1, 1) +end + +local function checkResumptionHMILevel() + common.getMobileSession(1):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + common.getHMIConnection():ExpectRequest("BasicCommunication.OnResumeAudioSource") + :Times(0) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App ", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Deactivate app to limited", common.deactivateAppToLimited, { 1 }) +runner.Step("Add resumption data for App ", addResumptionData) + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Wait 5 sec before LOW_VOLTAGE", common.wait, {5000}) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) +runner.Step("Wait 35 sec before registration", common.wait, {35000}) +runner.Step("Re-connect Mobile", common.connectMobile) +runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "SUCCESS", 5000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua b/test_scripts/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua new file mode 100644 index 0000000000..85c39cf812 --- /dev/null +++ b/test_scripts/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua @@ -0,0 +1,71 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in LIMITED HMILevel +-- 2. App has some persistent data that can be resumed +-- 2. Mobile app is disconnected during the time frame of 30 sec (inclusive) before "SDL_LOW_VOLTAGE" unix signal from HMI +-- 3. Mobile app registers with the same hashID during 30 sec. after "WAKE_UP" unix signal in the same ignition cycle +-- 4. there is application currently in LIMITED +-- SDL does: +-- 1. not resume LIMITED HMILevel for app +-- 2. resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Functions ]] +local function addResumptionData() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.rpcCheck.AddCommand(1, 1) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +local function checkResumptionHMILevel() + common.getMobileSession(1):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + common.getMobileSession(2):ExpectNotification("OnHMIStatus") + :Times(0) + common.getHMIConnection():ExpectRequest("BasicCommunication.OnResumeAudioSource") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App ", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Deactivate app to limited", common.deactivateAppToLimited, {1}) +runner.Step("Add resumption data for App ", addResumptionData) + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Wait 5 sec before LOW_VOLTAGE", common.wait, {5000}) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) +runner.Step("Wait 5 sec before registration", common.wait, {5000}) +runner.Step("Re-connect Mobile", common.connectMobile) +runner.Step("Register app2", common.registerApp, { 2 }) +runner.Step("Activate app2", common.activateApp, { 2 }) +runner.Step("Deactivate app2 to limited", common.deactivateAppToLimited, {2}) +runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "SUCCESS", 10000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua b/test_scripts/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua new file mode 100644 index 0000000000..83733614fb --- /dev/null +++ b/test_scripts/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua @@ -0,0 +1,58 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in FULL HMILevel +-- 2. App has some persistent data that can be resumed +-- 3. Mobile app is disconnected during the time frame of 30 sec (inclusive) before "SDL_LOW_VOLTAGE" unix signal from HMI +-- 4. "IGNITION_OFF" unix signal from HMI +-- 5. IGNITION_ON is performed +-- 6. Mobile app registers with the same hashID in next ignition cycle +-- 7. there is no application currently in FULL +-- SDL does: +-- 1. resume FULL HMILevel for app +-- 2. resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function addResumptionData() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.rpcCheck.AddCommand(1, 1) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App ", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Add resumption data for App ", addResumptionData) + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Wait 5 sec before LOW_VOLTAGE", common.wait, {5000}) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send IGNITION_OFF signal", common.sendIgnitionOffSignal) +runner.Step("Ignition On", common.start) +runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, common.checkResumptionHMILevel, "SUCCESS", 5000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua b/test_scripts/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua new file mode 100644 index 0000000000..ae645a2993 --- /dev/null +++ b/test_scripts/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua @@ -0,0 +1,67 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in LIMITED HMILevel +-- 2. App has some persistent data that can be resumed +-- 3. Mobile app is disconnected during the time frame of 30 sec (inclusive) before "SDL_LOW_VOLTAGE" unix signal from HMI +-- 4. "IGNITION_OFF" unix signal from HMI +-- 5. IGNITION_ON is performed +-- 6. Mobile app registers with the same hashID in next ignition cycle +-- 7. there is no application currently in FULL/LIMITED +-- SDL does: +-- 1. resume LIMITED HMILevel for app +-- 2. resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Functions ]] +local function addResumptionData() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.rpcCheck.AddCommand(1, 1) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +local function checkResumptionHMILevel() + common.getMobileSession(1):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE" }, + { hmiLevel = "LIMITED", systemContext = "MAIN", audioStreamingState = "AUDIBLE" }) + :Times(2) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App ", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Deactivate app to limited", common.deactivateAppToLimited, { 1 }) +runner.Step("Add resumption data for App ", addResumptionData) + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Wait 5 sec before LOW_VOLTAGE", common.wait, {5000}) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send IGNITION_OFF signal", common.sendIgnitionOffSignal) +runner.Step("Ignition On", common.start) +runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "SUCCESS", 5000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua b/test_scripts/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua new file mode 100644 index 0000000000..9469564e94 --- /dev/null +++ b/test_scripts/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in FULL HMILevel +-- 2. App has some persistent data that can be resumed +-- 3. "SDL_LOW_VOLTAGE" unix signal from HMI +-- 4. Mobile app registers with the same hashID during 30 sec. after "WAKE_UP" unix signal in the same ignition cycle +-- 5. there is no application currently in FULL +-- SDL does: +-- 1. resume FULL HMILevel for app +-- 2. resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function addResumptionData() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.rpcCheck.AddCommand(1, 1) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App ", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Add resumption data for App ", addResumptionData) + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) +runner.Step("Clean sessions", common.cleanSessions) +runner.Step("Wait 10 sec before registration", common.wait, {10000}) +runner.Step("Re-connect Mobile", common.connectMobile) +runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, common.checkResumptionHMILevel, "SUCCESS", 1000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua b/test_scripts/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua new file mode 100644 index 0000000000..6cda0a3e65 --- /dev/null +++ b/test_scripts/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua @@ -0,0 +1,65 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in LIMITED HMILevel +-- 2. App has some persistent data that can be resumed +-- 3. "SDL_LOW_VOLTAGE" unix signal from HMI +-- 4. Mobile app registers with the same hashID during 30 sec. after "WAKE_UP" unix signal in the same ignition cycle +-- 5. there is no application currently in FULL/LIMITED +-- SDL does: +-- 1. resume LIMITED HMILevel for app +-- 2. resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Functions ]] +local function addResumptionData() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.rpcCheck.AddCommand(1, 1) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +local function checkResumptionHMILevel() + common.getMobileSession(1):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE" }, + { hmiLevel = "LIMITED", systemContext = "MAIN", audioStreamingState = "AUDIBLE" }) + :Times(2) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Deactivate app to limited", common.deactivateAppToLimited, { 1 }) +runner.Step("Add resumption data for App ", addResumptionData) + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) +runner.Step("Clean sessions", common.cleanSessions) +runner.Step("Wait 10 sec before registration", common.wait, {10000}) +runner.Step("Re-connect Mobile", common.connectMobile) +runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "SUCCESS", 1000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua b/test_scripts/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua new file mode 100644 index 0000000000..ccd622d064 --- /dev/null +++ b/test_scripts/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua @@ -0,0 +1,66 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in FULL HMILevel +-- 2. App has some persistent data that can be resumed +-- 3. Mobile app is disconnected during the time frame of 30 sec (inclusive) before "SDL_LOW_VOLTAGE" unix signal from HMI +-- 4. "IGNITION_OFF" unix signal from HMI +-- 5. IGNITION_ON is performed +-- 6. Mobile app registers with the same hashID in next ignition cycle after 35 seconds after ignition on +-- 7. there is no application currently in FULL +-- SDL does: +-- 1. not resume FULL HMILevel for app +-- 2. resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function addResumptionData() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.rpcCheck.AddCommand(1, 1) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +local function checkResumptionHMILevel() + common.getMobileSession(1):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + common.getHMIConnection():ExpectRequest("BasicCommunication.ActivateApp") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App ", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Add resumption data for App ", addResumptionData) + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Wait 5 sec before LOW_VOLTAGE", common.wait, {5000}) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send IGNITION_OFF signal", common.sendIgnitionOffSignal) +runner.Step("Ignition On", common.start) +runner.Step("Wait 35 sec after IGNITION_ON", common.wait, {35000}) +runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "SUCCESS", 5000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua b/test_scripts/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua new file mode 100644 index 0000000000..53cd000655 --- /dev/null +++ b/test_scripts/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in LIMITED HMILevel +-- 2. App has some persistent data that can be resumed +-- 3. Mobile app is disconnected during the time frame of 30 sec (inclusive) before "SDL_LOW_VOLTAGE" unix signal from HMI +-- 4. "IGNITION_OFF" unix signal from HMI +-- 5. IGNITION_ON is performed +-- 6. Mobile app registers with the same hashID in next ignition cycle after 35 seconds after ignition on +-- 7. there is no application currently in FULL/LIMITED +-- SDL does: +-- 1. not resume LIMITED HMILevel for app +-- 2. resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Functions ]] +local function addResumptionData() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.rpcCheck.AddCommand(1, 1) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +local function checkResumptionHMILevel() + common.getMobileSession(1):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + common.getHMIConnection():ExpectRequest("BasicCommunication.OnResumeAudioSource") + :Times(0) + common.getHMIConnection():ExpectRequest("BasicCommunication.ActivateApp") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App ", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Deactivate app to limited", common.deactivateAppToLimited, { 1 }) +runner.Step("Add resumption data for App ", addResumptionData) + +runner.Title("Test") +runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) +runner.Step("Close mobile connection", common.cleanSessions) +runner.Step("Wait 5 sec before LOW_VOLTAGE", common.wait, {5000}) +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send IGNITION_OFF signal", common.sendIgnitionOffSignal) +runner.Step("Ignition On", common.start) +runner.Step("Wait 35 sec after IGNITION_ON", common.wait, {35000}) +runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "SUCCESS", 5000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua b/test_scripts/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua new file mode 100644 index 0000000000..b12c18edd9 --- /dev/null +++ b/test_scripts/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua @@ -0,0 +1,68 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in FULL HMILevel +-- 2. App sends AddCommand, however SDL is not saved resumption data since timer (10s) has not expired yet +-- 3. SDL get LOW_VOLTAGE signal +-- 4. App closes connection +-- 5. And then SDL get WAKE_UP signal +-- SDL does: +-- 1. not resume FULL HMILevel for app +-- 2. not resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function addCommand() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.getHMIConnection():ExpectRequest("VR.AddCommand") + :Times(0) +end + +local function checkResumptionHMILevel() + common.getHMIConnection():ExpectRequest("BasicCommunication.ActivateApp") + :Times(0) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID == common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with the same HMI App Id" + end + return true +end + +local function sendWakeUpSignal() + common.cleanSessions() + common.sendWakeUpSignal() + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppUnregistered") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App ", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Add command data for App ", addCommand) + +runner.Title("Test") +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send WAKE_UP signal", sendWakeUpSignal) +runner.Step("Re-connect Mobile", common.connectMobile) +runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "RESUME_FAILED", 11000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua b/test_scripts/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua new file mode 100644 index 0000000000..61f1537a46 --- /dev/null +++ b/test_scripts/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua @@ -0,0 +1,62 @@ +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is in FULL HMILevel +-- 2. App sends AddCommand, however SDL is not saved resumption data since timer (10s) has not expired yet +-- 3. SDL get LOW_VOLTAGE signal +-- 4. And then SDL get WAKE_UP signal +-- SDL does: +-- 1. save resumption data +-- 2. resume FULL HMILevel for app +-- 3. resume persistent data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/LowVoltage/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function addCommand() + common.rpcSend.AddCommand(1, 1) +end + +local function checkResumptionData() + common.rpcCheck.AddCommand(1, 1) +end + +local function checkAppId(pAppId, pData) + if pData.params.application.appID ~= common.getHMIAppId(pAppId) then + return false, "App " .. pAppId .. " is registered with not the same HMI App Id" + end + return true +end + +local function sendWakeUpSignal() + common.sendWakeUpSignal() + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppUnregistered", { + unexpectedDisconnect = true, + appID = common.getHMIAppId() + }) + common.cleanSessions() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile", common.start) +runner.Step("Register App ", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate) +runner.Step("Activate app", common.activateApp) +runner.Step("Add command data for App ", addCommand) + +runner.Title("Test") +runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) +runner.Step("Send WAKE_UP signal", sendWakeUpSignal) +runner.Step("Re-connect Mobile", common.connectMobile) +runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { + 1, checkAppId, checkResumptionData, common.checkResumptionHMILevel, "SUCCESS", 1000 +}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/common.lua b/test_scripts/LowVoltage/common.lua index 8eb7bf2cfe..7d78cc89ae 100644 --- a/test_scripts/LowVoltage/common.lua +++ b/test_scripts/LowVoltage/common.lua @@ -3,6 +3,7 @@ --------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 +config.ExitOnCrash = false --[[ Required Shared libraries ]] local commonFunctions = require('user_modules/shared_testcases/commonFunctions') @@ -23,8 +24,8 @@ m.wait = utils.wait --[[ Constants ]] m.appParams = { - [1] = { appHMIType = "MEDIA", isMediaApplication = false }, - [2] = { appHMIType = "DEFAULT", isMediaApplication = true }, + [1] = { appHMIType = "DEFAULT", isMediaApplication = false }, + [2] = { appHMIType = "MEDIA", isMediaApplication = true }, [3] = { appHMIType = "DEFAULT", isMediaApplication = false }, [4] = { appHMIType = "DEFAULT", isMediaApplication = false } } @@ -44,7 +45,6 @@ for i = 1, 4 do end --[[ Variables ]] -local isMobileConnected = false local grammarId = {} local hashId = {} local origGetMobileSession = actions.getMobileSession @@ -121,21 +121,11 @@ end --! @return: none --]] function m.cleanSessions() - if isMobileConnected == true then - EXPECT_EVENT(events.disconnectedEvent, "Disconnected") - :Do(function() - isMobileConnected = false - utils.cprint(35, "Mobile disconnected") - end) - end - local function toRun() - for i = 1, m.getAppsCount() do - test.mobileSession[i] = nil - utils.cprint(35, "Mobile session " .. i .. " deleted") - end - test.mobileConnection:Close() + for i = 1, m.getAppsCount() do + test.mobileSession[i] = nil + utils.cprint(35, "Mobile session " .. i .. " deleted") end - RUN_AFTER(toRun, 1000) + test.mobileConnection:Close() utils.wait() end @@ -248,6 +238,7 @@ end --]] function m.sendLowVoltageSignal() m.sendSignal("LOW_VOLTAGE") + m.wait() end --[[ @sendIgnitionOffSignal: send 'IGNITION_OFF' signal @@ -255,14 +246,17 @@ end --! @return: none --]] function m.sendIgnitionOffSignal() - SDL:DeleteFile() m.sendSignal("IGNITION_OFF") - local function toRun() - SDL:StopSDL() - waitUntilSDLLoggerIsClosed() + os.execute("sleep 1") + local count = 0 + while SDL:CheckStatusSDL() == SDL.RUNNING do + count = count + 1 + if count == 10 then + SDL:StopSDL() + waitUntilSDLLoggerIsClosed() + end + os.execute("sleep 1") end - RUN_AFTER(toRun, 1000) - utils.wait() end --[[ @sendWakeUpSignal: send 'WAKE_UP' signal @@ -280,12 +274,14 @@ end --]] function m.waitUntilResumptionDataIsStored() utils.cprint(35, "Wait ...") + local timeoutToSafe = commonFunctions:read_parameter_from_smart_device_link_ini("AppSavePersistentDataTimeout") local fileName = commonPreconditions:GetPathToSDL() .. commonFunctions:read_parameter_from_smart_device_link_ini("AppInfoStorage") local function isFileExist() local f = io.open(fileName, "r") if f ~= nil then io.close(f) + m.wait(timeoutToSafe + 1000) return true else return false @@ -475,4 +471,15 @@ function m.checkResumptionHMILevel(pAppId) f[pAppId]() end +--[[ @deactivateAppToLimited: bring app to LIMITED HMI level +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: none +--]] +function m.deactivateAppToLimited(pAppId) + m.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", {appID = m.getHMIAppId(pAppId)}) + m.getMobileSession(pAppId):ExpectNotification("OnHMIStatus", + {hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN"}) +end + return m diff --git a/test_sets/low_voltage.txt b/test_sets/low_voltage.txt index 3aa5170f44..bb807c2130 100644 --- a/test_sets/low_voltage.txt +++ b/test_sets/low_voltage.txt @@ -3,3 +3,21 @@ ./test_scripts/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua ./test_scripts/LowVoltage/004_App_unregister_itself_gracefully.lua ./test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua +./test_scripts/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua +./test_scripts/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua +./test_scripts/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua +./test_scripts/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua +./test_scripts/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua +./test_scripts/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua +./test_scripts/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua +./test_scripts/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua +./test_scripts/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua +./test_scripts/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua +./test_scripts/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua +./test_scripts/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua +./test_scripts/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua +./test_scripts/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua +./test_scripts/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua +./test_scripts/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua +./test_scripts/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua +./test_scripts/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua From 2ca05fe775ae4f8e88dc016674c9ae444f979de2 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 25 Jul 2018 15:49:55 +0300 Subject: [PATCH 491/681] Initial scripts updating DOP value range feature --- .../DOP/001_GVD_inbound_max_value_SUCCESS.lua | 49 +++++++++++++++++ ...2_GVD_outbound_max_value_GENERIC_ERROR.lua | 50 +++++++++++++++++ .../003_GVD_missing_one_parameter_SUCCESS.lua | 49 +++++++++++++++++ .../DOP/004_OVD_inbound_max_value_SUCCESS.lua | 46 ++++++++++++++++ .../005_OVD_outbound_max_value_ignored.lua | 47 ++++++++++++++++ .../006_OVD_missing_one_parameter_SUCCESS.lua | 45 +++++++++++++++ .../DOP/007_GVD_all_parameters_SUCCESS.lua | 43 +++++++++++++++ ...008_GVD_missing_all_parameters_SUCCESS.lua | 49 +++++++++++++++++ .../DOP/009_OVD_all_parameters_SUCCESS.lua | 39 +++++++++++++ ...010_OVD_missing_all_parameters_SUCCESS.lua | 45 +++++++++++++++ test_scripts/API/VehicleData/DOP/common.lua | 55 +++++++++++++++++++ test_sets/updating_dop_value_range.txt | 10 ++++ 12 files changed, 527 insertions(+) create mode 100644 test_scripts/API/VehicleData/DOP/001_GVD_inbound_max_value_SUCCESS.lua create mode 100644 test_scripts/API/VehicleData/DOP/002_GVD_outbound_max_value_GENERIC_ERROR.lua create mode 100644 test_scripts/API/VehicleData/DOP/003_GVD_missing_one_parameter_SUCCESS.lua create mode 100644 test_scripts/API/VehicleData/DOP/004_OVD_inbound_max_value_SUCCESS.lua create mode 100644 test_scripts/API/VehicleData/DOP/005_OVD_outbound_max_value_ignored.lua create mode 100644 test_scripts/API/VehicleData/DOP/006_OVD_missing_one_parameter_SUCCESS.lua create mode 100644 test_scripts/API/VehicleData/DOP/007_GVD_all_parameters_SUCCESS.lua create mode 100644 test_scripts/API/VehicleData/DOP/008_GVD_missing_all_parameters_SUCCESS.lua create mode 100644 test_scripts/API/VehicleData/DOP/009_OVD_all_parameters_SUCCESS.lua create mode 100644 test_scripts/API/VehicleData/DOP/010_OVD_missing_all_parameters_SUCCESS.lua create mode 100644 test_scripts/API/VehicleData/DOP/common.lua create mode 100644 test_sets/updating_dop_value_range.txt diff --git a/test_scripts/API/VehicleData/DOP/001_GVD_inbound_max_value_SUCCESS.lua b/test_scripts/API/VehicleData/DOP/001_GVD_inbound_max_value_SUCCESS.lua new file mode 100644 index 0000000000..ee1faa275e --- /dev/null +++ b/test_scripts/API/VehicleData/DOP/001_GVD_inbound_max_value_SUCCESS.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0175-Updating-DOP-value-range-for-GPS-notification.md +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. App sends 'GetVehicleData' request with gps=true +-- 2. And SDL transfers this request to HMI +-- 3. And HMI responds with gps data with one of the following parameters set to inbound max value (1000): +-- "pdop", "hdop", "vdop" +-- SDL does: +-- 1. Process this response and transfer it to App +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/API/VehicleData/DOP/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local value = 1000 + +--[[ Local Functions ]] +local function sendGetVehicleData(pParam) + local gpsData = common.getGPSData() + gpsData[pParam] = value + local cid = common.getMobileSession():SendRPC("GetVehicleData", { gps = true }) + common.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData", { gps = true }) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { gps = gpsData }) + end) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", gps = gpsData }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, p in pairs(common.params) do + runner.Step("Send GetVehicleData param " .. p .. "=" .. tostring(value), sendGetVehicleData, { p }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) + diff --git a/test_scripts/API/VehicleData/DOP/002_GVD_outbound_max_value_GENERIC_ERROR.lua b/test_scripts/API/VehicleData/DOP/002_GVD_outbound_max_value_GENERIC_ERROR.lua new file mode 100644 index 0000000000..a6e1dc424b --- /dev/null +++ b/test_scripts/API/VehicleData/DOP/002_GVD_outbound_max_value_GENERIC_ERROR.lua @@ -0,0 +1,50 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0175-Updating-DOP-value-range-for-GPS-notifiscation.md +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. App sends 'GetVehicleData' request with gps=true +-- 2. And SDL transfers this request to HMI +-- 3. And HMI responds with gps data with one of the following parameters set to outbound max value (1001): +-- "pdop", "hdop", "vdop" +-- SDL does: +-- 1. Ignore this response +-- 2. Respond GENERIC_ERROR to mobile +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/API/VehicleData/DOP/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local value = 1001 + +--[[ Local Functions ]] +local function sendGetVehicleData(pParam) + local gpsData = common.getGPSData() + gpsData[pParam] = value + local cid = common.getMobileSession():SendRPC("GetVehicleData", { gps = true }) + common.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { gps = gpsData }) + end) + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, p in pairs(common.params) do + runner.Step("Send GetVehicleData param " .. p .. "=" .. tostring(value), sendGetVehicleData, { p }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) + diff --git a/test_scripts/API/VehicleData/DOP/003_GVD_missing_one_parameter_SUCCESS.lua b/test_scripts/API/VehicleData/DOP/003_GVD_missing_one_parameter_SUCCESS.lua new file mode 100644 index 0000000000..4df50b47f3 --- /dev/null +++ b/test_scripts/API/VehicleData/DOP/003_GVD_missing_one_parameter_SUCCESS.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0175-Updating-DOP-value-range-for-GPS-notification.md +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. App sends 'GetVehicleData' request with gps=true +-- 2. And SDL transfers this request to HMI +-- 3. And HMI responds with gps data without one of the following parameters: +-- "pdop", "hdop", "vdop" +-- SDL does: +-- 1. Process this response and transfer it to App +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/API/VehicleData/DOP/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local value = nil + +--[[ Local Functions ]] +local function sendGetVehicleData(pParam) + local gpsData = common.getGPSData() + gpsData[pParam] = value + local cid = common.getMobileSession():SendRPC("GetVehicleData", { gps = true }) + common.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData", { gps = true }) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { gps = gpsData }) + end) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", gps = gpsData }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, p in pairs(common.params) do + runner.Step("Send GetVehicleData param " .. p .. "=" .. tostring(value), sendGetVehicleData, { p }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) + diff --git a/test_scripts/API/VehicleData/DOP/004_OVD_inbound_max_value_SUCCESS.lua b/test_scripts/API/VehicleData/DOP/004_OVD_inbound_max_value_SUCCESS.lua new file mode 100644 index 0000000000..ca9ab58f03 --- /dev/null +++ b/test_scripts/API/VehicleData/DOP/004_OVD_inbound_max_value_SUCCESS.lua @@ -0,0 +1,46 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0175-Updating-DOP-value-range-for-GPS-notification.md +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is subscribed to get gps data +-- 2. And HMI sends OnVehicleData with inbound max value (1000) for the one of the following parameters: +-- "pdop", "hdop", "vdop" +-- SDL does: +-- 1. Process this notification and transfer it to mobile +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/API/VehicleData/DOP/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local value = 1000 + +--[[ Local Functions ]] +local function sendOnVehicleData(pParam) + local gpsData = common.getGPSData() + gpsData[pParam] = value + common.getHMIConnection():SendNotification("VehicleInfo.OnVehicleData", { gps = gpsData }) + common.getMobileSession():ExpectNotification("OnVehicleData", { gps = gpsData }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Subscribe GPS VehicleData", common.subscribeVehicleData) +for _, p in pairs(common.params) do + runner.Step("Send OnVehicleData param " .. p .. "=" .. tostring(value), sendOnVehicleData, { p }) +end + + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) + diff --git a/test_scripts/API/VehicleData/DOP/005_OVD_outbound_max_value_ignored.lua b/test_scripts/API/VehicleData/DOP/005_OVD_outbound_max_value_ignored.lua new file mode 100644 index 0000000000..1d81e0713c --- /dev/null +++ b/test_scripts/API/VehicleData/DOP/005_OVD_outbound_max_value_ignored.lua @@ -0,0 +1,47 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0175-Updating-DOP-value-range-for-GPS-notification.md +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is subscribed to get gps data +-- 2. And HMI sends OnVehicleData with outbound max value (1001) for the one of the following parameters: +-- "pdop", "hdop", "vdop" +-- SDL does: +-- 1. Ignore this notification +-- 2. Not send OnVehicleData notification to mobile +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/API/VehicleData/DOP/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local value = 1001 + +--[[ Local Functions ]] +local function sendOnVehicleData(pParam) + local gpsData = common.getGPSData() + gpsData[pParam] = value + common.getHMIConnection():SendNotification("VehicleInfo.OnVehicleData", { gps = gpsData }) + common.getMobileSession():ExpectNotification("OnVehicleData") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Subscribe GPS VehicleData", common.subscribeVehicleData) +for _, p in pairs(common.params) do + runner.Step("Send GetVehicleData param " .. p .. "=" .. tostring(value), sendOnVehicleData, { p }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) + diff --git a/test_scripts/API/VehicleData/DOP/006_OVD_missing_one_parameter_SUCCESS.lua b/test_scripts/API/VehicleData/DOP/006_OVD_missing_one_parameter_SUCCESS.lua new file mode 100644 index 0000000000..59ed4b02d2 --- /dev/null +++ b/test_scripts/API/VehicleData/DOP/006_OVD_missing_one_parameter_SUCCESS.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0175-Updating-DOP-value-range-for-GPS-notification.md +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is subscribed to get gps data +-- 2. And HMI sends OnVehicleData without one of the following parameters: +-- "pdop", "hdop", "vdop" +-- SDL does: +-- 1. Process this notification and transfer it to mobile +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/API/VehicleData/DOP/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local value = nil + +--[[ Local Functions ]] +local function sendOnVehicleData(pParam) + local gpsData = common.getGPSData() + gpsData[pParam] = value + common.getHMIConnection():SendNotification("VehicleInfo.OnVehicleData", { gps = gpsData }) + common.getMobileSession():ExpectNotification("OnVehicleData", { gps = gpsData }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Subscribe GPS VehicleData", common.subscribeVehicleData) +for _, p in pairs(common.params) do + runner.Step("Send OnVehicleData param " .. p .. "=" .. tostring(value), sendOnVehicleData, { p }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) + diff --git a/test_scripts/API/VehicleData/DOP/007_GVD_all_parameters_SUCCESS.lua b/test_scripts/API/VehicleData/DOP/007_GVD_all_parameters_SUCCESS.lua new file mode 100644 index 0000000000..6aa73c9458 --- /dev/null +++ b/test_scripts/API/VehicleData/DOP/007_GVD_all_parameters_SUCCESS.lua @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0175-Updating-DOP-value-range-for-GPS-notification.md +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. App sends 'GetVehicleData' request with gps=true +-- 2. And SDL transfers this request to HMI +-- 3. And HMI responds with gps data with all of the following parameters set: +-- "pdop", "hdop", "vdop" +-- SDL does: +-- 1. Process this response and transfer it to App +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/API/VehicleData/DOP/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function sendGetVehicleData() + local gpsData = common.getGPSData() + local cid = common.getMobileSession():SendRPC("GetVehicleData", { gps = true }) + common.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData", { gps = true }) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { gps = gpsData }) + end) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", gps = gpsData }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Send GetVehicleData all params", sendGetVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) + diff --git a/test_scripts/API/VehicleData/DOP/008_GVD_missing_all_parameters_SUCCESS.lua b/test_scripts/API/VehicleData/DOP/008_GVD_missing_all_parameters_SUCCESS.lua new file mode 100644 index 0000000000..7397280a76 --- /dev/null +++ b/test_scripts/API/VehicleData/DOP/008_GVD_missing_all_parameters_SUCCESS.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0175-Updating-DOP-value-range-for-GPS-notification.md +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. App sends 'GetVehicleData' request with gps=true +-- 2. And SDL transfers this request to HMI +-- 3. And HMI responds with gps data without all following parameters: +-- "pdop", "hdop", "vdop" +-- SDL does: +-- 1. Process this response and transfer it to App +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/API/VehicleData/DOP/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local value = nil + +--[[ Local Functions ]] +local function sendGetVehicleData() + local gpsData = common.getGPSData() + for _, p in pairs(common.params) do + gpsData[p] = value + end + local cid = common.getMobileSession():SendRPC("GetVehicleData", { gps = true }) + common.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData", { gps = true }) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { gps = gpsData }) + end) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", gps = gpsData }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Send GetVehicleData all params", sendGetVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) + diff --git a/test_scripts/API/VehicleData/DOP/009_OVD_all_parameters_SUCCESS.lua b/test_scripts/API/VehicleData/DOP/009_OVD_all_parameters_SUCCESS.lua new file mode 100644 index 0000000000..d0aab6e609 --- /dev/null +++ b/test_scripts/API/VehicleData/DOP/009_OVD_all_parameters_SUCCESS.lua @@ -0,0 +1,39 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0175-Updating-DOP-value-range-for-GPS-notification.md +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is subscribed to get gps data +-- 2. And HMI sends OnVehicleData with all of the following parameters: +-- "pdop", "hdop", "vdop" +-- SDL does: +-- 1. Process this notification and transfer it to mobile +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/API/VehicleData/DOP/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function sendOnVehicleData() + local gpsData = common.getGPSData() + common.getHMIConnection():SendNotification("VehicleInfo.OnVehicleData", { gps = gpsData }) + common.getMobileSession():ExpectNotification("OnVehicleData", { gps = gpsData }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Subscribe GPS VehicleData", common.subscribeVehicleData) +runner.Step("Send OnVehicleData all params", sendOnVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) + diff --git a/test_scripts/API/VehicleData/DOP/010_OVD_missing_all_parameters_SUCCESS.lua b/test_scripts/API/VehicleData/DOP/010_OVD_missing_all_parameters_SUCCESS.lua new file mode 100644 index 0000000000..24c9f87a66 --- /dev/null +++ b/test_scripts/API/VehicleData/DOP/010_OVD_missing_all_parameters_SUCCESS.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0175-Updating-DOP-value-range-for-GPS-notification.md +--------------------------------------------------------------------------------------------------- +-- In case: +-- 1. Mobile app is subscribed to get gps data +-- 2. And HMI sends OnVehicleData without all following parameters: +-- "pdop", "hdop", "vdop" +-- SDL does: +-- 1. Process this notification and transfer it to mobile +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/API/VehicleData/DOP/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local value = nil + +--[[ Local Functions ]] +local function sendOnVehicleData() + local gpsData = common.getGPSData() + for _, p in pairs(common.params) do + gpsData[p] = value + end + common.getHMIConnection():SendNotification("VehicleInfo.OnVehicleData", { gps = gpsData }) + common.getMobileSession():ExpectNotification("OnVehicleData", { gps = gpsData }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Subscribe GPS VehicleData", common.subscribeVehicleData) +runner.Step("Send OnVehicleData all params", sendOnVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) + diff --git a/test_scripts/API/VehicleData/DOP/common.lua b/test_scripts/API/VehicleData/DOP/common.lua new file mode 100644 index 0000000000..2a63ff9404 --- /dev/null +++ b/test_scripts/API/VehicleData/DOP/common.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- Common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 2 + +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") +local utils = require("user_modules/utils") +-- local test = require("user_modules/dummy_connecttest") + +--[[ Module ]] +local m = actions + +m.gpsData = { + longitudeDegrees = 10, + latitudeDegrees = 20, + utcYear = 2010, + utcMonth = 1, + utcDay = 2, + utcHours = 3, + utcMinutes = 4, + utcSeconds = 5, + compassDirection = "NORTH", + actual = true, + satellites = 6, + dimension = "2D", + altitude = 7, + heading = 8, + speed = 9, + pdop = 10, + hdop = 11, + vdop = 12 +} + +m.params = { "pdop", "hdop", "vdop" } + +function m.getGPSData() + return utils.cloneTable(m.gpsData) +end + +function m.subscribeVehicleData() + local gpsResponseData = { + dataType = "VEHICLEDATA_GPS", + resultCode = "SUCCESS" + } + local cid = m.getMobileSession():SendRPC("SubscribeVehicleData", { gps = true }) + m.getHMIConnection():ExpectRequest("VehicleInfo.SubscribeVehicleData", { gps = true }) + :Do(function(_, data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { gps = gpsResponseData }) + end) + m.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", gps = gpsResponseData }) +end + +return m diff --git a/test_sets/updating_dop_value_range.txt b/test_sets/updating_dop_value_range.txt new file mode 100644 index 0000000000..072cd8dd2b --- /dev/null +++ b/test_sets/updating_dop_value_range.txt @@ -0,0 +1,10 @@ +./test_scripts/API/VehicleData/DOP/001_GVD_inbound_max_value_SUCCESS.lua +./test_scripts/API/VehicleData/DOP/002_GVD_outbound_max_value_GENERIC_ERROR.lua +./test_scripts/API/VehicleData/DOP/003_GVD_missing_one_parameter_SUCCESS.lua +./test_scripts/API/VehicleData/DOP/004_OVD_inbound_max_value_SUCCESS.lua +./test_scripts/API/VehicleData/DOP/005_OVD_outbound_max_value_ignored.lua +./test_scripts/API/VehicleData/DOP/006_OVD_missing_one_parameter_SUCCESS.lua +./test_scripts/API/VehicleData/DOP/007_GVD_all_parameters_SUCCESS.lua +./test_scripts/API/VehicleData/DOP/008_GVD_missing_all_parameters_SUCCESS.lua +./test_scripts/API/VehicleData/DOP/009_OVD_all_parameters_SUCCESS.lua +./test_scripts/API/VehicleData/DOP/010_OVD_missing_all_parameters_SUCCESS.lua From 560f07148e53b71b5da41f73f350544807eddea6 Mon Sep 17 00:00:00 2001 From: Conlain Kelly Date: Wed, 25 Jul 2018 10:46:18 -0400 Subject: [PATCH 492/681] Add test for choice with no vrCommands, fix typo in file --- ...PerfomInteraction_PositiveCase_SUCCESS.lua | 63 ++++++++++++++++--- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua index 751562663d..027202cac8 100644 --- a/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua @@ -91,13 +91,27 @@ local requestParams = { interactionLayout = "ICON_ONLY" } +local requestParams_noVR = { + initialText = "StartPerformInteraction", + initialPrompt = initialPromptValue, + interactionMode = "BOTH", + interactionChoiceSetIDList = { + 100, 200, 300, 400 + }, + helpPrompt = helpPromptValue, + timeoutPrompt = timeoutPromptValue, + timeout = 5000, + vrHelp = vrHelpvalue, + interactionLayout = "ICON_ONLY" +} + --[[ Local Functions ]] ---! @setChoiseSet: Creates Choice structure +--! @setChoiceSet: Creates Choice structure --! @parameters: --! choiceIDValue - Id for created choice --! @return: table of created choice structure -local function setChoiseSet(choiceIDValue) +local function setChoiceSet(choiceIDValue) local temp = { { choiceID = choiceIDValue, @@ -114,6 +128,24 @@ local function setChoiseSet(choiceIDValue) return temp end +--! @setChoiceSet: Creates Choice structure without VRcommands +--! @parameters: +--! choiceIDValue - Id for created choice +--! @return: table of created choice structure +local function setChoiceSet_noVR(choiceIDValue) + local temp = { + { + choiceID = choiceIDValue, + menuName ="Choice" .. tostring(choiceIDValue), + image = { + value ="icon.png", + imageType ="STATIC", + } + } + } + return temp +end + --! @SendOnSystemContext: OnSystemContext notification --! @parameters: --! self - test object, @@ -124,11 +156,11 @@ local function SendOnSystemContext(self, ctx) { appID = commonSmoke.getHMIAppId(), systemContext = ctx }) end ---! @setExChoiseSet: ChoiceSet structure for UI.PerformInteraction request +--! @setExChoiceSet: ChoiceSet structure for UI.PerformInteraction request --! @parameters: --! choiceIDValues - value of choice id --! @return: none -local function setExChoiseSet(choiceIDValues) +local function setExChoiceSet(choiceIDValues) local exChoiceSet = { } for i = 1, #choiceIDValues do exChoiceSet[i] = { @@ -186,7 +218,7 @@ local function CreateInteractionChoiceSet(choiceSetID, self) local choiceID = choiceSetID local cid = self.mobileSession1:SendRPC("CreateInteractionChoiceSet", { interactionChoiceSetID = choiceSetID, - choiceSet = setChoiseSet(choiceID), + choiceSet = setChoiceSet(choiceID), }) EXPECT_HMICALL("VR.AddCommand", { cmdID = choiceID, @@ -199,6 +231,20 @@ local function CreateInteractionChoiceSet(choiceSetID, self) self.mobileSession1:ExpectResponse(cid, { resultCode = "SUCCESS", success = true }) end +--! @CreateInteractionChoiceSet: Creation of Choice Set with no vrCommands +--! @parameters: +--! choiceSetID - id for choice set +--! self - test object +--! @return: none +local function CreateInteractionChoiceSet_noVR(choiceSetID, self) + local choiceID = choiceSetID + local cid = self.mobileSession1:SendRPC("CreateInteractionChoiceSet", { + interactionChoiceSetID = choiceSetID, + choiceSet = setChoiceSet_noVR(choiceID), + }) + self.mobileSession1:ExpectResponse(cid, { resultCode = "SUCCESS", success = true }) +end + --! @PI_PerformViaVR_ONLY: Processing PI with interaction mode VR_ONLY with performing selection --! @parameters: --! paramsSend - parameters for PI request @@ -260,7 +306,7 @@ local function PI_PerformViaMANUAL_ONLY(paramsSend, self) end) EXPECT_HMICALL("UI.PerformInteraction", { timeout = paramsSend.timeout, - choiceSet = setExChoiseSet(paramsSend.interactionChoiceSetIDList), + choiceSet = setExChoiceSet(paramsSend.interactionChoiceSetIDList), initialText = { fieldName = "initialInteractionText", fieldText = paramsSend.initialText @@ -312,7 +358,7 @@ local function PI_PerformViaBOTH(paramsSend, self) end) EXPECT_HMICALL("UI.PerformInteraction", { timeout = paramsSend.timeout, - choiceSet = setExChoiseSet(paramsSend.interactionChoiceSetIDList), + choiceSet = setExChoiceSet(paramsSend.interactionChoiceSetIDList), initialText = { fieldName = "initialInteractionText", fieldText = paramsSend.initialText @@ -346,11 +392,14 @@ runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) runner.Step("CreateInteractionChoiceSet with id 100", CreateInteractionChoiceSet, {100}) runner.Step("CreateInteractionChoiceSet with id 200", CreateInteractionChoiceSet, {200}) runner.Step("CreateInteractionChoiceSet with id 300", CreateInteractionChoiceSet, {300}) +runner.Step("CreateInteractionChoiceSet no VR commands with id 400", CreateInteractionChoiceSet_noVR, {400}) runner.Title("Test") runner.Step("PerformInteraction with VR_ONLY interaction mode", PI_PerformViaVR_ONLY, {requestParams}) runner.Step("PerformInteraction with MANUAL_ONLY interaction mode", PI_PerformViaMANUAL_ONLY, {requestParams}) runner.Step("PerformInteraction with BOTH interaction mode", PI_PerformViaBOTH, {requestParams}) +runner.Step("PerformInteraction with MANUAL_ONLY interaction mode no VR commands", PI_PerformViaMANUAL_ONLY, {requestParams}) + runner.Title("Postconditions") runner.Step("Stop SDL", commonSmoke.postconditions) From c963879031295b34cc18530b254382c82a398dc3 Mon Sep 17 00:00:00 2001 From: Conlain Kelly Date: Wed, 25 Jul 2018 13:23:38 -0400 Subject: [PATCH 493/681] use full app id over appID --- test_scripts/Smoke/commonSmoke.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/Smoke/commonSmoke.lua b/test_scripts/Smoke/commonSmoke.lua index b8b690ef58..02f36a8352 100644 --- a/test_scripts/Smoke/commonSmoke.lua +++ b/test_scripts/Smoke/commonSmoke.lua @@ -62,7 +62,7 @@ end function commonSmoke.getMobileAppId(pAppId) if not pAppId then pAppId = 1 end - return config["application" .. pAppId].registerAppInterfaceParams.appID + return config["application" .. pAppId].registerAppInterfaceParams.fullAppID end function commonSmoke.getSelfAndParams(...) From 083f933430748e9205173ce55eb2d60731adeca0 Mon Sep 17 00:00:00 2001 From: Conlain Kelly Date: Wed, 25 Jul 2018 16:01:41 -0400 Subject: [PATCH 494/681] use full app id in more places --- ...itApplication_Unsupported_HMI_Resource.lua | 4 +- test_scripts/API/ATC_RequestType.lua | 2 +- test_scripts/API/ATF_AddCommand.lua | 64 +++++------ test_scripts/API/ATF_Alert.lua | 104 +++++++++--------- test_scripts/API/ATF_AlertManeuver.lua | 4 +- .../API/ATF_All_RPCs_and_Notifications.lua | 10 +- .../API/ATF_CreateInteractionChoiceSet.lua | 2 +- test_scripts/API/ATF_DeleteCommand.lua | 4 +- test_scripts/API/ATF_DeleteFile.lua | 2 +- test_scripts/API/ATF_DeleteSubMenu.lua | 2 +- test_scripts/API/ATF_DiagnosticMessage.lua | 2 +- test_scripts/API/ATF_EndAudioPassThru.lua | 2 +- test_scripts/API/ATF_GetWayPoints.lua | 2 +- test_scripts/API/ATF_ListFiles.lua | 14 +-- .../API/ATF_OnAppInterfaceUnregistered.lua | 4 +- ...nterfaceUnregistered_TOO_MANY_REQUESTS.lua | 2 +- test_scripts/API/ATF_OnAppUnregistered.lua | 4 +- test_scripts/API/ATF_OnButtonEvent.lua | 2 +- test_scripts/API/ATF_OnButtonPress.lua | 2 +- test_scripts/API/ATF_OnCommand.lua | 2 +- test_scripts/API/ATF_OnExitApplication.lua | 2 +- test_scripts/API/ATF_OnPermissionsChange.lua | 2 +- .../API/ATF_OnScreenPresetsAvailable.lua | 4 +- test_scripts/API/ATF_OnSystemRequest.lua | 2 +- test_scripts/API/ATF_OnTBTClientState.lua | 2 +- test_scripts/API/ATF_OnTouchEvent.lua | 2 +- test_scripts/API/ATF_OnVehicleData.lua | 4 +- test_scripts/API/ATF_OnWayPointChange.lua | 2 +- test_scripts/API/ATF_PerformAudioPassThru.lua | 2 +- test_scripts/API/ATF_PerformInteraction.lua | 2 +- test_scripts/API/ATF_PutFile.lua | 2 +- .../API/ATF_ResetGlobalProperties.lua | 2 +- test_scripts/API/ATF_ScrollableMessage.lua | 2 +- test_scripts/API/ATF_SendLocation.lua | 2 +- test_scripts/API/ATF_SetAppIcon.lua | 4 +- test_scripts/API/ATF_SetGlobalProperties.lua | 14 +-- test_scripts/API/ATF_Show.lua | 10 +- test_scripts/API/ATF_ShowConstantTBT.lua | 2 +- test_scripts/API/ATF_Speak.lua | 2 +- test_scripts/API/ATF_SystemRequest.lua | 10 +- test_scripts/API/ATF_UIChangeRegistration.lua | 52 ++++----- test_scripts/API/ATF_UnsubscribeWayPoints.lua | 2 +- test_scripts/API/ATF_UpdateTurnList.lua | 2 +- test_scripts/API/ATF_WARNINGS_result_code.lua | 2 +- ...requestSubType_with_empty_array_in_ptu.lua | 2 +- ...estSubType_with_array_of_values_in_ptu.lua | 2 +- ...mRequest_without_requestSubType_in_ptu.lua | 4 +- ...ered_with_value_list_in_requestSubType.lua | 4 +- ...red_with_empty_array_in_requestSubType.lua | 4 +- ...OnAppRegistered_without_requestSubType.lua | 2 +- ...mRequest_OEM_SPECIFIC_type_not_allowed.lua | 2 +- ...st_requestType_with_empty_array_in_ptu.lua | 2 +- ...st_requestType_with_list_of_values_ptu.lua | 2 +- ...st_requestType_without_parameter_in_pt.lua | 4 +- ...ATF_TTS_IsReady_NotRespond_Split_RPC_1.lua | 2 +- ...ATF_TTS_IsReady_NotRespond_Split_RPC_2.lua | 2 +- ...ATF_TTS_IsReady_NotRespond_Split_RPC_3.lua | 2 +- ...tRespond_Split_RPC_APPLINK_25139_RETRY.lua | 2 +- ...tRespond_Split_RPC_APPLINK_25139_SAVED.lua | 2 +- ...espond_Split_RPC_APPLINK_25139_SUCCESS.lua | 4 +- ...spond_Split_RPC_APPLINK_25139_WARNINGS.lua | 2 +- ...Split_RPC_APPLINK_25139_WRONG_LANGUAGE.lua | 2 +- test_scripts/API/System/commonSystem.lua | 4 +- .../API/VehicleData/commonVehicleData.lua | 10 +- .../ATF_Expanded_smoke_test_Genivi.lua | 2 +- .../ATF_Buttons_GetCapabilities.lua | 2 +- ...havior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua | 2 +- .../Defects/4_5/1225_FACTORY_DEFAULTS.lua | 6 +- .../Defects/4_5/1376_PTU_all_flows.lua | 4 +- .../4_5/1772_update_default_section.lua | 2 +- .../1873_Parameters_empty_in_policy_table.lua | 2 +- ..._OnVD_Parameters_empty_in_policy_table.lua | 2 +- ...Invalid_PT_after_cutting_unknow_values.lua | 6 +- .../1888_1_navi.lua | 2 +- .../1888_2_non-navi.lua | 2 +- .../1888_3_navi_audio_force_off.lua | 2 +- .../1888_4_navi_video_force_off.lua | 2 +- .../1888_5_navi_audio_force_on.lua | 2 +- .../1888_6_navi_video_force_on.lua | 2 +- test_scripts/Defects/4_5/commonDefects.lua | 12 +- ..._no_active_PerformInteraction_KEYBOARD.lua | 6 +- ..._in_case_vi_interface_is_not_available.lua | 2 +- test_scripts/Defects/commonDefects.lua | 12 +- .../Image_template/commonImageTemplate.lua | 2 +- .../Languages/ATF_OnLanguageChange.lua | 4 +- ..._OnLanguageChange_additional_languages.lua | 2 +- .../Policies/ATF_Preloaded_PT_validation.lua | 2 +- ...sponse_Notification_On_Registering_App.lua | 2 +- ...Assigned_Policy_After_App_Registration.lua | 2 +- ...6_ATF_Steal_focus_validation_false_PTU.lua | 2 +- ...007_ATF_StealFocus_validation_true_PTU.lua | 2 +- ..._external_consent_status_groups_struct.lua | 2 +- ..._external_consent_status_groups_struct.lua | 2 +- ..._external_consent_status_groups_struct.lua | 2 +- ..._external_consent_status_groups_struct.lua | 2 +- ..._external_consent_status_groups_struct.lua | 2 +- ...ATF_P_Policies_Performance_Requirement.lua | 2 +- ...NotListed_PT_DeviceConsented_SecondApp.lua | 4 +- ...tSuccessful_AppID_ListedPT_NewIgnCycle.lua | 4 +- .../124_ATF_User_requests_PTU.lua | 2 +- .../125_ATF_User_PressButton_HMI_PTU.lua | 2 +- .../127_ATF_PTS_Creation_rule.lua | 2 +- ...F_HMI_sends_GetURLs_one_app_registered.lua | 2 +- ...TF_HMI_sends_GetURLs_no_app_registered.lua | 2 +- .../132_ATF_Timeout_to_wait_response_PTU.lua | 2 +- .../133_ATF_PTU_retry_timeout_definition.lua | 2 +- ...34_ATF_WiFi_one_application_registered.lua | 2 +- .../135_ATF_PM_sends_PTS_to_HMI.lua | 2 +- ...oliciesManager_changes_status_UPDATING.lua | 2 +- .../143_ATF_PTU_validation_rules.lua | 2 +- ...Lvl_on_PTU_affected_in_FULL_or_LIMITED.lua | 4 +- ...tifying_HMI_via_OnAppPermissionChanged.lua | 2 +- ...pply_PTU_and_OnPermissionChange_notify.lua | 2 +- .../156_ATF_PTU_OnStatusUpdate_Trigger.lua | 2 +- ...F_Default_Policy_For_The_App_After_PTU.lua | 2 +- ...egister_NewApp_not_exist_inLocalPT_PTU.lua | 6 +- ...r_NewApp_not_exist_inLocalPT_FinishPTU.lua | 8 +- ...t_exist_inLocalPT_start_PTU_for_NewApp.lua | 8 +- ...tURLs_one_app_registered_urls_3default.lua | 2 +- ...egistered_urls_3default_not_registered.lua | 2 +- ...pp_registered_urls_3default_registered.lua | 2 +- ..._HMILvl_on_PTU_affected_app_in_LIMITED.lua | 4 +- ...F_OnAppPermissionConsent_without_appID.lua | 4 +- ..._ATF_OnAppPermissionConsent_with_appID.lua | 4 +- ...ATF_GetListOfPermissions_without_appID.lua | 2 +- ...85_ATF_GetListOfPermissions_with_appID.lua | 2 +- ...ation_rules_request_type_array_omitted.lua | 4 +- ...quest_type_array_has_one_invalid_value.lua | 4 +- ...pe_array_has_only_one_value_is_invalid.lua | 4 +- ...rror_counts_update_minutes_in_hmi_none.lua | 4 +- ...r_counts_update_minutes_in_hmi_limited.lua | 4 +- ...rror_counts_update_minutes_in_hmi_full.lua | 4 +- ...ounts_update_minutes_in_hmi_background.lua | 4 +- ...lidation_rules_for_optional_parameters.lua | 2 +- ...alidation_rules_for_omitted_parameters.lua | 2 +- ...lidation_rules_for_required_parameters.lua | 2 +- ...dation_rules_consumer_friendly_message.lua | 2 +- ...TF_Validate_default_hmi_appId_policies.lua | 2 +- ...278_ATF_Validate_groups_appID_policies.lua | 2 +- ...ATF_Validate_appHMIType_appID_policies.lua | 2 +- ...lidate_default_priority_preDataConsent.lua | 6 +- ...ate_nondefault_priority_preDataConsent.lua | 6 +- ...299_ATF_Memory_Kb_Constraints_Ignoring.lua | 2 +- ...s_update_app_registration_language_vui.lua | 2 +- ...plying_Heart_Beat_Timeout_Ms_After_PTU.lua | 2 +- ...TF_Check_app_registration_language_gui.lua | 4 +- ...havior_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua | 2 +- ...bad_behavior_too_many_pending_requests.lua | 2 +- ...als_for_bad_behavior_too_many_requests.lua | 2 +- ...egister_App_Interface_App_Unauthorized.lua | 2 +- ...terface_Successful_Nickname_Validation.lua | 2 +- ...Interface_Order_Of_Nickname_Validation.lua | 2 +- ..._ATF_Register_App_Interface_Disallowed.lua | 2 +- ...nterface_Case-insensitivity_Of_AppName.lua | 2 +- ...036_ATF_Change_Registration_Disallowed.lua | 2 +- ...App_Interface_Assign_Existing_Policies.lua | 2 +- ..._Interface_Case-insensitivity_Of_AppId.lua | 2 +- ...RAI_with_NULL_policies_RPCs_DISALLOWED.lua | 2 +- ..._Status_Appid_Gets_Null_In_Case_Of_PTU.lua | 2 +- ...MI_Status_Value_Of_AppId_In_PT_Is_Null.lua | 2 +- ..._Application_Which_Appid_Exists_In_LPT.lua | 2 +- ...uild_Flag_DEXTENDED_POLICY_PROPRIETARY.lua | 4 +- ..._ATF_Timeout_to_wait_response_PTU_HTTP.lua | 2 +- ...eived_PTU_From_Mobile_Application_HTTP.lua | 4 +- .../066_ATF_PTU_Validation_Failure_HTTP.lua | 4 +- ...PTU_Local_PT_Start_Retry_Sequence_HTTP.lua | 2 +- ..._PTU_PM_Sets_Status_UPDATE_NEEDED_HTTP.lua | 2 +- ...PermissionChange_Notification_App_HTTP.lua | 4 +- ...PermissionChange_Notification_HMI_HTTP.lua | 4 +- ..._Level_Affected_Apps_FULL_LIMITED_HTTP.lua | 4 +- ...PTU_In_Progress_New_App_Registers_HTTP.lua | 2 +- .../086_ATF_PTU_Merging_wtih_LPT_HTTP.lua | 8 +- ...ATF_OnStatusUpdate_Trigger_PROPRIETARY.lua | 2 +- .../094_ATF_PTS_creation_rule_PROPRIETARY.lua | 2 +- ..._exist_inLocalPT_FinishPTU_PROPRIETARY.lua | 2 +- ...101_ATF_SDL_Build_EXTENDED_POLICY_HTTP.lua | 2 +- ...changes_status_to_UPDATING_PROPRIETARY.lua | 2 +- ...ATF_PTU_Trigger_IGN_cycles_PROPRIETARY.lua | 2 +- ..._exist_inLocalPT_FinishPTU_PROPRIETARY.lua | 4 +- ...calPT_start_PTU_for_NewApp_PROPRIETARY.lua | 2 +- .../201_ATF_User_consents_permissions.lua | 2 +- .../203_ATF_Master_reset.lua | 2 +- ...13_ATF_No_user_consent_prompt_in_group.lua | 2 +- .../214_ATF_User_consent_prompt_persists.lua | 6 +- .../221_ATF_Factory_reset.lua | 4 +- ...02_disallow_flow_by_policy_for_climate.lua | 2 +- .../003_disallow_flow_by_policy_for_radio.lua | 2 +- ..._processing_button_press_for_nonRC_App.lua | 2 +- ...n_press_allowed_if_moduleType_is_empty.lua | 2 +- ...ess_disallowed_if_moduleType_is_absent.lua | 2 +- .../002_Disallow_flow_by_policy_CLIMATE.lua | 2 +- .../003_Disallow_flow_by_policy_RADIO.lua | 2 +- ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 2 +- ...se_moduleType_is_an_empty_array_in_LPT.lua | 2 +- ...ow_in_case_moduleType_is_absent_in_LPT.lua | 2 +- .../001_Consent_true_SIVD.lua | 2 +- .../002_Consent_true_BP.lua | 2 +- .../003_Consent_false_SIVD.lua | 2 +- .../004_Consent_false_BP.lua | 2 +- .../005_TIMED_OUT_from_HMI_SIVD.lua | 2 +- .../006_TIMED_OUT_from_HMI_BP.lua | 2 +- .../007_HMI_no_response_SIVD.lua | 2 +- .../008_HMI_no_response_BP.lua | 2 +- .../009_HMI_invalid_response_SIVD.lua | 2 +- .../010_HMI_invalid_response_BP.lua | 2 +- .../011_TIMED_OUT_after_default_timeout.lua | 2 +- .../002_Disallow_flow_by_policy_CLIMATE.lua | 2 +- .../003_Disallow_flow_by_policy_RADIO.lua | 2 +- .../001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua | 2 +- .../002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua | 2 +- .../003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua | 2 +- .../004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua | 2 +- ...005_REJECTED_in_case_nonFULL_HMI_level.lua | 2 +- .../006_IN_USE_in_case_2_requests.lua | 2 +- .../007_IN_USE_in_case_AUTO_DENY.lua | 2 +- .../008_Allowed_false.lua | 4 +- ...009_Allowed_true_accessMode_AUTO_ALLOW.lua | 2 +- .../010_Allowed_true_accessMode_AUTO_DENY.lua | 2 +- ...011_Allowed_true_accessMode_ASK_DRIVER.lua | 2 +- .../012_Default_accessMode.lua | 2 +- .../013_sequence_switches_of_accessMode.lua | 2 +- .../014_Invalid_data_from_HMI.lua | 2 +- .../015_Empty_data_from_HMI.lua | 2 +- ...DENY_for_app_with_reject_in_ASK_DRIVER.lua | 2 +- ...017_Release_resource_on_unregister_app.lua | 4 +- ...low_for_rejected_app_on_unregister_app.lua | 4 +- .../019_Release_resource_on_RC_disable.lua | 2 +- ...20_Restore_accessMode_after_RC_disable.lua | 2 +- .../021_Release_resource_on_exit_app.lua | 2 +- ...e_resource_on_PTU_with_module_disallow.lua | 4 +- ...lease_resource_on_PTU_with_app_revoked.lua | 4 +- .../024_Allowed_false_no_PTU.lua | 4 +- .../002_Disallow_flow_by_policy_CLIMATE.lua | 2 +- .../003_Disallow_flow_by_policy_RADIO.lua | 2 +- ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 2 +- ...se_moduleType_is_an_empty_array_in_LPT.lua | 2 +- ...ow_in_case_moduleType_is_absent_in_LPT.lua | 2 +- ...ification_by_revoking_module_by_policy.lua | 4 +- ..._in_case_of_policy_permissions_absence.lua | 2 +- ..._by_revoking_several_modules_by_policy.lua | 4 +- .../RC/OnRCStatus/commonOnRCStatus.lua | 2 +- ...se_moduleType_is_an_empty_array_in_LPT.lua | 2 +- ...ow_in_case_moduleType_is_absent_in_LPT.lua | 2 +- .../002_Disallow_flow_by_policy_SEAT.lua | 2 +- ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 2 +- ...ow_in_case_moduleType_is_absent_in_LPT.lua | 2 +- test_scripts/RC/commonRC.lua | 12 +- .../ATF_No_Resumption_PersistentData.lua | 2 +- .../ATF_Resumption_MultiDevices.lua | 4 +- .../ATF_Resumption_PersistentData.lua | 2 +- .../SDL4_0_OnSystemRequest_QUERY_APPS.lua | 12 +- test_scripts/SDL4_6/TTSChunks/common.lua | 2 +- test_scripts/Security/DTLS/common.lua | 2 +- .../Security/GetSystemTime/common.lua | 2 +- .../Security/SSLHandshakeFlow/common.lua | 2 +- ...PerfomInteraction_PositiveCase_SUCCESS.lua | 2 +- ...isterAppInterface_PositiveCase_SUCCESS.lua | 5 +- ...raction_Non_Media_PositiveCase_SUCCESS.lua | 2 +- .../Smoke/Policies/001_PTU_all_flows.lua | 4 +- test_scripts/Smoke/commonSmoke.lua | 6 +- ...eleteCommand_TOO_MANY_PENDING_REQUESTS.lua | 4 +- .../ATF_Show_TOO_MANY_PENDING_REQUESTS.lua | 2 +- test_scripts/smoke_api.lua | 4 +- .../IsReady_Template/Interfaces_RPC.lua | 2 +- user_modules/common_functions.lua | 2 +- user_modules/shared_testcases/commonSteps.lua | 1 + .../testCasesForExternalUCS.lua | 4 +- ...stCasesForImageParameterInNotification.lua | 2 +- .../testCasesForPerformAudioPassThru.lua | 2 +- .../testCasesForPolicyTable.lua | 8 +- 270 files changed, 506 insertions(+), 504 deletions(-) diff --git a/test_scripts/API/ATC_OnExitApplication_Unsupported_HMI_Resource.lua b/test_scripts/API/ATC_OnExitApplication_Unsupported_HMI_Resource.lua index 34b6af87b8..767abb9dd2 100644 --- a/test_scripts/API/ATC_OnExitApplication_Unsupported_HMI_Resource.lua +++ b/test_scripts/API/ATC_OnExitApplication_Unsupported_HMI_Resource.lua @@ -1102,7 +1102,7 @@ function Test:PrecondCheckAppInfoDat(...) repeat Timeout = Timeout - 1 --do - --if IsStringInAppInfoDat("appID\" : " .. "\"" .. config.application1.registerAppInterfaceParams.appID) then + --if IsStringInAppInfoDat("appID\" : " .. "\"" .. config.application1.registerAppInterfaceParams.fullAppID) then if IsStringInAppInfoDat("appID\" : " .. "\"" .. applicationData.mediaApp.appID) then cond = false @@ -1139,7 +1139,7 @@ end function Test:CheckAppInfoDatAfterUHR(...) -- body - if IsStringInAppInfoDat("appID\" : " .. "\"" .. config.application1.registerAppInterfaceParams.appID) then + if IsStringInAppInfoDat("appID\" : " .. "\"" .. config.application1.registerAppInterfaceParams.fullAppID) then self:FailTestCase("App's data is present") end end diff --git a/test_scripts/API/ATC_RequestType.lua b/test_scripts/API/ATC_RequestType.lua index f0c05ac6c6..a46ab64bcd 100644 --- a/test_scripts/API/ATC_RequestType.lua +++ b/test_scripts/API/ATC_RequestType.lua @@ -107,7 +107,7 @@ config.application1 = } } -local storagePath = config.SDLStoragePath..config.application1.registerAppInterfaceParams.appID.. "_" .. config.deviceMAC.. "/" +local storagePath = config.SDLStoragePath..config.application1.registerAppInterfaceParams.fullAppID.. "_" .. config.deviceMAC.. "/" local applicationID local registerAppInterfaceParams = {syncMsgVersion = { diff --git a/test_scripts/API/ATF_AddCommand.lua b/test_scripts/API/ATF_AddCommand.lua index ba446d07af..83aba6de18 100644 --- a/test_scripts/API/ATF_AddCommand.lua +++ b/test_scripts/API/ATF_AddCommand.lua @@ -12,7 +12,7 @@ config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd40 --ToDo: shall be removed when APPLINK-16610 is fixed config.defaultProtocolVersion = 2 -local storagePath = config.pathToSDL .. "storage/" ..config.application1.registerAppInterfaceParams.appID.. "_" .. config.deviceMAC.. "/" +local storagePath = config.pathToSDL .. "storage/" ..config.application1.registerAppInterfaceParams.fullAppID.. "_" .. config.deviceMAC.. "/" local imageValues = {"i", "icon.png", "qwertyuiopasdfghjklzxcvbnm1234567890[]'.!@#$%^&*()_+-=qwertyuiopasdfghjklzxcvbnm1234567890[]'.!@#$%^&*()_+-=QWERTYUIOPASDFGHJKLZXCVBNM{}|?>:::HMI: N: BC.OnAppRegistered") - self.applications[config.application1.registerAppInterfaceParams.appID] = d1.params.application.appID + self.applications[config.application1.registerAppInterfaceParams.fullAppID] = d1.params.application.appID EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, {status = "UP_TO_DATE" }) :Do( function(_, d2) diff --git a/test_scripts/Policies/build_options/066_ATF_PTU_Validation_Failure_HTTP.lua b/test_scripts/Policies/build_options/066_ATF_PTU_Validation_Failure_HTTP.lua index 6e54361895..d0a822ca6d 100644 --- a/test_scripts/Policies/build_options/066_ATF_PTU_Validation_Failure_HTTP.lua +++ b/test_scripts/Policies/build_options/066_ATF_PTU_Validation_Failure_HTTP.lua @@ -31,7 +31,7 @@ local json = require("modules/json") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") --[[ Local Variables ]] -local app_id = config.application1.registerAppInterfaceParams.appID +local app_id = config.application1.registerAppInterfaceParams.fullAppID local sequence = { } local ptu_table @@ -124,7 +124,7 @@ function Test:RAI_PTU() :Do( function(_, d1) log("SDL->HMI: N: BC.OnAppRegistered") - self.applications[config.application1.registerAppInterfaceParams.appID] = d1.params.application.appID + self.applications[config.application1.registerAppInterfaceParams.fullAppID] = d1.params.application.appID EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) :Do( function(_, d2) diff --git a/test_scripts/Policies/build_options/071_ATF_PTU_Local_PT_Start_Retry_Sequence_HTTP.lua b/test_scripts/Policies/build_options/071_ATF_PTU_Local_PT_Start_Retry_Sequence_HTTP.lua index a2b5a2ca07..9617f5e6cc 100644 --- a/test_scripts/Policies/build_options/071_ATF_PTU_Local_PT_Start_Retry_Sequence_HTTP.lua +++ b/test_scripts/Policies/build_options/071_ATF_PTU_Local_PT_Start_Retry_Sequence_HTTP.lua @@ -104,7 +104,7 @@ function Test:RAI() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config.application1.registerAppInterfaceParams.appName } }) :Do( function(_, d1) - self.applications[config.application1.registerAppInterfaceParams.appID] = d1.params.application.appID + self.applications[config.application1.registerAppInterfaceParams.fullAppID] = d1.params.application.appID EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate") :Do( function(_, d2) diff --git a/test_scripts/Policies/build_options/072_ATF_PTU_PM_Sets_Status_UPDATE_NEEDED_HTTP.lua b/test_scripts/Policies/build_options/072_ATF_PTU_PM_Sets_Status_UPDATE_NEEDED_HTTP.lua index 663c7687e6..40b7061c98 100644 --- a/test_scripts/Policies/build_options/072_ATF_PTU_PM_Sets_Status_UPDATE_NEEDED_HTTP.lua +++ b/test_scripts/Policies/build_options/072_ATF_PTU_PM_Sets_Status_UPDATE_NEEDED_HTTP.lua @@ -87,7 +87,7 @@ function Test:RAI_PTU() :Do( function(_, d1) log("SDL->HMI: N: BC.OnAppRegistered") - self.applications[config.application1.registerAppInterfaceParams.appID] = d1.params.application.appID + self.applications[config.application1.registerAppInterfaceParams.fullAppID] = d1.params.application.appID EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATE_NEEDED"}, {status = "UPDATING"}, {status = "UPDATE_NEEDED"}, {status = "UPDATING"}) :Do(function(_, d) log("SDL->HMI: N: SDL.OnStatusUpdate", d.params.status) diff --git a/test_scripts/Policies/build_options/076_ATF_PTU_Changes_Applied_OnPermissionChange_Notification_App_HTTP.lua b/test_scripts/Policies/build_options/076_ATF_PTU_Changes_Applied_OnPermissionChange_Notification_App_HTTP.lua index f15e6989be..b244095e86 100644 --- a/test_scripts/Policies/build_options/076_ATF_PTU_Changes_Applied_OnPermissionChange_Notification_App_HTTP.lua +++ b/test_scripts/Policies/build_options/076_ATF_PTU_Changes_Applied_OnPermissionChange_Notification_App_HTTP.lua @@ -29,7 +29,7 @@ local commonSteps = require("user_modules/shared_testcases/commonSteps") local json = require("modules/json") --[[ Local Variables ]] -local app_id = config.application1.registerAppInterfaceParams.appID +local app_id = config.application1.registerAppInterfaceParams.fullAppID local sequence = { } local ptu_table @@ -121,7 +121,7 @@ function Test:RAI_PTU() :Do( function(_, d1) log("SDL->HMI: N: BC.OnAppRegistered") - self.applications[config.application1.registerAppInterfaceParams.appID] = d1.params.application.appID + self.applications[config.application1.registerAppInterfaceParams.fullAppID] = d1.params.application.appID EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, {status = "UP_TO_DATE" }) :Do( function(_, d2) diff --git a/test_scripts/Policies/build_options/077_ATF_PTU_Changes_Applied_OnPermissionChange_Notification_HMI_HTTP.lua b/test_scripts/Policies/build_options/077_ATF_PTU_Changes_Applied_OnPermissionChange_Notification_HMI_HTTP.lua index 9547e686ef..2f1cd59eb0 100644 --- a/test_scripts/Policies/build_options/077_ATF_PTU_Changes_Applied_OnPermissionChange_Notification_HMI_HTTP.lua +++ b/test_scripts/Policies/build_options/077_ATF_PTU_Changes_Applied_OnPermissionChange_Notification_HMI_HTTP.lua @@ -31,7 +31,7 @@ local commonSteps = require("user_modules/shared_testcases/commonSteps") local json = require("modules/json") --[[ Local Variables ]] -local app_id = config.application1.registerAppInterfaceParams.appID +local app_id = config.application1.registerAppInterfaceParams.fullAppID local ptu_table --[[ Local Functions ]] @@ -91,7 +91,7 @@ function Test:RAI_PTU() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config.application1.registerAppInterfaceParams.appName } }) :Do( function(_, d1) - self.applications[config.application1.registerAppInterfaceParams.appID] = d1.params.application.appID + self.applications[config.application1.registerAppInterfaceParams.fullAppID] = d1.params.application.appID EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, {status = "UP_TO_DATE" }) :Times(3) diff --git a/test_scripts/Policies/build_options/078_ATF_PTU_HMI_Level_Affected_Apps_FULL_LIMITED_HTTP.lua b/test_scripts/Policies/build_options/078_ATF_PTU_HMI_Level_Affected_Apps_FULL_LIMITED_HTTP.lua index 6d0a0e91e5..eaafa73735 100644 --- a/test_scripts/Policies/build_options/078_ATF_PTU_HMI_Level_Affected_Apps_FULL_LIMITED_HTTP.lua +++ b/test_scripts/Policies/build_options/078_ATF_PTU_HMI_Level_Affected_Apps_FULL_LIMITED_HTTP.lua @@ -81,8 +81,8 @@ function Test:Precondition_StartSession() end function Test.Precondition_PreparePTData() - PrepareJsonPTU1(config.application1.registerAppInterfaceParams.appID, ptu_first_app_registered) - PrepareJsonPTU1(config.application2.registerAppInterfaceParams.appID, ptu_second_app_registered) + PrepareJsonPTU1(config.application1.registerAppInterfaceParams.fullAppID, ptu_first_app_registered) + PrepareJsonPTU1(config.application2.registerAppInterfaceParams.fullAppID, ptu_second_app_registered) end --[[ end of Preconditions ]] diff --git a/test_scripts/Policies/build_options/085_ATF_PTU_In_Progress_New_App_Registers_HTTP.lua b/test_scripts/Policies/build_options/085_ATF_PTU_In_Progress_New_App_Registers_HTTP.lua index 836015594e..e67239e006 100644 --- a/test_scripts/Policies/build_options/085_ATF_PTU_In_Progress_New_App_Registers_HTTP.lua +++ b/test_scripts/Policies/build_options/085_ATF_PTU_In_Progress_New_App_Registers_HTTP.lua @@ -59,7 +59,7 @@ end function Test:TestStep_CheckThatAppID_SecondApp_Present_In_DataBase() local db_file = config.pathToSDL .. "/storage/policy.sqlite" - local sql = "SELECT id FROM application WHERE id = '" .. config.application2.registerAppInterfaceParams.appID .. "'" + local sql = "SELECT id FROM application WHERE id = '" .. config.application2.registerAppInterfaceParams.fullAppID .. "'" local AppIdValue_2 = commonFunctions:get_data_policy_sql(db_file, sql) if AppIdValue_2 == nil then self:FailTestCase("Value in DB is unexpected value " .. tostring(AppIdValue_2)) diff --git a/test_scripts/Policies/build_options/086_ATF_PTU_Merging_wtih_LPT_HTTP.lua b/test_scripts/Policies/build_options/086_ATF_PTU_Merging_wtih_LPT_HTTP.lua index 3649ffb5ac..b296f9d7cc 100644 --- a/test_scripts/Policies/build_options/086_ATF_PTU_Merging_wtih_LPT_HTTP.lua +++ b/test_scripts/Policies/build_options/086_ATF_PTU_Merging_wtih_LPT_HTTP.lua @@ -60,12 +60,12 @@ function Test:Precondition_CheckThatAppID_SecondApp_Present_In_DataBase() local app2_exist = false for _, value in pairs(app_id_table) do - if ( value == config.application2.registerAppInterfaceParams.appID) then + if ( value == config.application2.registerAppInterfaceParams.fullAppID) then app2_exist = true end end if(app2_exist == false) then - self:FailTestCase("Application " .. config.application2.registerAppInterfaceParams.appID .. " doesn't exist in Local PT.") + self:FailTestCase("Application " .. config.application2.registerAppInterfaceParams.fullAppID .. " doesn't exist in Local PT.") end end @@ -88,12 +88,12 @@ function Test:TestStep_CheckThatAppID_SecondApp_StillPresent_In_DataBase() local app2_exist = false for _, value in pairs(app_id_table) do - if ( value == config.application2.registerAppInterfaceParams.appID) then + if ( value == config.application2.registerAppInterfaceParams.fullAppID) then app2_exist = true end end if(app2_exist == false) then - self:FailTestCase("Application " .. config.application2.registerAppInterfaceParams.appID .. " doesn't exist in Local PT.") + self:FailTestCase("Application " .. config.application2.registerAppInterfaceParams.fullAppID .. " doesn't exist in Local PT.") end end diff --git a/test_scripts/Policies/build_options/093_ATF_OnStatusUpdate_Trigger_PROPRIETARY.lua b/test_scripts/Policies/build_options/093_ATF_OnStatusUpdate_Trigger_PROPRIETARY.lua index 950ef5e2d3..3800771b9e 100644 --- a/test_scripts/Policies/build_options/093_ATF_OnStatusUpdate_Trigger_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/093_ATF_OnStatusUpdate_Trigger_PROPRIETARY.lua @@ -30,7 +30,7 @@ local json = require("modules/json") --[[ Local Variables ]] local sequence = { } -local app_id = config.application1.registerAppInterfaceParams.appID +local app_id = config.application1.registerAppInterfaceParams.fullAppID local policy_file_name = "PolicyTableUpdate" local pts_file_name = "sdl_snapshot.json" diff --git a/test_scripts/Policies/build_options/094_ATF_PTS_creation_rule_PROPRIETARY.lua b/test_scripts/Policies/build_options/094_ATF_PTS_creation_rule_PROPRIETARY.lua index 8dd8654a5c..4ae1d4ddb1 100644 --- a/test_scripts/Policies/build_options/094_ATF_PTS_creation_rule_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/094_ATF_PTS_creation_rule_PROPRIETARY.lua @@ -37,7 +37,7 @@ require('user_modules/AppTypes') commonFunctions:newTestCasesGroup("Test") function Test:TestStep_PTS_Creation_rule() local result = testCasesForPolicyTableSnapshot:verify_PTS(true, - {config.application1.registerAppInterfaceParams.appID}, + {config.application1.registerAppInterfaceParams.fullAppID}, {utils.getDeviceMAC()}, {""}, "print", diff --git a/test_scripts/Policies/build_options/095_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua b/test_scripts/Policies/build_options/095_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua index ac28d6dfcf..5f85517a80 100644 --- a/test_scripts/Policies/build_options/095_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/095_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua @@ -155,7 +155,7 @@ function Test:TestStep_CheckThatAppID_Present_In_DataBase() if r[1] then wait = false end end - local sql = table.concat({"SELECT 1 FROM application WHERE id = '", tostring(registerAppInterfaceParams.appID), "'"}) + local sql = table.concat({"SELECT 1 FROM application WHERE id = '", tostring(registerAppInterfaceParams.fullAppID), "'"}) print(sql) local r_actual = commonFunctions:get_data_policy_sql(PolicyDBPath, sql) if r_actual[1] == nil then diff --git a/test_scripts/Policies/build_options/101_ATF_SDL_Build_EXTENDED_POLICY_HTTP.lua b/test_scripts/Policies/build_options/101_ATF_SDL_Build_EXTENDED_POLICY_HTTP.lua index f0216aff8d..d2d4781e38 100644 --- a/test_scripts/Policies/build_options/101_ATF_SDL_Build_EXTENDED_POLICY_HTTP.lua +++ b/test_scripts/Policies/build_options/101_ATF_SDL_Build_EXTENDED_POLICY_HTTP.lua @@ -32,7 +32,7 @@ local mobile_session = require('mobile_session') require('user_modules/AppTypes') config.application2.registerAppInterfaceParams.appName = "Media Application" -config.application2.registerAppInterfaceParams.appID = "MyTestApp" +config.application2.registerAppInterfaceParams.fullAppID = "MyTestApp" --[[ Local Variables ]] local filePTU = "files/ptu.json" diff --git a/test_scripts/Policies/build_options/106_ATF_PolicyManager_changes_status_to_UPDATING_PROPRIETARY.lua b/test_scripts/Policies/build_options/106_ATF_PolicyManager_changes_status_to_UPDATING_PROPRIETARY.lua index a6cf7217ff..15f43a8064 100644 --- a/test_scripts/Policies/build_options/106_ATF_PolicyManager_changes_status_to_UPDATING_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/106_ATF_PolicyManager_changes_status_to_UPDATING_PROPRIETARY.lua @@ -73,7 +73,7 @@ function Test:RAI() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config.application1.registerAppInterfaceParams.appName } }) :Do( function(_, d1) - self.applications[config.application1.registerAppInterfaceParams.appID] = d1.params.application.appID + self.applications[config.application1.registerAppInterfaceParams.fullAppID] = d1.params.application.appID EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) :Do( function(_, d2) diff --git a/test_scripts/Policies/build_options/109_ATF_PTU_Trigger_IGN_cycles_PROPRIETARY.lua b/test_scripts/Policies/build_options/109_ATF_PTU_Trigger_IGN_cycles_PROPRIETARY.lua index 638ae9e5c8..c62a700e2f 100644 --- a/test_scripts/Policies/build_options/109_ATF_PTU_Trigger_IGN_cycles_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/109_ATF_PTU_Trigger_IGN_cycles_PROPRIETARY.lua @@ -14,7 +14,7 @@ -- field ("module_config" section) of policies database, SDL must trigger a PolicyTableUpdate sequence --------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] -config.application1.registerAppInterfaceParams.appID = "123456" +config.application1.registerAppInterfaceParams.fullAppID = "123456" config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } --[[ Required Shared libraries ]] diff --git a/test_scripts/Policies/build_options/114_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua b/test_scripts/Policies/build_options/114_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua index e2b4ea7925..9e88403dc9 100644 --- a/test_scripts/Policies/build_options/114_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/114_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua @@ -125,8 +125,8 @@ function Test:TestStep_CheckThatAppID_Present_In_DataBase() commonFunctions:userPrint(31, "policy.sqlite file is not found") self:FailTestCase("PolicyTable is not avaliable " .. tostring(PolicyDBPath)) end - local select_value = "SELECT id FROM application WHERE id = '"..tostring(registerAppInterfaceParams.appID).."'" - local result = commonFunctions:is_db_contains(PolicyDBPath, select_value, {tostring(registerAppInterfaceParams.appID)}) + local select_value = "SELECT id FROM application WHERE id = '"..tostring(registerAppInterfaceParams.fullAppID).."'" + local result = commonFunctions:is_db_contains(PolicyDBPath, select_value, {tostring(registerAppInterfaceParams.fullAppID)}) if result == false then self:FailTestCase("DB doesn't contain special id") end diff --git a/test_scripts/Policies/build_options/115_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp_PROPRIETARY.lua b/test_scripts/Policies/build_options/115_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp_PROPRIETARY.lua index 911fbe3454..0d03217e2b 100644 --- a/test_scripts/Policies/build_options/115_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/115_ATF_Register_NewApp_not_exist_inLocalPT_start_PTU_for_NewApp_PROPRIETARY.lua @@ -176,7 +176,7 @@ function Test:TestStep_CheckThatAppID_Present_In_DataBase() self:FailTestCase("PolicyTable is not avaliable" .. tostring(PolicyDBPath)) end os.execute(" sleep 2 ") - local AppId_2 = "sqlite3 " .. tostring(PolicyDBPath) .. " \"SELECT id FROM application WHERE id = '"..tostring(registerAppInterfaceParams.appID).."'\"" + local AppId_2 = "sqlite3 " .. tostring(PolicyDBPath) .. " \"SELECT id FROM application WHERE id = '"..tostring(registerAppInterfaceParams.fullAppID).."'\"" local bHandle = assert( io.popen(AppId_2, 'r')) local AppIdValue_2 = bHandle:read( '*all') if AppIdValue_2 == nil then diff --git a/test_scripts/Policies/user_consent_of_Policies/201_ATF_User_consents_permissions.lua b/test_scripts/Policies/user_consent_of_Policies/201_ATF_User_consents_permissions.lua index 16a9046925..93b286d9e9 100644 --- a/test_scripts/Policies/user_consent_of_Policies/201_ATF_User_consents_permissions.lua +++ b/test_scripts/Policies/user_consent_of_Policies/201_ATF_User_consents_permissions.lua @@ -214,7 +214,7 @@ function Test:TestStep_trigger_user_request_update_from_HMI() end function Test:TestStep_verify_PermissionConsent() - local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.DrivingCharacteristics-3") + local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.fullAppID..".consent_groups.DrivingCharacteristics-3") if(app_permission ~= true) then self:FailTestCase("DrivingCharacteristics-3 is not assigned to application, real: " ..app_permission) end diff --git a/test_scripts/Policies/user_consent_of_Policies/203_ATF_Master_reset.lua b/test_scripts/Policies/user_consent_of_Policies/203_ATF_Master_reset.lua index bfbe53e7fe..f211c032f3 100644 --- a/test_scripts/Policies/user_consent_of_Policies/203_ATF_Master_reset.lua +++ b/test_scripts/Policies/user_consent_of_Policies/203_ATF_Master_reset.lua @@ -51,7 +51,7 @@ function Test:TestStep_CheckLocalPT() if ( commonSteps:file_exists('/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json')) then self:FailTestCase(" \27[31m /tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json is created \27[0m") else - testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.appID}, {utils.getDeviceMAC()},{hmi_app1_id}, "print") + testCasesForPolicyTableSnapshot:verify_PTS(true, {config.application1.registerAppInterfaceParams.fullAppID}, {utils.getDeviceMAC()},{hmi_app1_id}, "print") end end) end diff --git a/test_scripts/Policies/user_consent_of_Policies/213_ATF_No_user_consent_prompt_in_group.lua b/test_scripts/Policies/user_consent_of_Policies/213_ATF_No_user_consent_prompt_in_group.lua index 2334e60bee..aa5d8d1c97 100644 --- a/test_scripts/Policies/user_consent_of_Policies/213_ATF_No_user_consent_prompt_in_group.lua +++ b/test_scripts/Policies/user_consent_of_Policies/213_ATF_No_user_consent_prompt_in_group.lua @@ -63,7 +63,7 @@ function Test:TestStep1_PTU_lack_of_user_consent_prompt() end function Test:TestStep_app_no_consent() - local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID) + local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.fullAppID) if(app_permission ~= nil) then self:FailTestCase("Consented gropus are assigned to application") end diff --git a/test_scripts/Policies/user_consent_of_Policies/214_ATF_User_consent_prompt_persists.lua b/test_scripts/Policies/user_consent_of_Policies/214_ATF_User_consent_prompt_persists.lua index 112dd386b7..84d7c86cde 100644 --- a/test_scripts/Policies/user_consent_of_Policies/214_ATF_User_consent_prompt_persists.lua +++ b/test_scripts/Policies/user_consent_of_Policies/214_ATF_User_consent_prompt_persists.lua @@ -175,7 +175,7 @@ function Test:Precondition_IsPermissionsConsentNeeded_false_on_app_activation() EXPECT_HMICALL("BasicCommunication.PolicyUpdate", {file = "/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json"}) :Do(function() - local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID) + local app_permission = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.fullAppID) if(app_permission ~= nil) then self:FailTestCase("Consented gropus are assigned to application") end @@ -296,8 +296,8 @@ function Test:Precondition_PTU_user_consent_prompt_present() function Test.TestStep_verify_PermissionConsent() local is_test_passed = true - local app_permission_Location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Location-1") - local app_permission_Notifications = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Notifications") + local app_permission_Location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.fullAppID..".consent_groups.Location-1") + local app_permission_Notifications = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.fullAppID..".consent_groups.Notifications") if(app_permission_Location ~= nil) then commonFunctions:printError("Location-1 is assigned user_consent_records") is_test_passed = false diff --git a/test_scripts/Policies/user_consent_of_Policies/221_ATF_Factory_reset.lua b/test_scripts/Policies/user_consent_of_Policies/221_ATF_Factory_reset.lua index d15a18a7c2..27fea8db3d 100644 --- a/test_scripts/Policies/user_consent_of_Policies/221_ATF_Factory_reset.lua +++ b/test_scripts/Policies/user_consent_of_Policies/221_ATF_Factory_reset.lua @@ -217,8 +217,8 @@ function Test:Check_no_user_consent_records_in_PT() self:FailTestCase(config.pathToSDL .."sdl_preloaded_pt.json ".."is not created") else testCasesForPolicyTableSnapshot:extract_pts({self.applications[config.application1.registerAppInterfaceParams.appName]}) - local app_consent_location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Location-1") - local app_consent_notifications = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.appID..".consent_groups.Notifications") + local app_consent_location = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.fullAppID..".consent_groups.Location-1") + local app_consent_notifications = testCasesForPolicyTableSnapshot:get_data_from_PTS("device_data."..utils.getDeviceMAC()..".user_consent_records."..config.application1.registerAppInterfaceParams.fullAppID..".consent_groups.Notifications") if(app_consent_location == true) then commonFunctions:printError("Error: user_consent_records.consent_groups.Location was not reset in LPT") diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua index c393bd0497..ab75958e03 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua @@ -40,7 +40,7 @@ local function step1(self) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = { "RADIO" } end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/003_disallow_flow_by_policy_for_radio.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/003_disallow_flow_by_policy_for_radio.lua index 71c37d1a46..eb6f41479e 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/003_disallow_flow_by_policy_for_radio.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/003_disallow_flow_by_policy_for_radio.lua @@ -40,7 +40,7 @@ local function step1(self) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = { "CLIMATE" } end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua index 974147748c..727e6e1447 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua @@ -53,7 +53,7 @@ local function step2(self) end local function ptu_update_func(tbl) - local appId = config.application1.registerAppInterfaceParams.appID + local appId = config.application1.registerAppInterfaceParams.fullAppID tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } end diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua index 3727afa44e..9002a27613 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua @@ -44,7 +44,7 @@ local function getDataForModule(pModuleType, self) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = json.EMPTY_ARRAY end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua index 0f1f877f7d..98439a96ea 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua @@ -39,7 +39,7 @@ local function getDataForModule(pModuleType, self) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = nil end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 7746ffaefd..24c428e124 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -37,7 +37,7 @@ local function getDataForModule(pModuleType, self) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = { "RADIO" } end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index e163bbe968..ad00b83139 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -37,7 +37,7 @@ local function getDataForModule(pModuleType, self) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = { "CLIMATE" } end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 672b90282d..e3d463387b 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -39,7 +39,7 @@ local function getDataForModule(pModuleType, self) end local function ptu_update_func(tbl) - local appId = config.application1.registerAppInterfaceParams.appID + local appId = config.application1.registerAppInterfaceParams.fullAppID tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } end diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 274b130e87..df807d75de 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -48,7 +48,7 @@ local function getDataForModule(pModuleType, self) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = json.EMPTY_ARRAY end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 2d3e1389e5..580f69d90c 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -38,7 +38,7 @@ local function getDataForModule(module_type, self) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = nil end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua index 753d815958..b1d7f0f021 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua @@ -26,7 +26,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua index c1ff27508f..de738624fe 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua @@ -26,7 +26,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua index e73364055e..64ffb20a5e 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua @@ -30,7 +30,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua index e73a05f598..30507e88b2 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua @@ -30,7 +30,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua index ca4278b1d6..1c977af7d6 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua @@ -31,7 +31,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end local function rpcTimedOutHMIResponse(pModuleType, pAppId, pRPC, self) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua index 75c7edeb75..793ee42b98 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua @@ -31,7 +31,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end local function rpcTimedOutHMIResponse(pModuleType, pAppId, pRPC, self) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua index ee43ec6d2d..c788bf5876 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua @@ -29,7 +29,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end local function rpcNoHMIResponse(pModuleType, pAppId, pRPC, self) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua index 8edd8f8a51..eba337e0d7 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua @@ -29,7 +29,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end local function rpcNoHMIResponse(pModuleType, pAppId, pRPC, self) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua index d02876ba6f..7e001d80f1 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua @@ -29,7 +29,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end local function rpcInvalidHMIResponse(pModuleType, pAppId, pRPC, self) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua index 913017bd6f..bb83905bdb 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua @@ -29,7 +29,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end local function rpcInvalidHMIResponse(pModuleType, pAppId, pRPC, self) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua index 5309196f86..c69498a6d4 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua @@ -29,7 +29,7 @@ local pRPC1 = "SetInteriorVehicleData" --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end local function rpcHMIRespondAfterDefaultTimeout(self) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 9a4a6be45c..1560a5fa87 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -23,7 +23,7 @@ local commonRC = require('test_scripts/RC/commonRC') local mod = "CLIMATE" local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { mod } + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = { mod } end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index f1cb4cbeac..cebb5f21a5 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -23,7 +23,7 @@ local commonRC = require('test_scripts/RC/commonRC') local mod = "RADIO" local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { mod } + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = { mod } end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua index 1e7307d267..8204f9d0b6 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua @@ -26,7 +26,7 @@ local access_modes = { nil, "AUTO_ALLOW" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua index 681bf2178a..167e3f1ceb 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua @@ -26,7 +26,7 @@ local access_modes = { nil, "AUTO_ALLOW" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua index 449e83335d..a62b6478ec 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua @@ -26,7 +26,7 @@ local access_modes = { nil, "AUTO_ALLOW" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua index 30ea672fd2..ce66b0a06a 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua @@ -26,7 +26,7 @@ local access_modes = { nil, "AUTO_ALLOW" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua index 46fdc199bd..ca1d152485 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua @@ -28,7 +28,7 @@ local access_modes = { nil, "AUTO_ALLOW", "AUTO_DENY", "ASK_DRIVER" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua index a2c026b1cc..e0c5cf4625 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua @@ -36,7 +36,7 @@ local access_modes = { nil, "AUTO_ALLOW" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end local function step(pModuleType, pRPC1, pRPC2, self) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua index 6c79b8d044..8cd9b1c573 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua @@ -25,7 +25,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua index f272226a97..d7c1bbc38e 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua @@ -39,8 +39,8 @@ local function ptu_update_func(tbl) AppHMIType = { "NAVIGATION" } } - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() - tbl.policy_table.app_policies[config.application3.registerAppInterfaceParams.appID] = notRcAppConfig + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application3.registerAppInterfaceParams.fullAppID] = notRcAppConfig end local function disableRcFromHmi(self) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua index b34c1c7165..8e78872972 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua @@ -28,7 +28,7 @@ local rcRpcs = { "SetInteriorVehicleData", "ButtonPress" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end local function disableRcFromHmi(self) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua index 00f5e7cc21..1768f2534b 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua @@ -28,7 +28,7 @@ local rcRpcs = {"SetInteriorVehicleData", "ButtonPress"} --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end local function disableRcFromHmi(self) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua index 6651c7569f..9ec526028c 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua @@ -26,7 +26,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end local function disableRcFromHmi(self) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/012_Default_accessMode.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/012_Default_accessMode.lua index f10abc7c3a..689cbf8358 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/012_Default_accessMode.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/012_Default_accessMode.lua @@ -26,7 +26,7 @@ local rcRpcs = { "SetInteriorVehicleData", "ButtonPress" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua index c81bf9ed81..78e41b462b 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua @@ -43,7 +43,7 @@ local rcRpcs = { "SetInteriorVehicleData", "ButtonPress" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua index 614c759273..ec1a1fc273 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua @@ -22,7 +22,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end local function setRAMode(self) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/015_Empty_data_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/015_Empty_data_from_HMI.lua index 7df469d81c..8f672a8fab 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/015_Empty_data_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/015_Empty_data_from_HMI.lua @@ -22,7 +22,7 @@ local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end local function setRAMode(self) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua index fba44244cb..025fcab93d 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua @@ -24,7 +24,7 @@ local commonRC = require('test_scripts/RC/commonRC') --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua index dfc5e03342..4c8510b1fd 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua @@ -30,8 +30,8 @@ config.application3.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() - tbl.policy_table.app_policies[config.application3.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application3.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua index 96b301a381..7aa7604544 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua @@ -30,8 +30,8 @@ config.application3.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() - tbl.policy_table.app_policies[config.application3.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application3.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua index 89c6da5d71..1a7850130e 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua @@ -29,7 +29,7 @@ local HMILevels = { "FULL", "NOT_FULL" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua index dbd0b813d9..0a7e869627 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua @@ -25,7 +25,7 @@ local accessModes = { "AUTO_ALLOW", "AUTO_DENY", "ASK_DRIVER" } --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end local function disableRcFromHmi(self) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua index a2749a5ce0..3159910b3e 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua @@ -22,7 +22,7 @@ local exitAppReasons = {"USER_EXIT", "DRIVER_DISTRACTION_VIOLATION"} --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() table.insert(tbl.policy_table.functional_groupings.RemoteControl.rpcs.OnInteriorVehicleData.hmi_levels, "NONE") end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua index 63b96dea08..4d9001aa2c 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua @@ -19,7 +19,7 @@ local commonRC = require('test_scripts/RC/commonRC') --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = { + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID] = { keep_context = false, steal_focus = false, priority = "NONE", @@ -29,7 +29,7 @@ local function ptu_update_func(tbl) AppHMIType = { "REMOTE_CONTROL" } } table.insert(tbl.policy_table.functional_groupings.RemoteControl.rpcs.OnInteriorVehicleData.hmi_levels, "NONE") - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua index 29a473cf86..9f42830136 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua @@ -21,8 +21,8 @@ local json = require("modules/json") --[[ Local Functions ]] local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = json.null - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID] = json.null + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig() end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua index f3e8812b5c..e5abab7585 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua @@ -40,7 +40,7 @@ local function register_app(pAppId, self) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) :Do(function(_, d1) - hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = d1.params.application.appID + hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.fullAppID] = d1.params.application.appID end) self["mobileSession" .. pAppId]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() @@ -54,7 +54,7 @@ end local function activate_app(pAppId, self) local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", - { appID = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] }) + { appID = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.fullAppID] }) EXPECT_HMIRESPONSE(requestId) self["mobileSession" .. pAppId]:ExpectNotification("OnHMIStatus", diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 044a6748cb..09f2cbb7d4 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -37,7 +37,7 @@ local function setVehicleData(pModuleType, self) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = { "RADIO" } end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index 06b5067914..0d48f3f1e8 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -37,7 +37,7 @@ local function setVehicleData(pModuleType, self) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = { "CLIMATE" } end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 7a774630bc..033026ccad 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -39,7 +39,7 @@ local function setVehicleData(pModuleType, self) end local function ptu_update_func(tbl) - local appId = config.application1.registerAppInterfaceParams.appID + local appId = config.application1.registerAppInterfaceParams.fullAppID tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } end diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 40d3aecc34..b0a4fea4c9 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -42,7 +42,7 @@ local function setVehicleData(pModuleType, self) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = json.EMPTY_ARRAY end --[[ Scenario ]] diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 591d1b8195..402b3cae08 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -37,7 +37,7 @@ local function setVehicleData(pModuleType, self) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = nil end --[[ Scenario ]] diff --git a/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua b/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua index ff3a0aabdc..9dcc28dac3 100644 --- a/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua +++ b/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua @@ -25,10 +25,10 @@ config.application2.registerAppInterfaceParams.appHMIType = { "DEFAULT" } --[[ Local Functions ]] local function pTUfunc(tbl) - local appId1 = config.application1.registerAppInterfaceParams.appID + local appId1 = config.application1.registerAppInterfaceParams.fullAppID tbl.policy_table.app_policies[appId1] = common.getRCAppConfig(tbl) tbl.policy_table.app_policies[appId1].moduleType = { "RADIO" } - local appId2 = config.application2.registerAppInterfaceParams.appID + local appId2 = config.application2.registerAppInterfaceParams.fullAppID tbl.policy_table.app_policies[appId2] = common.getRCAppConfig(tbl) end diff --git a/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua b/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua index bb18f7c5ed..166f843b0d 100644 --- a/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua +++ b/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua @@ -26,7 +26,7 @@ local allocatedModules = {{}} --[[ Local Functions ]] local function pTUfunc(tbl) - local appId = config.application1.registerAppInterfaceParams.appID + local appId = config.application1.registerAppInterfaceParams.fullAppID tbl.policy_table.app_policies[appId] = common.getRCAppConfig() local HMILevels = { "NONE", "BACKGROUND", "FULL", "LIMITED" } local RCgroup = { diff --git a/test_scripts/RC/OnRCStatus/029_notification_by_revoking_several_modules_by_policy.lua b/test_scripts/RC/OnRCStatus/029_notification_by_revoking_several_modules_by_policy.lua index 56a3fc1c7c..d69bada8c1 100644 --- a/test_scripts/RC/OnRCStatus/029_notification_by_revoking_several_modules_by_policy.lua +++ b/test_scripts/RC/OnRCStatus/029_notification_by_revoking_several_modules_by_policy.lua @@ -32,10 +32,10 @@ local allocatedModules = { --[[ Local Functions ]] local function pTUfunc(tbl) - local appId1 = config.application1.registerAppInterfaceParams.appID + local appId1 = config.application1.registerAppInterfaceParams.fullAppID tbl.policy_table.app_policies[appId1] = common.getRCAppConfig(tbl) tbl.policy_table.app_policies[appId1].moduleType = json.EMPTY_ARRAY - local appId2 = config.application2.registerAppInterfaceParams.appID + local appId2 = config.application2.registerAppInterfaceParams.fullAppID tbl.policy_table.app_policies[appId2] = common.getRCAppConfig(tbl) end diff --git a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua index a4378561c0..c2d9ac5217 100644 --- a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua +++ b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua @@ -52,7 +52,7 @@ local function updatePreloadedPT(pCountOfRCApps) hmi_levels = { "FULL", "BACKGROUND", "LIMITED", "NONE" } } for i = 1, pCountOfRCApps do - local appId = config["application" .. i].registerAppInterfaceParams.appID + local appId = config["application" .. i].registerAppInterfaceParams.fullAppID preloadedTable.policy_table.app_policies[appId] = commonRC.getRCAppConfig(preloadedTable) preloadedTable.policy_table.app_policies[appId].AppHMIType = nil end diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 69e486cb04..ea884e5789 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -46,7 +46,7 @@ local function getDataForModule(pModuleType) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = json.EMPTY_ARRAY end --[[ Scenario ]] diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 75d229e2ca..809d383537 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -33,7 +33,7 @@ local function getDataForModule(module_type) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = nil end --[[ Scenario ]] diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_SEAT.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_SEAT.lua index 1d51794776..ef0588e88d 100644 --- a/test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_SEAT.lua +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_SEAT.lua @@ -30,7 +30,7 @@ local function setVehicleData(pModuleType) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = { "CLIMATE" } end --[[ Scenario ]] diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/003_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/003_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 9ee3e1ca6f..99b1d53a01 100644 --- a/test_scripts/RC/SEAT/SetInteriorVehicleData/003_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/003_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -33,7 +33,7 @@ local function setVehicleData(pModuleType) end local function ptu_update_func(tbl) - local appId = config.application1.registerAppInterfaceParams.appID + local appId = config.application1.registerAppInterfaceParams.fullAppID tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } end diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/005_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/005_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 17076cb644..870b6d661d 100644 --- a/test_scripts/RC/SEAT/SetInteriorVehicleData/005_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/005_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -30,7 +30,7 @@ local function setVehicleData(pModuleType) end local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].moduleType = nil end --[[ Scenario ]] diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 3526622f57..60a1203b78 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -61,7 +61,7 @@ function commonRC.getRCAppConfig(tbl) end local function updatePTU(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID] = commonRC.getRCAppConfig(tbl) end function commonRC.jsonFileToTable(file_name) @@ -197,7 +197,7 @@ function commonRC.rai_ptu_n(id, ptu_update_func, self) local corId = self["mobileSession" .. id]:SendRPC("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) :Do(function(_, d1) - hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + hmiAppIds[config["application" .. id].registerAppInterfaceParams.fullAppID] = d1.params.application.appID EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) :Times(3) EXPECT_HMICALL("BasicCommunication.PolicyUpdate") @@ -226,7 +226,7 @@ function commonRC.rai_n(id, self) local corId = self["mobileSession" .. id]:SendRPC("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) :Do(function(_, d1) - hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + hmiAppIds[config["application" .. id].registerAppInterfaceParams.fullAppID] = d1.params.application.appID end) self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() @@ -249,7 +249,7 @@ end function commonRC.activate_app(pAppId, self) self, pAppId = commonRC.getSelfAndParams(pAppId, self) if not pAppId then pAppId = 1 end - local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.fullAppID] local mobSession = commonRC.getMobileSession(self, pAppId) local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) EXPECT_HMIRESPONSE(requestId) @@ -628,7 +628,7 @@ end function commonRC.getHMIAppId(pAppId) if not pAppId then pAppId = 1 end - return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.fullAppID] end function commonRC.getMobileSession(self, pAppId) @@ -772,7 +772,7 @@ function commonRC.getHMIAppIds() end function commonRC.deleteHMIAppId(pAppId) - hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = nil + hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.fullAppID] = nil end diff --git a/test_scripts/Resumption/ATF_No_Resumption_PersistentData.lua b/test_scripts/Resumption/ATF_No_Resumption_PersistentData.lua index ddaecae91d..7bf4dbe2cc 100644 --- a/test_scripts/Resumption/ATF_No_Resumption_PersistentData.lua +++ b/test_scripts/Resumption/ATF_No_Resumption_PersistentData.lua @@ -136,7 +136,7 @@ local applicationData = --ToDo: shall be removed when APPLINK-16610 is fixed config.defaultProtocolVersion = 2 - local storagePath = config.pathToSDL .. "storage/"..config.application1.registerAppInterfaceParams.appID.. "_" .. config.deviceMAC.. "/" + local storagePath = config.pathToSDL .. "storage/"..config.application1.registerAppInterfaceParams.fullAppID.. "_" .. config.deviceMAC.. "/" local AppValuesOnHMIStatusFULL local AppValuesOnHMIStatusLIMITED diff --git a/test_scripts/Resumption/ATF_Resumption_MultiDevices.lua b/test_scripts/Resumption/ATF_Resumption_MultiDevices.lua index d0975cfadd..4816c11be8 100644 --- a/test_scripts/Resumption/ATF_Resumption_MultiDevices.lua +++ b/test_scripts/Resumption/ATF_Resumption_MultiDevices.lua @@ -33,7 +33,7 @@ local policyTable = require('user_modules/shared_testcases/testCasesForPolicyTab -- User required variables config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" -local appIDAndDeviceMac = config.application1.registerAppInterfaceParams.appID.. "_" .. config.deviceMAC.. "/" +local appIDAndDeviceMac = config.application1.registerAppInterfaceParams.fullAppID.. "_" .. config.deviceMAC.. "/" config.SDLStoragePath = config.pathToSDL .. "storage/" local storagePath = config.SDLStoragePath..appIDAndDeviceMac @@ -697,7 +697,7 @@ local Connections = { application = { appName = config.application1.registerAppInterfaceParams.appName, - policyAppID = config.application1.registerAppInterfaceParams.appID + policyAppID = config.application1.registerAppInterfaceParams.fullAppID }, resumeVrGrammars = true } diff --git a/test_scripts/Resumption/ATF_Resumption_PersistentData.lua b/test_scripts/Resumption/ATF_Resumption_PersistentData.lua index f0ca54256e..ef14f72fb2 100644 --- a/test_scripts/Resumption/ATF_Resumption_PersistentData.lua +++ b/test_scripts/Resumption/ATF_Resumption_PersistentData.lua @@ -101,7 +101,7 @@ local json = require("json") --ToDo: shall be removed when APPLINK-16610 is fixed config.defaultProtocolVersion = 2 - local storagePath = config.pathToSDL .. "storage/"..config.application1.registerAppInterfaceParams.appID.. "_" .. config.deviceMAC.. "/" + local storagePath = config.pathToSDL .. "storage/"..config.application1.registerAppInterfaceParams.fullAppID.. "_" .. config.deviceMAC.. "/" local AppValuesOnHMIStatusFULL local AppValuesOnHMIStatusLIMITED diff --git a/test_scripts/SDL4_0/SDL4_0_OnSystemRequest_QUERY_APPS.lua b/test_scripts/SDL4_0/SDL4_0_OnSystemRequest_QUERY_APPS.lua index e99933e7fa..4a317bf9b5 100644 --- a/test_scripts/SDL4_0/SDL4_0_OnSystemRequest_QUERY_APPS.lua +++ b/test_scripts/SDL4_0/SDL4_0_OnSystemRequest_QUERY_APPS.lua @@ -137,7 +137,7 @@ local function AppRegistration(self, sessionName , iappName , iappID, isMediaFla iappName = config.application1.registerAppInterfaceParams.appName end if iappID == nil then - iappID = config.application1.registerAppInterfaceParams.appID + iappID = config.application1.registerAppInterfaceParams.fullAppID end if isMediaFlag == nil then isMediaFlag = config.application1.registerAppInterfaceParams.isMediaApplication @@ -417,7 +417,7 @@ Precondition_UnregisterRegisterApp("OnSystemRequestQueryAppsOnlyToForegroundApp" function Test:Precondition_RegisterSecondApp() - AppRegistration(self, self.mobileSession1, config.application2.registerAppInterfaceParams.appName , config.application2.registerAppInterfaceParams.appID, config.application2.registerAppInterfaceParams.isMediaApplication) + AppRegistration(self, self.mobileSession1, config.application2.registerAppInterfaceParams.appName , config.application2.registerAppInterfaceParams.fullAppID, config.application2.registerAppInterfaceParams.isMediaApplication) self.mobileSession1:ExpectNotification("OnHMIStatus", { systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE"}) @@ -678,7 +678,7 @@ function Test:AbsenceOnSystemRequestQueryAppsNewRegisteredAppInForeground() SendingOnHMIStatusFromMobile(self, "BACKGROUND", _, _) - AppRegistration(self, self.mobileSession1, config.application2.registerAppInterfaceParams.appName , config.application2.registerAppInterfaceParams.appID, config.application2.registerAppInterfaceParams.isMediaApplication) + AppRegistration(self, self.mobileSession1, config.application2.registerAppInterfaceParams.appName , config.application2.registerAppInterfaceParams.fullAppID, config.application2.registerAppInterfaceParams.isMediaApplication) self.mobileSession1:ExpectNotification("OnHMIStatus", { systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE"}) @@ -742,7 +742,7 @@ end function Test:AbsenceOnSystemRequestQueryAppsToBackgroundApp_SecondApp() userPrint(34, "=================================== Test Case ===================================") - AppRegistration(self, self.mobileSession1, config.application2.registerAppInterfaceParams.appName , config.application2.registerAppInterfaceParams.appID, config.application2.registerAppInterfaceParams.isMediaApplication) + AppRegistration(self, self.mobileSession1, config.application2.registerAppInterfaceParams.appName , config.application2.registerAppInterfaceParams.fullAppID, config.application2.registerAppInterfaceParams.isMediaApplication) self.mobileSession1:ExpectNotification("OnHMIStatus", { systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE"}) @@ -935,7 +935,7 @@ function Test:Precondition_OpenFirstConnectionCreateSession() function Test:OnSystemRequestQueryAppsOnSecondDevice() userPrint(34, "=================================== Test Case ===================================") - AppRegistration(self, self.mobileSession2 , config.application2.registerAppInterfaceParams.appName , config.application2.registerAppInterfaceParams.appID) + AppRegistration(self, self.mobileSession2 , config.application2.registerAppInterfaceParams.appName , config.application2.registerAppInterfaceParams.fullAppID) self.mobileSession2:ExpectNotification("OnHMIStatus", { systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE"}) @@ -1145,7 +1145,7 @@ local function TC_APPLINK_17903() function Test:APPLINK_17903_Step2_RegisterSecondApp() - AppRegistration(self, self.mobileSession1, config.application2.registerAppInterfaceParams.appName , config.application2.registerAppInterfaceParams.appID, config.application2.registerAppInterfaceParams.isMediaApplication) + AppRegistration(self, self.mobileSession1, config.application2.registerAppInterfaceParams.appName , config.application2.registerAppInterfaceParams.fullAppID, config.application2.registerAppInterfaceParams.isMediaApplication) self.mobileSession1:ExpectNotification("OnHMIStatus", { systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE"}) diff --git a/test_scripts/SDL4_6/TTSChunks/common.lua b/test_scripts/SDL4_6/TTSChunks/common.lua index b2772ea258..5367741d66 100644 --- a/test_scripts/SDL4_6/TTSChunks/common.lua +++ b/test_scripts/SDL4_6/TTSChunks/common.lua @@ -62,7 +62,7 @@ end function m.getMobileAppId(pAppId) if not pAppId then pAppId = 1 end - return config["application" .. pAppId].registerAppInterfaceParams.appID + return config["application" .. pAppId].registerAppInterfaceParams.fullAppID end return m diff --git a/test_scripts/Security/DTLS/common.lua b/test_scripts/Security/DTLS/common.lua index fbf4ce0d3c..e6d600fe56 100644 --- a/test_scripts/Security/DTLS/common.lua +++ b/test_scripts/Security/DTLS/common.lua @@ -4,7 +4,7 @@ --[[ General configuration parameters ]] config.SecurityProtocol = "DTLS" config.application1.registerAppInterfaceParams.appName = "server" -config.application1.registerAppInterfaceParams.appID = "SPT" +config.application1.registerAppInterfaceParams.fullAppID = "SPT" -- config.cipherListString = ":SSLv2:AES256-GCM-SHA384" --[[ Required Shared libraries ]] diff --git a/test_scripts/Security/GetSystemTime/common.lua b/test_scripts/Security/GetSystemTime/common.lua index c740341cdf..fa0681cdb2 100644 --- a/test_scripts/Security/GetSystemTime/common.lua +++ b/test_scripts/Security/GetSystemTime/common.lua @@ -21,7 +21,7 @@ local m = actions config.defaultProtocolVersion = 3 config.isCheckClientCertificate = false config.application1.registerAppInterfaceParams.appName = "server" -config.application1.registerAppInterfaceParams.appID = "SPT" +config.application1.registerAppInterfaceParams.fullAppID = "SPT" m.appHMIType = "DEFAULT" config.application1.registerAppInterfaceParams.appHMIType = { m.appHMIType } diff --git a/test_scripts/Security/SSLHandshakeFlow/common.lua b/test_scripts/Security/SSLHandshakeFlow/common.lua index 8c18777eef..e2c606f9bc 100644 --- a/test_scripts/Security/SSLHandshakeFlow/common.lua +++ b/test_scripts/Security/SSLHandshakeFlow/common.lua @@ -13,7 +13,7 @@ local constants = require("protocol_handler/ford_protocol_constants") --[[ General configuration parameters ]] config.SecurityProtocol = "DTLS" config.application1.registerAppInterfaceParams.appName = "server" -config.application1.registerAppInterfaceParams.appID = "SPT" +config.application1.registerAppInterfaceParams.fullAppID = "SPT" --[[ Module ]] local m = actions diff --git a/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua index 751562663d..fc3af8c594 100644 --- a/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua @@ -46,7 +46,7 @@ local putFileParams = { } local storagePath = commonPreconditions:GetPathToSDL() .. "storage/" .. -config.application1.registerAppInterfaceParams.appID .. "_" .. commonSmoke.getDeviceMAC() .. "/" +config.application1.registerAppInterfaceParams.fullAppID .. "_" .. commonSmoke.getDeviceMAC() .. "/" local ImageValue = { value = storagePath .. "icon.png", diff --git a/test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua index 668f77cdea..6d90559750 100644 --- a/test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/037_RegisterAppInterface_PositiveCase_SUCCESS.lua @@ -51,7 +51,8 @@ local requestParams = { appHMIType = { "DEFAULT", }, - appID = "123456", + appID = "123", + fullAppID = "123456", deviceInfo = { hardware = "hardware", firmwareRev = "firmwareRev", @@ -77,7 +78,7 @@ local function SetNotificationParams() transportType = "WIFI", isSDLAllowed = true } - notificationParams.application.policyAppID = requestParams.appID + notificationParams.application.policyAppID = requestParams.fullAppID notificationParams.ttsName = requestParams.ttsName notificationParams.vrSynonyms = requestParams.vrSynonyms return notificationParams diff --git a/test_scripts/Smoke/API/039_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/039_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua index 8ea454da89..a6410261f8 100644 --- a/test_scripts/Smoke/API/039_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/039_PerfomInteraction_Non_Media_PositiveCase_SUCCESS.lua @@ -49,7 +49,7 @@ local putFileParams = { } local storagePath = commonPreconditions:GetPathToSDL() .. "storage/" .. -config.application1.registerAppInterfaceParams.appID .. "_" .. commonSmoke.getDeviceMAC() .. "/" +config.application1.registerAppInterfaceParams.fullAppID .. "_" .. commonSmoke.getDeviceMAC() .. "/" local ImageValue = { value = storagePath .. "icon.png", diff --git a/test_scripts/Smoke/Policies/001_PTU_all_flows.lua b/test_scripts/Smoke/Policies/001_PTU_all_flows.lua index b95d1bf67b..cfc974216b 100644 --- a/test_scripts/Smoke/Policies/001_PTU_all_flows.lua +++ b/test_scripts/Smoke/Policies/001_PTU_all_flows.lua @@ -95,14 +95,14 @@ local function getPTUFromPTS(ptu) -- remove preloaded_date ptu.policy_table.module_config.preloaded_date = nil -- Create structure in app_policies related to registered application - ptu.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = { + ptu.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID] = { keep_context = false, steal_focus = false, priority = "NONE", default_hmi = "NONE" } -- Added permissions for registered app from "Base-4", "Base-6" groups - ptu.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID]["groups"] = { + ptu.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID]["groups"] = { "Base-4", "Base-6" } end diff --git a/test_scripts/Smoke/commonSmoke.lua b/test_scripts/Smoke/commonSmoke.lua index 02f36a8352..5cd398e36f 100644 --- a/test_scripts/Smoke/commonSmoke.lua +++ b/test_scripts/Smoke/commonSmoke.lua @@ -87,7 +87,7 @@ end function commonSmoke.getHMIAppId(pAppId) if not pAppId then pAppId = 1 end - return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.fullAppID] end function commonSmoke.getPathToFileInStorage(fileName) @@ -166,7 +166,7 @@ end function commonSmoke.activateApp(pAppId, self) self, pAppId = commonSmoke.getSelfAndParams(pAppId, self) if not pAppId then pAppId = 1 end - local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.fullAppID] local mobSession = commonSmoke.getMobileSession(pAppId, self) local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) EXPECT_HMIRESPONSE(requestId) @@ -273,7 +273,7 @@ function commonSmoke.registerApp(pAppId, self) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) :Do(function(_, data) - hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = data.params.application.appID + hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.fullAppID] = data.params.application.appID end) mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() diff --git a/test_scripts/TOO_MANY_PENDING_REQUESTS/ATF_DeleteCommand_TOO_MANY_PENDING_REQUESTS.lua b/test_scripts/TOO_MANY_PENDING_REQUESTS/ATF_DeleteCommand_TOO_MANY_PENDING_REQUESTS.lua index 8c6018eaf7..b583fd8d19 100644 --- a/test_scripts/TOO_MANY_PENDING_REQUESTS/ATF_DeleteCommand_TOO_MANY_PENDING_REQUESTS.lua +++ b/test_scripts/TOO_MANY_PENDING_REQUESTS/ATF_DeleteCommand_TOO_MANY_PENDING_REQUESTS.lua @@ -47,7 +47,7 @@ local commonSteps = require('user_modules/shared_testcases/commonSteps') config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when APPLINK-16610 is fixed config.defaultProtocolVersion = 2 -local storagePath = config.pathToSDL .. "storage/" ..config.application1.registerAppInterfaceParams.appID.. "_" .. config.deviceMAC.. "/" +local storagePath = config.pathToSDL .. "storage/" ..config.application1.registerAppInterfaceParams.fullAppID.. "_" .. config.deviceMAC.. "/" local TooManyPenReqCount = 0 local IDsArray = {} @@ -127,7 +127,7 @@ end } }) :ValidIf(function(_,data) - local path = "bin/storage/"..config.application1.registerAppInterfaceParams.appID.. "_" .. config.deviceMAC.. "/" + local path = "bin/storage/"..config.application1.registerAppInterfaceParams.fullAppID.. "_" .. config.deviceMAC.. "/" local value_Icon = path .. "action.png" if(data.params.cmdIcon.imageType == "DYNAMIC") then diff --git a/test_scripts/TOO_MANY_PENDING_REQUESTS/ATF_Show_TOO_MANY_PENDING_REQUESTS.lua b/test_scripts/TOO_MANY_PENDING_REQUESTS/ATF_Show_TOO_MANY_PENDING_REQUESTS.lua index 6c13f59d56..0d505a6649 100644 --- a/test_scripts/TOO_MANY_PENDING_REQUESTS/ATF_Show_TOO_MANY_PENDING_REQUESTS.lua +++ b/test_scripts/TOO_MANY_PENDING_REQUESTS/ATF_Show_TOO_MANY_PENDING_REQUESTS.lua @@ -58,7 +58,7 @@ APIName = "Show" -- use for above required scripts. config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" --ToDo: shall be removed when APPLINK-16610 is fixed config.defaultProtocolVersion = 2 -local storagePath = config.pathToSDL .. "storage/" ..config.application1.registerAppInterfaceParams.appID.. "_" .. config.deviceMAC.. "/" +local storagePath = config.pathToSDL .. "storage/" ..config.application1.registerAppInterfaceParams.fullAppID.. "_" .. config.deviceMAC.. "/" local TooManyPenReqCount = 0 local IDsArray = {} diff --git a/test_scripts/smoke_api.lua b/test_scripts/smoke_api.lua index ff2ebf6b79..e95d9b9518 100644 --- a/test_scripts/smoke_api.lua +++ b/test_scripts/smoke_api.lua @@ -27,7 +27,7 @@ local iTimeout = 5000 local strMaxLengthFileName242 = string.rep("a", 238) .. ".png" -- max is 242 since docker limitation local textPromtValue = {"Please speak one of the following commands,", "Please say a command,"} -local storagePath = commonPreconditions:GetPathToSDL() .. "storage/" .. config.application1.registerAppInterfaceParams.appID .. "_" .. config.deviceMAC .. "/" +local storagePath = commonPreconditions:GetPathToSDL() .. "storage/" .. config.application1.registerAppInterfaceParams.fullAppID .. "_" .. config.deviceMAC .. "/" --------------------------------------------------------------------------------------------- -----------------------------Required Shared Libraries--------------------------------------- @@ -1120,7 +1120,7 @@ function Test:CreateInteractionChoiceSet_PositiveCase() EXPECT_HMICALL("VR.AddCommand", { cmdID = 1001, - appID = self.applications[config.application1.registerAppInterfaceParams.appID], + appID = self.applications[config.application1.registerAppInterfaceParams.fullAppID], type = "Choice", vrCommands = {"Choice1001" } }) diff --git a/user_modules/IsReady_Template/Interfaces_RPC.lua b/user_modules/IsReady_Template/Interfaces_RPC.lua index 64808ad986..cfb6025445 100644 --- a/user_modules/IsReady_Template/Interfaces_RPC.lua +++ b/user_modules/IsReady_Template/Interfaces_RPC.lua @@ -13,7 +13,7 @@ f:close() local json = require("modules/json") local HmiCapabilities = json.decode(fileContent) -local storagePath = config.SDLStoragePath..config.application1.registerAppInterfaceParams.appID.. "_" .. config.deviceMAC.. "/" +local storagePath = config.SDLStoragePath..config.application1.registerAppInterfaceParams.fullAppID.. "_" .. config.deviceMAC.. "/" local function image_field(name, width, heigth) xmlReporter.AddMessage(debug.getinfo(1, "n").name, tostring(name)) diff --git a/user_modules/common_functions.lua b/user_modules/common_functions.lua index 4e465e190e..1bde62de8b 100644 --- a/user_modules/common_functions.lua +++ b/user_modules/common_functions.lua @@ -810,7 +810,7 @@ end ----------------------------------------------------------------------------- function CommonFunctions:GetFullPathIcon(image_file_name, appId) if not appId then - appId = config.application1.registerAppInterfaceParams.appID + appId = config.application1.registerAppInterfaceParams.fullAppID end local full_path_icon = table.concat({config.pathToSDL, "storage/", appId, "_", config.deviceMAC, "/", image_file_name}) return full_path_icon diff --git a/user_modules/shared_testcases/commonSteps.lua b/user_modules/shared_testcases/commonSteps.lua index 78294caaff..606b98c42f 100644 --- a/user_modules/shared_testcases/commonSteps.lua +++ b/user_modules/shared_testcases/commonSteps.lua @@ -194,6 +194,7 @@ function commonSteps:RegisterTheSecondMediaApp() languageDesired ="EN-US", hmiDisplayLanguageDesired ="EN-US", appID ="2", + fullAppID ="2", ttsName = { { diff --git a/user_modules/shared_testcases/testCasesForExternalUCS.lua b/user_modules/shared_testcases/testCasesForExternalUCS.lua index 0b79e8e557..cf81b1c17b 100644 --- a/user_modules/shared_testcases/testCasesForExternalUCS.lua +++ b/user_modules/shared_testcases/testCasesForExternalUCS.lua @@ -78,7 +78,7 @@ local m = { } --! @parameters: NO --]] local function updatePTU() - local appId = config.application1.registerAppInterfaceParams.appID + local appId = config.application1.registerAppInterfaceParams.fullAppID m.pts.policy_table.consumer_friendly_messages.messages = nil m.pts.policy_table.device_data = nil m.pts.policy_table.module_meta = nil @@ -165,7 +165,7 @@ local m = { } --! that has to be passed as an input parameter --]] function m.activateApp(test, id, status, updateFunc) - local appId = config["application"..id].registerAppInterfaceParams.appID + local appId = config["application"..id].registerAppInterfaceParams.fullAppID local reqId = test.hmiConnection:SendRequest("SDL.ActivateApp", { appID = m.HMIAppIds[appId] }) EXPECT_HMIRESPONSE(reqId) :Do(function(_, d1) diff --git a/user_modules/shared_testcases/testCasesForImageParameterInNotification.lua b/user_modules/shared_testcases/testCasesForImageParameterInNotification.lua index 14d36f8ed3..b07c4eff44 100644 --- a/user_modules/shared_testcases/testCasesForImageParameterInNotification.lua +++ b/user_modules/shared_testcases/testCasesForImageParameterInNotification.lua @@ -6,7 +6,7 @@ local testCasesForImageParameter = {} local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local enumerationParameter = require('user_modules/shared_testcases/testCasesForEnumerationParameterInNotification') -local storagePath = config.pathToSDL..config.application1.registerAppInterfaceParams.appID.. "_" .. config.deviceMAC.. "/" +local storagePath = config.pathToSDL..config.application1.registerAppInterfaceParams.fullAppID.. "_" .. config.deviceMAC.. "/" --------------------------------------------------------------------------------------------- --Test cases to verify Image Parameter --------------------------------------------------------------------------------------------- diff --git a/user_modules/shared_testcases/testCasesForPerformAudioPassThru.lua b/user_modules/shared_testcases/testCasesForPerformAudioPassThru.lua index 08df9aeead..8d939ca288 100644 --- a/user_modules/shared_testcases/testCasesForPerformAudioPassThru.lua +++ b/user_modules/shared_testcases/testCasesForPerformAudioPassThru.lua @@ -8,7 +8,7 @@ local SDLConfig = require('user_modules/shared_testcases/SmartDeviceLinkConfigur local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local config_path_sdl = commonPreconditions:GetPathToSDL() -local PathToAppFolder = config_path_sdl .. SDLConfig:GetValue("AppStorageFolder") .. "/" .. tostring(config.application1.registerAppInterfaceParams.appID .. "_" .. tostring(config.deviceMAC) .. "/") +local PathToAppFolder = config_path_sdl .. SDLConfig:GetValue("AppStorageFolder") .. "/" .. tostring(config.application1.registerAppInterfaceParams.fullAppID .. "_" .. tostring(config.deviceMAC) .. "/") local testCasesForPerformAudioPassThru = {} diff --git a/user_modules/shared_testcases/testCasesForPolicyTable.lua b/user_modules/shared_testcases/testCasesForPolicyTable.lua index 1ff3c9d587..39b16bb851 100644 --- a/user_modules/shared_testcases/testCasesForPolicyTable.lua +++ b/user_modules/shared_testcases/testCasesForPolicyTable.lua @@ -897,7 +897,7 @@ end -- Difference with PROPRIETARY flow is clarified in "Can you clarify is PTU flows for External_Proprietary and Proprietary have differences?" -- But this should be checked in appropriate scripts function testCasesForPolicyTable:flow_SUCCEESS_EXTERNAL_PROPRIETARY(self, app_id, device_id, hmi_app_id, ptu_file_path, ptu_file_name, ptu_file) - if (app_id == nil) then app_id = config.application1.registerAppInterfaceParams.appID end + if (app_id == nil) then app_id = config.application1.registerAppInterfaceParams.fullAppID end if (device_id == nil) then device_id = utils.getDeviceMAC() end if (hmi_app_id == nil) then hmi_app_id = self.applications[config.application1.registerAppInterfaceParams.appName] end if (ptu_file_path == nil) then ptu_file_path = "files/" end @@ -966,7 +966,7 @@ function testCasesForPolicyTable:trigger_user_request_update_from_HMI(self) EXPECT_HMICALL("BasicCommunication.PolicyUpdate", { file = "/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json"}) :Do(function(_,data) testCasesForPolicyTableSnapshot:verify_PTS(true, - {config.application1.registerAppInterfaceParams.appID }, + {config.application1.registerAppInterfaceParams.fullAppID }, {utils.getDeviceMAC()}, {hmi_app1_id}) @@ -1021,7 +1021,7 @@ function testCasesForPolicyTable:trigger_getting_device_consent(self, app_name, EXPECT_HMICALL("BasicCommunication.PolicyUpdate", {file = "/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json"}) :Do(function(_,data) testCasesForPolicyTableSnapshot:verify_PTS(true, - {config.application1.registerAppInterfaceParams.appID }, + {config.application1.registerAppInterfaceParams.fullAppID }, {utils.getDeviceMAC()}, {hmi_app1_id}) @@ -1076,7 +1076,7 @@ function testCasesForPolicyTable:trigger_PTU_user_press_button_HMI(self, execute EXPECT_HMICALL("BasicCommunication.PolicyUpdate", {file = "/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json"}) :Do(function(_,data) testCasesForPolicyTableSnapshot:verify_PTS(true, - {config.application1.registerAppInterfaceParams.appID }, + {config.application1.registerAppInterfaceParams.fullAppID }, {utils.getDeviceMAC()}, {hmi_app1_id}) From a390f746c0b6dec12529aaedd41de8eb60d83ad4 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 26 Jul 2018 14:43:33 +0300 Subject: [PATCH 495/681] Add validation on absence of parameter --- .../DOP/003_GVD_missing_one_parameter_SUCCESS.lua | 3 +++ .../DOP/006_OVD_missing_one_parameter_SUCCESS.lua | 3 +++ .../DOP/008_GVD_missing_all_parameters_SUCCESS.lua | 10 ++++++++++ .../DOP/010_OVD_missing_all_parameters_SUCCESS.lua | 10 ++++++++++ test_scripts/API/VehicleData/DOP/common.lua | 7 +++++++ 5 files changed, 33 insertions(+) diff --git a/test_scripts/API/VehicleData/DOP/003_GVD_missing_one_parameter_SUCCESS.lua b/test_scripts/API/VehicleData/DOP/003_GVD_missing_one_parameter_SUCCESS.lua index 4df50b47f3..e7887f5f52 100644 --- a/test_scripts/API/VehicleData/DOP/003_GVD_missing_one_parameter_SUCCESS.lua +++ b/test_scripts/API/VehicleData/DOP/003_GVD_missing_one_parameter_SUCCESS.lua @@ -29,6 +29,9 @@ local function sendGetVehicleData(pParam) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { gps = gpsData }) end) common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", gps = gpsData }) + :ValidIf(function(_, data) + return common.checkAbsenceOfParam(pParam, data) + end) end --[[ Scenario ]] diff --git a/test_scripts/API/VehicleData/DOP/006_OVD_missing_one_parameter_SUCCESS.lua b/test_scripts/API/VehicleData/DOP/006_OVD_missing_one_parameter_SUCCESS.lua index 59ed4b02d2..00192bb704 100644 --- a/test_scripts/API/VehicleData/DOP/006_OVD_missing_one_parameter_SUCCESS.lua +++ b/test_scripts/API/VehicleData/DOP/006_OVD_missing_one_parameter_SUCCESS.lua @@ -24,6 +24,9 @@ local function sendOnVehicleData(pParam) gpsData[pParam] = value common.getHMIConnection():SendNotification("VehicleInfo.OnVehicleData", { gps = gpsData }) common.getMobileSession():ExpectNotification("OnVehicleData", { gps = gpsData }) + :ValidIf(function(_, data) + return common.checkAbsenceOfParam(pParam, data) + end) end --[[ Scenario ]] diff --git a/test_scripts/API/VehicleData/DOP/008_GVD_missing_all_parameters_SUCCESS.lua b/test_scripts/API/VehicleData/DOP/008_GVD_missing_all_parameters_SUCCESS.lua index 7397280a76..6643cbeed5 100644 --- a/test_scripts/API/VehicleData/DOP/008_GVD_missing_all_parameters_SUCCESS.lua +++ b/test_scripts/API/VehicleData/DOP/008_GVD_missing_all_parameters_SUCCESS.lua @@ -15,6 +15,7 @@ local runner = require('user_modules/script_runner') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false +config.checkAllValidations = true --[[ Local Variables ]] local value = nil @@ -31,6 +32,15 @@ local function sendGetVehicleData() common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { gps = gpsData }) end) common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", gps = gpsData }) + :ValidIf(function(_, data) + return common.checkAbsenceOfParam(common.params[1], data) + end) + :ValidIf(function(_, data) + return common.checkAbsenceOfParam(common.params[2], data) + end) + :ValidIf(function(_, data) + return common.checkAbsenceOfParam(common.params[3], data) + end) end --[[ Scenario ]] diff --git a/test_scripts/API/VehicleData/DOP/010_OVD_missing_all_parameters_SUCCESS.lua b/test_scripts/API/VehicleData/DOP/010_OVD_missing_all_parameters_SUCCESS.lua index 24c9f87a66..a308f7abb9 100644 --- a/test_scripts/API/VehicleData/DOP/010_OVD_missing_all_parameters_SUCCESS.lua +++ b/test_scripts/API/VehicleData/DOP/010_OVD_missing_all_parameters_SUCCESS.lua @@ -14,6 +14,7 @@ local runner = require('user_modules/script_runner') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false +config.checkAllValidations = true --[[ Local Variables ]] local value = nil @@ -26,6 +27,15 @@ local function sendOnVehicleData() end common.getHMIConnection():SendNotification("VehicleInfo.OnVehicleData", { gps = gpsData }) common.getMobileSession():ExpectNotification("OnVehicleData", { gps = gpsData }) + :ValidIf(function(_, data) + return common.checkAbsenceOfParam(common.params[1], data) + end) + :ValidIf(function(_, data) + return common.checkAbsenceOfParam(common.params[2], data) + end) + :ValidIf(function(_, data) + return common.checkAbsenceOfParam(common.params[3], data) + end) end --[[ Scenario ]] diff --git a/test_scripts/API/VehicleData/DOP/common.lua b/test_scripts/API/VehicleData/DOP/common.lua index 2a63ff9404..6eacf07cec 100644 --- a/test_scripts/API/VehicleData/DOP/common.lua +++ b/test_scripts/API/VehicleData/DOP/common.lua @@ -52,4 +52,11 @@ function m.subscribeVehicleData() m.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", gps = gpsResponseData }) end +function m.checkAbsenceOfParam(pParam, pData) + if pData.payload[pParam] ~= nil then + return false, "Parameter '" .. pParam .. "' is not expected" + end + return true +end + return m From 83706ef541c56422bccc875f333967351d71e91b Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 26 Jul 2018 16:44:23 +0300 Subject: [PATCH 496/681] Fix script for 'Ignition Off' signal without 'Low Voltage' case --- ...ake_Up_and_Ignition_Off_wo_Low_Voltage.lua | 21 ++++++++++++--- test_scripts/LowVoltage/common.lua | 27 ++++++++++--------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/test_scripts/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua b/test_scripts/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua index 05e337dfd1..ecbc0555f6 100644 --- a/test_scripts/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua +++ b/test_scripts/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua @@ -3,8 +3,8 @@ -- 1) SDL is started (there was no LOW_VOLTAGE signal sent) -- 2) SDL get IGNITION_OFF or WAKE_UP signal -- SDL does: --- 1) Ignore signal WAKE_UP and continue working as usual --- 2) Process IGNITION_OFF signal and shut down successfully +-- 1) Ignore WAKE_UP signal and continue working as usual +-- 2) Ignore IGNITION_OFF signal and continue working as usual --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local common = require('test_scripts/LowVoltage/common') @@ -24,6 +24,19 @@ local function processAddCommandSuccessfully() common.getMobileSession():ExpectNotification("OnHashChange") end +local function sendIgnitionOffSignal() + common.sendSignal("IGNITION_OFF") + os.execute("sleep 1") +end + +local function isSDLRunning() + if common.SDL:CheckStatusSDL() ~= common.SDL.RUNNING then + common.failTestCase("SDL is stopped") + else + common.cprint(35, "SDL is running") + end +end + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) @@ -35,8 +48,8 @@ runner.Step("Activate App", common.activateApp) runner.Title("Test") runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) runner.Step("AddCommand success", processAddCommandSuccessfully) -runner.Step("Send IGNITION_OFF signal", common.sendIgnitionOffSignal) -runner.Step("Check SDL stopped", common.isSDLStopped) +runner.Step("Send IGNITION_OFF signal", sendIgnitionOffSignal) +runner.Step("Check SDL is not stopped", isSDLRunning) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/LowVoltage/common.lua b/test_scripts/LowVoltage/common.lua index 7d78cc89ae..622b9ad17f 100644 --- a/test_scripts/LowVoltage/common.lua +++ b/test_scripts/LowVoltage/common.lua @@ -21,6 +21,7 @@ local m = actions m.cprint = utils.cprint m.wait = utils.wait +m.SDL = SDL --[[ Constants ]] m.appParams = { @@ -241,11 +242,21 @@ function m.sendLowVoltageSignal() m.wait() end +--[[ @failTestCase: fail test case +--! @parameters: +--! pCause - message with reason of the fail +--! @return: none +--]] +function m.failTestCase(pCause) + test:FailTestCase(pCause) +end + --[[ @sendIgnitionOffSignal: send 'IGNITION_OFF' signal --! @parameters: none --! @return: none --]] function m.sendIgnitionOffSignal() + local isSDLStoppedByItself = true m.sendSignal("IGNITION_OFF") os.execute("sleep 1") local count = 0 @@ -254,9 +265,13 @@ function m.sendIgnitionOffSignal() if count == 10 then SDL:StopSDL() waitUntilSDLLoggerIsClosed() + isSDLStoppedByItself = false end os.execute("sleep 1") end + if not isSDLStoppedByItself then + m.failTestCase("SDL was not stopped") + end end --[[ @sendWakeUpSignal: send 'WAKE_UP' signal @@ -292,18 +307,6 @@ function m.waitUntilResumptionDataIsStored() end end ---[[ @isSDLStopped: verifies if SDL stopped ---! @parameters: none ---! @return: none ---]] -function m.isSDLStopped() - local s = SDL:CheckStatusSDL() - if s ~= SDL.STOPPED then - return test:FailTestCase("SDL is not stopped") - end - utils.cprint(35, "SDL stopped") -end - m.rpcSend.AddCommand = function(pAppId, pCommandId) if not pCommandId then pCommandId = 1 end local cmd = "CMD" .. pCommandId From ea85c0836c8d702fa712da1dbed6f78306949a18 Mon Sep 17 00:00:00 2001 From: Conlain Kelly Date: Thu, 26 Jul 2018 09:49:49 -0400 Subject: [PATCH 497/681] Fix comments & naming, run correct noVR test --- .../API/012_PerfomInteraction_PositiveCase_SUCCESS.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua index 027202cac8..9df699a092 100644 --- a/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua @@ -128,7 +128,7 @@ local function setChoiceSet(choiceIDValue) return temp end ---! @setChoiceSet: Creates Choice structure without VRcommands +--! @setChoiceSet_noVR: Creates Choice structure without VRcommands --! @parameters: --! choiceIDValue - Id for created choice --! @return: table of created choice structure @@ -231,7 +231,7 @@ local function CreateInteractionChoiceSet(choiceSetID, self) self.mobileSession1:ExpectResponse(cid, { resultCode = "SUCCESS", success = true }) end ---! @CreateInteractionChoiceSet: Creation of Choice Set with no vrCommands +--! @CreateInteractionChoiceSet_noVR: Creation of Choice Set with no vrCommands --! @parameters: --! choiceSetID - id for choice set --! self - test object @@ -397,8 +397,8 @@ runner.Step("CreateInteractionChoiceSet no VR commands with id 400", CreateInter runner.Title("Test") runner.Step("PerformInteraction with VR_ONLY interaction mode", PI_PerformViaVR_ONLY, {requestParams}) runner.Step("PerformInteraction with MANUAL_ONLY interaction mode", PI_PerformViaMANUAL_ONLY, {requestParams}) +runner.Step("PerformInteraction with MANUAL_ONLY interaction mode no VR commands", PI_PerformViaMANUAL_ONLY, {requestParams_noVR}) runner.Step("PerformInteraction with BOTH interaction mode", PI_PerformViaBOTH, {requestParams}) -runner.Step("PerformInteraction with MANUAL_ONLY interaction mode no VR commands", PI_PerformViaMANUAL_ONLY, {requestParams}) runner.Title("Postconditions") From 5330bd050ea96fab4af514b6a6c7e0facc9efd29 Mon Sep 17 00:00:00 2001 From: Conlain Kelly Date: Thu, 26 Jul 2018 10:46:27 -0400 Subject: [PATCH 498/681] use full app id in onrcstatus code --- test_scripts/RC/OnRCStatus/commonOnRCStatus.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua index c2d9ac5217..61ef8dff7f 100644 --- a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua +++ b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua @@ -158,7 +158,7 @@ function m.getHMIAppIdsRC() for appID, hmiAppId in pairs(commonRC.getHMIAppIds()) do for i = 1, 5 do local params = config["application" .. i].registerAppInterfaceParams - if params.appID == appID and params.appHMIType[1] == "REMOTE_CONTROL" then + if params.fullAppID == appID and params.appHMIType[1] == "REMOTE_CONTROL" then table.insert(out, hmiAppId) end end From ea7b8d3195f0dfaa78e12a1b688246e98cd83826 Mon Sep 17 00:00:00 2001 From: Ashwin Karemore Date: Thu, 28 Jun 2018 16:47:36 +0200 Subject: [PATCH 499/681] tests for image not available in storage --- test_scripts/API/ATF_AddCommand.lua | 50 +++ test_scripts/API/ATF_Alert.lua | 181 +++++++++++ .../API/ATF_CreateInteractionChoiceSet.lua | 51 +++ test_scripts/API/ATF_PerformInteraction.lua | 67 ++++ test_scripts/API/ATF_SetGlobalProperties.lua | 216 ++++++++++++- test_scripts/API/ATF_Show.lua | 298 ++++++++++++++++++ 6 files changed, 858 insertions(+), 5 deletions(-) diff --git a/test_scripts/API/ATF_AddCommand.lua b/test_scripts/API/ATF_AddCommand.lua index ba446d07af..f67d9c919c 100644 --- a/test_scripts/API/ATF_AddCommand.lua +++ b/test_scripts/API/ATF_AddCommand.lua @@ -1276,6 +1276,56 @@ end end --End Test case CommonRequestCheck.4.9 + ----------------------------------------------------------------------------------------- + + --Begin Test case CommonRequestCheck.4.10 + --Description: Mandatory missing - vrCommands + function Test:AddCommand_iconNotSent() + --mobile side: sending AddCommand request + local cid = self.mobileSession:SendRPC("AddCommand", + { + cmdID = 511, + menuParams = + { + parentID = 1, + position = 0, + menuName ="Command511" + }, + cmdIcon = + { + value ="missed_icon.png", + imageType ="DYNAMIC" + } + }) + + --hmi side: expect UI.AddCommand request + EXPECT_HMICALL("UI.AddCommand", + { + cmdID = 511, + menuParams = + { + parentID = 1, + position = 0, + menuName ="Command511" + }, + cmdIcon = + { + value ="missed_icon.png", + imageType ="DYNAMIC" + } + }) + :Do(function(_,data) + --hmi side: sending UI.AddCommand response + self.hmiConnection:SendResponse(data.id, data.method, "WARNINGS", {info = "Requested image(s) not found."}) + end) + + --mobile side: expect AddCommand response + EXPECT_RESPONSE(cid, { success = true, resultCode = "WARNINGS" }) + + --mobile side: expect OnHashChange notification + EXPECT_NOTIFICATION("OnHashChange") + end + --End Test case CommonRequestCheck.4.10 --End Test case CommonRequestCheck.4 ----------------------------------------------------------------------------------------- diff --git a/test_scripts/API/ATF_Alert.lua b/test_scripts/API/ATF_Alert.lua index 97cfc0503e..3c95f7968a 100644 --- a/test_scripts/API/ATF_Alert.lua +++ b/test_scripts/API/ATF_Alert.lua @@ -10941,6 +10941,7 @@ end --End Test case ResultCodeCheck.2 --Begin Test case ResultCodeCheck.3 + --Begin Test case ResultCodeCheck.3.1 --Description: Check WARNINGS result code wirh success true --Requirement id in JAMA: SDLAQ-CRS-1029 @@ -11046,6 +11047,186 @@ end end + --Begin Test case ResultCodeCheck.3.2 + --Description:SoftButtons: type = IMAGE; image value is missing + + function Test:Alert_SoftButtonIMAGEValueNotAvailanbleInStorage() + + --mobile side: Alert request + local CorIdAlert = self.mobileSession:SendRPC("Alert", + { + + alertText1 = "alertText1", + alertText2 = "alertText2", + alertText3 = "alertText3", + ttsChunks = + { + + { + text = "TTSChunk", + type = "TEXT", + } + }, + duration = 3000, + playTone = true, + progressIndicator = true, + softButtons = + { + + { + type = "BOTH", + text = "Close", + image = + + { + value = "icon.png", + imageType = "DYNAMIC", + }, + isHighlighted = true, + softButtonID = 3, + systemAction = "DEFAULT_ACTION", + }, + + { + type = "TEXT", + text = "Keep", + isHighlighted = true, + softButtonID = 4, + systemAction = "KEEP_CONTEXT", + }, + + { + type = "IMAGE", + image = + + { + value = "icon.png", + imageType = "DYNAMIC", + }, + softButtonID = 5, + systemAction = "STEAL_FOCUS", + }, + } + + }) + + local AlertId + --hmi side: UI.Alert request + EXPECT_HMICALL("UI.Alert", + { + alertStrings = + { + {fieldName = "alertText1", fieldText = "alertText1"}, + {fieldName = "alertText2", fieldText = "alertText2"}, + {fieldName = "alertText3", fieldText = "alertText3"} + }, + alertType = "BOTH", + duration = 0, + progressIndicator = true, + softButtons = + { + + { + type = "BOTH", + text = "Close", + --[[ TODO: update after resolving APPLINK-16052 + + + image = + + { + value = config.SDLStoragePath..config.application1.registerAppInterfaceParams.appID.. "_" .. config.deviceMAC.."/icon.png", + imageType = "DYNAMIC", + },]] + isHighlighted = true, + softButtonID = 3, + systemAction = "DEFAULT_ACTION", + }, + + { + type = "TEXT", + text = "Keep", + isHighlighted = true, + softButtonID = 4, + systemAction = "KEEP_CONTEXT", + }, + + { + type = "IMAGE", + --[[ TODO: update after resolving APPLINK-16052 + + image = + + { + value = config.SDLStoragePath .. config.application1.registerAppInterfaceParams.appID .. "_" .. config.deviceMAC .. "/icon.png", + imageType = "DYNAMIC", + },]] + softButtonID = 5, + systemAction = "STEAL_FOCUS", + }, + } + }) + :Do(function(_,data) + SendOnSystemContext(self,"ALERT") + AlertId = data.id + + local function alertResponse() + self.hmiConnection:SendResponse(AlertId, "UI.Alert", "WARNINGS", {info="Requested image(s) not found."}) + + SendOnSystemContext(self,"MAIN") + end + + RUN_AFTER(alertResponse, 3000) + end) + + local SpeakId + --hmi side: TTS.Speak request + EXPECT_HMICALL("TTS.Speak", + { + ttsChunks = + { + + { + text = "TTSChunk", + type = "TEXT" + } + }, + speakType = "ALERT", + playTone = true + }) + :Do(function(_,data) + self.hmiConnection:SendNotification("TTS.Started") + SpeakId = data.id + + local function speakResponse() + self.hmiConnection:SendResponse(SpeakId, "TTS.Speak", "SUCCESS", { }) + + self.hmiConnection:SendNotification("TTS.Stopped") + end + + RUN_AFTER(speakResponse, 2000) + + end) + :ValidIf(function(_,data) + if #data.params.ttsChunks == 1 then + return true + else + print("ttsChunks array in TTS.Speak request has wrong element number. Expected 1, actual "..tostring(#data.params.ttsChunks)) + return false + end + end) + + -- due to CRQ APPLINK-17388 this notification is commented out, playTone parameter is moved to TTS.Speak + --hmi side: BC.PalayTone request + -- EXPECT_HMINOTIFICATION("BasicCommunication.PlayTone",{ methodName = "ALERT"}) + + ExpectOnHMIStatusWithAudioStateChanged(self) + + --mobile side: Alert response + EXPECT_RESPONSE(CorIdAlert, { success = true, resultCode = "WARNINGS", info="Requested image(s) not found." }) + end + + --End Test case ResultCodeCheck.3.2 --End Test case ResultCodeCheck.3 --Begin Test case ResultCodeCheck.4 diff --git a/test_scripts/API/ATF_CreateInteractionChoiceSet.lua b/test_scripts/API/ATF_CreateInteractionChoiceSet.lua index 4647a97302..cda9a898d9 100644 --- a/test_scripts/API/ATF_CreateInteractionChoiceSet.lua +++ b/test_scripts/API/ATF_CreateInteractionChoiceSet.lua @@ -651,6 +651,57 @@ end end --End Test case CommonRequestCheck.3.10 + --Begin Test case CommonRequestCheck.4 + + function Test:CreateInteractionChoiceSet_InvalidImage() + --mobile side: sending CreateInteractionChoiceSet request + local cid = self.mobileSession:SendRPC("CreateInteractionChoiceSet", + { + interactionChoiceSetID = 1108, + choiceSet = + { + + { + choiceID = 1108, + menuName ="Choice1108", + vrCommands = + { + "Choice1108", + }, + image = + { + value ="notavailable.png", + imageType ="DYNAMIC", + }, + } + } + }) + + + --hmi side: expect VR.AddCommand request + EXPECT_HMICALL("VR.AddCommand", + { + cmdID = 1108, + appID = applicationID, + type = "Choice", + vrCommands = {"Choice1108" } + }) + :Do(function(_,data) + --hmi side: sending VR.AddCommand response + grammarIDValue = data.params.grammarID + self.hmiConnection:SendResponse(data.id, data.method, "WARNINGS", {info="Requested image(s) not found."}) + end) + + --mobile side: expect CreateInteractionChoiceSet response + EXPECT_RESPONSE(cid, { success = true, resultCode = "WARNINGS",info="Requested image(s) not found." }) + + --mobile side: expect OnHashChange notification + EXPECT_NOTIFICATION("OnHashChange") + end + --End Test case CommonRequestCheck.4 + + ----------------------------------------------------------------------------------------- + --Begin Test case CommonRequestCheck.3 ----------------------------------------------------------------------------------------- diff --git a/test_scripts/API/ATF_PerformInteraction.lua b/test_scripts/API/ATF_PerformInteraction.lua index 1ed433d5a6..34071a180d 100644 --- a/test_scripts/API/ATF_PerformInteraction.lua +++ b/test_scripts/API/ATF_PerformInteraction.lua @@ -187,6 +187,44 @@ function setChoiseSet(choiceIDValue, size) return temp end end + +function setChoiseSetWithInvalidImage(choiceIDValue, size) + if (size == nil) then + local temp = {{ + choiceID = choiceIDValue, + menuName ="Choice" .. tostring(choiceIDValue), + vrCommands = + { + "VrChoice" .. tostring(choiceIDValue), + }, + image = + { + value ="notavailable.png", + imageType ="STATIC", + } + }} + return temp + else + local temp = {} + for i = 1, size do + temp[i] = { + choiceID = choiceIDValue+i-1, + menuName ="Choice" .. tostring(choiceIDValue+i-1), + vrCommands = + { + "VrChoice" .. tostring(choiceIDValue+i-1), + }, + image = + { + value ="notavailable.png", + imageType ="STATIC", + } + } + end + return temp + end +end + function setImage() local temp = { value = "icon.png", @@ -1068,6 +1106,35 @@ function Test:activationApp(appIDValue) end end --End Precondition.6 + ----------------------------------------------------------------------------------------- + + --Begin Precondition.7 + --Description: CreateInteractionChoiceSet + Test["CreateInteractionChoiceSetWithInValidImage"] = function(self) + --mobile side: sending CreateInteractionChoiceSet request + local infoText = "Requested image(s) not found." + cid = self.mobileSession:SendRPC("CreateInteractionChoiceSet", + { + interactionChoiceSetID = 500, + choiceSet = setChoiseSetWithInvalidImage(500), + }) + + --hmi side: expect VR.AddCommand + EXPECT_HMICALL("VR.AddCommand", + { + cmdID = 500, + type = "Choice", + vrCommands = {"VrChoice"..tostring(500) } + }) + :Do(function(_,data) + --hmi side: sending VR.AddCommand response + self.hmiConnection:SendResponse(data.id, data.method, "WARNINGS", {}) + end) + + --mobile side: expect CreateInteractionChoiceSet response + EXPECT_RESPONSE(cid, { success = true,resultCode = "SUCCESS" }) + end + --End Precondition.7 -- ---------------------------------------------------------------------------------------------- -- -----------------------------------------VI TEST BLOCK---------------------------------------- diff --git a/test_scripts/API/ATF_SetGlobalProperties.lua b/test_scripts/API/ATF_SetGlobalProperties.lua index 5220f7dd9b..6e41654c5b 100644 --- a/test_scripts/API/ATF_SetGlobalProperties.lua +++ b/test_scripts/API/ATF_SetGlobalProperties.lua @@ -310,7 +310,7 @@ end --Verification criteria: --SetGlobalProperties sets-up global properties for the current application. --SDL sets-up default values for "vrHelpTitle" and "vrHelp" parameters if they both don't exist in request. - --VRHelpTitle and VRHelpItems are sent with SetGlobalProperties request for setting app’s help items. HMI will open by itself a top level HelpList as a result of VR activation. + --VRHelpTitle and VRHelpItems are sent with SetGlobalProperties request for setting app�s help items. HMI will open by itself a top level HelpList as a result of VR activation. --Begin test case CommonRequestCheck.1 @@ -2033,7 +2033,213 @@ end --End test case CommonRequestCheck.20 ----------------------------------------------------------------------------------------- + --Begin test case CommonRequestCheck.21 + --Description: Check request with all parameters + function Test:SetGlobalProperties_ImageNotAvailableInStorag_WARNINGS() + + --mobile side: sending SetGlobalProperties request + local cid = self.mobileSession:SendRPC("SetGlobalProperties", + { + menuTitle = "Menu Title", + timeoutPrompt = + { + { + text = "Timeout prompt duplicate", + type = "TEXT" + } + }, + vrHelp = + { + { + position = 1, + image = + { + value = "action.png", + imageType = "DYNAMIC" + }, + text = "VR help item" + } + }, + menuIcon = + { + value = "imagenotavailable.png", + imageType = "DYNAMIC" + }, + helpPrompt = + { + { + text = "Help prompt", + type = "TEXT" + } + }, + vrHelpTitle = "VR help title", + keyboardProperties = + { + keyboardLayout = "QWERTY", + keypressMode = "SINGLE_KEYPRESS", + limitedCharacterList = + { + "a" + }, + language = "EN-US", + autoCompleteText = "Daemon, Freedom" + } + }) + + + --hmi side: expect TTS.SetGlobalProperties request + EXPECT_HMICALL("TTS.SetGlobalProperties") + :Times(2) + :Do(function(_,data) + --hmi side: sending UI.SetGlobalProperties response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + + --hmi side: expect UI.SetGlobalProperties request + EXPECT_HMICALL("UI.SetGlobalProperties") + :Times(2) + :Do(function(_,data) + --hmi side: sending UI.SetGlobalProperties response + self.hmiConnection:SendResponse(data.id, data.method, "WARNINGS", {info ="Requested image(s) not found."}) + end) + :Do(function(exp,data) + if exp.occurences == 1 then + local msg = + { + serviceType = 7, + frameInfo = 0, + rpcType = 0, + rpcFunctionId = 3, --SetGlobalPropertiesID + rpcCorrelationId = cid, + payload = '{"vrHelp":[{"image":{"imageType":"DYNAMIC","value":"action.png"},"position":1,"text":"VR help item"}],"helpPrompt":[{"type":"TEXT","text":"Help prompt"}],"menuTitle":"Menu Title","vrHelpTitle":"VR help title","timeoutPrompt":[{"type":"TEXT","text":"Timeout prompt duplicate"}],"menuIcon":{"imageType":"DYNAMIC","value":"action.png"}}' + } + + self.mobileSession:Send(msg) + end + + --hmi side: sending UI.SetGlobalProperties response + self.hmiConnection:SendResponse(data.id, data.method, "WARNINGS", {info ="Requested image(s) not found."}) + + end) + + + --mobile side: expect SetGlobalProperties response + EXPECT_RESPONSE(cid, { success = true, resultCode = "WARNINGS",info ="Requested image(s) not found."}) + :Times(2) + + --mobile side: expect OnHashChange notification + EXPECT_NOTIFICATION("OnHashChange") + :Times(2) + end + --End test case CommonRequestCheck.21 + ----------------------------------------------------------------------------------------- + + --Begin test case CommonRequestCheck.22 + --Description: Check request with all parameters + + function Test:SetGlobalProperties_VRImageNotAvailableInStorag_WARNINGS() + + --mobile side: sending SetGlobalProperties request + local cid = self.mobileSession:SendRPC("SetGlobalProperties", + { + menuTitle = "Menu Title", + timeoutPrompt = + { + { + text = "Timeout prompt duplicate", + type = "TEXT" + } + }, + vrHelp = + { + { + position = 1, + image = + { + value = "imagenotavailable.png", + imageType = "DYNAMIC" + }, + text = "VR help item" + } + }, + menuIcon = + { + value = "action.png", + imageType = "DYNAMIC" + }, + helpPrompt = + { + { + text = "Help prompt", + type = "TEXT" + } + }, + vrHelpTitle = "VR help title", + keyboardProperties = + { + keyboardLayout = "QWERTY", + keypressMode = "SINGLE_KEYPRESS", + limitedCharacterList = + { + "a" + }, + language = "EN-US", + autoCompleteText = "Daemon, Freedom" + } + }) + + + --hmi side: expect TTS.SetGlobalProperties request + EXPECT_HMICALL("TTS.SetGlobalProperties") + :Times(2) + :Do(function(_,data) + --hmi side: sending UI.SetGlobalProperties response + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + + + --hmi side: expect UI.SetGlobalProperties request + EXPECT_HMICALL("UI.SetGlobalProperties") + :Times(2) + :Do(function(_,data) + --hmi side: sending UI.SetGlobalProperties response + self.hmiConnection:SendResponse(data.id, data.method, "WARNINGS", {info ="Requested image(s) not found."}) + end) + :Do(function(exp,data) + if exp.occurences == 1 then + local msg = + { + serviceType = 7, + frameInfo = 0, + rpcType = 0, + rpcFunctionId = 3, --SetGlobalPropertiesID + rpcCorrelationId = cid, + payload = '{"vrHelp":[{"image":{"imageType":"DYNAMIC","value":"action.png"},"position":1,"text":"VR help item"}],"helpPrompt":[{"type":"TEXT","text":"Help prompt"}],"menuTitle":"Menu Title","vrHelpTitle":"VR help title","timeoutPrompt":[{"type":"TEXT","text":"Timeout prompt duplicate"}],"menuIcon":{"imageType":"DYNAMIC","value":"action.png"}}' + } + + self.mobileSession:Send(msg) + end + + --hmi side: sending UI.SetGlobalProperties response + self.hmiConnection:SendResponse(data.id, data.method, "WARNINGS", {info ="Requested image(s) not found."}) + + end) + + + --mobile side: expect SetGlobalProperties response + EXPECT_RESPONSE(cid, { success = true, resultCode = "WARNINGS",info ="Requested image(s) not found."}) + :Times(2) + + --mobile side: expect OnHashChange notification + EXPECT_NOTIFICATION("OnHashChange") + :Times(2) + end + --End test case CommonRequestCheck.22 + ----------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------- @@ -35873,7 +36079,7 @@ end ----------------------------------------------------------------------------------------- --Begin test case SequenceCheck.3 - --Description: Check for manual test case TC_SetGlobalProperties_02: SDL sends TTS.SetGlobalProperties request in 20 seconds from activation to FULL with the default list of HelpPrompts is a list of TTSChunks ( UI commands) defined as “TEXT” type, which are the list of the commands. + --Description: Check for manual test case TC_SetGlobalProperties_02: SDL sends TTS.SetGlobalProperties request in 20 seconds from activation to FULL with the default list of HelpPrompts is a list of TTSChunks ( UI commands) defined as �TEXT� type, which are the list of the commands. function Test:Begin_TC_SetGlobalProperties_03() print("--------------------------------------------------------") @@ -36099,7 +36305,7 @@ end --[[ Description: Check for manual test case TC_SetGlobalProperties_02, extra check, not covered in original: SDL sends TTS.SetGlobalProperties request in 20 seconds from activation to LIMITED with the default list of - HelpPrompts is a list of TTSChunks ( UI commands) defined as “TEXT” type, which are the list of the commands. + HelpPrompts is a list of TTSChunks ( UI commands) defined as �TEXT� type, which are the list of the commands. --]] function Test:Begin_TC_SetGlobalProperties_3_1() @@ -36726,7 +36932,7 @@ end --[[TODO: Next test suit is blocked by defect APPLINK-21931, after resolving the issue need to uncomment suit]] --[[ --Begin test case SequenceCheck.6.1 - --Description:Check for manual test case TC_SetGlobalProperties_02: SDL sends TTS.SetGlobalProperties request in 20 seconds from activation to LIMITED with the default list of HelpPrompts is a list of TTSChunks ( UI commands) defined as “TEXT” type, which are the list of the commands. + --Description:Check for manual test case TC_SetGlobalProperties_02: SDL sends TTS.SetGlobalProperties request in 20 seconds from activation to LIMITED with the default list of HelpPrompts is a list of TTSChunks ( UI commands) defined as �TEXT� type, which are the list of the commands. function Test:Begin_TC_SetGlobalProperties_6_1() @@ -37010,7 +37216,7 @@ end --[[TODO: Next test suit is blocked by defect APPLINK-21931, after resolving the issue need to uncomment suit]] --[[ -- Begin test case SequenceCheck.6.2 - --Description:Check for manual test case TC_SetGlobalProperties_02: SDL sends TTS.SetGlobalProperties request in 20 seconds from activation to LIMITED with the default list of HelpPrompts is a list of TTSChunks ( UI commands) defined as “TEXT” type, which are the list of the commands. + --Description:Check for manual test case TC_SetGlobalProperties_02: SDL sends TTS.SetGlobalProperties request in 20 seconds from activation to LIMITED with the default list of HelpPrompts is a list of TTSChunks ( UI commands) defined as �TEXT� type, which are the list of the commands. function Test:Begin_TC_SetGlobalProperties_6_2() diff --git a/test_scripts/API/ATF_Show.lua b/test_scripts/API/ATF_Show.lua index a99405a5c5..1310d32d8a 100644 --- a/test_scripts/API/ATF_Show.lua +++ b/test_scripts/API/ATF_Show.lua @@ -38,6 +38,7 @@ require('user_modules/AppTypes') --------------------------------------------------------------------------------------------- APIName = "Show" -- set request name strMaxLengthFileName255 = string.rep("a", 251) .. ".png" -- set max length file name +strMaxLengthInvalidFileName255 = string.rep("a", 251) .. ".png" -- set max length file name --local storagePath = config.pathToSDL .. SDLConfig:GetValue("AppStorageFolder") .. "/" .. tostring(config.application1.registerAppInterfaceParams.appID .. "_" .. tostring(config.deviceMAC) .. "/") --Debug = {"graphic", "value"} --use to print request before sending to SDL. @@ -270,6 +271,87 @@ function Test:verify_SUCCESS_Case(Request) --mobile side: expect SetGlobalProperties response EXPECT_RESPONSE(cid, { success = true, resultCode = "SUCCESS" }) +end + +--This function sends a request from mobile and verify result on HMI and mobile for WARNINGS resultCode cases. +function Test:verify_WARNINGS_invalid_image_Case(Request) + + local temp = json.encode(Request) + local cid = 0 + if string.find(temp, "{}") ~= nil or string.find(temp, "{{}}") ~= nil then + temp = string.gsub(temp, "{}", "[]") + temp = string.gsub(temp, "{{}}", "[{}]") + + self.mobileSession.correlationId = self.mobileSession.correlationId + 1 + + local msg = + { + serviceType = 7, + frameInfo = 0, + rpcType = 0, + rpcFunctionId = 13, + rpcCorrelationId = self.mobileSession.correlationId, + payload = temp + } + + cid = self.mobileSession.correlationId + + self.mobileSession:Send(msg) + else + --mobile side: sending Show request + cid = self.mobileSession:SendRPC("Show", Request) + end + + -- TODO: remove after resolving APPLINK-16094 + --------------------------------------------- + if + (Request.graphic and + #Request.graphic == 0) then + Request.graphic = nil + end + + if + (Request.secondaryGraphic and + #Request.secondaryGraphic == 0) then + Request.secondaryGraphic = nil + end + + if + (Request.softButtons and + #Request.softButtons == 0) then + Request.softButtons = nil + end + + if + (Request.customPresets and + #Request.customPresets == 0) then + Request.customPresets = nil + end + + if Request.softButtons then + for i=1,#Request.softButtons do + if Request.softButtons[i].image then + Request.softButtons[i].image = nil + end + end + + end + --------------------------------------------- + + UIParams = self:createUIParameters(Request) + + + --hmi side: expect UI.Show request + EXPECT_HMICALL("UI.Show", UIParams) + :Do(function(_,data) + --hmi side: sending UI.Show response + self.hmiConnection:SendResponse(data.id, data.method, "WARNINGS", {info = "Requested image(s) not found."}) + end) + + + --mobile side: expect SetGlobalProperties response + EXPECT_RESPONSE(cid, { success = true, resultCode = "WARNINGS",info = "Requested image(s) not found." }) + end --------------------------------------------------------------------------------------------- @@ -330,6 +412,44 @@ end --2. All parameters are upper bound ----------------------------------------------------------------------------------------------- + Test["Show_AllParametersWithInvalidImage_WARNINGS"] = function(self) + + --mobile side: request parameters + local RequestParams = + { + mainField1 = "a", + mainField2 = "a", + mainField3 = "a", + mainField4 = "a", + statusBar= "a", + mediaClock = "a", + mediaTrack = "a", + alignment = "CENTERED", + graphic = + { + imageType = "DYNAMIC", + value = "invalidimange.png" + }, + secondaryGraphic = + { + imageType = "DYNAMIC", + value = "invalidimange.png" + }, + softButtons = {}, + customPresets = {}, + metadataTags = + { + mainField1 = {}, + mainField2 = {}, + mainField3 = {}, + mainField4 = {} + } + } + + self:verify_WARNINGS_invalid_image_Case(RequestParams) + + end + Test["Show_AllParametersLowerBound_SUCCESS"] = function(self) --mobile side: request parameters @@ -546,6 +666,184 @@ end end ----------------------------------------------------------------------------------------- + ----------------------------------------------------------------------------------------- + + Test["Show_AllParametersUpperBound_WARNINGS"] = function(self) + + --mobile side: request parameters + local string500Characters = commonFunctions:createString(500) + local string499Characters = commonFunctions:createString(499) + local RequestParams = + { + mainField1 = string500Characters, + mainField2 = string500Characters, + mainField3 = string500Characters, + mainField4 = string500Characters, + statusBar= string500Characters, + mediaClock = string500Characters, + mediaTrack = string500Characters, + alignment = "CENTERED", + graphic = + { + imageType = "DYNAMIC", + value = strMaxLengthFileName255 + }, + secondaryGraphic = + { + imageType = "DYNAMIC", + value = strMaxLengthFileName255 + }, + softButtons = + { + { + text = "1" .. string499Characters, + systemAction = "KEEP_CONTEXT", + type = "BOTH", + isHighlighted = true, + image = + { + imageType = "DYNAMIC", + value = strMaxLengthFileName255 + }, + softButtonID = 1 + }, + { + text = "2" .. string499Characters, + systemAction = "KEEP_CONTEXT", + type = "BOTH", + isHighlighted = true, + image = + { + imageType = "DYNAMIC", + value = strMaxLengthFileName255 + }, + softButtonID = 2 + }, + { + text = "3" .. string499Characters, + systemAction = "KEEP_CONTEXT", + type = "BOTH", + isHighlighted = true, + image = + { + imageType = "DYNAMIC", + value = strMaxLengthFileName255 + }, + softButtonID = 3 + }, + { + text = "4" .. string499Characters, + systemAction = "KEEP_CONTEXT", + type = "BOTH", + isHighlighted = true, + image = + { + imageType = "DYNAMIC", + value = strMaxLengthInvalidFileName255 + }, + softButtonID = 4 + }, + { + text = "5" .. string499Characters, + systemAction = "KEEP_CONTEXT", + type = "BOTH", + isHighlighted = true, + image = + { + imageType = "DYNAMIC", + value = strMaxLengthInvalidFileName255 + }, + softButtonID = 5 + }, + { + text = "6" .. string499Characters, + systemAction = "KEEP_CONTEXT", + type = "BOTH", + isHighlighted = true, + image = + { + imageType = "DYNAMIC", + value = strMaxLengthInvalidFileName255 + }, + softButtonID = 6 + }, + { + text = "7" .. string499Characters, + systemAction = "KEEP_CONTEXT", + type = "BOTH", + isHighlighted = true, + image = + { + imageType = "DYNAMIC", + value = strMaxLengthInvalidFileName255 + }, + softButtonID = 7 + }, + { + text = "8" .. string499Characters, + systemAction = "KEEP_CONTEXT", + type = "BOTH", + isHighlighted = true, + image = + { + imageType = "DYNAMIC", + value = strMaxLengthFileName255 + }, + softButtonID = 8 + } + }, + customPresets = + { + "1" .. string499Characters, + "2" .. string499Characters, + "3" .. string499Characters, + "4" .. string499Characters, + "5" .. string499Characters, + "6" .. string499Characters, + "7" .. string499Characters, + "8" .. string499Characters, + }, + metadataTags = + { + mainField1 = + { + "mediaTitle", + "mediaArtist", + "mediaAlbum", + "mediaYear", + "mediaGenre" + }, + mainField2 = + { + "mediaTitle", + "mediaArtist", + "mediaAlbum", + "mediaYear", + "mediaGenre" + }, + mainField3 = + { + "mediaTitle", + "mediaArtist", + "mediaAlbum", + "mediaYear", + "mediaGenre" + }, + mainField4 = + { + "mediaTitle", + "mediaArtist", + "mediaAlbum", + "mediaYear", + "mediaGenre" + } + } + } + + self:verify_WARNINGS_invalid_image_Case(RequestParams) + + end + ----------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------- --Test cases for parameter 1-7: mainField1, mainField2, mainField3, mainField4, statusBar, mediaClock, mediaTrack: type=String, maxlength=500, mandatory=false From 2e91d1f3b090863aee891d6ad8c266e4a40b79d7 Mon Sep 17 00:00:00 2001 From: Ashwin Karemore Date: Thu, 28 Jun 2018 17:52:43 +0200 Subject: [PATCH 500/681] test script for invalid image transfer --- test_scripts/API/ATF_AlertManeuver.lua | 303 +++++++++++++++++++++ test_scripts/API/ATF_ScrollableMessage.lua | 99 +++++++ test_scripts/API/ATF_ShowConstantTBT.lua | 221 +++++++++++++++ test_scripts/API/ATF_UpdateTurnList.lua | 153 +++++++++++ 4 files changed, 776 insertions(+) diff --git a/test_scripts/API/ATF_AlertManeuver.lua b/test_scripts/API/ATF_AlertManeuver.lua index 4ab1ca3335..4da7aceae7 100644 --- a/test_scripts/API/ATF_AlertManeuver.lua +++ b/test_scripts/API/ATF_AlertManeuver.lua @@ -1328,6 +1328,309 @@ end --End Test case CommonRequestCheck.6 + --Begin Test case CommonRequestCheck.7 + --Description: Positive case and in boundary conditions (with conditional parameters) and invalid image + + function Test:AlertManeuver_InvalidImage() + + --mobile side: AlertManeuver request + local CorIdAlertM = self.mobileSession:SendRPC("AlertManeuver", + { + + ttsChunks = + { + + { + text ="FirstAlert", + type ="TEXT", + }, + + { + text ="SecondAlert", + type ="TEXT", + }, + }, + softButtons = + { + + { + type = "BOTH", + text = "Close", + image = + + { + value = "icon.png", + imageType = "DYNAMIC", + }, + isHighlighted = true, + softButtonID = 7821, + systemAction = "DEFAULT_ACTION", + }, + + { + type = "BOTH", + text = "AnotherClose", + image = + + { + value = "notavailable.png", + imageType = "DYNAMIC", + }, + isHighlighted = false, + softButtonID = 7822, + systemAction = "DEFAULT_ACTION", + }, + } + + }) + + local AlertId + --hmi side: Navigation.AlertManeuver request + EXPECT_HMICALL("Navigation.AlertManeuver", + { + appID = self.applications["Test Application"], + softButtons = + { + + { + type = "BOTH", + text = "Close", + --[[ TODO: update after resolving APPLINK-16052 + + image = + + { + value = pathToIconFolder .. "/icon.png", + imageType = "DYNAMIC", + },]] + isHighlighted = true, + softButtonID = 7821, + systemAction = "DEFAULT_ACTION", + }, + + { + type = "BOTH", + text = "AnotherClose", + --[[ TODO: update after resolving APPLINK-16052 + + image = + + { + value = pathToIconFolder.. "/notavailable.png", + imageType = "DYNAMIC", + },]] + isHighlighted = false, + softButtonID = 7822, + systemAction = "DEFAULT_ACTION", + } + } + }) + :Do(function(_,data) + AlertId = data.id + local function alertResponse() + self.hmiConnection:SendResponse(AlertId, "Navigation.AlertManeuver", "WARNINGS", {info = "Requested image(s) not found."}) + end + + RUN_AFTER(alertResponse, 2000) + end) + + local SpeakId + --hmi side: TTS.Speak request + EXPECT_HMICALL("TTS.Speak", + { + ttsChunks = + { + + { + text ="FirstAlert", + type ="TEXT", + }, + + { + text ="SecondAlert", + type ="TEXT", + } + }, + speakType = "ALERT_MANEUVER", + + }) + :Do(function(_,data) + self.hmiConnection:SendNotification("TTS.Started") + SpeakId = data.id + + local function speakResponse() + self.hmiConnection:SendResponse(SpeakId, "TTS.Speak", "SUCCESS", { }) + + self.hmiConnection:SendNotification("TTS.Stopped") + end + + RUN_AFTER(speakResponse, 1000) + + end) + + + --mobile side: OnHMIStatus notifications + ExpectOnHMIStatusWithAudioStateChanged(self) + + --mobile side: expect AlertManeuver response + EXPECT_RESPONSE(CorIdAlertM, { success = true, resultCode = "WARNINGS",info = "Requested image(s) not found." }) + :Timeout(11000) + + end + + --End Test case CommonRequestCheck.7 + + --Begin Test case CommonRequestCheck.8 + --Description: Positive case and in boundary conditions (with conditional parameters) and invalid image + + function Test:AlertManeuver_InvalidImage_SoftButton() + + --mobile side: AlertManeuver request + local CorIdAlertM = self.mobileSession:SendRPC("AlertManeuver", + { + + ttsChunks = + { + + { + text ="FirstAlert", + type ="TEXT", + }, + + { + text ="SecondAlert", + type ="TEXT", + }, + }, + softButtons = + { + + { + type = "BOTH", + text = "Close", + image = + + { + value = "notavailable.png", + imageType = "DYNAMIC", + }, + isHighlighted = true, + softButtonID = 8821, + systemAction = "DEFAULT_ACTION", + }, + + { + type = "BOTH", + text = "AnotherClose", + image = + + { + value = "icon.png", + imageType = "DYNAMIC", + }, + isHighlighted = false, + softButtonID = 8822, + systemAction = "DEFAULT_ACTION", + }, + } + + }) + + local AlertId + --hmi side: Navigation.AlertManeuver request + EXPECT_HMICALL("Navigation.AlertManeuver", + { + appID = self.applications["Test Application"], + softButtons = + { + + { + type = "BOTH", + text = "Close", + --[[ TODO: update after resolving APPLINK-16052 + + image = + + { + value = pathToIconFolder .. "/notavailable.png", + imageType = "DYNAMIC", + },]] + isHighlighted = true, + softButtonID = 8821, + systemAction = "DEFAULT_ACTION", + }, + + { + type = "BOTH", + text = "AnotherClose", + --[[ TODO: update after resolving APPLINK-16052 + + image = + + { + value = pathToIconFolder.. "/icon.png", + imageType = "DYNAMIC", + },]] + isHighlighted = false, + softButtonID = 8822, + systemAction = "DEFAULT_ACTION", + } + } + }) + :Do(function(_,data) + AlertId = data.id + local function alertResponse() + self.hmiConnection:SendResponse(AlertId, "Navigation.AlertManeuver", "WARNINGS", {info = "Requested image(s) not found."}) + end + + RUN_AFTER(alertResponse, 2000) + end) + + local SpeakId + --hmi side: TTS.Speak request + EXPECT_HMICALL("TTS.Speak", + { + ttsChunks = + { + + { + text ="FirstAlert", + type ="TEXT", + }, + + { + text ="SecondAlert", + type ="TEXT", + } + }, + speakType = "ALERT_MANEUVER", + + }) + :Do(function(_,data) + self.hmiConnection:SendNotification("TTS.Started") + SpeakId = data.id + + local function speakResponse() + self.hmiConnection:SendResponse(SpeakId, "TTS.Speak", "SUCCESS", { }) + + self.hmiConnection:SendNotification("TTS.Stopped") + end + + RUN_AFTER(speakResponse, 1000) + + end) + + + --mobile side: OnHMIStatus notifications + ExpectOnHMIStatusWithAudioStateChanged(self) + + --mobile side: expect AlertManeuver response + EXPECT_RESPONSE(CorIdAlertM, { success = true, resultCode = "WARNINGS",info = "Requested image(s) not found." }) + :Timeout(11000) + + end + + --End Test case CommonRequestCheck.8 --End Test suit CommonRequestCheck diff --git a/test_scripts/API/ATF_ScrollableMessage.lua b/test_scripts/API/ATF_ScrollableMessage.lua index 02f694465e..aebfe550d3 100644 --- a/test_scripts/API/ATF_ScrollableMessage.lua +++ b/test_scripts/API/ATF_ScrollableMessage.lua @@ -191,6 +191,67 @@ function Test:verify_SUCCESS_Case(Request, HmiLevel) end +--------------------------------------------------------------------------------------------- + +--This function sends a request from mobile and verify result on HMI and mobile for WARNINGS resultCode cases. +function Test:verify_WARNINGS_Case(Request, HmiLevel) + + local cid = commonFunctions:sendRequest(self, Request, APIName, APIId) + + --TODO: update after resolving APPLINK-16052 + if Request.softButtons then + for i=1,#Request.softButtons do + if Request.softButtons[i].image then + Request.softButtons[i].image = nil + end + end + end + + local UIParams = self:createUIParameters(Request) + + --hmi side: expect UI.ScrollableMessage request + EXPECT_HMICALL("UI.ScrollableMessage", UIParams) + :Do(function(_,data) + + --HMI sends UI.OnSystemContext + self.hmiConnection:SendNotification("UI.OnSystemContext",{ appID = self.applications["Test Application"], systemContext = "HMI_OBSCURED" }) + scrollableMessageId = data.id + + local function scrollableMessageResponse() + + --hmi sends response + self.hmiConnection:SendResponse(scrollableMessageId, "UI.ScrollableMessage", "WARNINGS", {info = "Requested image(s) not found."}) + + --HMI sends UI.OnSystemContext + self.hmiConnection:SendNotification("UI.OnSystemContext",{ appID = self.applications["Test Application"], systemContext = "MAIN" }) + end + RUN_AFTER(scrollableMessageResponse, 1000) + + end) + + + --mobile side: expect OnHMIStatus notification + if HmiLevel == nil then + HmiLevel = "FULL" + end + if + HmiLevel == "BACKGROUND" or + HmiLevel == "LIMITED" then + EXPECT_NOTIFICATION("OnHMIStatus",{}) + :Times(0) + else + + EXPECT_NOTIFICATION("OnHMIStatus", + {systemContext = "HMI_OBSCURED", hmiLevel = HmiLevel, audioStreamingState = audibleState}, + {systemContext = "MAIN", hmiLevel = HmiLevel, audioStreamingState = audibleState} + ) + :Times(2) + end + + --mobile side: expect the response + EXPECT_RESPONSE(cid, { success = true, resultCode = "WARNINGS",info = "Requested image(s) not found." }) + +end --------------------------------------------------------------------------------------------- -------------------------------------------Preconditions------------------------------------- --------------------------------------------------------------------------------------------- @@ -242,6 +303,7 @@ end --1. Positive request --2. All parameters are lower bound --3. All parameters are upper bound +--4. Positive request with invalid image function Test:ScrollableMessage_PositiveRequest() local Request = @@ -280,6 +342,43 @@ function Test:ScrollableMessage_PositiveRequest() self:verify_SUCCESS_Case(Request) end +function Test:ScrollableMessage_PositiveRequest_WithInvalidImage() + local Request = + { + scrollableMessageBody = "abc", + softButtons = + { + { + softButtonID = 1, + text = "Button1", + type = "IMAGE", + image = + { + value = "notavailable.png", + imageType = "DYNAMIC" + }, + isHighlighted = false, + systemAction = "DEFAULT_ACTION" + }, + { + softButtonID = 2, + text = "Button2", + type = "IMAGE", + image = + { + value = "action.png", + imageType = "DYNAMIC" + }, + isHighlighted = false, + systemAction = "DEFAULT_ACTION" + } + }, + timeout = 5000 + } + + self:verify_WARNINGS_Case(Request) +end + function Test:ScrollableMessage_AllParametersLowerBound() local Request = { diff --git a/test_scripts/API/ATF_ShowConstantTBT.lua b/test_scripts/API/ATF_ShowConstantTBT.lua index 20f7b27cfd..7ecbcffe9c 100644 --- a/test_scripts/API/ATF_ShowConstantTBT.lua +++ b/test_scripts/API/ATF_ShowConstantTBT.lua @@ -253,6 +253,71 @@ end --------------------------------------------------------------------------------------------- + +--This function sends a request from mobile and verify result on HMI and mobile for WARNINGS resultCode cases. +function Test:verify_WARNINGS_Case(RequestParams) + --Check if send any empty array or empty struct + local temp = json.encode(RequestParams) + local cid = 0 + if string.find(temp, "{}") ~= nil or string.find(temp, "{{}}") ~= nil then + temp = string.gsub(temp, "{}", "[]") + temp = string.gsub(temp, "{{}}", "[{}]") + + self.mobileSession.correlationId = self.mobileSession.correlationId + 1 + + local msg = + { + serviceType = 7, + frameInfo = 0, + rpcType = 0, + rpcFunctionId = 27, + rpcCorrelationId = self.mobileSession.correlationId, + payload = temp + } + + cid = self.mobileSession.correlationId + + self.mobileSession:Send(msg) + + else + --mobile side: sending ShowConstantTBT request + cid = self.mobileSession:SendRPC("ShowConstantTBT", RequestParams) + end + + -- TODO: remove after resolving APPLINK-16094 + --------------------------------------------- + + if + (RequestParams.softButtons and + #RequestParams.softButtons == 0) then + RequestParams.softButtons = nil + end + + if RequestParams.softButtons then + for i=1,#RequestParams.softButtons do + if RequestParams.softButtons[i].image then + RequestParams.softButtons[i].image = nil + end + end + + end + --------------------------------------------- + + UIParams = self:createUIParameters(RequestParams) + + --hmi side: expect Navigation.ShowConstantTBT request + EXPECT_HMICALL("Navigation.ShowConstantTBT", UIParams) + :Do(function(_,data) + --hmi side: sending Navigation.ShowConstantTBT response + self.hmiConnection:SendResponse(data.id, data.method, "WARNINGS", {info = "Requested image(s) not found."}) + end) + + --mobile side: expect SetGlobalProperties response + EXPECT_RESPONSE(cid, { success = true, resultCode = "WARNINGS",info = "Requested image(s) not found." }) +end + +--------------------------------------------------------------------------------------------- +-- --This function sends a request from mobile with INVALID_DATA and verify result on mobile. function Test:verify_INVALID_DATA_Case(RequestParams) --Check if send any empty array or empty struct @@ -523,6 +588,162 @@ end function Test:ShowConstantTBT_Positive() self:verify_SUCCESS_Case(Request) end + + local Request = { + navigationText1 ="navigationText1", + navigationText2 ="navigationText2", + eta ="12:34", + totalDistance ="100miles", + turnIcon = + { + value ="notavailable.png", + imageType ="DYNAMIC", + }, + nextTurnIcon = + { + value ="notavailable.png", + imageType ="DYNAMIC", + }, + distanceToManeuver = 50.5, + distanceToManeuverScale = 100.5, + maneuverComplete = false, + softButtons = + { + + { + type ="BOTH", + text ="Close", + image = + { + value ="notavailable.png", + imageType ="DYNAMIC", + }, + isHighlighted = true, + softButtonID = 44, + systemAction ="DEFAULT_ACTION", + }, + }, + } + function Test:ShowConstantTBT_Positive_InvalidImage() + self:verify_WARNINGS_Case(Request) + end + + local Request = { + navigationText1 ="navigationText1", + navigationText2 ="navigationText2", + eta ="12:34", + totalDistance ="100miles", + turnIcon = + { + value ="notavailable.png", + imageType ="DYNAMIC", + }, + nextTurnIcon = + { + value ="icon.png", + imageType ="DYNAMIC", + }, + distanceToManeuver = 50.5, + distanceToManeuverScale = 100.5, + maneuverComplete = false, + softButtons = + { + + { + type ="BOTH", + text ="Close", + image = + { + value ="icon.png", + imageType ="DYNAMIC", + }, + isHighlighted = true, + softButtonID = 44, + systemAction ="DEFAULT_ACTION", + }, + }, + } + function Test:ShowConstantTBT_Positive_InvalidImage_TurnIcon() + self:verify_WARNINGS_Case(Request) + end + + local Request = { + navigationText1 ="navigationText1", + navigationText2 ="navigationText2", + eta ="12:34", + totalDistance ="100miles", + turnIcon = + { + value ="icon.png", + imageType ="DYNAMIC", + }, + nextTurnIcon = + { + value ="icon.png", + imageType ="DYNAMIC", + }, + distanceToManeuver = 50.5, + distanceToManeuverScale = 100.5, + maneuverComplete = false, + softButtons = + { + + { + type ="BOTH", + text ="Close", + image = + { + value ="notavailable.png", + imageType ="DYNAMIC", + }, + isHighlighted = true, + softButtonID = 44, + systemAction ="DEFAULT_ACTION", + }, + }, + } + function Test:ShowConstantTBT_Positive_InvalidImage_SoftButton() + self:verify_WARNINGS_Case(Request) + end + + local Request = { + navigationText1 ="navigationText1", + navigationText2 ="navigationText2", + eta ="12:34", + totalDistance ="100miles", + turnIcon = + { + value ="icon.png", + imageType ="DYNAMIC", + }, + nextTurnIcon = + { + value ="notavailable.png", + imageType ="DYNAMIC", + }, + distanceToManeuver = 50.5, + distanceToManeuverScale = 100.5, + maneuverComplete = false, + softButtons = + { + + { + type ="BOTH", + text ="Close", + image = + { + value ="icon.png", + imageType ="DYNAMIC", + }, + isHighlighted = true, + softButtonID = 44, + systemAction ="DEFAULT_ACTION", + }, + }, + } + function Test:ShowConstantTBT_Positive_InvalidImage_NextTurnIcon() + self:verify_WARNINGS_Case(Request) + end local Request = { navigationText1 ="navigationText1", diff --git a/test_scripts/API/ATF_UpdateTurnList.lua b/test_scripts/API/ATF_UpdateTurnList.lua index f2aaa76149..5b81b98cf5 100644 --- a/test_scripts/API/ATF_UpdateTurnList.lua +++ b/test_scripts/API/ATF_UpdateTurnList.lua @@ -194,6 +194,49 @@ function Test:updateTurnListSuccess(paramsSend) EXPECT_RESPONSE(CorIdUpdateTurnList, { success = true, resultCode = "SUCCESS" }) end +function Test:updateTurnListWARNINGS(paramsSend) + --mobile side: send UpdateTurnList request + local CorIdUpdateTurnList = self.mobileSession:SendRPC("UpdateTurnList", paramsSend) + + --Set location for DYNAMIC image + if paramsSend.softButtons then + --If type is IMAGE -> text parameter is omitted and vice versa + if paramsSend.softButtons[1].type == "IMAGE" then + paramsSend.softButtons[1].text = nil + else + if paramsSend.softButtons[1].type == "TEXT" then + paramsSend.softButtons[1].image = nil + end + end + + --TODO: update after resolving APPLINK-16052 + -- if paramsSend.softButtons[1].image then + -- paramsSend.softButtons[1].image.value = storagePath..paramsSend.softButtons[1].image.value + -- end + if paramsSend.softButtons then + for i=1,#paramsSend.softButtons do + if paramsSend.softButtons[i].image then + paramsSend.softButtons[i].image = nil + end + end + end + end + + --hmi side: expect Navigation.UpdateTurnList request + EXPECT_HMICALL("Navigation.UpdateTurnList", + { + turnList = setExTurnList(1), + softButtons = paramsSend.softButtons + }) + :Do(function(_,data) + --hmi side: send Navigation.UpdateTurnList response + self.hmiConnection:SendResponse(data.id, data.method, "WARNINGS",{info = "Requested image(s) not found."}) + end) + + --mobile side: expect UpdateTurnList response + EXPECT_RESPONSE(CorIdUpdateTurnList, { success = true, resultCode = "WARNINGS",info = "Requested image(s) not found." }) +end + --------------------------------------------------------------------------------------------- -------------------------------------------Preconditions------------------------------------- --------------------------------------------------------------------------------------------- @@ -957,6 +1000,116 @@ commonSteps:DeleteLogsFileAndPolicyTable() end --End Test case CommonRequestCheck.8 ]] + + --Begin Test case CommonRequestCheck.9 + --Description: This test is intended to check positive cases and when all parameters are in boundary conditions and with Invalid Image + + + function Test:UpdateTurnList_InvalidImage() + local request = { + turnList = + { + { + navigationText ="Text", + turnIcon = + { + value ="notavailable.png", + imageType ="DYNAMIC", + } + } + }, + softButtons = + { + { + type ="BOTH", + text ="Close", + image = + { + value ="notavailable.png", + imageType ="DYNAMIC", + }, + isHighlighted = true, + softButtonID = 111, + systemAction ="DEFAULT_ACTION", + } + } + } + self:updateTurnListWARNINGS(request) + end + --End Test case CommonRequestCheck.9 + + --Begin Test case CommonRequestCheck.10 + --Description: This test is intended to check positive cases and when all parameters are in boundary conditions and with Invalid Image + + + function Test:UpdateTurnList_InvalidImage_SoftButton() + local request = { + turnList = + { + { + navigationText ="Text", + turnIcon = + { + value ="icon.png", + imageType ="DYNAMIC", + } + } + }, + softButtons = + { + { + type ="BOTH", + text ="Close", + image = + { + value ="notavailable.png", + imageType ="DYNAMIC", + }, + isHighlighted = true, + softButtonID = 111, + systemAction ="DEFAULT_ACTION", + } + } + } + self:updateTurnListWARNINGS(request) + end + --End Test case CommonRequestCheck.10 + --Begin Test case CommonRequestCheck.11 + --Description: This test is intended to check positive cases and when all parameters are in boundary conditions and with Invalid Image + + function Test:UpdateTurnList_InvalidImage_TurnIcon() + local request = { + turnList = + { + { + navigationText ="Text", + turnIcon = + { + value ="icon.png", + imageType ="DYNAMIC", + } + } + }, + softButtons = + { + { + type ="BOTH", + text ="Close", + image = + { + value ="notavailable.png", + imageType ="DYNAMIC", + }, + isHighlighted = true, + softButtonID = 111, + systemAction ="DEFAULT_ACTION", + } + } + } + self:updateTurnListWARNINGS(request) + end + --End Test case CommonRequestCheck.11 + --End Test suit CommonRequestCheck --------------------------------------------------------------------------------------------- From 2595c5d68d731f174c465de468059d03fdaf5717 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 27 Jul 2018 14:39:32 +0300 Subject: [PATCH 501/681] Add logging in case if preloaded file was not updated --- user_modules/shared_testcases/testCasesForPolicyTable.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/user_modules/shared_testcases/testCasesForPolicyTable.lua b/user_modules/shared_testcases/testCasesForPolicyTable.lua index 1ff3c9d587..8653824e20 100644 --- a/user_modules/shared_testcases/testCasesForPolicyTable.lua +++ b/user_modules/shared_testcases/testCasesForPolicyTable.lua @@ -873,7 +873,10 @@ function testCasesForPolicyTable:Precondition_updatePolicy_By_overwriting_preloa commonPreconditions:BackupFile(pt_fileName) --Copy new policy table to /sdl/bin folder - os.execute(" cp -f " .. PTName .. " " .. commonPreconditions:GetPathToSDL() .. pt_fileName) + local cmd = " cp -f " .. PTName .. " " .. commonPreconditions:GetPathToSDL() .. pt_fileName + if not os.execute(cmd) then + commonFunctions:printError("Preloaded was not updated") + end --Delete policy table commonSteps:DeletePolicyTable() From 8433b904ac13c1be7bf9307897d1ca6f1d710805 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 27 Jul 2018 22:32:02 +0300 Subject: [PATCH 502/681] Fix issue related to SDL binaries path --- .../shared_testcases/testCasesForPolicyTableSnapshot.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua b/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua index e0be2c392f..b4ad85b7e3 100644 --- a/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua +++ b/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua @@ -1,6 +1,7 @@ local testCasesForPolicyTableSnapshot = {} local commonFunctions = require('user_modules/shared_testcases/commonFunctions') local commonSteps = require('user_modules/shared_testcases/commonSteps') +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') testCasesForPolicyTableSnapshot.preloaded_elements = {} testCasesForPolicyTableSnapshot.pts_elements = {} @@ -80,7 +81,7 @@ end function testCasesForPolicyTableSnapshot:extract_preloaded_pt() testCasesForPolicyTableSnapshot.preloaded_elements = {} testCasesForPolicyTableSnapshot.seconds_between_retries = {} - local preloaded_pt = config.pathToSDL ..'sdl_preloaded_pt.json' + local preloaded_pt = commonPreconditions:GetPathToSDL() ..'sdl_preloaded_pt.json' extract_json(preloaded_pt) local k = 1 for i = 1, #json_elements do From 38d997eaff2173c0c0702fa4fa94bd89d6a3ffe2 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Sat, 28 Jul 2018 00:16:04 +0300 Subject: [PATCH 503/681] Update policy .json files used in HTTP scripts --- .../Policies/Policy_Table_Update/endpoints_appId.json | 3 ++- .../exchange_after_1000_kilometers_ptu.json | 3 ++- .../Policy_Table_Update/few_endpoints_appId.json | 3 ++- .../Policies/Policy_Table_Update/preloaded_18192.json | 5 +++-- .../jsons/Policies/Policy_Table_Update/ptu_18192.json | 6 ++++-- .../Policy_Table_Update/ptu_without_preloaded.json | 3 ++- files/jsons/Policies/build_options/ptu_14740.json | 6 ++++-- files/jsons/Policies/build_options/ptu_18269.json | 6 ++++-- files/jsons/Policies/build_options/retry_seq.json | 3 ++- files/ptu_general.json | 11 +++++++---- 10 files changed, 32 insertions(+), 17 deletions(-) diff --git a/files/jsons/Policies/Policy_Table_Update/endpoints_appId.json b/files/jsons/Policies/Policy_Table_Update/endpoints_appId.json index ca979ea968..63d4853bac 100644 --- a/files/jsons/Policies/Policy_Table_Update/endpoints_appId.json +++ b/files/jsons/Policies/Policy_Table_Update/endpoints_appId.json @@ -2246,7 +2246,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/Policy_Table_Update/exchange_after_1000_kilometers_ptu.json b/files/jsons/Policies/Policy_Table_Update/exchange_after_1000_kilometers_ptu.json index 1ff8cc5558..0cbe23bf17 100644 --- a/files/jsons/Policies/Policy_Table_Update/exchange_after_1000_kilometers_ptu.json +++ b/files/jsons/Policies/Policy_Table_Update/exchange_after_1000_kilometers_ptu.json @@ -2342,7 +2342,8 @@ "steal_focus" : false, "priority" : "NONE", "default_hmi" : "NONE", - "groups" : ["Base-4"] + "groups" : ["Base-4"], + "RequestType": [] }, "device" : { "keep_context" : false, diff --git a/files/jsons/Policies/Policy_Table_Update/few_endpoints_appId.json b/files/jsons/Policies/Policy_Table_Update/few_endpoints_appId.json index f0c7f1a57a..1ae9eae3ba 100644 --- a/files/jsons/Policies/Policy_Table_Update/few_endpoints_appId.json +++ b/files/jsons/Policies/Policy_Table_Update/few_endpoints_appId.json @@ -2250,7 +2250,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/Policy_Table_Update/preloaded_18192.json b/files/jsons/Policies/Policy_Table_Update/preloaded_18192.json index 98b3e53b32..897ccc91c4 100644 --- a/files/jsons/Policies/Policy_Table_Update/preloaded_18192.json +++ b/files/jsons/Policies/Policy_Table_Update/preloaded_18192.json @@ -943,7 +943,7 @@ "textBody": "TEXTBODY_DataConsent" } } - } + } } }, "app_policies": { @@ -952,7 +952,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/Policy_Table_Update/ptu_18192.json b/files/jsons/Policies/Policy_Table_Update/ptu_18192.json index aceaa481df..62fc472825 100644 --- a/files/jsons/Policies/Policy_Table_Update/ptu_18192.json +++ b/files/jsons/Policies/Policy_Table_Update/ptu_18192.json @@ -6,14 +6,16 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4", "Base-6"] + "groups": ["Base-4", "Base-6"], + "RequestType": [] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/Policy_Table_Update/ptu_without_preloaded.json b/files/jsons/Policies/Policy_Table_Update/ptu_without_preloaded.json index 88a467795d..2b92bb6069 100644 --- a/files/jsons/Policies/Policy_Table_Update/ptu_without_preloaded.json +++ b/files/jsons/Policies/Policy_Table_Update/ptu_without_preloaded.json @@ -2346,7 +2346,8 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4"], - "nicknames": ["Media Application", "MediaApp"] + "nicknames": ["Media Application", "MediaApp"], + "RequestType": [] } } } diff --git a/files/jsons/Policies/build_options/ptu_14740.json b/files/jsons/Policies/build_options/ptu_14740.json index b3be773caf..5db1a0cfbc 100644 --- a/files/jsons/Policies/build_options/ptu_14740.json +++ b/files/jsons/Policies/build_options/ptu_14740.json @@ -2307,14 +2307,16 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-6"] + "groups": ["Base-6"], + "RequestType": [] }, "0000001": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-6"] + "groups": ["Base-6"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/build_options/ptu_18269.json b/files/jsons/Policies/build_options/ptu_18269.json index 5bfb400162..4d7dfeeb9f 100644 --- a/files/jsons/Policies/build_options/ptu_18269.json +++ b/files/jsons/Policies/build_options/ptu_18269.json @@ -6,14 +6,16 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4", "Base-6"] + "groups": ["Base-4", "Base-6"], + "RequestType": [] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/build_options/retry_seq.json b/files/jsons/Policies/build_options/retry_seq.json index 44408f1172..1444b397b6 100644 --- a/files/jsons/Policies/build_options/retry_seq.json +++ b/files/jsons/Policies/build_options/retry_seq.json @@ -2251,7 +2251,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/ptu_general.json b/files/ptu_general.json index ab9d2a28ff..f1559a9a41 100644 --- a/files/ptu_general.json +++ b/files/ptu_general.json @@ -2265,21 +2265,24 @@ "steal_focus": true, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4", "Navigation-1","DrivingCharacteristics-3", "Location-1", "VehicleInfo-3", "Emergency-1", "OnKeyboardInputOnlyGroup", "PropriataryData-1"] + "groups": ["Base-4", "Navigation-1","DrivingCharacteristics-3", "Location-1", "VehicleInfo-3", "Emergency-1", "OnKeyboardInputOnlyGroup", "PropriataryData-1"], + "RequestType": [] }, "0000001": { "keep_context": true, "steal_focus": true, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4", "Navigation-1","DrivingCharacteristics-3", "Location-1", "VehicleInfo-3", "Emergency-1", "OnKeyboardInputOnlyGroup", "PropriataryData-1", "SendLocation"] + "groups": ["Base-4", "Navigation-1","DrivingCharacteristics-3", "Location-1", "VehicleInfo-3", "Emergency-1", "OnKeyboardInputOnlyGroup", "PropriataryData-1", "SendLocation"], + "RequestType": [] }, "0000004": { "keep_context": true, "steal_focus": true, "priority": "NONE", "default_hmi": "BACKGROUND", - "groups": ["Base-4", "Navigation-1","DrivingCharacteristics-3", "Location-1", "VehicleInfo-3", "Emergency-1", "OnKeyboardInputOnlyGroup", "PropriataryData-1", "SendLocation"] + "groups": ["Base-4", "Navigation-1","DrivingCharacteristics-3", "Location-1", "VehicleInfo-3", "Emergency-1", "OnKeyboardInputOnlyGroup", "PropriataryData-1", "SendLocation"], + "RequestType": [] }, "background": { "keep_context": false, @@ -2304,4 +2307,4 @@ } } } -} \ No newline at end of file +} From 6909459ada95aa57abaaee184b3bce2a9acbbff1 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 27 Jul 2018 22:43:03 +0300 Subject: [PATCH 504/681] Update policy .json files used in EXTERNAL_PROPRIETARY scripts --- files/Base4InPreDataConsent_preloaded_pt.json | 3 +- ...AppPermissionsForConsent_preloaded_pt.json | 6 ++-- ...DeviceGroupInPreconsented_preloadedPT.json | 5 +-- files/FocusContextTrue_preloaded_pt.json | 3 +- files/GroupsForApp_preloaded_pt.json | 6 ++-- files/KeepContextTrue_preloaded_pt.json | 3 +- files/PTFromCloud_Nickname_validation.json | 22 ++++++------ files/PTU_AppIDAppHMIType.json | 6 ++-- files/PTU_AppIDDefaultHMI.json | 6 ++-- files/PTU_AppIDGroups.json | 6 ++-- files/PTU_AppRevokedGroup.json | 3 +- files/PTU_BackgroundDefaultHMI_InDefault.json | 3 +- ..._GetUserFriendlyMessage_without_DE_DE.json | 35 ++++++++++--------- files/PTU_NewDefaultPermissions.json | 3 +- files/PTU_NewPermissionsForUserConsent.json | 6 ++-- files/PTU_RequestType_for_app_1234567.json | 3 +- files/PTU_UpdateDefaultGroups.json | 3 +- .../PTU_UpdateDefaultPreconsentedGroups.json | 3 +- .../PTU_with_permissions_for_app_0000001.json | 6 ++-- .../PTU_with_permissions_for_app_1234567.json | 6 ++-- files/PriorityNormal_preloaded_pt.json | 3 +- .../App_Permissions/DisallowedRPCs.json | 3 +- .../Policies/App_Permissions/ptu_014.json | 23 ++++++------ .../PTU_ValidationRules/PTU_has_omitted.json | 3 +- .../PTU_invalid_optional.json | 5 +-- ...d_PTU_missing_seconds_between_retries.json | 6 ++-- .../preloaded_memory_kb_exist.json | 3 +- .../Policies/PTU_ValidationRules/ptu_012.json | 10 +++--- .../Policies/PTU_ValidationRules/ptu_RAI.json | 6 ++-- ..._preloaded_pt_without_optional_params.json | 5 +-- .../few_endpoints_appId_default.json | 5 +-- .../few_endpoints_appId_not_registered.json | 3 +- .../few_endpoints_appId_registered.json | 3 +- .../Policies/Policy_Table_Update/ptu.json | 9 ++--- .../Policy_Table_Update/ptu_18190.json | 6 ++-- .../Policy_Table_Update/ptu_18707_1.json | 6 ++-- .../Policy_Table_Update/ptu_19168.json | 6 ++-- .../Policy_Table_Update/ptu_22420.json | 6 ++-- .../Policy_Table_Update/ptu_22421_1Mb.json | 6 ++-- .../Policy_Table_Update/ptu_22734.json | 12 ++++--- .../Policy_Table_Update/ptu_after_n_ign.json | 14 +++++--- .../OnAppPermissionConsent.json | 6 ++-- .../OnAppPermissionConsent_ptu.json | 6 ++-- .../OnAppPermissionConsent_ptu1.json | 6 ++-- .../Policies/appID_Management/ptu_0.json | 6 ++-- .../Policies/appID_Management/ptu_01.json | 6 ++-- .../Policies/appID_Management/ptu_013_1.json | 10 +++--- .../Policies/appID_Management/ptu_013_2.json | 10 +++--- .../Policies/appID_Management/ptu_1.json | 12 ++++--- .../Policies/appID_Management/ptu_19849.json | 9 +++-- .../OnAppPermissionConsent_1.json | 6 ++-- .../user_consent/pre_dataconsent.json | 3 +- files/ptu_for_navi_app.json | 12 ++++--- files/ptu_general.json | 3 +- files/ptu_general_0000001.json | 6 ++-- files/ptu_general_default_app-1234567.json | 6 ++-- ...tu_general_default_keep_context_false.json | 3 +- ...ptu_general_default_keep_context_true.json | 3 +- ...ptu_general_default_steal_focus_false.json | 3 +- .../ptu_general_default_steal_focus_true.json | 3 +- ...preloaded_pt_AlertOnlyNotifications_1.json | 3 +- 61 files changed, 251 insertions(+), 151 deletions(-) diff --git a/files/Base4InPreDataConsent_preloaded_pt.json b/files/Base4InPreDataConsent_preloaded_pt.json index 661d3c6e59..7e23dbd5d6 100644 --- a/files/Base4InPreDataConsent_preloaded_pt.json +++ b/files/Base4InPreDataConsent_preloaded_pt.json @@ -2251,7 +2251,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/DeviceConsentedAndAppPermissionsForConsent_preloaded_pt.json b/files/DeviceConsentedAndAppPermissionsForConsent_preloaded_pt.json index 87bbd439fd..2c0affccf3 100644 --- a/files/DeviceConsentedAndAppPermissionsForConsent_preloaded_pt.json +++ b/files/DeviceConsentedAndAppPermissionsForConsent_preloaded_pt.json @@ -2251,14 +2251,16 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "0000001": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["DrivingCharacteristics-3","Base-4"] + "groups": ["DrivingCharacteristics-3","Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/DeviceGroupInPreconsented_preloadedPT.json b/files/DeviceGroupInPreconsented_preloadedPT.json index 4730627388..c0f9af8c60 100644 --- a/files/DeviceGroupInPreconsented_preloadedPT.json +++ b/files/DeviceGroupInPreconsented_preloadedPT.json @@ -2251,7 +2251,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, @@ -2259,7 +2260,7 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["DataConsent-2"], - "preconsented_groups":["DataConsent-2"] + "preconsented_groups":["DataConsent-2"] }, "pre_DataConsent": { "keep_context": false, diff --git a/files/FocusContextTrue_preloaded_pt.json b/files/FocusContextTrue_preloaded_pt.json index adba27975b..d587d43624 100644 --- a/files/FocusContextTrue_preloaded_pt.json +++ b/files/FocusContextTrue_preloaded_pt.json @@ -2251,7 +2251,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/GroupsForApp_preloaded_pt.json b/files/GroupsForApp_preloaded_pt.json index 8aa37894f0..24463f156f 100644 --- a/files/GroupsForApp_preloaded_pt.json +++ b/files/GroupsForApp_preloaded_pt.json @@ -2252,7 +2252,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "0000001": { "keep_context": false, @@ -2262,7 +2263,8 @@ "groups": [ "SendLocation", "DataConsent-2" - ] + ], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/KeepContextTrue_preloaded_pt.json b/files/KeepContextTrue_preloaded_pt.json index 698f1e1494..d64189c41f 100644 --- a/files/KeepContextTrue_preloaded_pt.json +++ b/files/KeepContextTrue_preloaded_pt.json @@ -2251,7 +2251,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/PTFromCloud_Nickname_validation.json b/files/PTFromCloud_Nickname_validation.json index 9ace18dcd2..c549219cac 100644 --- a/files/PTFromCloud_Nickname_validation.json +++ b/files/PTFromCloud_Nickname_validation.json @@ -382,15 +382,17 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] - }, - "1234567": { - "keep_context": false, - "steal_focus": false, - "priority": "NONE", - "default_hmi": "NONE", - "groups": ["Base-4"], - "nicknames": ["AnotherName"] + "groups": ["Base-4"], + "RequestType": [] + }, + "1234567": { + "keep_context": false, + "steal_focus": false, + "priority": "NONE", + "default_hmi": "NONE", + "groups": ["Base-4"], + "nicknames": ["AnotherName"], + "RequestType": [] }, "device": { "keep_context": false, @@ -408,4 +410,4 @@ } } } -} \ No newline at end of file +} diff --git a/files/PTU_AppIDAppHMIType.json b/files/PTU_AppIDAppHMIType.json index 94cb68c0a7..30377c1aac 100644 --- a/files/PTU_AppIDAppHMIType.json +++ b/files/PTU_AppIDAppHMIType.json @@ -2250,7 +2250,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "0000002": { "keep_context": false, @@ -2258,7 +2259,8 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4"], - "AppHMIType": ["MEDIA","INFORMATION"] + "AppHMIType": ["MEDIA","INFORMATION"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/PTU_AppIDDefaultHMI.json b/files/PTU_AppIDDefaultHMI.json index 9a155090ea..7cc3e69e98 100644 --- a/files/PTU_AppIDDefaultHMI.json +++ b/files/PTU_AppIDDefaultHMI.json @@ -2250,14 +2250,16 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "0000002": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "BACKGROUND", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/PTU_AppIDGroups.json b/files/PTU_AppIDGroups.json index 0fab5224cb..5e8fada630 100644 --- a/files/PTU_AppIDGroups.json +++ b/files/PTU_AppIDGroups.json @@ -2250,14 +2250,16 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "0000002": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Location-1", "Navigation-1"] + "groups": ["Location-1", "Navigation-1"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/PTU_AppRevokedGroup.json b/files/PTU_AppRevokedGroup.json index 8edef850b1..2cc9c8fb0b 100644 --- a/files/PTU_AppRevokedGroup.json +++ b/files/PTU_AppRevokedGroup.json @@ -2293,7 +2293,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "0000001":null, "device": { diff --git a/files/PTU_BackgroundDefaultHMI_InDefault.json b/files/PTU_BackgroundDefaultHMI_InDefault.json index 83b224bf57..b6e8a2df4e 100644 --- a/files/PTU_BackgroundDefaultHMI_InDefault.json +++ b/files/PTU_BackgroundDefaultHMI_InDefault.json @@ -2250,7 +2250,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "BACKGROUND", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/PTU_GetUserFriendlyMessage_without_DE_DE.json b/files/PTU_GetUserFriendlyMessage_without_DE_DE.json index 0f96f06a57..cd04f6320d 100644 --- a/files/PTU_GetUserFriendlyMessage_without_DE_DE.json +++ b/files/PTU_GetUserFriendlyMessage_without_DE_DE.json @@ -41,7 +41,7 @@ }, "Base-4" : { "rpcs" : { - + "ReadDID": { "hmi_levels": [ "BACKGROUND", @@ -49,8 +49,8 @@ "LIMITED" ] } - , - + , + "GetDTCs": { "hmi_levels": [ "BACKGROUND", @@ -58,8 +58,8 @@ "LIMITED" ] } - , - + , + "DiagnosticMessage": { "hmi_levels": [ "BACKGROUND", @@ -67,8 +67,8 @@ "LIMITED" ] } - , - + , + "SubscribeVehicleData": { "hmi_levels": [ "BACKGROUND", @@ -76,8 +76,8 @@ "LIMITED" ] } - , - + , + "GetVehicleData": { "hmi_levels": [ "BACKGROUND", @@ -85,8 +85,8 @@ "LIMITED" ] } - , - + , + "UnsubscribeVehicleData": { "hmi_levels": [ "BACKGROUND", @@ -94,7 +94,7 @@ "LIMITED" ] } - , + , "AddCommand" : { "hmi_levels" : ["BACKGROUND", "FULL", @@ -1602,7 +1602,7 @@ } } }, - + "group1" : { "languages" : { "de-de" : { @@ -2375,21 +2375,24 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4", "groupName_11", "groupName_12"] + "groups": ["Base-4", "groupName_11", "groupName_12"], + "RequestType": [] }, "0000002": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4", "groupName_21", "groupName_22"] + "groups": ["Base-4", "groupName_21", "groupName_22"], + "RequestType": [] }, "default" : { "keep_context" : false, "steal_focus" : false, "priority" : "NONE", "default_hmi" : "NONE", - "groups": ["Base-4", "Location-1", "DrivingCharacteristics-3", "VehicleInfo-3", "Emergency-1", "PropriataryData-1"] + "groups": ["Base-4", "Location-1", "DrivingCharacteristics-3", "VehicleInfo-3", "Emergency-1", "PropriataryData-1"], + "RequestType": [] }, "device" : { "keep_context" : false, diff --git a/files/PTU_NewDefaultPermissions.json b/files/PTU_NewDefaultPermissions.json index 562ea0fc2a..05aced56d4 100644 --- a/files/PTU_NewDefaultPermissions.json +++ b/files/PTU_NewDefaultPermissions.json @@ -2251,7 +2251,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4", "Location-1"] + "groups": ["Base-4", "Location-1"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/PTU_NewPermissionsForUserConsent.json b/files/PTU_NewPermissionsForUserConsent.json index c05e831112..334d48cfbe 100644 --- a/files/PTU_NewPermissionsForUserConsent.json +++ b/files/PTU_NewPermissionsForUserConsent.json @@ -2293,7 +2293,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, @@ -2316,7 +2317,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4", "Location-1", "DrivingCharacteristics-3"] + "groups": ["Base-4", "Location-1", "DrivingCharacteristics-3"], + "RequestType": [] } } } diff --git a/files/PTU_RequestType_for_app_1234567.json b/files/PTU_RequestType_for_app_1234567.json index 30eaa66ee8..3a6039ee57 100644 --- a/files/PTU_RequestType_for_app_1234567.json +++ b/files/PTU_RequestType_for_app_1234567.json @@ -2053,7 +2053,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/PTU_UpdateDefaultGroups.json b/files/PTU_UpdateDefaultGroups.json index e13301d219..36cfa3159a 100644 --- a/files/PTU_UpdateDefaultGroups.json +++ b/files/PTU_UpdateDefaultGroups.json @@ -2250,7 +2250,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Location-1"] + "groups": ["Location-1"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/PTU_UpdateDefaultPreconsentedGroups.json b/files/PTU_UpdateDefaultPreconsentedGroups.json index 2108dfd06d..c25f2fdc63 100644 --- a/files/PTU_UpdateDefaultPreconsentedGroups.json +++ b/files/PTU_UpdateDefaultPreconsentedGroups.json @@ -2251,7 +2251,8 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4"], - "preconsented_groups":["Location-1"] + "preconsented_groups":["Location-1"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/PTU_with_permissions_for_app_0000001.json b/files/PTU_with_permissions_for_app_0000001.json index 02d82be782..80e1f429ca 100644 --- a/files/PTU_with_permissions_for_app_0000001.json +++ b/files/PTU_with_permissions_for_app_0000001.json @@ -2046,14 +2046,16 @@ "priority": "EMERGENCY", "default_hmi": "BACKGROUND", "groups": ["Location-1"], - "nicknames": ["Test Application"] + "nicknames": ["Test Application"], + "RequestType": [] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/PTU_with_permissions_for_app_1234567.json b/files/PTU_with_permissions_for_app_1234567.json index cad94b4720..b36ac707e7 100644 --- a/files/PTU_with_permissions_for_app_1234567.json +++ b/files/PTU_with_permissions_for_app_1234567.json @@ -2045,14 +2045,16 @@ "priority": "EMERGENCY", "default_hmi": "BACKGROUND", "groups": ["Permission_for_1234567"], - "nicknames": ["SPT"] + "nicknames": ["SPT"], + "RequestType": [] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/PriorityNormal_preloaded_pt.json b/files/PriorityNormal_preloaded_pt.json index 9e1926cbbc..5b13b084f1 100644 --- a/files/PriorityNormal_preloaded_pt.json +++ b/files/PriorityNormal_preloaded_pt.json @@ -2251,7 +2251,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/App_Permissions/DisallowedRPCs.json b/files/jsons/Policies/App_Permissions/DisallowedRPCs.json index 857922336d..9199c511c8 100644 --- a/files/jsons/Policies/App_Permissions/DisallowedRPCs.json +++ b/files/jsons/Policies/App_Permissions/DisallowedRPCs.json @@ -2242,7 +2242,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/App_Permissions/ptu_014.json b/files/jsons/Policies/App_Permissions/ptu_014.json index e33b77faa3..89c361152f 100644 --- a/files/jsons/Policies/App_Permissions/ptu_014.json +++ b/files/jsons/Policies/App_Permissions/ptu_014.json @@ -1,12 +1,13 @@ { - "policy_table": { - "app_policies": { + "policy_table": { + "app_policies": { "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, @@ -23,9 +24,9 @@ "groups": ["BaseBeforeDataConsent"] } }, - "functional_groupings": { + "functional_groupings": { "SpecificPermissions": { - "rpcs": { + "rpcs": { "PutFile": { "hmi_levels": [ "BACKGROUND", @@ -33,7 +34,7 @@ "LIMITED", "NONE" ] - } + } } }, "BackgroundAPT": { @@ -57,8 +58,8 @@ }, "Base-4": { "rpcs": { - - + + "ChangeRegistration": { "hmi_levels": [ "BACKGROUND", @@ -296,7 +297,7 @@ "BACKGROUND" ] }, - + "Slider": { "hmi_levels": [ "FULL" @@ -315,7 +316,7 @@ "LIMITED" ] }, - + "UnregisterAppInterface": { "hmi_levels": [ "BACKGROUND", @@ -1198,7 +1199,7 @@ }, "user_consent_prompt": "VehicleInfo" } - }, + }, "module_config": { "endpoints": { "0x04": { diff --git a/files/jsons/Policies/PTU_ValidationRules/PTU_has_omitted.json b/files/jsons/Policies/PTU_ValidationRules/PTU_has_omitted.json index 7789f0f180..5ac14ae3ba 100644 --- a/files/jsons/Policies/PTU_ValidationRules/PTU_has_omitted.json +++ b/files/jsons/Policies/PTU_ValidationRules/PTU_has_omitted.json @@ -2251,7 +2251,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/PTU_ValidationRules/PTU_invalid_optional.json b/files/jsons/Policies/PTU_ValidationRules/PTU_invalid_optional.json index 23af2723b9..fe0a210273 100644 --- a/files/jsons/Policies/PTU_ValidationRules/PTU_invalid_optional.json +++ b/files/jsons/Policies/PTU_ValidationRules/PTU_invalid_optional.json @@ -2545,7 +2545,8 @@ "default_hmi": "NONE", "groups": [ "Base-4" - ] + ], + "RequestType": [] } }, "module_config": { @@ -2593,4 +2594,4 @@ "exchange_after_x_ignition_cycles": 100 } } -} \ No newline at end of file +} diff --git a/files/jsons/Policies/PTU_ValidationRules/invalid_PTU_missing_seconds_between_retries.json b/files/jsons/Policies/PTU_ValidationRules/invalid_PTU_missing_seconds_between_retries.json index 2eb9e5727c..d3a87f5f3b 100644 --- a/files/jsons/Policies/PTU_ValidationRules/invalid_PTU_missing_seconds_between_retries.json +++ b/files/jsons/Policies/PTU_ValidationRules/invalid_PTU_missing_seconds_between_retries.json @@ -2293,7 +2293,7 @@ "RequestType":[ "PROPRIETARY", "HTTP", - "QUERY_APPS" + "QUERY_APPS" ] }, "device": { @@ -2314,7 +2314,7 @@ "BaseBeforeDataConsent" ], "RequestType":[ - "PROPRIETARY" + "PROPRIETARY" ] }, "123456": { @@ -2329,7 +2329,7 @@ "TRAFFIC_MESSAGE_CHANNEL", "PROPRIETARY", "HTTP", - "QUERY_APPS" + "QUERY_APPS" ] } }, diff --git a/files/jsons/Policies/PTU_ValidationRules/preloaded_memory_kb_exist.json b/files/jsons/Policies/PTU_ValidationRules/preloaded_memory_kb_exist.json index 40542dcb42..1a91e84037 100644 --- a/files/jsons/Policies/PTU_ValidationRules/preloaded_memory_kb_exist.json +++ b/files/jsons/Policies/PTU_ValidationRules/preloaded_memory_kb_exist.json @@ -2252,7 +2252,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/PTU_ValidationRules/ptu_012.json b/files/jsons/Policies/PTU_ValidationRules/ptu_012.json index 86ac34fa67..7c3e26f618 100644 --- a/files/jsons/Policies/PTU_ValidationRules/ptu_012.json +++ b/files/jsons/Policies/PTU_ValidationRules/ptu_012.json @@ -1,5 +1,5 @@ { - "policy_table": { + "policy_table": { "app_policies": { "0000001": { "keep_context": false, @@ -7,14 +7,16 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4", "Base-6"], - "nicknames": ["App1"] + "nicknames": ["App1"], + "RequestType": [] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, @@ -1225,7 +1227,7 @@ }, "user_consent_prompt": "VehicleInfo" } - }, + }, "module_config": { "endpoints": { "0x04": { diff --git a/files/jsons/Policies/PTU_ValidationRules/ptu_RAI.json b/files/jsons/Policies/PTU_ValidationRules/ptu_RAI.json index 6743d664eb..847a847892 100644 --- a/files/jsons/Policies/PTU_ValidationRules/ptu_RAI.json +++ b/files/jsons/Policies/PTU_ValidationRules/ptu_RAI.json @@ -2296,7 +2296,8 @@ "default_hmi": "NONE", "groups": [ "Base-4" - ] + ], + "RequestType": [] }, "654321": { "keep_context": true, @@ -2306,7 +2307,8 @@ "groups": [ "Base-4" ], - "nicknames":["Tester"] + "nicknames":["Tester"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/PTU_ValidationRules/sdl_preloaded_pt_without_optional_params.json b/files/jsons/Policies/PTU_ValidationRules/sdl_preloaded_pt_without_optional_params.json index 117415c289..4e6993bc63 100644 --- a/files/jsons/Policies/PTU_ValidationRules/sdl_preloaded_pt_without_optional_params.json +++ b/files/jsons/Policies/PTU_ValidationRules/sdl_preloaded_pt_without_optional_params.json @@ -2556,7 +2556,8 @@ "default_hmi": "NONE", "groups": [ "Base-4" - ] + ], + "RequestType": [] }, "device": { "keep_context": false, @@ -2578,4 +2579,4 @@ } } } -} \ No newline at end of file +} diff --git a/files/jsons/Policies/Policy_Table_Update/few_endpoints_appId_default.json b/files/jsons/Policies/Policy_Table_Update/few_endpoints_appId_default.json index d5b3a3eecb..35a082a0cc 100644 --- a/files/jsons/Policies/Policy_Table_Update/few_endpoints_appId_default.json +++ b/files/jsons/Policies/Policy_Table_Update/few_endpoints_appId_default.json @@ -17,7 +17,7 @@ "http://policies.telematics.ford.com/api/policies3", "http://policies.telematics.ford.com/api/policies1", "http://policies.telematics.ford.com/api/policies2" - + ] }, "0x04": { @@ -2250,7 +2250,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/Policy_Table_Update/few_endpoints_appId_not_registered.json b/files/jsons/Policies/Policy_Table_Update/few_endpoints_appId_not_registered.json index 2a707cdaba..9d4b2e1e22 100644 --- a/files/jsons/Policies/Policy_Table_Update/few_endpoints_appId_not_registered.json +++ b/files/jsons/Policies/Policy_Table_Update/few_endpoints_appId_not_registered.json @@ -2249,7 +2249,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/Policy_Table_Update/few_endpoints_appId_registered.json b/files/jsons/Policies/Policy_Table_Update/few_endpoints_appId_registered.json index 47950080d8..4e86e60740 100644 --- a/files/jsons/Policies/Policy_Table_Update/few_endpoints_appId_registered.json +++ b/files/jsons/Policies/Policy_Table_Update/few_endpoints_appId_registered.json @@ -2249,7 +2249,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/Policy_Table_Update/ptu.json b/files/jsons/Policies/Policy_Table_Update/ptu.json index 312d7ec155..e69ef446e8 100644 --- a/files/jsons/Policies/Policy_Table_Update/ptu.json +++ b/files/jsons/Policies/Policy_Table_Update/ptu.json @@ -2301,7 +2301,7 @@ "RequestType":[ "PROPRIETARY", "HTTP", - "QUERY_APPS" + "QUERY_APPS" ] }, "device": { @@ -2322,7 +2322,7 @@ "BaseBeforeDataConsent" ], "RequestType":[ - "PROPRIETARY" + "PROPRIETARY" ] }, "0000001": { @@ -2335,7 +2335,7 @@ "TRAFFIC_MESSAGE_CHANNEL", "PROPRIETARY", "HTTP", - "QUERY_APPS" + "QUERY_APPS" ] }, "MyTestApp": { @@ -2344,7 +2344,8 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4"], - "nicknames": ["Media Application", "MediaApp"] + "nicknames": ["Media Application", "MediaApp"], + "RequestType": [] } } } diff --git a/files/jsons/Policies/Policy_Table_Update/ptu_18190.json b/files/jsons/Policies/Policy_Table_Update/ptu_18190.json index 6a72708cbc..6b739f47e9 100644 --- a/files/jsons/Policies/Policy_Table_Update/ptu_18190.json +++ b/files/jsons/Policies/Policy_Table_Update/ptu_18190.json @@ -9,14 +9,16 @@ "groups": ["Base-4", "Base-6"], "heart_beat_timeout_ms": 0, "memory_kb": 0, - "nicknames": ["Test Application"] + "nicknames": ["Test Application"], + "RequestType": [] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/Policy_Table_Update/ptu_18707_1.json b/files/jsons/Policies/Policy_Table_Update/ptu_18707_1.json index ba4f55fb19..aaa2849645 100644 --- a/files/jsons/Policies/Policy_Table_Update/ptu_18707_1.json +++ b/files/jsons/Policies/Policy_Table_Update/ptu_18707_1.json @@ -6,14 +6,16 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/Policy_Table_Update/ptu_19168.json b/files/jsons/Policies/Policy_Table_Update/ptu_19168.json index 485313f736..8c4a313be2 100644 --- a/files/jsons/Policies/Policy_Table_Update/ptu_19168.json +++ b/files/jsons/Policies/Policy_Table_Update/ptu_19168.json @@ -6,14 +6,16 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4", "Base-6"] + "groups": ["Base-4", "Base-6"], + "RequestType": [] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/Policy_Table_Update/ptu_22420.json b/files/jsons/Policies/Policy_Table_Update/ptu_22420.json index 9aac39dc2c..25b6d4a375 100644 --- a/files/jsons/Policies/Policy_Table_Update/ptu_22420.json +++ b/files/jsons/Policies/Policy_Table_Update/ptu_22420.json @@ -6,14 +6,16 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4", "Base-6"] + "groups": ["Base-4", "Base-6"], + "RequestType": [] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/Policy_Table_Update/ptu_22421_1Mb.json b/files/jsons/Policies/Policy_Table_Update/ptu_22421_1Mb.json index 05e9d5aa59..2f6a725943 100644 --- a/files/jsons/Policies/Policy_Table_Update/ptu_22421_1Mb.json +++ b/files/jsons/Policies/Policy_Table_Update/ptu_22421_1Mb.json @@ -6,14 +6,16 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4", "Base-6"] + "groups": ["Base-4", "Base-6"], + "RequestType": [] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/Policy_Table_Update/ptu_22734.json b/files/jsons/Policies/Policy_Table_Update/ptu_22734.json index 682e943e14..9bee2227eb 100644 --- a/files/jsons/Policies/Policy_Table_Update/ptu_22734.json +++ b/files/jsons/Policies/Policy_Table_Update/ptu_22734.json @@ -1,19 +1,21 @@ { - "policy_table": { + "policy_table": { "app_policies": { "0000001": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4", "Base-6"] + "groups": ["Base-4", "Base-6"], + "RequestType": [] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, @@ -30,7 +32,7 @@ "groups": ["BaseBeforeDataConsent"] } }, - "functional_groupings": { + "functional_groupings": { "BackgroundAPT": { "rpcs": { "EndAudioPassThru": { @@ -1224,7 +1226,7 @@ }, "user_consent_prompt": "VehicleInfo" } - }, + }, "module_config": { "endpoints": { "0x04": { diff --git a/files/jsons/Policies/Policy_Table_Update/ptu_after_n_ign.json b/files/jsons/Policies/Policy_Table_Update/ptu_after_n_ign.json index bdf302ef1f..4a6e4df833 100644 --- a/files/jsons/Policies/Policy_Table_Update/ptu_after_n_ign.json +++ b/files/jsons/Policies/Policy_Table_Update/ptu_after_n_ign.json @@ -2265,28 +2265,32 @@ "steal_focus": true, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4", "Navigation-1","DrivingCharacteristics-3", "Location-1", "VehicleInfo-3", "Emergency-1", "OnKeyboardInputOnlyGroup", "PropriataryData-1"] + "groups": ["Base-4", "Navigation-1","DrivingCharacteristics-3", "Location-1", "VehicleInfo-3", "Emergency-1", "OnKeyboardInputOnlyGroup", "PropriataryData-1"], + "RequestType": [] }, "0000001": { "keep_context": true, "steal_focus": true, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4", "Navigation-1","DrivingCharacteristics-3", "Location-1", "VehicleInfo-3", "Emergency-1", "OnKeyboardInputOnlyGroup", "PropriataryData-1", "SendLocation"] + "groups": ["Base-4", "Navigation-1","DrivingCharacteristics-3", "Location-1", "VehicleInfo-3", "Emergency-1", "OnKeyboardInputOnlyGroup", "PropriataryData-1", "SendLocation"], + "RequestType": [] }, "0000004": { "keep_context": true, "steal_focus": true, "priority": "NONE", "default_hmi": "BACKGROUND", - "groups": ["Base-4", "Navigation-1","DrivingCharacteristics-3", "Location-1", "VehicleInfo-3", "Emergency-1", "OnKeyboardInputOnlyGroup", "PropriataryData-1", "SendLocation"] + "groups": ["Base-4", "Navigation-1","DrivingCharacteristics-3", "Location-1", "VehicleInfo-3", "Emergency-1", "OnKeyboardInputOnlyGroup", "PropriataryData-1", "SendLocation"], + "RequestType": [] }, "background": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "BACKGROUND", - "groups": ["Base-4", "Navigation-1"] + "groups": ["Base-4", "Navigation-1"], + "RequestType": [] }, "device": { "keep_context": false, @@ -2304,4 +2308,4 @@ } } } -} \ No newline at end of file +} diff --git a/files/jsons/Policies/Related_HMI_API/OnAppPermissionConsent.json b/files/jsons/Policies/Related_HMI_API/OnAppPermissionConsent.json index aef1e17683..6fd3fa8c3b 100644 --- a/files/jsons/Policies/Related_HMI_API/OnAppPermissionConsent.json +++ b/files/jsons/Policies/Related_HMI_API/OnAppPermissionConsent.json @@ -2296,7 +2296,8 @@ "default_hmi": "NONE", "groups": [ "Base-4" - ] + ], + "RequestType": [] }, "0000001": { "keep_context": false, @@ -2305,7 +2306,8 @@ "default_hmi": "NONE", "groups": [ "Base-4", "Notifications", "Location-1" - ] + ], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/Related_HMI_API/OnAppPermissionConsent_ptu.json b/files/jsons/Policies/Related_HMI_API/OnAppPermissionConsent_ptu.json index 367f868b0f..af9b977100 100644 --- a/files/jsons/Policies/Related_HMI_API/OnAppPermissionConsent_ptu.json +++ b/files/jsons/Policies/Related_HMI_API/OnAppPermissionConsent_ptu.json @@ -2295,7 +2295,8 @@ "default_hmi": "NONE", "groups": [ "Base-4" - ] + ], + "RequestType": [] }, "0000001": { "keep_context": false, @@ -2304,7 +2305,8 @@ "default_hmi": "NONE", "groups": [ "Base-4", "Notifications", "Location-1" - ] + ], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/Related_HMI_API/OnAppPermissionConsent_ptu1.json b/files/jsons/Policies/Related_HMI_API/OnAppPermissionConsent_ptu1.json index 13ec87b803..d1662750c4 100644 --- a/files/jsons/Policies/Related_HMI_API/OnAppPermissionConsent_ptu1.json +++ b/files/jsons/Policies/Related_HMI_API/OnAppPermissionConsent_ptu1.json @@ -2295,7 +2295,8 @@ "default_hmi": "NONE", "groups": [ "Base-4" - ] + ], + "RequestType": [] }, "0000001": { "keep_context": false, @@ -2304,7 +2305,8 @@ "default_hmi": "NONE", "groups": [ "Base-4", "DrivingCharacteristics-3" - ] + ], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/appID_Management/ptu_0.json b/files/jsons/Policies/appID_Management/ptu_0.json index 2456b913b7..a2e0d4c5f0 100644 --- a/files/jsons/Policies/appID_Management/ptu_0.json +++ b/files/jsons/Policies/appID_Management/ptu_0.json @@ -8,14 +8,16 @@ "steal_focus": false, "default_hmi": "NONE", "priority": "NONE", - "nicknames": ["Media Application", "MediaApp"] + "nicknames": ["Media Application", "MediaApp"], + "RequestType": [] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/appID_Management/ptu_01.json b/files/jsons/Policies/appID_Management/ptu_01.json index 233d027548..d070ae78f6 100644 --- a/files/jsons/Policies/appID_Management/ptu_01.json +++ b/files/jsons/Policies/appID_Management/ptu_01.json @@ -8,14 +8,16 @@ "keep_context": false, "steal_focus": false, "default_hmi": "NONE", - "nicknames": ["Media Application", "MediaApp"] + "nicknames": ["Media Application", "MediaApp"], + "RequestType": [] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/appID_Management/ptu_013_1.json b/files/jsons/Policies/appID_Management/ptu_013_1.json index 326edc245a..45b43aa7b9 100644 --- a/files/jsons/Policies/appID_Management/ptu_013_1.json +++ b/files/jsons/Policies/appID_Management/ptu_013_1.json @@ -4,17 +4,19 @@ "0000001": { "groups": ["Base-4", "Base-6"], "priority": "NONE", - "keep_context": false, + "keep_context": false, "steal_focus": false, - "default_hmi": "NONE", - "nicknames": ["App1"] + "default_hmi": "NONE", + "nicknames": ["App1"], + "RequestType": [] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/appID_Management/ptu_013_2.json b/files/jsons/Policies/appID_Management/ptu_013_2.json index 70b7b5b044..097f4f5eeb 100644 --- a/files/jsons/Policies/appID_Management/ptu_013_2.json +++ b/files/jsons/Policies/appID_Management/ptu_013_2.json @@ -4,10 +4,11 @@ "0000001": { "groups": ["Base-4", "Base-6"], "priority": "NONE", - "keep_context": false, + "keep_context": false, "steal_focus": false, - "default_hmi": "NONE", - "nicknames": ["App1"] + "default_hmi": "NONE", + "nicknames": ["App1"], + "RequestType": [] }, "123_xyz": null, "default": { @@ -15,7 +16,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/appID_Management/ptu_1.json b/files/jsons/Policies/appID_Management/ptu_1.json index 7c5febea7a..75dd03ad30 100644 --- a/files/jsons/Policies/appID_Management/ptu_1.json +++ b/files/jsons/Policies/appID_Management/ptu_1.json @@ -7,7 +7,8 @@ "keep_context": false, "steal_focus": false, "default_hmi": "NONE", - "nicknames": ["App1"] + "nicknames": ["App1"], + "RequestType": [] }, "123_xyz": { "groups": ["Base-6"], @@ -15,7 +16,8 @@ "keep_context": false, "steal_focus": false, "default_hmi": "NONE", - "nicknames": ["Media Application", "MediaApp"] + "nicknames": ["Media Application", "MediaApp"], + "RequestType": [] }, "456_abc": { "groups": ["Base-6"], @@ -23,14 +25,16 @@ "keep_context": false, "steal_focus": false, "default_hmi": "NONE", - "nicknames": ["ABC Application"] + "nicknames": ["ABC Application"], + "RequestType": [] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/appID_Management/ptu_19849.json b/files/jsons/Policies/appID_Management/ptu_19849.json index 0190ccf202..1ca330a397 100644 --- a/files/jsons/Policies/appID_Management/ptu_19849.json +++ b/files/jsons/Policies/appID_Management/ptu_19849.json @@ -6,21 +6,24 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4", "Base-6"] + "groups": ["Base-4", "Base-6"], + "RequestType": [] }, "123_xyz": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["SpecificPermissions"] + "groups": ["SpecificPermissions"], + "RequestType": [] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/user_consent/OnAppPermissionConsent_1.json b/files/jsons/Policies/user_consent/OnAppPermissionConsent_1.json index 544ec9c408..699d49d5f9 100644 --- a/files/jsons/Policies/user_consent/OnAppPermissionConsent_1.json +++ b/files/jsons/Policies/user_consent/OnAppPermissionConsent_1.json @@ -2250,14 +2250,16 @@ "default_hmi": "NONE", "groups": [ "Base-4", "Notifications", "Location-1" - ] + ], + "RequestType": [] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/user_consent/pre_dataconsent.json b/files/jsons/Policies/user_consent/pre_dataconsent.json index 15c0739913..5cdb7bea6b 100644 --- a/files/jsons/Policies/user_consent/pre_dataconsent.json +++ b/files/jsons/Policies/user_consent/pre_dataconsent.json @@ -2251,7 +2251,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/ptu_for_navi_app.json b/files/ptu_for_navi_app.json index 55e349c926..7a88b06d10 100644 --- a/files/ptu_for_navi_app.json +++ b/files/ptu_for_navi_app.json @@ -2266,28 +2266,32 @@ "steal_focus": true, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "0000001": { "keep_context": true, "steal_focus": true, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "0000004": { "keep_context": true, "steal_focus": true, "priority": "NONE", "default_hmi": "BACKGROUND", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "background": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "BACKGROUND", - "groups": ["Base-4", "Navigation-1"] + "groups": ["Base-4", "Navigation-1"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/ptu_general.json b/files/ptu_general.json index f1559a9a41..013537f8b4 100644 --- a/files/ptu_general.json +++ b/files/ptu_general.json @@ -2289,7 +2289,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "BACKGROUND", - "groups": ["Base-4", "Navigation-1"] + "groups": ["Base-4", "Navigation-1"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/ptu_general_0000001.json b/files/ptu_general_0000001.json index 56c4768058..45cbe02a82 100644 --- a/files/ptu_general_0000001.json +++ b/files/ptu_general_0000001.json @@ -1810,14 +1810,16 @@ "steal_focus": true, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "0000001": { "keep_context": true, "steal_focus": true, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-8"] + "groups": ["Base-8"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/ptu_general_default_app-1234567.json b/files/ptu_general_default_app-1234567.json index 8b56aefc62..d137969294 100644 --- a/files/ptu_general_default_app-1234567.json +++ b/files/ptu_general_default_app-1234567.json @@ -2051,14 +2051,16 @@ "steal_focus": true, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "background": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "BACKGROUND", - "groups": ["Base-4", "Navigation-1"] + "groups": ["Base-4", "Navigation-1"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/ptu_general_default_keep_context_false.json b/files/ptu_general_default_keep_context_false.json index 78f8587722..4dd89e1a09 100644 --- a/files/ptu_general_default_keep_context_false.json +++ b/files/ptu_general_default_keep_context_false.json @@ -2251,7 +2251,8 @@ "steal_focus": true, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/ptu_general_default_keep_context_true.json b/files/ptu_general_default_keep_context_true.json index f886069ad7..79e95632f5 100644 --- a/files/ptu_general_default_keep_context_true.json +++ b/files/ptu_general_default_keep_context_true.json @@ -2251,7 +2251,8 @@ "steal_focus": true, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/ptu_general_default_steal_focus_false.json b/files/ptu_general_default_steal_focus_false.json index 15c0739913..5cdb7bea6b 100644 --- a/files/ptu_general_default_steal_focus_false.json +++ b/files/ptu_general_default_steal_focus_false.json @@ -2251,7 +2251,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/ptu_general_default_steal_focus_true.json b/files/ptu_general_default_steal_focus_true.json index 78f8587722..4dd89e1a09 100644 --- a/files/ptu_general_default_steal_focus_true.json +++ b/files/ptu_general_default_steal_focus_true.json @@ -2251,7 +2251,8 @@ "steal_focus": true, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/sdl_preloaded_pt_AlertOnlyNotifications_1.json b/files/sdl_preloaded_pt_AlertOnlyNotifications_1.json index e9418c7f5a..67922ede69 100644 --- a/files/sdl_preloaded_pt_AlertOnlyNotifications_1.json +++ b/files/sdl_preloaded_pt_AlertOnlyNotifications_1.json @@ -2252,7 +2252,8 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [] }, "device": { "keep_context": false, From 2841b00304bcec8679de4b91319bf1e800dccb25 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Sat, 28 Jul 2018 17:11:15 +0300 Subject: [PATCH 505/681] Update policy scripts due to OnDriverDistraction changes --- files/ptu_general.json | 3 ++- ...t_into_local_pt_usage_and_error_counts.lua | 4 ++-- ...ATF_Check_count_of_rejected_rpcs_calls.lua | 20 ++++++++----------- ...F_Check_count_of_rpcs_sent_in_hmi_none.lua | 20 ++++++++----------- ...User_consent_initing_after_PTU_LIMITED.lua | 2 +- 5 files changed, 21 insertions(+), 28 deletions(-) diff --git a/files/ptu_general.json b/files/ptu_general.json index 013537f8b4..6f65d90db2 100644 --- a/files/ptu_general.json +++ b/files/ptu_general.json @@ -142,7 +142,8 @@ "OnDriverDistraction": { "hmi_levels": ["BACKGROUND", "FULL", - "LIMITED"] + "LIMITED", + "NONE"] }, "OnEncodedSyncPData": { "hmi_levels": ["BACKGROUND", diff --git a/test_scripts/Policies/Validation_of_PolicyTables/253_ATF_merge_preloaded_pt_into_local_pt_usage_and_error_counts.lua b/test_scripts/Policies/Validation_of_PolicyTables/253_ATF_merge_preloaded_pt_into_local_pt_usage_and_error_counts.lua index 024ece23e3..8c023c775c 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/253_ATF_merge_preloaded_pt_into_local_pt_usage_and_error_counts.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/253_ATF_merge_preloaded_pt_into_local_pt_usage_and_error_counts.lua @@ -95,7 +95,7 @@ local function updatePreloadedPt(updaters) updateFunc(data) end end - + data.policy_table.app_policies["0000001"] = "default" local dataToWrite = json.encode(data) file = io.open(pathToFile, "w") file:write(dataToWrite) @@ -198,7 +198,7 @@ testCasesForPolicyTable.Delete_Policy_table_snapshot() commonSteps:DeleteLogsFileAndPolicyTable() commonPreconditions:BackupFile(PRELOADED_PT_FILE_NAME) prepareInitialPreloadedPT() -commonPreconditions:Connecttest_without_ExitBySDLDisconnect_WithoutOpenConnectionRegisterApp("connecttest_ConnectMobile.lua") +-- commonPreconditions:Connecttest_without_ExitBySDLDisconnect_WithoutOpenConnectionRegisterApp("connecttest_ConnectMobile.lua") --[[ General configuration parameters ]] -- Test = require('user_modules/connecttest_ConnectMobile') diff --git a/test_scripts/Policies/Validation_of_PolicyTables/309_ATF_Check_count_of_rejected_rpcs_calls.lua b/test_scripts/Policies/Validation_of_PolicyTables/309_ATF_Check_count_of_rejected_rpcs_calls.lua index 054a8f3150..57b6ea92c3 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/309_ATF_Check_count_of_rejected_rpcs_calls.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/309_ATF_Check_count_of_rejected_rpcs_calls.lua @@ -21,27 +21,21 @@ --------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') -local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local testCasesForPolicyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") --[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 commonSteps:DeleteLogsFileAndPolicyTable() +testCasesForPolicyTable:Precondition_updatePolicy_By_overwriting_preloaded_pt("files/ptu_general.json") --[[ General Settings for configuration ]] -Test = require('connecttest') -require('cardinalities') +Test = require("connecttest") require('user_modules/AppTypes') --[[ Test ]] function Test:SendDissalowedRpcInNone() - local cid = self.mobileSession:SendRPC("AddCommand", - { - cmdID = 10, - menuParams = - { - position = 0, - menuName ="Command" - } - }) + local cid = self.mobileSession:SendRPC("GetVehicleData", { gps = true}) EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) end @@ -55,4 +49,6 @@ function Test:CheckDB_updated_count_of_rejected_rpcs_calls() end end +testCasesForPolicyTable:Restore_preloaded_pt() + return Test diff --git a/test_scripts/Policies/Validation_of_PolicyTables/313_ATF_Check_count_of_rpcs_sent_in_hmi_none.lua b/test_scripts/Policies/Validation_of_PolicyTables/313_ATF_Check_count_of_rpcs_sent_in_hmi_none.lua index 90febc2f37..f27428a65a 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/313_ATF_Check_count_of_rpcs_sent_in_hmi_none.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/313_ATF_Check_count_of_rpcs_sent_in_hmi_none.lua @@ -19,27 +19,21 @@ --------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local commonSteps = require('user_modules/shared_testcases/commonSteps') -local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local testCasesForPolicyTable = require("user_modules/shared_testcases/testCasesForPolicyTable") --[[ General Precondition before ATF start ]] +config.defaultProtocolVersion = 2 commonSteps:DeleteLogsFileAndPolicyTable() +testCasesForPolicyTable:Precondition_updatePolicy_By_overwriting_preloaded_pt("files/ptu_general.json") --[[ General Settings for configuration ]] -Test = require('connecttest') -require('cardinalities') +Test = require("connecttest") require('user_modules/AppTypes') --[[ Test ]] function Test:SendDissalowedRpcInNone() - local cid = self.mobileSession:SendRPC("AddCommand", - { - cmdID = 10, - menuParams = - { - position = 0, - menuName ="Command" - } - }) + local cid = self.mobileSession:SendRPC("GetVehicleData", { gps = true}) EXPECT_RESPONSE(cid, { success = false, resultCode = "DISALLOWED" }) end @@ -53,4 +47,6 @@ function Test:CheckDB_updated_count_of_rejections_duplicate_name() end end +testCasesForPolicyTable:Restore_preloaded_pt() + return Test diff --git a/test_scripts/Policies/user_consent_of_Policies/211_ATF_User_consent_initing_after_PTU_LIMITED.lua b/test_scripts/Policies/user_consent_of_Policies/211_ATF_User_consent_initing_after_PTU_LIMITED.lua index 3c304cf906..603b02f0cc 100644 --- a/test_scripts/Policies/user_consent_of_Policies/211_ATF_User_consent_initing_after_PTU_LIMITED.lua +++ b/test_scripts/Policies/user_consent_of_Policies/211_ATF_User_consent_initing_after_PTU_LIMITED.lua @@ -35,7 +35,7 @@ function Test:Precondition_Activate_app() end function Test:Precondition_Switch_app_to_LIMITED() - self.hmiConnection:SendNotification("BasicCommunication.OnEventChanged",{isActive = true,eventName ="AUDIO_SOURCE"}) + self.hmiConnection:SendNotification("BasicCommunication.OnAppDeactivated", {appID = self.applications[config.application1.registerAppInterfaceParams.appName] }) self.mobileSession:ExpectNotification("OnHMIStatus",{hmiLevel ="LIMITED", systemContext = "MAIN"}) end From a00afe22298ada8594bafb801676325834e33355 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Sat, 28 Jul 2018 17:11:55 +0300 Subject: [PATCH 506/681] Update policy scripts due to Mobile Projection changes --- .../shared_testcases/testCasesForPolicyTableSnapshot.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua b/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua index b4ad85b7e3..2a20241352 100644 --- a/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua +++ b/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua @@ -131,6 +131,7 @@ function testCasesForPolicyTableSnapshot:verify_PTS(is_created, app_IDs, device_ { name = "module_config.notifications_per_minute_by_priority.COMMUNICATION", elem_required = "required"}, { name = "module_config.notifications_per_minute_by_priority.NORMAL", elem_required = "required"}, { name = "module_config.notifications_per_minute_by_priority.NONE", elem_required = "required"}, + { name = "module_config.notifications_per_minute_by_priority.PROJECTION", elem_required = "optional"}, { name = "module_config.certificate", elem_required = "optional"}, { name = "module_config.vehicle_make", elem_required = "optional"}, { name = "module_config.vehicle_model", elem_required = "optional"}, From 28d4b5aad964f68e6655cdb9070db3ca18d4fd6c Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Sun, 29 Jul 2018 15:15:59 +0300 Subject: [PATCH 507/681] Update script according to changes in SDL --- .../023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test_scripts/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua b/test_scripts/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua index 61f1537a46..cf7615f118 100644 --- a/test_scripts/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua +++ b/test_scripts/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua @@ -38,7 +38,9 @@ local function sendWakeUpSignal() unexpectedDisconnect = true, appID = common.getHMIAppId() }) - common.cleanSessions() + :Do(function() + common.cleanSessions() + end) end --[[ Scenario ]] From 8406a99cbba4b08f2c95eb42345a71fa7c875947 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 27 Jul 2018 14:11:53 +0300 Subject: [PATCH 508/681] Initial scripts for Transfer_RPC_with_Invalid_Image feature --- .../001_AddCommand.lua | 120 +++++++ .../002_AddSubMenu.lua | 72 ++++ .../003_Alert.lua | 183 ++++++++++ .../004_CreateInteractionChoiceSet.lua | 83 +++++ .../005_PerfomInteraction.lua | 324 ++++++++++++++++++ .../006_ScrollableMessage.lua | 99 ++++++ .../007_Show.lua | 111 ++++++ .../008_ShowConstantTBT.lua | 116 +++++++ .../009_SendLocation.lua | 62 ++++ .../010_SetAppIcon.lua | 57 +++ .../011_UpdateTurnList.lua | 82 +++++ .../012_AlertManeuver.lua | 121 +++++++ .../013_GetWayPoints.lua | 91 +++++ .../014_OnWayPointChange.lua | 80 +++++ .../015_SetGlobalProperties.lua | 112 ++++++ .../common.lua | 56 +++ ...L_0042_Transfer_RPC_with_Invalid_Image.txt | 15 + 17 files changed, 1784 insertions(+) create mode 100644 test_scripts/API/Transfer_RPC_with_invalid_image/001_AddCommand.lua create mode 100644 test_scripts/API/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua create mode 100644 test_scripts/API/Transfer_RPC_with_invalid_image/003_Alert.lua create mode 100644 test_scripts/API/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua create mode 100644 test_scripts/API/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua create mode 100644 test_scripts/API/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua create mode 100644 test_scripts/API/Transfer_RPC_with_invalid_image/007_Show.lua create mode 100644 test_scripts/API/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua create mode 100644 test_scripts/API/Transfer_RPC_with_invalid_image/009_SendLocation.lua create mode 100644 test_scripts/API/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua create mode 100644 test_scripts/API/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua create mode 100644 test_scripts/API/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua create mode 100644 test_scripts/API/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua create mode 100644 test_scripts/API/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua create mode 100644 test_scripts/API/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua create mode 100644 test_scripts/API/Transfer_RPC_with_invalid_image/common.lua create mode 100644 test_sets/SDL_0042_Transfer_RPC_with_Invalid_Image.txt diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/001_AddCommand.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/001_AddCommand.lua new file mode 100644 index 0000000000..ec134c1136 --- /dev/null +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/001_AddCommand.lua @@ -0,0 +1,120 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0042-transfer-invalid-image-rpc.md +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1. Mobile app requests AddCommand with image that is absent on file system +-- SDL must: +-- 1. transfer this RPC to HMI for processing +-- 2. transfer the received from HMI response (WARNINGS, message: “Requested image(s) not foundâ€) to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + menuParams = { + position = 0, + menuName ="Commandpositive" + }, + cmdIcon = { + value = "missed_icon.png", + imageType = "DYNAMIC" + } +} + +local requestUiParams = { + cmdID = requestParams.cmdID, + cmdIcon = requestParams.cmdIcon, + menuParams = requestParams.menuParams +} + +local requestVrParams = { + cmdID = requestParams.cmdID, + type = "Command", + vrCommands = requestParams.vrCommands +} + +local allParams = { + requestParams = requestParams, + responseUiParams = requestUiParams, + responseVrParams = requestVrParams +} + +--[[ Local Functions ]] +local function addCommand(pId, pParams) + pParams.requestParams.cmdID = pId + pParams.requestParams.menuParams.menuName = requestParams.menuParams.menuName .. pId + pParams.responseUiParams.cmdIcon.value = common.getPathToFileInStorage("missed_icon.png") + pParams.responseUiParams.appID = common.getHMIAppId() + + local cid = common.getMobileSession():SendRPC("AddCommand", pParams.requestParams) + + EXPECT_HMICALL("UI.AddCommand", pParams.responseUiParams) + :Do(function(_,data) + common.getHMIConnection():SendError(data.id, data.method, "WARNINGS", "Requested image(s) not found") + end) + + common.getMobileSession():ExpectResponse(cid, + { success = true, resultCode = "WARNINGS", info = "Requested image(s) not found" }) + + common.getMobileSession():ExpectNotification("OnHashChange") +end + +local function addCommandVR(pId, pParams) + pParams.requestParams.cmdID = pId + pParams.requestParams.menuParams.menuName = requestParams.menuParams.menuName .. pId + pParams.responseUiParams.cmdIcon.value = common.getPathToFileInStorage("missed_icon.png") + pParams.responseUiParams.appID = common.getHMIAppId() + pParams.requestParams.vrCommands = { + "VRCommandonepositive", + "VRCommandonepositivedouble" + } + pParams.responseVrParams.appID = common.getHMIAppId() + + EXPECT_HMICALL("VR.AddCommand", pParams.responseVrParams) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + if data.params.grammarID ~= nil then + return true + else + return false, "grammarID should not be empty" + end + end) + + + local cid = common.getMobileSession():SendRPC("AddCommand", pParams.requestParams) + + EXPECT_HMICALL("UI.AddCommand", pParams.responseUiParams) + :Do(function(_,data) + common.getHMIConnection():SendError(data.id, data.method, "WARNINGS", "Requested image(s) not found") + end) + + common.getMobileSession():ExpectResponse(cid, + { success = true, resultCode = "WARNINGS", info = "Requested image(s) not found" }) + + common.getMobileSession():ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", common.registerAppWOPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("AddCommand with invalid image only UI interface", addCommand, { 1, allParams }) +runner.Step("AddCommand with invalid image with VR interface", addCommandVR, { 2, allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua new file mode 100644 index 0000000000..e86c374b8d --- /dev/null +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua @@ -0,0 +1,72 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0042-transfer-invalid-image-rpc.md +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1. Mobile app requests AddSubMenu with image that is absent on file system +-- SDL must: +-- 1. transfer this RPC to HMI for processing +-- 2. transfer the received from HMI response (WARNINGS, message: “Requested image(s) not foundâ€) to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + menuID = 1000, + position = 500, + menuName ="SubMenupositive", + menuIcon = { + value ="missed_icon.png", + imageType ="DYNAMIC" + } +} + +local requestUiParams = { + menuID = requestParams.menuID, + menuParams = { + position = requestParams.position, + menuName = requestParams.menuName + }, + menuIcon = requestParams.menuIcon +} + +local allParams = { + requestParams = requestParams, + requestUiParams = requestUiParams +} + +--[[ Local Functions ]] +local function addSubMenu(pParams) + local cid = common.getMobileSession():SendRPC("AddSubMenu", pParams.requestParams) + pParams.requestUiParams.menuIcon.value = common.getPathToFileInStorage(requestParams.menuIcon.value) + pParams.requestUiParams.appID = common.getHMIAppId() + EXPECT_HMICALL("UI.AddSubMenu", pParams.requestUiParams) + :Do(function(_,data) + common.getHMIConnection():SendError(data.id, data.method, "WARNINGS", "Requested image(s) not found") + end) + + common.getMobileSession():ExpectResponse(cid, + { success = true, resultCode = "WARNINGS", info = "Requested image(s) not found" }) + common.getMobileSession():ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", common.registerAppWOPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("AddSubMenu with invalid image", addSubMenu, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/003_Alert.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/003_Alert.lua new file mode 100644 index 0000000000..706990849c --- /dev/null +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/003_Alert.lua @@ -0,0 +1,183 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0042-transfer-invalid-image-rpc.md +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1. Mobile app requests Alert with image that is absent on file system +-- SDL must: +-- 1. transfer this RPC to HMI for processing +-- 2. transfer the received from HMI response (WARNINGS, message: “Requested image(s) not foundâ€) to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variable s ]] +local softButtons = { + softButtons = { + { + type = "BOTH", + text = "Close", + image = { + value = "missed_icon.png", + imageType = "DYNAMIC", + }, + isHighlighted = true, + softButtonID = 3, + systemAction = "DEFAULT_ACTION", + }, + { + type = "TEXT", + text = "Keep", + isHighlighted = true, + softButtonID = 4, + systemAction = "KEEP_CONTEXT", + }, + { + type = "IMAGE", + image = { + value = "missed_icon.png", + imageType = "DYNAMIC", + }, + softButtonID = 5, + systemAction = "STEAL_FOCUS", + } + } +} + +local requestParams = { + alertText1 = "alertText1", + alertText2 = "alertText2", + alertText3 = "alertText3", + ttsChunks = { + { + text = "TTSChunk", + type = "TEXT", + } + }, + playTone = true, + progressIndicator = true +} + +local responseUiParams = { + alertStrings = { + { + fieldName = requestParams.alertText1, + fieldText = requestParams.alertText1 + }, + { + fieldName = requestParams.alertText2, + fieldText = requestParams.alertText2 + }, + { + fieldName = requestParams.alertText3, + fieldText = requestParams.alertText3 + } + }, + alertType = "BOTH", + progressIndicator = requestParams.progressIndicator, +} + +local ttsSpeakRequestParams = { + ttsChunks = requestParams.ttsChunks, + speakType = "ALERT", + playTone = requestParams.playTone +} + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams, + ttsSpeakRequestParams = ttsSpeakRequestParams +} + +--[[ Local Functions ]] +local function sendOnSystemContext(pCtx) + common.getHMIConnection():SendNotification("UI.OnSystemContext", + { + appID = common.getHMIAppId(), + systemContext = pCtx + }) +end + +local function prepareAlertParams(pParams, pAdditionalParams) + pParams.responseUiParams.appID = common.getHMIAppId() + pParams.requestParams.duration = nil + pParams.requestParams.softButtons = pAdditionalParams.softButtons + pParams.responseUiParams.duration = nil; + pParams.responseUiParams.softButtons = pAdditionalParams.softButtons + pParams.responseUiParams.softButtons[1].image.value = + common.getPathToFileInStorage(pAdditionalParams.softButtons[1].image.value) + pParams.responseUiParams.softButtons[3].image.value = + common.getPathToFileInStorage(pAdditionalParams.softButtons[3].image.value) +end + +local function alert(pParams, pAdditionalParams) + prepareAlertParams(pParams, pAdditionalParams) + + local responseDelay = 3000 + local cid = common.getMobileSession():SendRPC("Alert", pParams.requestParams) + + EXPECT_HMICALL("UI.Alert", pParams.responseUiParams) + :Do(function(_,data) + sendOnSystemContext("ALERT") + + local alertId = data.id + local function alertResponse() + common.getHMIConnection():SendError(alertId, "UI.Alert", "WARNINGS", "Requested image(s) not found") + sendOnSystemContext("MAIN") + end + + RUN_AFTER(alertResponse, responseDelay) + end) + + pParams.ttsSpeakRequestParams.appID = common.getHMIAppId() + EXPECT_HMICALL("TTS.Speak", pParams.ttsSpeakRequestParams) + :Do(function(_,data) + common.getHMIConnection():SendNotification("TTS.Started") + + local speakId = data.id + local function speakResponse() + common.getHMIConnection():SendResponse(speakId, "TTS.Speak", "SUCCESS", { }) + common.getHMIConnection():SendNotification("TTS.Stopped") + end + + RUN_AFTER(speakResponse, responseDelay - 1000) + end) + :ValidIf(function(_,data) + if #data.params.ttsChunks == 1 then + return true + else + return false, "ttsChunks array in TTS.Speak request has wrong element number." .. + " Expected 1, actual " .. tostring(#data.params.ttsChunks) + end + end) + + common.getMobileSession():ExpectNotification("OnHMIStatus", + { systemContext = "ALERT", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }, + { systemContext = "ALERT", hmiLevel = "FULL", audioStreamingState = "ATTENUATED" }, + { systemContext = "ALERT", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }) + :Times(4) + + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "WARNINGS", + info = "Requested image(s) not found" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", common.registerAppWOPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Alert with soft buttons with invalid image", alert, { allParams, softButtons }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua new file mode 100644 index 0000000000..cb172cb68c --- /dev/null +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua @@ -0,0 +1,83 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0042-transfer-invalid-image-rpc.md +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1. Mobile app requests createInteractionChoiceSet with image that is absent on file system +-- SDL must: +-- 1. transfer this RPC to HMI for processing +-- 2. transfer the received from HMI response (WARNINGS, message: “Requested image(s) not foundâ€) to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + interactionChoiceSetID = 1001, + choiceSet = { + { + choiceID = 1001, + menuName ="Choice1001", + vrCommands = { + "Choice1001" + }, + image = { + value ="missed_icon.png", + imageType ="DYNAMIC" + } + } + } +} + +local responseVrParams = { + cmdID = requestParams.interactionChoiceSetID, + type = "Choice", + vrCommands = requestParams.vrCommands +} + +local allParams = { + requestParams = requestParams, + responseVrParams = responseVrParams +} + +--[[ Local Functions ]] +local function createInteractionChoiceSet(pParams) + local cid = common.getMobileSession():SendRPC("CreateInteractionChoiceSet", pParams.requestParams) + + pParams.responseVrParams.appID = common.getHMIAppId() + EXPECT_HMICALL("VR.AddCommand", pParams.responseVrParams) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + if data.params.grammarID ~= nil then + return true + else + return false, "grammarID should not be empty" + end + end) + + common.getMobileSession():ExpectResponse(cid, { resultCode = "WARNINGS", success = true, + info = "Requested image(s) not found." }) + common.getMobileSession():ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", common.registerAppWOPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("CreateInteractionChoiceSet with invalid image", createInteractionChoiceSet, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua new file mode 100644 index 0000000000..1f66ff5c27 --- /dev/null +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua @@ -0,0 +1,324 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0042-transfer-invalid-image-rpc.md +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1. Mobile app requests PerfromInteraction with image that is absent on file system +-- SDL must: +-- 1. transfer this RPC to HMI for processing +-- 2. transfer the received from HMI response (WARNINGS, message: “Requested image(s) not foundâ€) to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local ImageValue = { + value = common.getPathToFileInStorage("missed_icon.png"), + imageType = "DYNAMIC", +} + +local function PromptValue(text) + local tmp = { + { + text = text, + type = "TEXT" + } + } + return tmp +end + +local initialPromptValue = PromptValue(" Make your choice ") + +local helpPromptValue = PromptValue(" Help Prompt ") + +local timeoutPromptValue = PromptValue(" Time out ") + +local vrHelpvalue = { + { + text = " New VRHelp ", + position = 1, + image = ImageValue + } +} + +local requestParams = { + initialText = "StartPerformInteraction", + initialPrompt = initialPromptValue, + interactionMode = "BOTH", + interactionChoiceSetIDList = { + 100, 200, 300 + }, + helpPrompt = helpPromptValue, + timeoutPrompt = timeoutPromptValue, + timeout = 5000, + vrHelp = vrHelpvalue, + interactionLayout = "ICON_ONLY" +} + +--[[ Local Functions ]] + +--! @setChoiseSet: Creates Choice structure +--! @parameters: +--! choiceIDValue - Id for created choice +--! @return: table of created choice structure +local function setChoiseSet(choiceIDValue) + local temp = { + { + choiceID = choiceIDValue, + menuName ="Choice" .. tostring(choiceIDValue), + vrCommands = { + "VrChoice" .. tostring(choiceIDValue) + }, + image = { + value ="missed_icon.png", + imageType ="DYNAMIC" + } + } + } + return temp +end + +--! @SendOnSystemContext: OnSystemContext notification +--! @parameters: +--! ctx - systemContext value +--! @return: none +local function SendOnSystemContext(ctx) + common.getHMIConnection():SendNotification("UI.OnSystemContext", + { appID = common.getHMIAppId(), systemContext = ctx }) +end + +--! @setExChoiseSet: ChoiceSet structure for UI.PerformInteraction request +--! @parameters: +--! choiceIDValues - value of choice id +--! @return: none +local function setExChoiseSet(choiceIDValues) + local exChoiceSet = { } + for i = 1, #choiceIDValues do + exChoiceSet[i] = { + choiceID = choiceIDValues[i], + image = { + value = common.getPathToFileInStorage("missed_icon.png"), + imageType = "DYNAMIC", + }, + menuName = "Choice" .. choiceIDValues[i] + } + end + return exChoiceSet +end + +--! @ExpectOnHMIStatusWithAudioStateChanged_PI: Expectations of OnHMIStatus notification depending on the application +--! type, HMI level and interaction mode +--! @parameters: +--! request - interaction mode, +--! @return: none +local function ExpectOnHMIStatusWithAudioStateChanged_PI(request) + if "BOTH" == request then + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "VRSESSION" }, + { hmiLevel = "FULL", audioStreamingState = "ATTENUATED", systemContext = "VRSESSION" }, + { hmiLevel = "FULL", audioStreamingState = "ATTENUATED", systemContext = "HMI_OBSCURED" }, + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "HMI_OBSCURED" }, + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + :Times(6) + elseif "VR" == request then + common.getMobileSession():ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "ATTENUATED" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE" }, + { systemContext = "VRSESSION", hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE" }, + { systemContext = "VRSESSION", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }) + :Times(5) + elseif "MANUAL" == request then + common.getMobileSession():ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "ATTENUATED" }, + { systemContext = "HMI_OBSCURED", hmiLevel = "FULL", audioStreamingState = "ATTENUATED" }, + { systemContext = "HMI_OBSCURED", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }) + :Times(4) + end +end + +--! @CreateInteractionChoiceSet: Creation of Choice Set +--! @parameters: +--! choiceSetID - id for choice set +--! @return: none +local function CreateInteractionChoiceSet(choiceSetID) + local choiceID = choiceSetID + local cid = common.getMobileSession():SendRPC("CreateInteractionChoiceSet", { + interactionChoiceSetID = choiceSetID, + choiceSet = setChoiseSet(choiceID), + }) + EXPECT_HMICALL("VR.AddCommand", { + cmdID = choiceID, + type = "Choice", + vrCommands = { "VrChoice" .. tostring(choiceID) } + }) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { }) + end) + common.getMobileSession():ExpectResponse(cid, { resultCode = "WARNINGS", success = true, + info = "Requested image(s) not found." }) +end + +--! @PI_PerformViaVR_ONLY: Processing PI with interaction mode VR_ONLY with performing selection +--! @parameters: +--! paramsSend - parameters for PI request +--! @return: none +local function PI_PerformViaVR_ONLY(paramsSend) + paramsSend.interactionMode = "VR_ONLY" + local cid = common.getMobileSession():SendRPC("PerformInteraction",paramsSend) + EXPECT_HMICALL("VR.PerformInteraction", { + helpPrompt = paramsSend.helpPrompt, + initialPrompt = paramsSend.initialPrompt, + timeout = paramsSend.timeout, + timeoutPrompt = paramsSend.timeoutPrompt + }) + :Do(function(_,data) + local function vrResponse() + common.getHMIConnection():SendNotification("TTS.Started") + common.getHMIConnection():SendNotification("VR.Started") + SendOnSystemContext("VRSESSION") + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", + { choiceID = paramsSend.interactionChoiceSetIDList[1] }) + common.getHMIConnection():SendNotification("TTS.Stopped") + common.getHMIConnection():SendNotification("VR.Stopped") + SendOnSystemContext("MAIN") + end + RUN_AFTER(vrResponse, 1000) + end) + + EXPECT_HMICALL("UI.PerformInteraction", { + timeout = paramsSend.timeout, + vrHelp = paramsSend.vrHelp, + vrHelpTitle = paramsSend.initialText, + }) + :Do(function(_,data) + common.getHMIConnection():SendError( data.id, data.method, "WARNINGS", "Requested image(s) not found" ) + end) + ExpectOnHMIStatusWithAudioStateChanged_PI("VR") + common.getMobileSession():ExpectResponse(cid, + { success = true, resultCode = "WARNINGS", choiceID = paramsSend.interactionChoiceSetIDList[1], + info = "Requested image(s) not found" }) +end + +--! @PI_PerformViaMANUAL_ONLY: Processing PI with interaction mode MANUAL_ONLY with performing selection +--! @parameters: +--! paramsSend - parameters for PI request +--! @return: none +local function PI_PerformViaMANUAL_ONLY(paramsSend) + paramsSend.interactionMode = "MANUAL_ONLY" + local cid = common.getMobileSession():SendRPC("PerformInteraction", paramsSend) + EXPECT_HMICALL("VR.PerformInteraction", { + helpPrompt = paramsSend.helpPrompt, + initialPrompt = paramsSend.initialPrompt, + timeout = paramsSend.timeout, + timeoutPrompt = paramsSend.timeoutPrompt + }) + :Do(function(_,data) + common.getHMIConnection():SendNotification("TTS.Started") + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { }) + end) + EXPECT_HMICALL("UI.PerformInteraction", { + timeout = paramsSend.timeout, + choiceSet = setExChoiseSet(paramsSend.interactionChoiceSetIDList), + initialText = { + fieldName = "initialInteractionText", + fieldText = paramsSend.initialText + } + }) + :Do(function(_,data) + SendOnSystemContext("HMI_OBSCURED") + local function uiResponse() + common.getHMIConnection():SendResponse(data.id, data.method, "WARNINGS", + { choiceID = paramsSend.interactionChoiceSetIDList[1], info = "Requested image(s) not found." } ) + common.getHMIConnection():SendNotification("TTS.Stopped") + SendOnSystemContext("MAIN") + end + RUN_AFTER(uiResponse, 1000) + end) + ExpectOnHMIStatusWithAudioStateChanged_PI("MANUAL") + common.getMobileSession():ExpectResponse(cid, + { success = true, resultCode = "WARNINGS", choiceID = paramsSend.interactionChoiceSetIDList[1], + info = "Requested image(s) not found." }) +end + +--! @PI_PerformViaBOTH: Processing PI with interaction mode BOTH with timeout on VR and IU +--! @parameters: +--! paramsSend - parameters for PI request +--! @return: none +local function PI_PerformViaBOTH(paramsSend) + paramsSend.interactionMode = "BOTH" + local cid = common.getMobileSession():SendRPC("PerformInteraction",paramsSend) + EXPECT_HMICALL("VR.PerformInteraction", { + helpPrompt = paramsSend.helpPrompt, + initialPrompt = paramsSend.initialPrompt, + timeout = paramsSend.timeout, + timeoutPrompt = paramsSend.timeoutPrompt + }) + :Do(function(_,data) + common.getHMIConnection():SendNotification("VR.Started") + common.getHMIConnection():SendNotification("TTS.Started") + SendOnSystemContext("VRSESSION") + local function firstSpeakTimeOut() + common.getHMIConnection():SendNotification("TTS.Stopped") + common.getHMIConnection():SendNotification("TTS.Started") + end + RUN_AFTER(firstSpeakTimeOut, 5) + local function vrResponse() + common.getHMIConnection():SendError(data.id, data.method, "TIMED_OUT", "Perform Interaction error response.") + common.getHMIConnection():SendNotification("VR.Stopped") + end + RUN_AFTER(vrResponse, 20) + end) + EXPECT_HMICALL("UI.PerformInteraction", { + timeout = paramsSend.timeout, + choiceSet = setExChoiseSet(paramsSend.interactionChoiceSetIDList), + initialText = { + fieldName = "initialInteractionText", + fieldText = paramsSend.initialText + }, + vrHelp = paramsSend.vrHelp, + vrHelpTitle = paramsSend.initialText + }) + :Do(function(_,data) + local function choiceIconDisplayed() + SendOnSystemContext("HMI_OBSCURED") + end + RUN_AFTER(choiceIconDisplayed, 25) + local function uiResponse() + common.getHMIConnection():SendNotification("TTS.Stopped") + common.getHMIConnection():SendError(data.id, data.method, "WARNINGS", "Requested image(s) not found") + SendOnSystemContext("MAIN") + end + RUN_AFTER(uiResponse, 30) + end) + ExpectOnHMIStatusWithAudioStateChanged_PI("BOTH") + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "WARNINGS", + info = "Requested image(s) not found, Perform Interaction error response." }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", common.registerAppWOPTU) +runner.Step("Activate App", common.activateApp) +runner.Step("CreateInteractionChoiceSet with id 100", CreateInteractionChoiceSet, {100}) +runner.Step("CreateInteractionChoiceSet with id 200", CreateInteractionChoiceSet, {200}) +runner.Step("CreateInteractionChoiceSet with id 300", CreateInteractionChoiceSet, {300}) + +runner.Title("Test") +runner.Step("PerformInteraction with VR_ONLY interaction mode with invalid image", PI_PerformViaVR_ONLY, {requestParams}) +runner.Step("PerformInteraction with MANUAL_ONLY interaction mode with invalid image", PI_PerformViaMANUAL_ONLY, {requestParams}) +runner.Step("PerformInteraction with BOTH interaction mode with invalid image", PI_PerformViaBOTH, {requestParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua new file mode 100644 index 0000000000..4450c85d73 --- /dev/null +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua @@ -0,0 +1,99 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0042-transfer-invalid-image-rpc.md +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1. Mobile app requests ScrollableMessage with image that is absent on file system +-- SDL must: +-- 1. transfer this RPC to HMI for processing +-- 2. transfer the received from HMI response (WARNINGS, message: “Requested image(s) not foundâ€) to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + scrollableMessageBody = "abc", + softButtons = { + { + softButtonID = 1, + text = "Button1", + type = "BOTH", + image = { + value = "missed_icon.png", + imageType = "DYNAMIC" + }, + isHighlighted = false, + systemAction = "DEFAULT_ACTION" + }, + { + softButtonID = 2, + text = "Button2", + type = "TEXT", + isHighlighted = false, + systemAction = "DEFAULT_ACTION" + } + }, + timeout = 5000 +} + +local responseUiParams = { + messageText = { + fieldName = "scrollableMessageBody", + fieldText = requestParams.scrollableMessageBody + }, + softButtons = requestParams.softButtons +} + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams, +} + +--[[ Local Functions ]] +local function ScrollableMessage(pParams) + local cid = common.getMobileSession():SendRPC("ScrollableMessage", pParams.requestParams) + pParams.responseUiParams.appID = common.getHMIAppId() + for _, v in pairs(pParams.responseUiParams.softButtons) do + if v.image then + v.image.value = common.getPathToFileInStorage("missed_icon.png") + end + end + EXPECT_HMICALL("UI.ScrollableMessage", pParams.responseUiParams) + :Do(function(_,data) + common.getHMIConnection():SendNotification("UI.OnSystemContext", + { appID = pParams.responseUiParams.appID, systemContext = "HMI_OBSCURED" }) + local function uiResponse() + common.getHMIConnection():SendError(data.id, data.method, "WARNINGS", "Requested image(s) not found") + common.getHMIConnection():SendNotification("UI.OnSystemContext", + { appID = pParams.responseUiParams.appID, systemContext = "MAIN" }) + end + RUN_AFTER(uiResponse, 1000) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { systemContext = "HMI_OBSCURED", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }) + :Times(2) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "WARNINGS", + info = "Requested image(s) not found" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", common.registerAppWOPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("ScrollableMessage with invalid image", ScrollableMessage, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/007_Show.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/007_Show.lua new file mode 100644 index 0000000000..233fb211d6 --- /dev/null +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/007_Show.lua @@ -0,0 +1,111 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0042-transfer-invalid-image-rpc.md +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1. Mobile app requests Show with image that is absent on file system +-- SDL must: +-- 1. transfer this RPC to HMI for processing +-- 2. transfer the received from HMI response (WARNINGS, message: “Requested image(s) not foundâ€) to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + mainField1 = "a", + mainField2 = "a", + mainField3 = "a", + mainField4 = "a", + statusBar = "a", + mediaClock = "a", + mediaTrack = "a", + alignment = "CENTERED", + graphic = { + imageType = "DYNAMIC", + value = "missed_icon.png" + }, + secondaryGraphic = { + imageType = "DYNAMIC", + value = "missed_icon.png" + }, +} + +local responseUiParams = { + showStrings = { + { + fieldName = "mainField1", + fieldText = requestParams.mainField1 + }, + { + fieldName = "mainField2", + fieldText = requestParams.mainField2 + }, + { + fieldName = "mainField3", + fieldText = requestParams.mainField3 + }, + { + fieldName = "mainField4", + fieldText = requestParams.mainField4 + }, + { + fieldName = "mediaClock", + fieldText = requestParams.mediaClock + }, + { + fieldName = "mediaTrack", + fieldText = requestParams.mediaTrack + }, + { + fieldName = "statusBar", + fieldText = requestParams.statusBar + } + }, + alignment = requestParams.alignment, + graphic = { + imageType = requestParams.graphic.imageType, + value = common.getPathToFileInStorage(requestParams.graphic.value) + }, + secondaryGraphic = { + imageType = requestParams.secondaryGraphic.imageType, + value = common.getPathToFileInStorage(requestParams.secondaryGraphic.value) + } +} + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams, +} + +--[[ Local Functions ]] +local function Show(pParams) + local cid = common.getMobileSession():SendRPC("Show", pParams.requestParams) + pParams.responseUiParams.appID = common.getHMIAppId() + EXPECT_HMICALL("UI.Show", pParams.responseUiParams) + :Do(function(_,data) + common.getHMIConnection():SendError(data.id, data.method, "WARNINGS", "Requested image(s) not found") + end) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "WARNINGS", + info = "Requested image(s) not found" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", common.registerAppWOPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Show with invalid image", Show, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua new file mode 100644 index 0000000000..5312ba2880 --- /dev/null +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua @@ -0,0 +1,116 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0042-transfer-invalid-image-rpc.md +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1. Mobile app requests ShowConstantTBT with image that is absent on file system +-- SDL must: +-- 1. transfer this RPC to HMI for processing +-- 2. transfer the received from HMI response (WARNINGS, message: “Requested image(s) not foundâ€) to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + navigationText1 = "navigationText1", + navigationText2 = "navigationText2", + eta = "12:34", + totalDistance = "100miles", + timeToDestination = "10 minutes", + turnIcon = { + value = "missed_icon.png", + imageType = "DYNAMIC", + }, + nextTurnIcon = { + value = "missed_icon.png", + imageType = "DYNAMIC", + }, + distanceToManeuver = 50.5, + distanceToManeuverScale = 100.5, + maneuverComplete = false, + softButtons = { + { + type = "BOTH", + text = "Close", + image = { + value = "missed_icon.png", + imageType = "DYNAMIC", + }, + isHighlighted = true, + softButtonID = 44, + systemAction ="DEFAULT_ACTION", + }, + }, +} + +local responseUiParams = { + navigationTexts = { + { + fieldName = "navigationText1", + fieldText = requestParams.navigationText1 + }, + { + fieldName = "navigationText2", + fieldText = requestParams.navigationText2 + }, + { + fieldName = "ETA", + fieldText = requestParams.eta + }, + { + fieldName = "totalDistance", + fieldText = requestParams.totalDistance + }, + { + fieldName = "timeToDestination", + fieldText = requestParams.timeToDestination + } + }, + turnIcon = requestParams.turnIcon, + nextTurnIcon = requestParams.nextTurnIcon, + distanceToManeuver = requestParams.distanceToManeuver, + distanceToManeuverScale = requestParams.distanceToManeuverScale, + maneuverComplete = requestParams.maneuverComplete, + softButtons = requestParams.softButtons +} + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams +} + +--[[ Local Functions ]] +local function showConstantTBT(pParams) + local cid = common.getMobileSession():SendRPC("ShowConstantTBT", pParams.requestParams) + pParams.responseUiParams.appID = common.getHMIAppId() + pParams.responseUiParams.turnIcon.value = common.getPathToFileInStorage(pParams.requestParams.turnIcon.value) + pParams.responseUiParams.nextTurnIcon.value = common.getPathToFileInStorage(pParams.requestParams.nextTurnIcon.value) + pParams.responseUiParams.softButtons[1].image.value = common.getPathToFileInStorage(pParams.requestParams.softButtons[1].image.value) + EXPECT_HMICALL("Navigation.ShowConstantTBT", pParams.responseUiParams) + :Do(function(_,data) + common.getHMIConnection():SendError(data.id, data.method, "WARNINGS", "Requested image(s) not found") + end) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "WARNINGS", + info = "Requested image(s) not found" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", common.registerAppWOPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("ShowConstantTBT with invalid image", showConstantTBT, {allParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/009_SendLocation.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/009_SendLocation.lua new file mode 100644 index 0000000000..7c7cbc933d --- /dev/null +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/009_SendLocation.lua @@ -0,0 +1,62 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0042-transfer-invalid-image-rpc.md +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1. Mobile app requests SendLocation with image that is absent on file system +-- SDL must: +-- 1. transfer this RPC to HMI for processing +-- 2. transfer the received from HMI response (WARNINGS, message: “Requested image(s) not foundâ€) to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + longitudeDegrees = 1.1, + latitudeDegrees = 1.1, + locationName = "location Name", + locationDescription = "location Description", + addressLines = { + "line1", + "line2", + }, + phoneNumber = "phone Number", + locationImage ={ + value = "missed_icon.png", + imageType = "DYNAMIC" + } +} + +--[[ Local Functions ]] +local function sendLocation(pParams) + local cid = common.getMobileSession():SendRPC("SendLocation", pParams) + pParams.appID = common.getHMIAppId() + pParams.locationImage.value = common.getPathToFileInStorage(pParams.locationImage.value) + EXPECT_HMICALL("Navigation.SendLocation", pParams) + :Do(function(_, data) + common.getHMIConnection():SendError(data.id, data.method, "WARNINGS", "Requested image(s) not found") + end) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "WARNINGS", + info = "Requested image(s) not found"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", common.registerAppWOPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("SendLocation with invalid image", sendLocation, { requestParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua new file mode 100644 index 0000000000..a4dbf8258f --- /dev/null +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0042-transfer-invalid-image-rpc.md +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1. Mobile app requests SetAppIcon with image that is absent on file system +-- SDL must: +-- 1. responds INVALID_DATA to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + syncFileName = "missed_icon.png" +} + +local requestUiParams = { + syncFileName = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage(requestParams.syncFileName) + } +} + +local allParams = { + requestParams = requestParams, + requestUiParams = requestUiParams +} + +--[[ Local Functions ]] +local function setAppIcon(pParams) + local cid = common.getMobileSession():SendRPC("SetAppIcon", pParams.requestParams) + pParams.requestUiParams.appID = common.getHMIAppId() + EXPECT_HMICALL("UI.SetAppIcon", pParams.requestUiParams) + :Times(0) + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", common.registerAppWOPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("SetAppIcon with invalid image", setAppIcon, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua new file mode 100644 index 0000000000..6467b4824d --- /dev/null +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua @@ -0,0 +1,82 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0042-transfer-invalid-image-rpc.md +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1. Mobile app requests UpdateTurnList with image that is absent on file system +-- SDL must: +-- 1. transfer this RPC to HMI for processing +-- 2. transfer the received from HMI response (WARNINGS, message: “Requested image(s) not foundâ€) to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + turnList = { + { + navigationText = "Text", + turnIcon = { + value = "missed_icon.png", + imageType = "DYNAMIC", + } + } + }, + softButtons = { + { + type = "BOTH", + text = "Close", + image = { + value = "missed_icon.png", + imageType = "DYNAMIC", + }, + isHighlighted = true, + softButtonID = 111, + systemAction = "DEFAULT_ACTION", + } + } +} + +local responseUiParams = commonFunctions:cloneTable(requestParams) +responseUiParams.turnList[1].navigationText = { + fieldText = requestParams.turnList[1].navigationText, + fieldName = "turnText" +} +responseUiParams.turnList[1].turnIcon.value = common.getPathToFileInStorage(requestParams.turnList[1].turnIcon.value) +responseUiParams.softButtons[1].image.value = common.getPathToFileInStorage(requestParams.softButtons[1].image.value) + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams, +} + +--[[ Local Functions ]] +local function updateTurnList(pParams) + local cid = common.getMobileSession():SendRPC("UpdateTurnList", pParams.requestParams) + EXPECT_HMICALL("Navigation.UpdateTurnList", pParams.responseUiParams) + :Do(function(_,data) + common.getHMIConnection():SendError(data.id, data.method, "WARNINGS", "Requested image(s) not found") + end) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "WARNINGS", info = "Requested image(s) not found"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", common.registerAppWOPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("UpdateTurnList with invalid image", updateTurnList, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua new file mode 100644 index 0000000000..290b1d98a5 --- /dev/null +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua @@ -0,0 +1,121 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0042-transfer-invalid-image-rpc.md +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1. Mobile app requests AlertManeuver with image that is absent on file system +-- SDL must: +-- 1. transfer this RPC to HMI for processing +-- 2. transfer the received from HMI response (WARNINGS, message: “Requested image(s) not foundâ€) to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + ttsChunks = { + { + text = "FirstAlert", + type = "TEXT", + }, + { + text = "SecondAlert", + type = "TEXT", + }, + }, + softButtons = { + { + type = "BOTH", + text = "Close", + image = { + value = "missed_icon.png", + imageType = "DYNAMIC", + }, + isHighlighted = true, + softButtonID = 821, + systemAction = "DEFAULT_ACTION", + }, + { + type = "BOTH", + text = "AnotherClose", + image = { + value = "missed_icon.png", + imageType = "DYNAMIC", + }, + isHighlighted = false, + softButtonID = 822, + systemAction = "DEFAULT_ACTION", + }, + } +} + +local function naviParamsSet(tbl) + local Params = commonFunctions:cloneTable(tbl) + for k, _ in pairs(Params) do + if Params[k].image then + Params[k].image.value = common.getPathToFileInStorage(Params[k].image.value) + end + end + return Params +end + +local responseNaviParams = { + softButtons = naviParamsSet(requestParams.softButtons) +} + +local responseTtsParams = { + ttsChunks = requestParams.ttsChunks +} + +local allParams = { + requestParams = requestParams, + responseNaviParams = responseNaviParams, + responseTtsParams = responseTtsParams +} + +--[[ Local Functions ]] +local function alertManeuver(pParams) + local cid = common.getMobileSession():SendRPC("AlertManeuver", pParams.requestParams) + EXPECT_HMICALL("Navigation.AlertManeuver", pParams.responseNaviParams) + :Do(function(_, data) + local function alertResp() + common.getHMIConnection():SendError(data.id, data.method, "WARNINGS", "Requested image(s) not found") + end + RUN_AFTER(alertResp, 2000) + end) + EXPECT_HMICALL("TTS.Speak", pParams.responseTtsParams) + :Do(function(_, data) + common.getHMIConnection():SendNotification("TTS.Started") + local function SpeakResp() + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { }) + common.getHMIConnection():SendNotification("TTS.Stopped") + end + RUN_AFTER(SpeakResp, 1000) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "ATTENUATED" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }) + :Times(2) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "WARNINGS", info = "Requested image(s) not found" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", common.registerAppWOPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("AlertManeuver with invalid image", alertManeuver, { allParams }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua new file mode 100644 index 0000000000..3c529e6d11 --- /dev/null +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua @@ -0,0 +1,91 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0042-transfer-invalid-image-rpc.md +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1. Mobile app requests GetWayPoints with image that is absent on file system +-- SDL must: +-- 1. transfer this RPC to HMI for processing +-- 2. transfer the received from HMI response (WARNINGS, message: “Requested image(s) not foundâ€) to mobile app +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + wayPointType = "DESTINATION" +} + +local responseParams = { + wayPoints = { + { + coordinate = + { + latitudeDegrees = 1.1, + longitudeDegrees = 1.1 + }, + locationName = "Hotel", + addressLines = + { + "Hotel Bora", + "Hotel 5 stars" + }, + locationDescription = "VIP Hotel", + phoneNumber = "Phone39300434", + locationImage = + { + value ="missed_icon.png", + imageType ="DYNAMIC", + }, + searchAddress = + { + countryName = "countryName", + countryCode = "countryCode", + postalCode = "postalCode", + administrativeArea = "administrativeArea", + subAdministrativeArea = "subAdministrativeArea", + locality = "locality", + subLocality = "subLocality", + thoroughfare = "thoroughfare", + subThoroughfare = "subThoroughfare" + } + } + } +} + +--[[ Local Functions ]] +local function getWayPoints() + local cid = common.getMobileSession():SendRPC("GetWayPoints", requestParams) + requestParams.appID = common.getHMIAppId() + responseParams.appID = common.getHMIAppId() + EXPECT_HMICALL("Navigation.GetWayPoints", requestParams) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "WARNINGS", responseParams) + end) + + local ExpectedResponse = common.cloneTable(responseParams) + ExpectedResponse.appID = nil + ExpectedResponse["success"] = true + ExpectedResponse["resultCode"] = "WARNINGS" + common.getMobileSession():ExpectResponse(cid, ExpectedResponse) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", common.registerAppWOPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("GetWayPoints with invalid image", getWayPoints) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua new file mode 100644 index 0000000000..a8bf79b81c --- /dev/null +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua @@ -0,0 +1,80 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0042-transfer-invalid-image-rpc.md +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1. HMI sends OnWayPointChange with image that is absent on file system +-- SDL must: +-- 1. transfer this RPC to mobile app for processing +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local notifParams = { + wayPoints = + { + { + coordinate = { + latitudeDegrees = -90, + longitudeDegrees = -180 + }, + locationName = "Ho Chi Minh", + addressLines = {"182 Le Dai Hanh"}, + locationDescription = "Toa nha Flemington", + phoneNumber = "1231414", + locationImage = { + value = common.getPathToFileInStorage("missed_icon.png"), + imageType = "DYNAMIC" + }, + searchAddress = { + countryName = "aaa", + countryCode = "084", + postalCode = "test", + administrativeArea = "aa", + subAdministrativeArea = "a", + locality = "a", + subLocality = "a", + thoroughfare = "a", + subThoroughfare = "a" + } + } + } +} + +--[[ Local Functions ]] +local function subcribleWayPoints() + local cid = common.getMobileSession():SendRPC("SubscribeWayPoints",{}) + EXPECT_HMICALL("Navigation.SubscribeWayPoints") + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS",{}) + end) + common.getMobileSession():ExpectResponse(cid, {success = true , resultCode = "SUCCESS"}) + common.getMobileSession():ExpectNotification("OnHashChange") +end + +local function onWayPointChange() + common.getHMIConnection():SendNotification("Navigation.OnWayPointChange", notifParams) + common.getMobileSession():ExpectNotification("OnWayPointChange", notifParams) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", common.registerAppWOPTU) +runner.Step("Activate App", common.activateApp) +runner.Step("SubcribleWayPoints", subcribleWayPoints) + +runner.Title("Test") +runner.Step("OnWayPointChange with invalid image", onWayPointChange) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua new file mode 100644 index 0000000000..ac62e3a942 --- /dev/null +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua @@ -0,0 +1,112 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0042-transfer-invalid-image-rpc.md +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1. Mobile app requests SetGlobalProperties with image that is absent on file system +-- SDL must: +-- 1. transfer this RPC to HMI for processing +-- 2. transfer the received from HMI response (WARNINGS, message: “Requested image(s) not foundâ€) to mobile app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local requestParams = { + helpPrompt = { + { + text = "Help prompt", + type = "TEXT" + } + }, + timeoutPrompt = { + { + text = "Timeout prompt", + type = "TEXT" + } + }, + vrHelpTitle = "VR help title", + vrHelp = { + { + position = 1, + image = { + value = "missed_icon.png", + imageType = "DYNAMIC" + }, + text = "VR help item" + } + }, + menuTitle = "Menu Title", + menuIcon = { + value = "missed_icon.png", + imageType = "DYNAMIC" + }, + keyboardProperties = { + keyboardLayout = "QWERTY", + keypressMode = "SINGLE_KEYPRESS", + limitedCharacterList = {"a"}, + language = "EN-US", + autoCompleteText = "Daemon, Freedom" + } +} + +local responseUiParams = { + vrHelpTitle = requestParams.vrHelpTitle, + vrHelp = requestParams.vrHelp, + menuTitle = requestParams.menuTitle, + menuIcon = requestParams.menuIcon, + keyboardProperties = requestParams.keyboardProperties +} + +local responseTtsParams = { + timeoutPrompt = requestParams.timeoutPrompt, + helpPrompt = requestParams.helpPrompt +} + +local allParams = { + requestParams = requestParams, + responseUiParams = responseUiParams, + responseTtsParams = responseTtsParams +} + +--[[ Local Functions ]] +local function setGlobalProperties(pParams) + local cid = common.getMobileSession():SendRPC("SetGlobalProperties", pParams.requestParams) + + pParams.responseUiParams.appID = common.getHMIAppId() + pParams.responseUiParams.vrHelp[1].image.value = common.getPathToFileInStorage("missed_icon.png") + pParams.responseUiParams.menuIcon.value = common.getPathToFileInStorage("missed_icon.png") + EXPECT_HMICALL("UI.SetGlobalProperties", pParams.responseUiParams) + :Do(function(_,data) + common.getHMIConnection():SendError(data.id, data.method, "WARNINGS", "Requested image(s) not found") + end) + + pParams.responseTtsParams.appID = common.getHMIAppId() + EXPECT_HMICALL("TTS.SetGlobalProperties", pParams.responseTtsParams) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "WARNINGS", + info = "Requested image(s) not found"}) + common.getMobileSession():ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", common.registerAppWOPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("SetGlobalProperties with invalid image", setGlobalProperties, {allParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/common.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/common.lua new file mode 100644 index 0000000000..423152326b --- /dev/null +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/common.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.defaultProtocolVersion = 2 + +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") +local utils = require('user_modules/utils') +local json = require("modules/json") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') + +--[[ Local Variables ]] +local common = actions +common.cloneTable = utils.cloneTable +local preloadedPT = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + +--[[Module functions]] +function common.preconditions() + commonFunctions:SDLForceStop() + commonSteps:DeletePolicyTable() + commonSteps:DeleteLogsFiles() + commonPreconditions:BackupFile(preloadedPT) + common.updatePreloadedPT() +end + +function common.postconditions() + StopSDL() + commonPreconditions:RestoreFile(preloadedPT) +end + +function common.updatePreloadedPT() + local preloadedFile = commonPreconditions:GetPathToSDL() .. preloadedPT + local pt = utils.jsonFileToTable(preloadedFile) + pt.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + local additionalRPCs = { + "SendLocation", "SubscribeVehicleData", "UnsubscribeVehicleData", "GetVehicleData", "UpdateTurnList", + "AlertManeuver", "DialNumber", "ReadDID", "GetDTCs", "ShowConstantTBT", "GetWayPoints", "SubscribeWayPoints", + "OnWayPointChange" + } + pt.policy_table.functional_groupings.NewTestCaseGroup = { rpcs = { } } + for _, v in pairs(additionalRPCs) do + pt.policy_table.functional_groupings.NewTestCaseGroup.rpcs[v] = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED" } + } + end + pt.policy_table.app_policies["0000001"] = common.cloneTable(pt.policy_table.app_policies.default) + pt.policy_table.app_policies["0000001"].groups = { "Base-4", "NewTestCaseGroup" } + pt.policy_table.app_policies["0000001"].keep_context = true + pt.policy_table.app_policies["0000001"].steal_focus = true + utils.tableToJsonFile(pt, preloadedFile) +end + +return common diff --git a/test_sets/SDL_0042_Transfer_RPC_with_Invalid_Image.txt b/test_sets/SDL_0042_Transfer_RPC_with_Invalid_Image.txt new file mode 100644 index 0000000000..32d81ba275 --- /dev/null +++ b/test_sets/SDL_0042_Transfer_RPC_with_Invalid_Image.txt @@ -0,0 +1,15 @@ +./test_scripts/API/Transfer_RPC_with_invalid_image/001_AddCommand.lua +./test_scripts/API/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua +./test_scripts/API/Transfer_RPC_with_invalid_image/003_Alert.lua +./test_scripts/API/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua +./test_scripts/API/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua +./test_scripts/API/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua +./test_scripts/API/Transfer_RPC_with_invalid_image/007_Show.lua +./test_scripts/API/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua +./test_scripts/API/Transfer_RPC_with_invalid_image/009_SendLocation.lua +./test_scripts/API/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua +./test_scripts/API/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua +./test_scripts/API/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua +./test_scripts/API/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua +./test_scripts/API/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua +./test_scripts/API/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua From f7945c862345bc0f10bf2d8d251c67f66e2cca1d Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 27 Jul 2018 18:59:20 +0300 Subject: [PATCH 509/681] Update for 'AddSubMenu feature' script --- ...03_menuIcon_selected_not_existing_file.lua | 52 +++++++++++++------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/test_scripts/API/SubMenuIcon/003_menuIcon_selected_not_existing_file.lua b/test_scripts/API/SubMenuIcon/003_menuIcon_selected_not_existing_file.lua index 6312b46286..f8e9f19722 100644 --- a/test_scripts/API/SubMenuIcon/003_menuIcon_selected_not_existing_file.lua +++ b/test_scripts/API/SubMenuIcon/003_menuIcon_selected_not_existing_file.lua @@ -1,5 +1,6 @@ - --------------------------------------------------------------------------------------------------- + --------------------------------------------------------------------------------------------------- -- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0085-submenu-icon.md +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0042-transfer-invalid-image-rpc.md -- User story:TBD -- Use case:TBD -- @@ -11,7 +12,7 @@ -- 1) Mobile application sends AddSubMenu request to SDL with "menuIcon"= icon.png -- ("Icon.png" is missing on the system, it was not added via PutFile) -- SDL does: --- 1) Respond with (resultCode: INVALID_DATA, success:false) to mobile application. +-- 1) resend request to HMI --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -21,21 +22,40 @@ local common = require('test_scripts/API/SubMenuIcon/commonSubMenuIcon') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] +local requestParams = { + menuID = 1000, + position = 500, + menuName ="SubMenupositive", + menuIcon = { + imageType = "DYNAMIC", + value = "icon.png" + } +} + +local requestUiParams = { + menuID = requestParams.menuID, + menuParams = { + position = requestParams.position, + menuName = requestParams.menuName + }, + menuIcon = { + imageType = "DYNAMIC", + value = common.getPathToFileInStorage("icon.png") + } +} + +--[[ Local Functions ]] local function menuIconNotExistingFile() - local params = { - menuID = 1000, - position = 500, - menuName ="SubMenupositive", - menuIcon = { - imageType = "DYNAMIC", - value = "icon.png" - } - } - local corId = common.getMobileSession():SendRPC("AddSubMenu", params) - common.getHMIConnection():ExpectRequest("UI.AddSubMenu", params.requestUiParams) - :Times(0) - common.getMobileSession():ExpectResponse(corId, { success = false, resultCode = "INVALID_DATA"}) + local corId = common.getMobileSession():SendRPC("AddSubMenu", requestParams) + common.getHMIConnection():ExpectRequest("UI.AddSubMenu", requestUiParams) + :Do(function(_,data) + common.getHMIConnection():SendError(data.id, data.method, "WARNINGS", "Requested image(s) not found") + end) + common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "WARNINGS", + info = "Requested image(s) not found"}) + common.getMobileSession():ExpectNotification("OnHashChange") end + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) @@ -44,7 +64,7 @@ runner.Step("App registration", common.registerAppWOPTU) runner.Step("Activate Application", common.activateApp) runner.Title("Test") -runner.Step("MenuIcon with result code_INVALID_DATA", menuIconNotExistingFile) +runner.Step("MenuIcon with result code WARNINGS", menuIconNotExistingFile) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) From 274ee6dd509cbc3f985c467c5acd911a20255925 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Mon, 30 Jul 2018 16:45:42 +0300 Subject: [PATCH 510/681] Moved scripts for defects from 4_6 to 5_0 folder --- ...ve_App_when_there_is_no_active_PerformInteraction_KEYBOARD.lua | 0 ...es_choice_set_with_duplicate_vrCommands_menuName_inside_it.lua | 0 ...e_to_mobile_app_when_activating_app_from_HMI_with_activate.lua | 0 ...eAvailable_is_not_provided_in_response_for_PutFile_request.lua | 0 .../Defects/{4_6 => 5_0}/959_resumption_limited_non_media.lua | 0 ...D_in_setAppIcon_responce_if_HMI_responds_with_INVALID_DATA.lua | 0 ...t_unregistered_by_reason_=_REQUEST_WHILE_IN_NONE_HMI_LEVELlua} | 0 ...SubscribeVehicleData_in_case_vi_interface_is_not_available.lua | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename test_scripts/Defects/{4_6 => 5_0}/1031_SDL_transfer_OnKeyboardInput_notification_to_not_active_App_when_there_is_no_active_PerformInteraction_KEYBOARD.lua (100%) rename test_scripts/Defects/{4_6 => 5_0}/1032_CreateInteractionChoiceSet_core_successfully_creates_choice_set_with_duplicate_vrCommands_menuName_inside_it.lua (100%) rename test_scripts/Defects/{4_6 => 5_0}/1035_SDL_doesnt_send_REJECTED_code_to_mobile_app_when_activating_app_from_HMI_with_activate.lua (100%) rename test_scripts/Defects/{4_6 => 5_0}/1218_Mandatory_parameter_spaceAvailable_is_not_provided_in_response_for_PutFile_request.lua (100%) rename test_scripts/Defects/{4_6 => 5_0}/959_resumption_limited_non_media.lua (100%) rename test_scripts/Defects/{4_6 => 5_0}/964_SDL_sends_to_mobile_APPLICATION_NOT_REGISTRED_in_setAppIcon_responce_if_HMI_responds_with_INVALID_DATA.lua (100%) rename test_scripts/Defects/{4_6/965_API_App_is_not_unregistered_by_reason_=_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua => 5_0/965_API_App_is_not_unregistered_by_reason_=_REQUEST_WHILE_IN_NONE_HMI_LEVELlua} (100%) rename test_scripts/Defects/{4_6 => 5_0}/972_SDL_should_respond_IGNORED_with_correct_result_code_for_UnSubscribeVehicleData_in_case_vi_interface_is_not_available.lua (100%) diff --git a/test_scripts/Defects/4_6/1031_SDL_transfer_OnKeyboardInput_notification_to_not_active_App_when_there_is_no_active_PerformInteraction_KEYBOARD.lua b/test_scripts/Defects/5_0/1031_SDL_transfer_OnKeyboardInput_notification_to_not_active_App_when_there_is_no_active_PerformInteraction_KEYBOARD.lua similarity index 100% rename from test_scripts/Defects/4_6/1031_SDL_transfer_OnKeyboardInput_notification_to_not_active_App_when_there_is_no_active_PerformInteraction_KEYBOARD.lua rename to test_scripts/Defects/5_0/1031_SDL_transfer_OnKeyboardInput_notification_to_not_active_App_when_there_is_no_active_PerformInteraction_KEYBOARD.lua diff --git a/test_scripts/Defects/4_6/1032_CreateInteractionChoiceSet_core_successfully_creates_choice_set_with_duplicate_vrCommands_menuName_inside_it.lua b/test_scripts/Defects/5_0/1032_CreateInteractionChoiceSet_core_successfully_creates_choice_set_with_duplicate_vrCommands_menuName_inside_it.lua similarity index 100% rename from test_scripts/Defects/4_6/1032_CreateInteractionChoiceSet_core_successfully_creates_choice_set_with_duplicate_vrCommands_menuName_inside_it.lua rename to test_scripts/Defects/5_0/1032_CreateInteractionChoiceSet_core_successfully_creates_choice_set_with_duplicate_vrCommands_menuName_inside_it.lua diff --git a/test_scripts/Defects/4_6/1035_SDL_doesnt_send_REJECTED_code_to_mobile_app_when_activating_app_from_HMI_with_activate.lua b/test_scripts/Defects/5_0/1035_SDL_doesnt_send_REJECTED_code_to_mobile_app_when_activating_app_from_HMI_with_activate.lua similarity index 100% rename from test_scripts/Defects/4_6/1035_SDL_doesnt_send_REJECTED_code_to_mobile_app_when_activating_app_from_HMI_with_activate.lua rename to test_scripts/Defects/5_0/1035_SDL_doesnt_send_REJECTED_code_to_mobile_app_when_activating_app_from_HMI_with_activate.lua diff --git a/test_scripts/Defects/4_6/1218_Mandatory_parameter_spaceAvailable_is_not_provided_in_response_for_PutFile_request.lua b/test_scripts/Defects/5_0/1218_Mandatory_parameter_spaceAvailable_is_not_provided_in_response_for_PutFile_request.lua similarity index 100% rename from test_scripts/Defects/4_6/1218_Mandatory_parameter_spaceAvailable_is_not_provided_in_response_for_PutFile_request.lua rename to test_scripts/Defects/5_0/1218_Mandatory_parameter_spaceAvailable_is_not_provided_in_response_for_PutFile_request.lua diff --git a/test_scripts/Defects/4_6/959_resumption_limited_non_media.lua b/test_scripts/Defects/5_0/959_resumption_limited_non_media.lua similarity index 100% rename from test_scripts/Defects/4_6/959_resumption_limited_non_media.lua rename to test_scripts/Defects/5_0/959_resumption_limited_non_media.lua diff --git a/test_scripts/Defects/4_6/964_SDL_sends_to_mobile_APPLICATION_NOT_REGISTRED_in_setAppIcon_responce_if_HMI_responds_with_INVALID_DATA.lua b/test_scripts/Defects/5_0/964_SDL_sends_to_mobile_APPLICATION_NOT_REGISTRED_in_setAppIcon_responce_if_HMI_responds_with_INVALID_DATA.lua similarity index 100% rename from test_scripts/Defects/4_6/964_SDL_sends_to_mobile_APPLICATION_NOT_REGISTRED_in_setAppIcon_responce_if_HMI_responds_with_INVALID_DATA.lua rename to test_scripts/Defects/5_0/964_SDL_sends_to_mobile_APPLICATION_NOT_REGISTRED_in_setAppIcon_responce_if_HMI_responds_with_INVALID_DATA.lua diff --git a/test_scripts/Defects/4_6/965_API_App_is_not_unregistered_by_reason_=_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua b/test_scripts/Defects/5_0/965_API_App_is_not_unregistered_by_reason_=_REQUEST_WHILE_IN_NONE_HMI_LEVELlua similarity index 100% rename from test_scripts/Defects/4_6/965_API_App_is_not_unregistered_by_reason_=_REQUEST_WHILE_IN_NONE_HMI_LEVEL.lua rename to test_scripts/Defects/5_0/965_API_App_is_not_unregistered_by_reason_=_REQUEST_WHILE_IN_NONE_HMI_LEVELlua diff --git a/test_scripts/Defects/4_6/972_SDL_should_respond_IGNORED_with_correct_result_code_for_UnSubscribeVehicleData_in_case_vi_interface_is_not_available.lua b/test_scripts/Defects/5_0/972_SDL_should_respond_IGNORED_with_correct_result_code_for_UnSubscribeVehicleData_in_case_vi_interface_is_not_available.lua similarity index 100% rename from test_scripts/Defects/4_6/972_SDL_should_respond_IGNORED_with_correct_result_code_for_UnSubscribeVehicleData_in_case_vi_interface_is_not_available.lua rename to test_scripts/Defects/5_0/972_SDL_should_respond_IGNORED_with_correct_result_code_for_UnSubscribeVehicleData_in_case_vi_interface_is_not_available.lua From bd5458a0785b72d049ed977bb74bb4a0a117cd01 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 31 Jul 2018 09:36:00 +0300 Subject: [PATCH 511/681] fixup! Initial scripts for Transfer_RPC_with_Invalid_Image feature --- .../005_PerfomInteraction.lua | 14 +++++++------- .../013_GetWayPoints.lua | 4 ++-- .../014_OnWayPointChange.lua | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua index 1f66ff5c27..ff34b0b35d 100644 --- a/test_scripts/API/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua @@ -64,11 +64,11 @@ local requestParams = { --[[ Local Functions ]] ---! @setChoiseSet: Creates Choice structure +--! @setChoiceSet: Creates Choice structure --! @parameters: --! choiceIDValue - Id for created choice --! @return: table of created choice structure -local function setChoiseSet(choiceIDValue) +local function setChoiceSet(choiceIDValue) local temp = { { choiceID = choiceIDValue, @@ -94,11 +94,11 @@ local function SendOnSystemContext(ctx) { appID = common.getHMIAppId(), systemContext = ctx }) end ---! @setExChoiseSet: ChoiceSet structure for UI.PerformInteraction request +--! @setExChoiceSet: ChoiceSet structure for UI.PerformInteraction request --! @parameters: --! choiceIDValues - value of choice id --! @return: none -local function setExChoiseSet(choiceIDValues) +local function setExChoiceSet(choiceIDValues) local exChoiceSet = { } for i = 1, #choiceIDValues do exChoiceSet[i] = { @@ -154,7 +154,7 @@ local function CreateInteractionChoiceSet(choiceSetID) local choiceID = choiceSetID local cid = common.getMobileSession():SendRPC("CreateInteractionChoiceSet", { interactionChoiceSetID = choiceSetID, - choiceSet = setChoiseSet(choiceID), + choiceSet = setChoiceSet(choiceID), }) EXPECT_HMICALL("VR.AddCommand", { cmdID = choiceID, @@ -228,7 +228,7 @@ local function PI_PerformViaMANUAL_ONLY(paramsSend) end) EXPECT_HMICALL("UI.PerformInteraction", { timeout = paramsSend.timeout, - choiceSet = setExChoiseSet(paramsSend.interactionChoiceSetIDList), + choiceSet = setExChoiceSet(paramsSend.interactionChoiceSetIDList), initialText = { fieldName = "initialInteractionText", fieldText = paramsSend.initialText @@ -280,7 +280,7 @@ local function PI_PerformViaBOTH(paramsSend) end) EXPECT_HMICALL("UI.PerformInteraction", { timeout = paramsSend.timeout, - choiceSet = setExChoiseSet(paramsSend.interactionChoiceSetIDList), + choiceSet = setExChoiceSet(paramsSend.interactionChoiceSetIDList), initialText = { fieldName = "initialInteractionText", fieldText = paramsSend.initialText diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua index 3c529e6d11..1ef4fd8a7d 100644 --- a/test_scripts/API/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua @@ -41,8 +41,8 @@ local responseParams = { phoneNumber = "Phone39300434", locationImage = { - value ="missed_icon.png", - imageType ="DYNAMIC", + value = common.getPathToFileInStorage("missed_icon.png"), + imageType = "DYNAMIC", }, searchAddress = { diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua index a8bf79b81c..6be4db6d92 100644 --- a/test_scripts/API/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua @@ -50,7 +50,7 @@ local notifParams = { } --[[ Local Functions ]] -local function subcribleWayPoints() +local function subscribeWayPoints() local cid = common.getMobileSession():SendRPC("SubscribeWayPoints",{}) EXPECT_HMICALL("Navigation.SubscribeWayPoints") :Do(function(_,data) @@ -71,7 +71,7 @@ runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) -runner.Step("SubcribleWayPoints", subcribleWayPoints) +runner.Step("SubcribleWayPoints", subscribeWayPoints) runner.Title("Test") runner.Step("OnWayPointChange with invalid image", onWayPointChange) From c81880227fd549ecdee3aa9e818a652aaa1d5887 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 31 Jul 2018 09:45:17 +0300 Subject: [PATCH 512/681] Fix indentations --- files/PTFromCloud_Nickname_validation.json | 4 ++-- files/PTU_with_permissions_for_app_0000001.json | 4 ++-- files/PTU_with_permissions_for_app_1234567.json | 4 ++-- files/jsons/Policies/appID_Management/ptu_01.json | 4 ++-- files/jsons/Policies/appID_Management/ptu_013_1.json | 6 +++--- files/jsons/Policies/appID_Management/ptu_013_2.json | 4 ++-- files/jsons/Policies/appID_Management/ptu_1.json | 12 ++++++------ .../user_consent/OnAppPermissionConsent_1.json | 2 +- files/ptu_for_navi_app.json | 8 ++++---- files/ptu_general.json | 8 ++++---- files/ptu_general_0000001.json | 4 ++-- files/ptu_general_default_app-1234567.json | 4 ++-- 12 files changed, 32 insertions(+), 32 deletions(-) diff --git a/files/PTFromCloud_Nickname_validation.json b/files/PTFromCloud_Nickname_validation.json index c549219cac..fb6b368ded 100644 --- a/files/PTFromCloud_Nickname_validation.json +++ b/files/PTFromCloud_Nickname_validation.json @@ -383,7 +383,7 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4"], - "RequestType": [] + "RequestType": [] }, "1234567": { "keep_context": false, @@ -392,7 +392,7 @@ "default_hmi": "NONE", "groups": ["Base-4"], "nicknames": ["AnotherName"], - "RequestType": [] + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/PTU_with_permissions_for_app_0000001.json b/files/PTU_with_permissions_for_app_0000001.json index 80e1f429ca..1fb5494580 100644 --- a/files/PTU_with_permissions_for_app_0000001.json +++ b/files/PTU_with_permissions_for_app_0000001.json @@ -2047,7 +2047,7 @@ "default_hmi": "BACKGROUND", "groups": ["Location-1"], "nicknames": ["Test Application"], - "RequestType": [] + "RequestType": [] }, "default": { "keep_context": false, @@ -2055,7 +2055,7 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4"], - "RequestType": [] + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/PTU_with_permissions_for_app_1234567.json b/files/PTU_with_permissions_for_app_1234567.json index b36ac707e7..7234d411c9 100644 --- a/files/PTU_with_permissions_for_app_1234567.json +++ b/files/PTU_with_permissions_for_app_1234567.json @@ -2046,7 +2046,7 @@ "default_hmi": "BACKGROUND", "groups": ["Permission_for_1234567"], "nicknames": ["SPT"], - "RequestType": [] + "RequestType": [] }, "default": { "keep_context": false, @@ -2054,7 +2054,7 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4"], - "RequestType": [] + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/appID_Management/ptu_01.json b/files/jsons/Policies/appID_Management/ptu_01.json index d070ae78f6..3b4285770b 100644 --- a/files/jsons/Policies/appID_Management/ptu_01.json +++ b/files/jsons/Policies/appID_Management/ptu_01.json @@ -5,9 +5,9 @@ "123_xyz": { "groups": ["Base-6"], "priority": "NONE", - "keep_context": false, + "keep_context": false, "steal_focus": false, - "default_hmi": "NONE", + "default_hmi": "NONE", "nicknames": ["Media Application", "MediaApp"], "RequestType": [] }, diff --git a/files/jsons/Policies/appID_Management/ptu_013_1.json b/files/jsons/Policies/appID_Management/ptu_013_1.json index 45b43aa7b9..1932fa42ab 100644 --- a/files/jsons/Policies/appID_Management/ptu_013_1.json +++ b/files/jsons/Policies/appID_Management/ptu_013_1.json @@ -4,10 +4,10 @@ "0000001": { "groups": ["Base-4", "Base-6"], "priority": "NONE", - "keep_context": false, + "keep_context": false, "steal_focus": false, - "default_hmi": "NONE", - "nicknames": ["App1"], + "default_hmi": "NONE", + "nicknames": ["App1"], "RequestType": [] }, "default": { diff --git a/files/jsons/Policies/appID_Management/ptu_013_2.json b/files/jsons/Policies/appID_Management/ptu_013_2.json index 097f4f5eeb..8ffd7b71ba 100644 --- a/files/jsons/Policies/appID_Management/ptu_013_2.json +++ b/files/jsons/Policies/appID_Management/ptu_013_2.json @@ -4,9 +4,9 @@ "0000001": { "groups": ["Base-4", "Base-6"], "priority": "NONE", - "keep_context": false, + "keep_context": false, "steal_focus": false, - "default_hmi": "NONE", + "default_hmi": "NONE", "nicknames": ["App1"], "RequestType": [] }, diff --git a/files/jsons/Policies/appID_Management/ptu_1.json b/files/jsons/Policies/appID_Management/ptu_1.json index 75dd03ad30..d2e4397329 100644 --- a/files/jsons/Policies/appID_Management/ptu_1.json +++ b/files/jsons/Policies/appID_Management/ptu_1.json @@ -4,27 +4,27 @@ "0000001": { "groups": ["Base-4", "Base-6"], "priority": "NONE", - "keep_context": false, + "keep_context": false, "steal_focus": false, - "default_hmi": "NONE", + "default_hmi": "NONE", "nicknames": ["App1"], "RequestType": [] }, "123_xyz": { "groups": ["Base-6"], "priority": "NONE", - "keep_context": false, + "keep_context": false, "steal_focus": false, - "default_hmi": "NONE", + "default_hmi": "NONE", "nicknames": ["Media Application", "MediaApp"], "RequestType": [] }, "456_abc": { "groups": ["Base-6"], "priority": "NONE", - "keep_context": false, + "keep_context": false, "steal_focus": false, - "default_hmi": "NONE", + "default_hmi": "NONE", "nicknames": ["ABC Application"], "RequestType": [] }, diff --git a/files/jsons/Policies/user_consent/OnAppPermissionConsent_1.json b/files/jsons/Policies/user_consent/OnAppPermissionConsent_1.json index 699d49d5f9..d5433368df 100644 --- a/files/jsons/Policies/user_consent/OnAppPermissionConsent_1.json +++ b/files/jsons/Policies/user_consent/OnAppPermissionConsent_1.json @@ -2251,7 +2251,7 @@ "groups": [ "Base-4", "Notifications", "Location-1" ], - "RequestType": [] + "RequestType": [] }, "default": { "keep_context": false, diff --git a/files/ptu_for_navi_app.json b/files/ptu_for_navi_app.json index 7a88b06d10..4e35e8abaf 100644 --- a/files/ptu_for_navi_app.json +++ b/files/ptu_for_navi_app.json @@ -2267,7 +2267,7 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4"], - "RequestType": [] + "RequestType": [] }, "0000001": { "keep_context": true, @@ -2275,7 +2275,7 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4"], - "RequestType": [] + "RequestType": [] }, "0000004": { "keep_context": true, @@ -2283,7 +2283,7 @@ "priority": "NONE", "default_hmi": "BACKGROUND", "groups": ["Base-4"], - "RequestType": [] + "RequestType": [] }, "background": { "keep_context": false, @@ -2291,7 +2291,7 @@ "priority": "NONE", "default_hmi": "BACKGROUND", "groups": ["Base-4", "Navigation-1"], - "RequestType": [] + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/ptu_general.json b/files/ptu_general.json index 6f65d90db2..f0add2070b 100644 --- a/files/ptu_general.json +++ b/files/ptu_general.json @@ -2267,7 +2267,7 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4", "Navigation-1","DrivingCharacteristics-3", "Location-1", "VehicleInfo-3", "Emergency-1", "OnKeyboardInputOnlyGroup", "PropriataryData-1"], - "RequestType": [] + "RequestType": [] }, "0000001": { "keep_context": true, @@ -2275,7 +2275,7 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4", "Navigation-1","DrivingCharacteristics-3", "Location-1", "VehicleInfo-3", "Emergency-1", "OnKeyboardInputOnlyGroup", "PropriataryData-1", "SendLocation"], - "RequestType": [] + "RequestType": [] }, "0000004": { "keep_context": true, @@ -2283,7 +2283,7 @@ "priority": "NONE", "default_hmi": "BACKGROUND", "groups": ["Base-4", "Navigation-1","DrivingCharacteristics-3", "Location-1", "VehicleInfo-3", "Emergency-1", "OnKeyboardInputOnlyGroup", "PropriataryData-1", "SendLocation"], - "RequestType": [] + "RequestType": [] }, "background": { "keep_context": false, @@ -2291,7 +2291,7 @@ "priority": "NONE", "default_hmi": "BACKGROUND", "groups": ["Base-4", "Navigation-1"], - "RequestType": [] + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/ptu_general_0000001.json b/files/ptu_general_0000001.json index 45cbe02a82..281ea519ed 100644 --- a/files/ptu_general_0000001.json +++ b/files/ptu_general_0000001.json @@ -1811,7 +1811,7 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4"], - "RequestType": [] + "RequestType": [] }, "0000001": { "keep_context": true, @@ -1819,7 +1819,7 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-8"], - "RequestType": [] + "RequestType": [] }, "device": { "keep_context": false, diff --git a/files/ptu_general_default_app-1234567.json b/files/ptu_general_default_app-1234567.json index d137969294..576db0da0c 100644 --- a/files/ptu_general_default_app-1234567.json +++ b/files/ptu_general_default_app-1234567.json @@ -2052,7 +2052,7 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4"], - "RequestType": [] + "RequestType": [] }, "background": { "keep_context": false, @@ -2060,7 +2060,7 @@ "priority": "NONE", "default_hmi": "BACKGROUND", "groups": ["Base-4", "Navigation-1"], - "RequestType": [] + "RequestType": [] }, "device": { "keep_context": false, From dc3ef5e5017cf054ace574e83f2b2b5dca9c9303 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 31 Jul 2018 17:54:31 +0300 Subject: [PATCH 513/681] Fix policy script 066 according to clarification --- .../build_options/066_ATF_PTU_Validation_Failure_HTTP.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_scripts/Policies/build_options/066_ATF_PTU_Validation_Failure_HTTP.lua b/test_scripts/Policies/build_options/066_ATF_PTU_Validation_Failure_HTTP.lua index 6e54361895..ac9b9c79e1 100644 --- a/test_scripts/Policies/build_options/066_ATF_PTU_Validation_Failure_HTTP.lua +++ b/test_scripts/Policies/build_options/066_ATF_PTU_Validation_Failure_HTTP.lua @@ -125,12 +125,12 @@ function Test:RAI_PTU() function(_, d1) log("SDL->HMI: N: BC.OnAppRegistered") self.applications[config.application1.registerAppInterfaceParams.appID] = d1.params.application.appID - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UPDATE_NEEDED" }) :Do( function(_, d2) log("SDL->HMI: N: SDL.OnStatusUpdate", d2.params.status) end) - :Times(4) + :Times(3) -- workaround due to issue in Mobile API: APPLINK-30390 local onSystemRequestRecieved = false From 177f1414e291055e51b8a2b205d988766aa27bcf Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 31 Jul 2018 19:08:05 +0300 Subject: [PATCH 514/681] fixup! Initial scripts for Transfer_RPC_with_Invalid_Image feature --- .../004_CreateInteractionChoiceSet.lua | 5 ++--- .../005_PerfomInteraction.lua | 3 +-- .../013_GetWayPoints.lua | 10 +++++----- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua index cb172cb68c..2d08639f0a 100644 --- a/test_scripts/API/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua @@ -8,7 +8,7 @@ -- 1. Mobile app requests createInteractionChoiceSet with image that is absent on file system -- SDL must: -- 1. transfer this RPC to HMI for processing --- 2. transfer the received from HMI response (WARNINGS, message: “Requested image(s) not foundâ€) to mobile app +-- 2. transfer the received from HMI response (WARNINGS) to mobile app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] @@ -64,8 +64,7 @@ local function createInteractionChoiceSet(pParams) end end) - common.getMobileSession():ExpectResponse(cid, { resultCode = "WARNINGS", success = true, - info = "Requested image(s) not found." }) + common.getMobileSession():ExpectResponse(cid, { resultCode = "WARNINGS", success = true }) common.getMobileSession():ExpectNotification("OnHashChange") end diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua index ff34b0b35d..840e94e609 100644 --- a/test_scripts/API/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua @@ -164,8 +164,7 @@ local function CreateInteractionChoiceSet(choiceSetID) :Do(function(_,data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { }) end) - common.getMobileSession():ExpectResponse(cid, { resultCode = "WARNINGS", success = true, - info = "Requested image(s) not found." }) + common.getMobileSession():ExpectResponse(cid, { resultCode = "WARNINGS", success = true }) end --! @PI_PerformViaVR_ONLY: Processing PI with interaction mode VR_ONLY with performing selection diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua b/test_scripts/API/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua index 1ef4fd8a7d..be843b551b 100644 --- a/test_scripts/API/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua +++ b/test_scripts/API/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua @@ -5,10 +5,10 @@ -- -- Description: -- In case: --- 1. Mobile app requests GetWayPoints with image that is absent on file system +-- 1. Mobile app requests GetWayPoints +-- 2. HMI sends Navigation.GetWayPoints with image that is absent on file system -- SDL must: --- 1. transfer this RPC to HMI for processing --- 2. transfer the received from HMI response (WARNINGS, message: “Requested image(s) not foundâ€) to mobile app +-- 1. transfer the received from HMI response to mobile app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] @@ -67,13 +67,13 @@ local function getWayPoints() responseParams.appID = common.getHMIAppId() EXPECT_HMICALL("Navigation.GetWayPoints", requestParams) :Do(function(_,data) - common.getHMIConnection():SendResponse(data.id, data.method, "WARNINGS", responseParams) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", responseParams) end) local ExpectedResponse = common.cloneTable(responseParams) ExpectedResponse.appID = nil ExpectedResponse["success"] = true - ExpectedResponse["resultCode"] = "WARNINGS" + ExpectedResponse["resultCode"] = "SUCCESS" common.getMobileSession():ExpectResponse(cid, ExpectedResponse) end From 2884c15a444e59a77529a5867cb8b6d9df4db169 Mon Sep 17 00:00:00 2001 From: HSavynetska Date: Thu, 5 Jul 2018 15:13:33 +0300 Subject: [PATCH 515/681] Script for reproducing issue 1866 --- ...I_request_with_missed_mandatory_params.lua | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 test_scripts/Defects/5_0/1866_SDL_does_not_respond_to_HMI_request_with_missed_mandatory_params.lua diff --git a/test_scripts/Defects/5_0/1866_SDL_does_not_respond_to_HMI_request_with_missed_mandatory_params.lua b/test_scripts/Defects/5_0/1866_SDL_does_not_respond_to_HMI_request_with_missed_mandatory_params.lua new file mode 100644 index 0000000000..df5cb6bba9 --- /dev/null +++ b/test_scripts/Defects/5_0/1866_SDL_does_not_respond_to_HMI_request_with_missed_mandatory_params.lua @@ -0,0 +1,36 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/SmartDeviceLink/sdl_core/issues/1866 +-- +-- Precondition: +-- 1) Core, HMI started. +-- 2) App is registered on HMI. +-- Description: +-- SDL does not respond to HMI request with missed mandatory params +-- Steps to reproduce: +-- 1) HMI sends SDL.GetUserFriendlyMessage request with missed mandatory parameter messageCodes. +-- Expected result: +-- SDL responds with code INVALID_DATA to HMI. +-- Actual result: +-- SDL does not send response to HMI. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/commonDefects') + +--[[ Local Functions ]] +local function GetUserFriendlyMessage(self) + local RequestId = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US"}) + EXPECT_HMIRESPONSE(RequestId,{result = {code = 11, method = "SDL.GetUserFriendlyMessage"}}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.rai_ptu) + +runner.Title("Test") +runner.Step("GetUserFriendlyMessage request with missed mandatory parameter messageCodes", GetUserFriendlyMessage) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From 4d8ce8485df81871956962551cffe15b0f9d7df3 Mon Sep 17 00:00:00 2001 From: HSavynetska Date: Tue, 26 Jun 2018 10:42:49 +0300 Subject: [PATCH 516/681] Script for reproducing issue 1868 --- ...MI_request_with_empty_string_parameter.lua | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 test_scripts/Defects/4_6/1868_SDL_does_not_respond_to_HMI_request_with_empty_string_parameter.lua diff --git a/test_scripts/Defects/4_6/1868_SDL_does_not_respond_to_HMI_request_with_empty_string_parameter.lua b/test_scripts/Defects/4_6/1868_SDL_does_not_respond_to_HMI_request_with_empty_string_parameter.lua new file mode 100644 index 0000000000..6cc3b5817c --- /dev/null +++ b/test_scripts/Defects/4_6/1868_SDL_does_not_respond_to_HMI_request_with_empty_string_parameter.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/SmartDeviceLink/sdl_core/issues/1868 +-- +-- Precondition: +-- 1) Core, HMI started. +-- 2) App is registered on HMI. +-- Description: +-- SDL does not respond to HMI request with empty string parameter. +-- Steps to reproduce: +-- 1) HMI sends SDL.GetUserFriendlyMessage request with empty string in messageCodes. +-- Expected result: +-- SDL responds with code INVALID_DATA to HMI. +-- Actual result: +-- SDL does not send response to HMI. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/commonDefects') + +--[[ Local Functions ]] +local function GetUserFriendlyMessage(self) + local RequestId = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {{""}}} ) + EXPECT_HMIRESPONSE(RequestId,{result = {code = 11, method = "SDL.GetUserFriendlyMessage"}}) + :ValidIf(function(_, data) + if data.result.code ==11 then + return true + else + return false,"SDL responds with code:".. tostring(data.result.code) .. " to request with invalid characters from HMI" + end + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.rai_ptu) +runner.Step("Activate App", common.activate_app) + +runner.Title("Test") +runner.Step("GetUserFriendlyMessage_request_with_empty_string_in_messageCodes", GetUserFriendlyMessage) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From 3f12bd7cde277d74d9c71e17cd59a064846d4d5d Mon Sep 17 00:00:00 2001 From: HSavynetska Date: Wed, 4 Jul 2018 09:44:05 +0300 Subject: [PATCH 517/681] Update test script --- ...d_to_HMI_request_with_empty_string_parameter.lua | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) rename test_scripts/Defects/{4_6 => 5_0}/1868_SDL_does_not_respond_to_HMI_request_with_empty_string_parameter.lua (80%) diff --git a/test_scripts/Defects/4_6/1868_SDL_does_not_respond_to_HMI_request_with_empty_string_parameter.lua b/test_scripts/Defects/5_0/1868_SDL_does_not_respond_to_HMI_request_with_empty_string_parameter.lua similarity index 80% rename from test_scripts/Defects/4_6/1868_SDL_does_not_respond_to_HMI_request_with_empty_string_parameter.lua rename to test_scripts/Defects/5_0/1868_SDL_does_not_respond_to_HMI_request_with_empty_string_parameter.lua index 6cc3b5817c..7e98e01f7f 100644 --- a/test_scripts/Defects/4_6/1868_SDL_does_not_respond_to_HMI_request_with_empty_string_parameter.lua +++ b/test_scripts/Defects/5_0/1868_SDL_does_not_respond_to_HMI_request_with_empty_string_parameter.lua @@ -7,7 +7,7 @@ -- Description: -- SDL does not respond to HMI request with empty string parameter. -- Steps to reproduce: --- 1) HMI sends SDL.GetUserFriendlyMessage request with empty string in messageCodes. +-- 1) HMI sends SDL.GetUserFriendlyMessage request with empty string in messageCodes -- Expected result: -- SDL responds with code INVALID_DATA to HMI. -- Actual result: @@ -19,15 +19,9 @@ local common = require('test_scripts/Defects/commonDefects') --[[ Local Functions ]] local function GetUserFriendlyMessage(self) - local RequestId = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {{""}}} ) + local RequestId = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", + {language = "EN-US", messageCodes = {""} }) EXPECT_HMIRESPONSE(RequestId,{result = {code = 11, method = "SDL.GetUserFriendlyMessage"}}) - :ValidIf(function(_, data) - if data.result.code ==11 then - return true - else - return false,"SDL responds with code:".. tostring(data.result.code) .. " to request with invalid characters from HMI" - end - end) end --[[ Scenario ]] @@ -35,7 +29,6 @@ runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("RAI, PTU", common.rai_ptu) -runner.Step("Activate App", common.activate_app) runner.Title("Test") runner.Step("GetUserFriendlyMessage_request_with_empty_string_in_messageCodes", GetUserFriendlyMessage) From 7d2151855a25200f5006a3024485fdd52bd62616 Mon Sep 17 00:00:00 2001 From: HSavynetska Date: Sat, 23 Jun 2018 12:04:24 +0300 Subject: [PATCH 518/681] Script for reproducing issue 1867 --- ..._HMI_request_with_wrong_type_of_params.lua | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 test_scripts/Defects/5_0/1867_SDL_does_not_respond_to_HMI_request_with_wrong_type_of_params.lua diff --git a/test_scripts/Defects/5_0/1867_SDL_does_not_respond_to_HMI_request_with_wrong_type_of_params.lua b/test_scripts/Defects/5_0/1867_SDL_does_not_respond_to_HMI_request_with_wrong_type_of_params.lua new file mode 100644 index 0000000000..f4a7211adb --- /dev/null +++ b/test_scripts/Defects/5_0/1867_SDL_does_not_respond_to_HMI_request_with_wrong_type_of_params.lua @@ -0,0 +1,37 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/SmartDeviceLink/sdl_core/issues/1867 +-- +-- Precondition: +-- 1) Core, HMI started. +-- 2) App is registered on HMI. +-- Description: +-- SDL does not respond to HMI request with wrong type of parameters. +-- Steps to reproduce: +-- 1) HMI sends SDL.GetUserFriendlyMessage request with wrong type(Integer) of parameter messageCodes. +-- Expected: +-- SDL responds with code INVALID_DATA to HMI. +-- Actual result +-- SDL does not send response to HMI. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/commonDefects') + +-- [[ Local Functions ]] +local function GetUserFriendlyMessage(self) + local RequestId = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = 1} ) + EXPECT_HMIRESPONSE(RequestId,{result = {code = 11, method = "SDL.GetUserFriendlyMessage"}}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration, PTU", common.rai_n) +runner.Step("Activate App", common.activate_app) + +runner.Title("Test") +runner.Step("SDL sends GetUserFriendlyMessage request with wrong type", GetUserFriendlyMessage) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From 118b0059fc0de975eec9ddab26cdedeb07d21433 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 1 Aug 2018 12:50:11 +0300 Subject: [PATCH 519/681] Adopt DTLS scripts from EXTERNAL_PROPRIETARY flow --- test_scripts/Security/DTLS/common.lua | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test_scripts/Security/DTLS/common.lua b/test_scripts/Security/DTLS/common.lua index fbf4ce0d3c..c065c523bd 100644 --- a/test_scripts/Security/DTLS/common.lua +++ b/test_scripts/Security/DTLS/common.lua @@ -230,4 +230,18 @@ function m.preconditions() common.initSDLCertificates("./files/Security/client_credential.pem", false) end +local policyTableUpdate_orig = m.policyTableUpdate + +function m.policyTableUpdate(pPTUpdateFunc) + local function expNotificationFunc() + m.getHMIConnection():ExpectRequest("BasicCommunication.DecryptCertificate") + :Do(function(_, d) + m.getHMIConnection():SendResponse(d.id, d.method, "SUCCESS", { }) + end) + :Times(AnyNumber()) + m.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) + end + policyTableUpdate_orig(pPTUpdateFunc, expNotificationFunc) +end + return m From a619c22b47ac10fe2ca67609473fc90079c1f44b Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 1 Aug 2018 13:19:39 +0300 Subject: [PATCH 520/681] Adopt GST scripts from EXTERNAL_PROPRIETARY flow --- test_scripts/Security/GetSystemTime/common.lua | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test_scripts/Security/GetSystemTime/common.lua b/test_scripts/Security/GetSystemTime/common.lua index c740341cdf..1bb1d9c0a8 100644 --- a/test_scripts/Security/GetSystemTime/common.lua +++ b/test_scripts/Security/GetSystemTime/common.lua @@ -132,4 +132,18 @@ function m.preconditions() common.initSDLCertificates("./files/Security/GetSystemTime_certificates/client_credential.pem", false) end +local policyTableUpdate_orig = m.policyTableUpdate + +function m.policyTableUpdate(pPTUpdateFunc) + local function expNotificationFunc() + m.getHMIConnection():ExpectRequest("BasicCommunication.DecryptCertificate") + :Do(function(_, d) + m.getHMIConnection():SendResponse(d.id, d.method, "SUCCESS", { }) + end) + :Times(AnyNumber()) + m.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) + end + policyTableUpdate_orig(pPTUpdateFunc, expNotificationFunc) +end + return m From 73baba653226539c4a361c343bd19fb28475a525 Mon Sep 17 00:00:00 2001 From: Conlain Kelly Date: Wed, 1 Aug 2018 14:19:33 -0400 Subject: [PATCH 521/681] Add CreateInteractionChoiceSet with no vrcommands test --- ...eractionChoiceSet_PositiveCase_SUCCESS.lua | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua index 7fdf63822a..abaee13b3b 100644 --- a/test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua @@ -62,6 +62,19 @@ local requestParams = { } } } +local requestParams_noVR = { + interactionChoiceSetID = 1002, + choiceSet = { + { + choiceID = 1002, + menuName ="Choice1002", + image = { + value ="icon.png", + imageType ="DYNAMIC" + } + } + } +} local responseVrParams = { cmdID = requestParams.interactionChoiceSetID, @@ -74,6 +87,7 @@ local allParams = { responseVrParams = responseVrParams } + --[[ Local Functions ]] local function createInteractionChoiceSet(params, self) local cid = self.mobileSession1:SendRPC("CreateInteractionChoiceSet", params.requestParams) @@ -95,6 +109,11 @@ local function createInteractionChoiceSet(params, self) self.mobileSession1:ExpectNotification("OnHashChange") end +local function createInteractionChoiceSet_noVR(params, self) + local cid = self.mobileSession1:SendRPC("CreateInteractionChoiceSet", params) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonSmoke.preconditions) @@ -105,6 +124,7 @@ runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) runner.Title("Test") runner.Step("CreateInteractionChoiceSet Positive Case", createInteractionChoiceSet, {allParams}) +runner.Step("CreateInteractionChoiceSet No VR Commands Positive Case", createInteractionChoiceSet_noVR, {requestParams_noVR}) runner.Title("Postconditions") runner.Step("Stop SDL", commonSmoke.postconditions) From 45ea7ab03cf178fa66c76477916072f300692860 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 2 Aug 2018 10:51:58 +0300 Subject: [PATCH 522/681] Correct descriptions and rename scripts --- ...ax_value_SUCCESS.lua => 001_GVD_max_value_SUCCESS.lua} | 2 +- ...ROR.lua => 002_GVD_beyond_max_value_GENERIC_ERROR.lua} | 2 +- ...ax_value_SUCCESS.lua => 004_OVD_max_value_SUCCESS.lua} | 2 +- ...e_ignored.lua => 005_OVD_beyond_max_value_ignored.lua} | 2 +- test_sets/updating_dop_value_range.txt | 8 ++++---- 5 files changed, 8 insertions(+), 8 deletions(-) rename test_scripts/API/VehicleData/DOP/{001_GVD_inbound_max_value_SUCCESS.lua => 001_GVD_max_value_SUCCESS.lua} (98%) rename test_scripts/API/VehicleData/DOP/{002_GVD_outbound_max_value_GENERIC_ERROR.lua => 002_GVD_beyond_max_value_GENERIC_ERROR.lua} (97%) rename test_scripts/API/VehicleData/DOP/{004_OVD_inbound_max_value_SUCCESS.lua => 004_OVD_max_value_SUCCESS.lua} (96%) rename test_scripts/API/VehicleData/DOP/{005_OVD_outbound_max_value_ignored.lua => 005_OVD_beyond_max_value_ignored.lua} (94%) diff --git a/test_scripts/API/VehicleData/DOP/001_GVD_inbound_max_value_SUCCESS.lua b/test_scripts/API/VehicleData/DOP/001_GVD_max_value_SUCCESS.lua similarity index 98% rename from test_scripts/API/VehicleData/DOP/001_GVD_inbound_max_value_SUCCESS.lua rename to test_scripts/API/VehicleData/DOP/001_GVD_max_value_SUCCESS.lua index ee1faa275e..f120a1b0e4 100644 --- a/test_scripts/API/VehicleData/DOP/001_GVD_inbound_max_value_SUCCESS.lua +++ b/test_scripts/API/VehicleData/DOP/001_GVD_max_value_SUCCESS.lua @@ -4,7 +4,7 @@ -- In case: -- 1. App sends 'GetVehicleData' request with gps=true -- 2. And SDL transfers this request to HMI --- 3. And HMI responds with gps data with one of the following parameters set to inbound max value (1000): +-- 3. And HMI responds with gps data with one of the following parameters set to exactly max value (1000): -- "pdop", "hdop", "vdop" -- SDL does: -- 1. Process this response and transfer it to App diff --git a/test_scripts/API/VehicleData/DOP/002_GVD_outbound_max_value_GENERIC_ERROR.lua b/test_scripts/API/VehicleData/DOP/002_GVD_beyond_max_value_GENERIC_ERROR.lua similarity index 97% rename from test_scripts/API/VehicleData/DOP/002_GVD_outbound_max_value_GENERIC_ERROR.lua rename to test_scripts/API/VehicleData/DOP/002_GVD_beyond_max_value_GENERIC_ERROR.lua index a6e1dc424b..a3fcd35a8e 100644 --- a/test_scripts/API/VehicleData/DOP/002_GVD_outbound_max_value_GENERIC_ERROR.lua +++ b/test_scripts/API/VehicleData/DOP/002_GVD_beyond_max_value_GENERIC_ERROR.lua @@ -4,7 +4,7 @@ -- In case: -- 1. App sends 'GetVehicleData' request with gps=true -- 2. And SDL transfers this request to HMI --- 3. And HMI responds with gps data with one of the following parameters set to outbound max value (1001): +-- 3. And HMI responds with gps data with one of the following parameters set to beyond max value (1001): -- "pdop", "hdop", "vdop" -- SDL does: -- 1. Ignore this response diff --git a/test_scripts/API/VehicleData/DOP/004_OVD_inbound_max_value_SUCCESS.lua b/test_scripts/API/VehicleData/DOP/004_OVD_max_value_SUCCESS.lua similarity index 96% rename from test_scripts/API/VehicleData/DOP/004_OVD_inbound_max_value_SUCCESS.lua rename to test_scripts/API/VehicleData/DOP/004_OVD_max_value_SUCCESS.lua index ca9ab58f03..bd7b4b59e6 100644 --- a/test_scripts/API/VehicleData/DOP/004_OVD_inbound_max_value_SUCCESS.lua +++ b/test_scripts/API/VehicleData/DOP/004_OVD_max_value_SUCCESS.lua @@ -3,7 +3,7 @@ --------------------------------------------------------------------------------------------------- -- In case: -- 1. Mobile app is subscribed to get gps data --- 2. And HMI sends OnVehicleData with inbound max value (1000) for the one of the following parameters: +-- 2. And HMI sends OnVehicleData with exactly max value (1000) for the one of the following parameters: -- "pdop", "hdop", "vdop" -- SDL does: -- 1. Process this notification and transfer it to mobile diff --git a/test_scripts/API/VehicleData/DOP/005_OVD_outbound_max_value_ignored.lua b/test_scripts/API/VehicleData/DOP/005_OVD_beyond_max_value_ignored.lua similarity index 94% rename from test_scripts/API/VehicleData/DOP/005_OVD_outbound_max_value_ignored.lua rename to test_scripts/API/VehicleData/DOP/005_OVD_beyond_max_value_ignored.lua index 1d81e0713c..83ddbd62e4 100644 --- a/test_scripts/API/VehicleData/DOP/005_OVD_outbound_max_value_ignored.lua +++ b/test_scripts/API/VehicleData/DOP/005_OVD_beyond_max_value_ignored.lua @@ -3,7 +3,7 @@ --------------------------------------------------------------------------------------------------- -- In case: -- 1. Mobile app is subscribed to get gps data --- 2. And HMI sends OnVehicleData with outbound max value (1001) for the one of the following parameters: +-- 2. And HMI sends OnVehicleData with beyond max value (1001) for the one of the following parameters: -- "pdop", "hdop", "vdop" -- SDL does: -- 1. Ignore this notification diff --git a/test_sets/updating_dop_value_range.txt b/test_sets/updating_dop_value_range.txt index 072cd8dd2b..a881a4e553 100644 --- a/test_sets/updating_dop_value_range.txt +++ b/test_sets/updating_dop_value_range.txt @@ -1,8 +1,8 @@ -./test_scripts/API/VehicleData/DOP/001_GVD_inbound_max_value_SUCCESS.lua -./test_scripts/API/VehicleData/DOP/002_GVD_outbound_max_value_GENERIC_ERROR.lua +./test_scripts/API/VehicleData/DOP/001_GVD_max_value_SUCCESS.lua +./test_scripts/API/VehicleData/DOP/002_GVD_beyond_max_value_GENERIC_ERROR.lua ./test_scripts/API/VehicleData/DOP/003_GVD_missing_one_parameter_SUCCESS.lua -./test_scripts/API/VehicleData/DOP/004_OVD_inbound_max_value_SUCCESS.lua -./test_scripts/API/VehicleData/DOP/005_OVD_outbound_max_value_ignored.lua +./test_scripts/API/VehicleData/DOP/004_OVD_max_value_SUCCESS.lua +./test_scripts/API/VehicleData/DOP/005_OVD_beyond_max_value_ignored.lua ./test_scripts/API/VehicleData/DOP/006_OVD_missing_one_parameter_SUCCESS.lua ./test_scripts/API/VehicleData/DOP/007_GVD_all_parameters_SUCCESS.lua ./test_scripts/API/VehicleData/DOP/008_GVD_missing_all_parameters_SUCCESS.lua From 925f0e0dc1f36f30183bd6b9d00a5192ebec786a Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 3 Aug 2018 11:53:02 +0300 Subject: [PATCH 523/681] Add additional check into policy script 122 --- .../122_ATF_PTU_NotSuccessful_AppID_ListedPT_NewIgnCycle.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/test_scripts/Policies/Policy_Table_Update/122_ATF_PTU_NotSuccessful_AppID_ListedPT_NewIgnCycle.lua b/test_scripts/Policies/Policy_Table_Update/122_ATF_PTU_NotSuccessful_AppID_ListedPT_NewIgnCycle.lua index fd58af3c64..9449423bc4 100644 --- a/test_scripts/Policies/Policy_Table_Update/122_ATF_PTU_NotSuccessful_AppID_ListedPT_NewIgnCycle.lua +++ b/test_scripts/Policies/Policy_Table_Update/122_ATF_PTU_NotSuccessful_AppID_ListedPT_NewIgnCycle.lua @@ -136,6 +136,7 @@ end commonFunctions:newTestCasesGroup("Test") function Test:TestStep_PTU_NotSuccessful_AppID_ListedPT_NewIgnCycle() local is_test_fail + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATE_NEEDED"}) local correlationId = self.mobileSession:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config.application1.appName } }) From 9b7de089b27d170c1387a36ad97bc921bf7288de Mon Sep 17 00:00:00 2001 From: JackLivio Date: Mon, 6 Aug 2018 19:00:52 -0400 Subject: [PATCH 524/681] Add tests for app version negotiation --- .../001_register_legacy_app.lua | 118 +++++++++++++++++ .../002_register_app_on_legacy_module.lua | 124 ++++++++++++++++++ test_sets/mobile_api_versioning.txt | 2 + 3 files changed, 244 insertions(+) create mode 100644 test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua create mode 100644 test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua create mode 100644 test_sets/mobile_api_versioning.txt diff --git a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua new file mode 100644 index 0000000000..a00b033824 --- /dev/null +++ b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua @@ -0,0 +1,118 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Mobile Versioning +-- Use case: RegisterAppInterface +-- Item: Happy path +-- +-- Requirement summary: +-- [RegisterAppInterface] SUCCESS: getting SUCCESS:RegisterAppInterface() during reregistration +-- SyncMsgVersion response from Core should be negotiated to lower app msg version +-- +-- Description: +-- Mobile application sends valid RegisterAppInterface request after unregistration and +-- gets RegisterAppInterface "SUCCESS" response from SDL + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests RegisterAppInterface + +-- Expected: +-- SDL checks if RegisterAppInterface is allowed by Policies +-- SDL sends the BasicCommunication notification to HMI +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +-- SDL responds with SyncMsgVersion 2.2 in RAI response +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local requestParams = { + syncMsgVersion = { + majorVersion = 2, + minorVersion = 2, + }, + appName = "SyncProxyTester", + ttsName = { + { + text ="SyncProxyTester", + type ="TEXT", + }, + }, + ngnMediaScreenAppName = "SPT", + vrSynonyms = { + "VRSyncProxyTester", + }, + isMediaApplication = true, + languageDesired = "EN-US", + hmiDisplayLanguageDesired = "EN-US", + appHMIType = { + "DEFAULT", + }, + appID = "123456", + deviceInfo = { + hardware = "hardware", + firmwareRev = "firmwareRev", + os = "os", + osVersion = "osVersion", + carrier = "carrier", + maxNumberRFCOMMPorts = 5 + } +} + +local function SetNotificationParams() + local notificationParams = { + application = {} + } + notificationParams.application.appName = requestParams.appName + notificationParams.application.ngnMediaScreenAppName = requestParams.ngnMediaScreenAppName + notificationParams.application.isMediaApplication = requestParams.isMediaApplication + notificationParams.application.hmiDisplayLanguageDesired = requestParams.hmiDisplayLanguageDesired + notificationParams.application.appType = requestParams.appHMIType + notificationParams.application.deviceInfo = { + name = commonSmoke.getDeviceName(), + id = commonSmoke.getDeviceMAC(), + transportType = "WIFI", + isSDLAllowed = true + } + notificationParams.application.policyAppID = requestParams.appID + notificationParams.ttsName = requestParams.ttsName + notificationParams.vrSynonyms = requestParams.vrSynonyms + return notificationParams +end + +--[[ Local Functions ]] +local function unregisterAppInterface(self) + local cid = self.mobileSession1:SendRPC("UnregisterAppInterface", { }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", + { appID = commonSmoke.getHMIAppId(), unexpectedDisconnect = false }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function RegisterAppInterface(self) + local CorIdRAI = self.mobileSession1:SendRPC("RegisterAppInterface", requestParams) + local notificationParams = SetNotificationParams() + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", notificationParams) + self.mobileSession1:ExpectResponse(CorIdRAI, { success = true, resultCode = "SUCCESS", syncMsgVersion = requestParams.syncMsgVersion}) + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + self.mobileSession1:ExpectNotification("OnPermissionsChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI", commonSmoke.registerApp) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("UnregisterAppInterface Positive Case", unregisterAppInterface) + +runner.Title("Test") +runner.Step("RegisterAppInterface Legacy App Case", RegisterAppInterface) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua new file mode 100644 index 0000000000..1a63954e9a --- /dev/null +++ b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua @@ -0,0 +1,124 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Mobile Versioning +-- Use case: RegisterAppInterface +-- Item: Happy path +-- +-- Requirement summary: +-- [RegisterAppInterface] SUCCESS: getting SUCCESS:RegisterAppInterface() during reregistration +-- SyncMsgVersion response from Core should be negotiated to highest message version Core supports +-- +-- Description: +-- Mobile application sends valid RegisterAppInterface request after unregistration and +-- gets RegisterAppInterface "SUCCESS" response from SDL + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests RegisterAppInterface + +-- Expected: +-- SDL checks if RegisterAppInterface is allowed by Policies +-- SDL sends the BasicCommunication notification to HMI +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +-- SDL responds with negotiated SyncMsgVersion that Core supports +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] +local requestParams = { + syncMsgVersion = { + majorVersion = 9, + minorVersion = 0, + }, + appName = "SyncProxyTester", + ttsName = { + { + text ="SyncProxyTester", + type ="TEXT", + }, + }, + ngnMediaScreenAppName = "SPT", + vrSynonyms = { + "VRSyncProxyTester", + }, + isMediaApplication = true, + languageDesired = "EN-US", + hmiDisplayLanguageDesired = "EN-US", + appHMIType = { + "DEFAULT", + }, + appID = "123456", + deviceInfo = { + hardware = "hardware", + firmwareRev = "firmwareRev", + os = "os", + osVersion = "osVersion", + carrier = "carrier", + maxNumberRFCOMMPorts = 5 + } +} + +local responseSyncMsgVersion = { + majorVersion = 5, + minorVersion = 0, + patchVersion = 0 +} + +local function SetNotificationParams() + local notificationParams = { + application = {} + } + notificationParams.application.appName = requestParams.appName + notificationParams.application.ngnMediaScreenAppName = requestParams.ngnMediaScreenAppName + notificationParams.application.isMediaApplication = requestParams.isMediaApplication + notificationParams.application.hmiDisplayLanguageDesired = requestParams.hmiDisplayLanguageDesired + notificationParams.application.appType = requestParams.appHMIType + notificationParams.application.deviceInfo = { + name = commonSmoke.getDeviceName(), + id = commonSmoke.getDeviceMAC(), + transportType = "WIFI", + isSDLAllowed = true + } + notificationParams.application.policyAppID = requestParams.appID + notificationParams.ttsName = requestParams.ttsName + notificationParams.vrSynonyms = requestParams.vrSynonyms + return notificationParams +end + +--[[ Local Functions ]] +local function unregisterAppInterface(self) + local cid = self.mobileSession1:SendRPC("UnregisterAppInterface", { }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", + { appID = commonSmoke.getHMIAppId(), unexpectedDisconnect = false }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function RegisterAppInterface(self) + local CorIdRAI = self.mobileSession1:SendRPC("RegisterAppInterface", requestParams) + local notificationParams = SetNotificationParams() + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", notificationParams) + self.mobileSession1:ExpectResponse(CorIdRAI, { success = true, resultCode = "SUCCESS", syncMsgVersion = responseSyncMsgVersion}) + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + self.mobileSession1:ExpectNotification("OnPermissionsChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI", commonSmoke.registerApp) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("UnregisterAppInterface Positive Case", unregisterAppInterface) + +runner.Title("Test") +runner.Step("RegisterAppInterface New App on Legacy Module Positive Case", RegisterAppInterface) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_sets/mobile_api_versioning.txt b/test_sets/mobile_api_versioning.txt new file mode 100644 index 0000000000..b16d29000c --- /dev/null +++ b/test_sets/mobile_api_versioning.txt @@ -0,0 +1,2 @@ +./test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua +./test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua \ No newline at end of file From a6779af4c210d4993195a038e7df2642d711aae2 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 7 Aug 2018 13:59:18 -0400 Subject: [PATCH 525/681] Update SyncMsgVersion for vrOptional Apps --- .../008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua | 3 +++ .../Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua | 3 +++ 2 files changed, 6 insertions(+) diff --git a/test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua index abaee13b3b..6aabbc28cd 100644 --- a/test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua @@ -35,6 +35,9 @@ local runner = require('user_modules/script_runner') local commonSmoke = require('test_scripts/Smoke/commonSmoke') +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 +config.application1.registerAppInterfaceParams.syncMsgVersion.minorVersion = 0 + --[[ Local Variables ]] local putFileParams = { requestParams = { diff --git a/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua index 9df699a092..6ee26ba1ca 100644 --- a/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua @@ -34,6 +34,9 @@ local runner = require('user_modules/script_runner') local commonSmoke = require('test_scripts/Smoke/commonSmoke') local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 +config.application1.registerAppInterfaceParams.syncMsgVersion.minorVersion = 0 + --[[ Local Variables ]] local putFileParams = { requestParams = { From fd8a530a3c5f61ca95a41837f3d61a816c983642 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 7 Aug 2018 14:33:29 -0400 Subject: [PATCH 526/681] Add mobile versioning tests for create interaction choice set --- ..._interaction_choice_success_legacy_app.lua | 114 ++++++++++++++++++ ...raction_choice_invalid_data_legacy_app.lua | 76 ++++++++++++ test_sets/mobile_api_versioning.txt | 4 + 3 files changed, 194 insertions(+) create mode 100644 test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/001_create_interaction_choice_success_legacy_app.lua create mode 100644 test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/002_create_interaction_choice_invalid_data_legacy_app.lua create mode 100644 test_sets/mobile_api_versioning.txt diff --git a/test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/001_create_interaction_choice_success_legacy_app.lua b/test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/001_create_interaction_choice_success_legacy_app.lua new file mode 100644 index 0000000000..d78d906ce6 --- /dev/null +++ b/test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/001_create_interaction_choice_success_legacy_app.lua @@ -0,0 +1,114 @@ +--------------------------------------------------------------------------------------------------- +-- User story: MobileVersioning Legacy App +-- Use case: CreateInteractionChoiceSet +-- Item: Happy path +-- +-- Requirement summary: +-- [CreateInteractionChoiceSet] SUCCESS +-- +-- Description: +-- Mobile application sends valid CreateInteractionChoiceSet request with +-- {interactionChoiceSetID, ChoiceSet: [(choiceID1, vrCommands, params), +-- (choiceID2, vrCommands, params)] and SDL successfully stores UI-related +-- choices and gets successful responses to corresponding VR.AddCommands +-- (VR-related choices) from HMI. + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests CreateInteractionChoiceSet with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if VR interface is available on HMI +-- SDL checks if CreateInteractionChoiceSet is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL transfers the VR.AddCommand with allowed parameters to HMI +-- SDL receives successful responses to corresponding VR.AddCommands from HMI +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 3 +config.application1.registerAppInterfaceParams.syncMsgVersion.minorVersion = 0 + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local requestParams = { + interactionChoiceSetID = 1001, + choiceSet = { + { + choiceID = 1001, + menuName ="Choice1001", + vrCommands = { + "Choice1001" + }, + image = { + value ="icon.png", + imageType ="DYNAMIC" + } + } + } +} + +local responseVrParams = { + cmdID = requestParams.interactionChoiceSetID, + type = "Choice", + vrCommands = requestParams.vrCommands +} + +local allParams = { + requestParams = requestParams, + responseVrParams = responseVrParams +} + + +--[[ Local Functions ]] +local function createInteractionChoiceSet(params, self) + local cid = self.mobileSession1:SendRPC("CreateInteractionChoiceSet", params.requestParams) + + params.responseVrParams.appID = commonSmoke.getHMIAppId() + EXPECT_HMICALL("VR.AddCommand", params.responseVrParams) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + if data.params.grammarID ~= nil then + return true + else + return false, "grammarID should not be empty" + end + end) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI", commonSmoke.registerApp) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) + +runner.Title("Test") +runner.Step("CreateInteractionChoiceSet Positive Case", createInteractionChoiceSet, {allParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/002_create_interaction_choice_invalid_data_legacy_app.lua b/test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/002_create_interaction_choice_invalid_data_legacy_app.lua new file mode 100644 index 0000000000..6f78c02424 --- /dev/null +++ b/test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/002_create_interaction_choice_invalid_data_legacy_app.lua @@ -0,0 +1,76 @@ +--------------------------------------------------------------------------------------------------- +-- User story: MobileVersioning Legacy App +-- Use case: CreateInteractionChoiceSet +-- Item: Happy path +-- +-- Requirement summary: +-- [CreateInteractionChoiceSet] INVALID_DATA +-- +-- Description: +-- Mobile application sends valid CreateInteractionChoiceSet request with +-- no vrCommands, which is a mandatory parameter for legacy apps. + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests CreateInteractionChoiceSet with no vrCommands + +-- Expected: +-- SDL invalidates parameters of the request +-- SDL responds with (resultCode: INVALID_DATA, success:false) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 3 +config.application1.registerAppInterfaceParams.syncMsgVersion.minorVersion = 0 + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local requestParams_noVR = { + interactionChoiceSetID = 1002, + choiceSet = { + { + choiceID = 1002, + menuName ="Choice1002", + image = { + value ="icon.png", + imageType ="DYNAMIC" + } + } + } +} + +--[[ Local Functions ]] +local function createInteractionChoiceSet_noVR(params, self) + local cid = self.mobileSession1:SendRPC("CreateInteractionChoiceSet", params) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI", commonSmoke.registerApp) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) + +runner.Title("Test") +runner.Step("CreateInteractionChoiceSet No VR Commands INVALID_DATA Case", createInteractionChoiceSet_noVR, {requestParams_noVR}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_sets/mobile_api_versioning.txt b/test_sets/mobile_api_versioning.txt new file mode 100644 index 0000000000..a1078fa961 --- /dev/null +++ b/test_sets/mobile_api_versioning.txt @@ -0,0 +1,4 @@ +./test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua +./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/001_create_interaction_choice_success_legacy_app.lua +./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/002_create_interaction_choice_invalid_data_legacy_app.lua From bc462bc185cfc7bd6f17cbf2f319b95baa40a7dd Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 7 Aug 2018 15:00:19 -0400 Subject: [PATCH 527/681] Add perform interaction success legacy app --- ...perform_interaction_success_legacy_app.lua | 360 ++++++++++++++++++ test_sets/mobile_api_versioning.txt | 1 + 2 files changed, 361 insertions(+) create mode 100644 test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/003_perform_interaction_success_legacy_app.lua diff --git a/test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/003_perform_interaction_success_legacy_app.lua b/test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/003_perform_interaction_success_legacy_app.lua new file mode 100644 index 0000000000..52f5159f26 --- /dev/null +++ b/test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/003_perform_interaction_success_legacy_app.lua @@ -0,0 +1,360 @@ +--------------------------------------------------------------------------------------------------- +-- User story: MobileVersioning Legacy App +-- Use case: PerformInteraction +-- Item: Happy path +-- +-- Requirement summary: +-- [PerformInteraction]: +-- SUCCESS result code +-- TIMED_OUT result code +-- +-- Description: +-- Mobile application sends PerformInteraction request with valid parameters to SDL + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level +-- d. ChoiceSets are already added + +-- Steps: +-- appID requests PerformInteraction with valid parameters to SDL + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if PerformInteraction is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL provides ability to perform choice on HMI manually or by voice +-- After user provide the choice SDL responds with (resultCode: SUCCESS, success:true) to mobile application +-- After user does not provide the choice SDL responds with (resultCode: TIMED_OUT, success:false) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') + +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 3 +config.application1.registerAppInterfaceParams.syncMsgVersion.minorVersion = 0 + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local storagePath = commonPreconditions:GetPathToSDL() .. "storage/" .. +config.application1.registerAppInterfaceParams.appID .. "_" .. commonSmoke.getDeviceMAC() .. "/" + +local ImageValue = { + value = storagePath .. "icon.png", + imageType = "DYNAMIC", +} + +local function PromptValue(text) + local tmp = { + { + text = text, + type = "TEXT" + } + } + return tmp +end + +local initialPromptValue = PromptValue(" Make your choice ") + +local helpPromptValue = PromptValue(" Help Prompt ") + +local timeoutPromptValue = PromptValue(" Time out ") + +local vrHelpvalue = { + { + text = " New VRHelp ", + position = 1, + image = ImageValue + } +} + +local requestParams = { + initialText = "StartPerformInteraction", + initialPrompt = initialPromptValue, + interactionMode = "BOTH", + interactionChoiceSetIDList = { + 100, 200, 300 + }, + helpPrompt = helpPromptValue, + timeoutPrompt = timeoutPromptValue, + timeout = 5000, + vrHelp = vrHelpvalue, + interactionLayout = "ICON_ONLY" +} + +--[[ Local Functions ]] + +--! @setChoiceSet: Creates Choice structure +--! @parameters: +--! choiceIDValue - Id for created choice +--! @return: table of created choice structure +local function setChoiceSet(choiceIDValue) + local temp = { + { + choiceID = choiceIDValue, + menuName ="Choice" .. tostring(choiceIDValue), + vrCommands = { + "VrChoice" .. tostring(choiceIDValue), + }, + image = { + value ="icon.png", + imageType ="STATIC", + } + } + } + return temp +end + +--! @SendOnSystemContext: OnSystemContext notification +--! @parameters: +--! self - test object, +--! ctx - systemContext value +--! @return: none +local function SendOnSystemContext(self, ctx) + self.hmiConnection:SendNotification("UI.OnSystemContext", + { appID = commonSmoke.getHMIAppId(), systemContext = ctx }) +end + +--! @setExChoiceSet: ChoiceSet structure for UI.PerformInteraction request +--! @parameters: +--! choiceIDValues - value of choice id +--! @return: none +local function setExChoiceSet(choiceIDValues) + local exChoiceSet = { } + for i = 1, #choiceIDValues do + exChoiceSet[i] = { + choiceID = choiceIDValues[i], + image = { + value = "icon.png", + imageType = "STATIC", + }, + menuName = "Choice" .. choiceIDValues[i] + } + end + return exChoiceSet +end + +--! @ExpectOnHMIStatusWithAudioStateChanged_PI: Expectations of OnHMIStatus notification depending on the application +--! type, HMI level and interaction mode +--! @parameters: +--! self - test object, +--! request - interaction mode, +--! @return: none +local function ExpectOnHMIStatusWithAudioStateChanged_PI(self, request) + if "BOTH" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "VRSESSION" }, + { hmiLevel = "FULL", audioStreamingState = "ATTENUATED", systemContext = "VRSESSION" }, + { hmiLevel = "FULL", audioStreamingState = "ATTENUATED", systemContext = "HMI_OBSCURED" }, + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "HMI_OBSCURED" }, + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + :Times(6) + elseif "VR" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "ATTENUATED" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE" }, + { systemContext = "VRSESSION", hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE" }, + { systemContext = "VRSESSION", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }) + :Times(5) + elseif "MANUAL" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "ATTENUATED" }, + { systemContext = "HMI_OBSCURED", hmiLevel = "FULL", audioStreamingState = "ATTENUATED" }, + { systemContext = "HMI_OBSCURED", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }) + :Times(4) + end +end + +--! @CreateInteractionChoiceSet: Creation of Choice Set +--! @parameters: +--! choiceSetID - id for choice set +--! self - test object +--! @return: none +local function CreateInteractionChoiceSet(choiceSetID, self) + local choiceID = choiceSetID + local cid = self.mobileSession1:SendRPC("CreateInteractionChoiceSet", { + interactionChoiceSetID = choiceSetID, + choiceSet = setChoiceSet(choiceID), + }) + EXPECT_HMICALL("VR.AddCommand", { + cmdID = choiceID, + type = "Choice", + vrCommands = { "VrChoice" .. tostring(choiceID) } + }) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + self.mobileSession1:ExpectResponse(cid, { resultCode = "SUCCESS", success = true }) +end + +--! @PI_PerformViaVR_ONLY: Processing PI with interaction mode VR_ONLY with performing selection +--! @parameters: +--! paramsSend - parameters for PI request +--! self - test object +--! @return: none +local function PI_PerformViaVR_ONLY(paramsSend, self) + paramsSend.interactionMode = "VR_ONLY" + local cid = self.mobileSession1:SendRPC("PerformInteraction",paramsSend) + EXPECT_HMICALL("VR.PerformInteraction", { + helpPrompt = paramsSend.helpPrompt, + initialPrompt = paramsSend.initialPrompt, + timeout = paramsSend.timeout, + timeoutPrompt = paramsSend.timeoutPrompt + }) + :Do(function(_,data) + local function vrResponse() + self.hmiConnection:SendNotification("TTS.Started") + self.hmiConnection:SendNotification("VR.Started") + SendOnSystemContext(self, "VRSESSION") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + { choiceID = paramsSend.interactionChoiceSetIDList[1] }) + self.hmiConnection:SendNotification("TTS.Stopped") + self.hmiConnection:SendNotification("VR.Stopped") + SendOnSystemContext(self, "MAIN") + end + RUN_AFTER(vrResponse, 1000) + end) + + EXPECT_HMICALL("UI.PerformInteraction", { + timeout = paramsSend.timeout, + vrHelp = paramsSend.vrHelp, + vrHelpTitle = paramsSend.initialText, + }) + :Do(function(_,data) + self.hmiConnection:SendResponse( data.id, data.method, "SUCCESS", { } ) + end) + ExpectOnHMIStatusWithAudioStateChanged_PI(self, "VR") + self.mobileSession1:ExpectResponse(cid, + { success = true, resultCode = "SUCCESS", choiceID = paramsSend.interactionChoiceSetIDList[1] }) +end + +--! @PI_PerformViaMANUAL_ONLY: Processing PI with interaction mode MANUAL_ONLY with performing selection +--! @parameters: +--! paramsSend - parameters for PI request +--! self - test object +--! @return: none +local function PI_PerformViaMANUAL_ONLY(paramsSend, self) + paramsSend.interactionMode = "MANUAL_ONLY" + local cid = self.mobileSession1:SendRPC("PerformInteraction", paramsSend) + EXPECT_HMICALL("VR.PerformInteraction", { + helpPrompt = paramsSend.helpPrompt, + initialPrompt = paramsSend.initialPrompt, + timeout = paramsSend.timeout, + timeoutPrompt = paramsSend.timeoutPrompt + }) + :Do(function(_,data) + self.hmiConnection:SendNotification("TTS.Started") + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + EXPECT_HMICALL("UI.PerformInteraction", { + timeout = paramsSend.timeout, + choiceSet = setExChoiceSet(paramsSend.interactionChoiceSetIDList), + initialText = { + fieldName = "initialInteractionText", + fieldText = paramsSend.initialText + } + }) + :Do(function(_,data) + SendOnSystemContext(self,"HMI_OBSCURED") + local function uiResponse() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + { choiceID = paramsSend.interactionChoiceSetIDList[1] }) + self.hmiConnection:SendNotification("TTS.Stopped") + SendOnSystemContext(self,"MAIN") + end + RUN_AFTER(uiResponse, 1000) + end) + ExpectOnHMIStatusWithAudioStateChanged_PI(self, "MANUAL") + self.mobileSession1:ExpectResponse(cid, + { success = true, resultCode = "SUCCESS", choiceID = paramsSend.interactionChoiceSetIDList[1] }) +end + +--! @PI_PerformViaBOTH: Processing PI with interaction mode BOTH with timeout on VR and IU +--! @parameters: +--! paramsSend - parameters for PI request +--! self - test object +--! @return: none +local function PI_PerformViaBOTH(paramsSend, self) + paramsSend.interactionMode = "BOTH" + local cid = self.mobileSession1:SendRPC("PerformInteraction",paramsSend) + EXPECT_HMICALL("VR.PerformInteraction", { + helpPrompt = paramsSend.helpPrompt, + initialPrompt = paramsSend.initialPrompt, + timeout = paramsSend.timeout, + timeoutPrompt = paramsSend.timeoutPrompt + }) + :Do(function(_,data) + self.hmiConnection:SendNotification("VR.Started") + self.hmiConnection:SendNotification("TTS.Started") + SendOnSystemContext(self,"VRSESSION") + local function firstSpeakTimeOut() + self.hmiConnection:SendNotification("TTS.Stopped") + self.hmiConnection:SendNotification("TTS.Started") + end + RUN_AFTER(firstSpeakTimeOut, 5) + local function vrResponse() + self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", "Perform Interaction error response.") + self.hmiConnection:SendNotification("VR.Stopped") + end + RUN_AFTER(vrResponse, 20) + end) + EXPECT_HMICALL("UI.PerformInteraction", { + timeout = paramsSend.timeout, + choiceSet = setExChoiceSet(paramsSend.interactionChoiceSetIDList), + initialText = { + fieldName = "initialInteractionText", + fieldText = paramsSend.initialText + }, + vrHelp = paramsSend.vrHelp, + vrHelpTitle = paramsSend.initialText + }) + :Do(function(_,data) + local function choiceIconDisplayed() + SendOnSystemContext(self,"HMI_OBSCURED") + end + RUN_AFTER(choiceIconDisplayed, 25) + local function uiResponse() + self.hmiConnection:SendNotification("TTS.Stopped") + self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", "Perform Interaction error response.") + SendOnSystemContext(self,"MAIN") + end + RUN_AFTER(uiResponse, 30) + end) + ExpectOnHMIStatusWithAudioStateChanged_PI(self, "BOTH") + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "TIMED_OUT" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI", commonSmoke.registerApp) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) +runner.Step("CreateInteractionChoiceSet with id 100", CreateInteractionChoiceSet, {100}) +runner.Step("CreateInteractionChoiceSet with id 200", CreateInteractionChoiceSet, {200}) +runner.Step("CreateInteractionChoiceSet with id 300", CreateInteractionChoiceSet, {300}) + +runner.Title("Test") +runner.Step("PerformInteraction with VR_ONLY interaction mode", PI_PerformViaVR_ONLY, {requestParams}) +runner.Step("PerformInteraction with MANUAL_ONLY interaction mode", PI_PerformViaMANUAL_ONLY, {requestParams}) +runner.Step("PerformInteraction with BOTH interaction mode", PI_PerformViaBOTH, {requestParams}) + + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_sets/mobile_api_versioning.txt b/test_sets/mobile_api_versioning.txt index a1078fa961..09bd1f658e 100644 --- a/test_sets/mobile_api_versioning.txt +++ b/test_sets/mobile_api_versioning.txt @@ -2,3 +2,4 @@ ./test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua ./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/001_create_interaction_choice_success_legacy_app.lua ./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/002_create_interaction_choice_invalid_data_legacy_app.lua +./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/003_perform_interaction_success_legacy_app.lua \ No newline at end of file From a6460ffa3567331a275c866bce50a995a9b8e462 Mon Sep 17 00:00:00 2001 From: Conlain Kelly Date: Tue, 7 Aug 2018 16:27:55 -0400 Subject: [PATCH 528/681] Add tests for vrcommands failures, successes are in smoke ATM --- ...te_interaction_choice_set_invalid_data.lua | 87 ++++++ .../002_perform_interaction_invalid_data.lua | 287 ++++++++++++++++++ 2 files changed, 374 insertions(+) create mode 100644 test_scripts/SDL4_6/vrCommandOptional/001_create_interaction_choice_set_invalid_data.lua create mode 100644 test_scripts/SDL4_6/vrCommandOptional/002_perform_interaction_invalid_data.lua diff --git a/test_scripts/SDL4_6/vrCommandOptional/001_create_interaction_choice_set_invalid_data.lua b/test_scripts/SDL4_6/vrCommandOptional/001_create_interaction_choice_set_invalid_data.lua new file mode 100644 index 0000000000..b65dabef3b --- /dev/null +++ b/test_scripts/SDL4_6/vrCommandOptional/001_create_interaction_choice_set_invalid_data.lua @@ -0,0 +1,87 @@ +--------------------------------------------------------------------------------------------------- +-- User story: MobileVersioning Legacy App +-- Use case: CreateInteractionChoiceSet +-- Item: Happy path +-- +-- Requirement summary: +-- [CreateInteractionChoiceSet] INVALID_DATA +-- +-- Description: +-- Mobile application sends valid CreateInteractionChoiceSet request where +-- only some choices have vrCommands + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests CreateInteractionChoiceSet with mixed vrCommands + +-- Expected: +-- SDL invalidates parameters of the request +-- SDL responds with (resultCode: INVALID_DATA, success:false) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 +config.application1.registerAppInterfaceParams.syncMsgVersion.minorVersion = 0 + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local requestParams = { + interactionChoiceSetID = 1001, + choiceSet = { + { + choiceID = 1001, + menuName = "Choice1001", + vrCommands = { + "Choice1001" + }, + image = { + value = "icon.png", + imageType = "DYNAMIC" + } + }, + { + choiceID = 1002, + menuName = "Choice1002", + image = { + value = "icon.png", + imageType = "DYNAMIC" + } + } + } +} + +--[[ Local Functions ]] +local function createInteractionChoiceSet_mixedVR(params, self) + local cid = self.mobileSession1:SendRPC("CreateInteractionChoiceSet", params) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI", commonSmoke.registerApp) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) + +runner.Title("Test") +runner.Step("CreateInteractionChoiceSet mixed VR Commands INVALID_DATA Case", createInteractionChoiceSet_mixedVR, {requestParams}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) diff --git a/test_scripts/SDL4_6/vrCommandOptional/002_perform_interaction_invalid_data.lua b/test_scripts/SDL4_6/vrCommandOptional/002_perform_interaction_invalid_data.lua new file mode 100644 index 0000000000..64bcb0fbeb --- /dev/null +++ b/test_scripts/SDL4_6/vrCommandOptional/002_perform_interaction_invalid_data.lua @@ -0,0 +1,287 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: PerformInteraction +-- Item: Happy path +-- +-- Requirement summary: +-- [PerformInteraction]: +-- INVALID_DATA +-- +-- Description: +-- Mobile application sends PerformInteraction VR request with invalid parameters to SDL +-- It will have several choice sets with vrCommands and one without, so it cannot do a VR interaction + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level +-- d. ChoiceSets are already added + +-- Steps: +-- appID requests PerformInteraction using VR with non-VR choice sets + +-- Expected: +-- SDL invalidates parameters of the request +-- SDL responds with (resultCode: INVALID_DATA, success:false) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') + +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 +config.application1.registerAppInterfaceParams.syncMsgVersion.minorVersion = 0 + +--[[ Local Variables ]] +local putFileParams = { + requestParams = { + syncFileName = 'icon.png', + fileType = "GRAPHIC_PNG", + persistentFile = false, + systemFile = false + }, + filePath = "files/icon.png" +} + +local storagePath = commonPreconditions:GetPathToSDL() .. "storage/" .. +config.application1.registerAppInterfaceParams.appID .. "_" .. commonSmoke.getDeviceMAC() .. "/" + +local ImageValue = { + value = storagePath .. "icon.png", + imageType = "DYNAMIC", +} + +local function PromptValue(text) + local tmp = { + { + text = text, + type = "TEXT" + } + } + return tmp +end + +local initialPromptValue = PromptValue(" Make your choice ") + +local helpPromptValue = PromptValue(" Help Prompt ") + +local timeoutPromptValue = PromptValue(" Time out ") + +local vrHelpvalue = { + { + text = " New VRHelp ", + position = 1, + image = ImageValue + } +} + +local requestParams = { + initialText = "StartPerformInteraction", + initialPrompt = initialPromptValue, + interactionMode = "BOTH", + interactionChoiceSetIDList = { + 100, 200, 300 + }, + helpPrompt = helpPromptValue, + timeoutPrompt = timeoutPromptValue, + timeout = 5000, + vrHelp = vrHelpvalue, + interactionLayout = "ICON_ONLY" +} + +local requestParams_noVR = { + initialText = "StartPerformInteraction", + initialPrompt = initialPromptValue, + interactionMode = "BOTH", + interactionChoiceSetIDList = { + 100, 200, 300, 400 + }, + helpPrompt = helpPromptValue, + timeoutPrompt = timeoutPromptValue, + timeout = 5000, + vrHelp = vrHelpvalue, + interactionLayout = "ICON_ONLY" +} + +--[[ Local Functions ]] + +--! @setChoiceSet: Creates Choice structure +--! @parameters: +--! choiceIDValue - Id for created choice +--! @return: table of created choice structure +local function setChoiceSet(choiceIDValue) + local temp = { + { + choiceID = choiceIDValue, + menuName ="Choice" .. tostring(choiceIDValue), + vrCommands = { + "VrChoice" .. tostring(choiceIDValue), + }, + image = { + value ="icon.png", + imageType ="STATIC", + } + } + } + return temp +end + +--! @setChoiceSet_noVR: Creates Choice structure without VRcommands +--! @parameters: +--! choiceIDValue - Id for created choice +--! @return: table of created choice structure +local function setChoiceSet_noVR(choiceIDValue) + local temp = { + { + choiceID = choiceIDValue, + menuName ="Choice" .. tostring(choiceIDValue), + image = { + value ="icon.png", + imageType ="STATIC", + } + } + } + return temp +end + +--! @SendOnSystemContext: OnSystemContext notification +--! @parameters: +--! self - test object, +--! ctx - systemContext value +--! @return: none +local function SendOnSystemContext(self, ctx) + self.hmiConnection:SendNotification("UI.OnSystemContext", + { appID = commonSmoke.getHMIAppId(), systemContext = ctx }) +end + +--! @setExChoiceSet: ChoiceSet structure for UI.PerformInteraction request +--! @parameters: +--! choiceIDValues - value of choice id +--! @return: none +local function setExChoiceSet(choiceIDValues) + local exChoiceSet = { } + for i = 1, #choiceIDValues do + exChoiceSet[i] = { + choiceID = choiceIDValues[i], + image = { + value = "icon.png", + imageType = "STATIC", + }, + menuName = "Choice" .. choiceIDValues[i] + } + end + return exChoiceSet +end + +--! @ExpectOnHMIStatusWithAudioStateChanged_PI: Expectations of OnHMIStatus notification depending on the application +--! type, HMI level and interaction mode +--! @parameters: +--! self - test object, +--! request - interaction mode, +--! @return: none +local function ExpectOnHMIStatusWithAudioStateChanged_PI(self, request) + if "BOTH" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "VRSESSION" }, + { hmiLevel = "FULL", audioStreamingState = "ATTENUATED", systemContext = "VRSESSION" }, + { hmiLevel = "FULL", audioStreamingState = "ATTENUATED", systemContext = "HMI_OBSCURED" }, + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "HMI_OBSCURED" }, + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + :Times(6) + elseif "VR" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "ATTENUATED" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE" }, + { systemContext = "VRSESSION", hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE" }, + { systemContext = "VRSESSION", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }) + :Times(5) + elseif "MANUAL" == request then + self.mobileSession1:ExpectNotification("OnHMIStatus", + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "ATTENUATED" }, + { systemContext = "HMI_OBSCURED", hmiLevel = "FULL", audioStreamingState = "ATTENUATED" }, + { systemContext = "HMI_OBSCURED", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }, + { systemContext = "MAIN", hmiLevel = "FULL", audioStreamingState = "AUDIBLE" }) + :Times(4) + end +end + +--! @CreateInteractionChoiceSet: Creation of Choice Set +--! @parameters: +--! choiceSetID - id for choice set +--! self - test object +--! @return: none +local function CreateInteractionChoiceSet(choiceSetID, self) + local choiceID = choiceSetID + local cid = self.mobileSession1:SendRPC("CreateInteractionChoiceSet", { + interactionChoiceSetID = choiceSetID, + choiceSet = setChoiceSet(choiceID), + }) + EXPECT_HMICALL("VR.AddCommand", { + cmdID = choiceID, + type = "Choice", + vrCommands = { "VrChoice" .. tostring(choiceID) } + }) + :Do(function(_,data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { }) + end) + self.mobileSession1:ExpectResponse(cid, { resultCode = "SUCCESS", success = true }) +end + +--! @CreateInteractionChoiceSet_noVR: Creation of Choice Set with no vrCommands +--! @parameters: +--! choiceSetID - id for choice set +--! self - test object +--! @return: none +local function CreateInteractionChoiceSet_noVR(choiceSetID, self) + local choiceID = choiceSetID + local cid = self.mobileSession1:SendRPC("CreateInteractionChoiceSet", { + interactionChoiceSetID = choiceSetID, + choiceSet = setChoiceSet_noVR(choiceID), + }) + self.mobileSession1:ExpectResponse(cid, { resultCode = "SUCCESS", success = true }) +end + +--! @PI_PerformViaVR_ONLY: Processing PI with interaction mode VR_ONLY with performing selection +--! @parameters: +--! paramsSend - parameters for PI request +--! self - test object +--! @return: none +local function PI_PerformViaVR_ONLY(paramsSend, self) + paramsSend.interactionMode = "VR_ONLY" + local cid = self.mobileSession1:SendRPC("PerformInteraction",paramsSend) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +--! @PI_PerformViaBOTH: Processing PI with interaction mode BOTH with timeout on VR and IU +--! @parameters: +--! paramsSend - parameters for PI request +--! self - test object +--! @return: none +local function PI_PerformViaBOTH(paramsSend, self) + paramsSend.interactionMode = "BOTH" + local cid = self.mobileSession1:SendRPC("PerformInteraction",paramsSend) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI", commonSmoke.registerApp) +runner.Step("Activate App", commonSmoke.activateApp) +runner.Step("Upload icon file", commonSmoke.putFile, {putFileParams}) +runner.Step("CreateInteractionChoiceSet with id 100", CreateInteractionChoiceSet, {100}) +runner.Step("CreateInteractionChoiceSet with id 200", CreateInteractionChoiceSet, {200}) +runner.Step("CreateInteractionChoiceSet with id 300", CreateInteractionChoiceSet, {300}) +runner.Step("CreateInteractionChoiceSet no VR commands with id 400", CreateInteractionChoiceSet_noVR, {400}) + +runner.Title("Test") +runner.Step("PerformInteraction with VR_ONLY interaction mode invalid data", PI_PerformViaVR_ONLY, {requestParams_noVR}) +runner.Step("PerformInteraction with BOTH interaction mode invalid data", PI_PerformViaBOTH, {requestParams_noVR}) + + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) From 5f784bd4cc9514724a29d8e50417e4d2ad735169 Mon Sep 17 00:00:00 2001 From: Conlain Kelly Date: Thu, 9 Aug 2018 13:28:44 -0400 Subject: [PATCH 529/681] Add new tests for full app id functionality --- .../FullAppID/001_PTU_full_app_ID_true.lua | 40 +++ .../FullAppID/002_PTU_full_app_ID_false.lua | 45 +++ test_scripts/SDL4_6/FullAppID/common.lua | 293 ++++++++++++++++++ user_modules/sequences/actions.lua | 4 +- 4 files changed, 380 insertions(+), 2 deletions(-) create mode 100644 test_scripts/SDL4_6/FullAppID/001_PTU_full_app_ID_true.lua create mode 100644 test_scripts/SDL4_6/FullAppID/002_PTU_full_app_ID_false.lua create mode 100644 test_scripts/SDL4_6/FullAppID/common.lua diff --git a/test_scripts/SDL4_6/FullAppID/001_PTU_full_app_ID_true.lua b/test_scripts/SDL4_6/FullAppID/001_PTU_full_app_ID_true.lua new file mode 100644 index 0000000000..71e8cf9f82 --- /dev/null +++ b/test_scripts/SDL4_6/FullAppID/001_PTU_full_app_ID_true.lua @@ -0,0 +1,40 @@ +--------------------------------------------------------------------------------------------- +-- Script verifies that a PT snapshot contains the correct full_app_id_supported flag +-- Supports PROPRIETARY +--------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonPreconditions = require("user_modules/shared_testcases/commonPreconditions") +local mobile_session = require("mobile_session") +local actions = require("user_modules/sequences/actions") +local json = require("modules/json") +local atf_logger = require("atf_logger") +local sdl = require("SDL") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +local common = require("test_scripts/SDL4_6/FullAppID/common") + +local full_app_id_supported = "true" + +-- This is the id in the policy table +common.policy_app_id = config.application1.registerAppInterfaceParams.fullAppID + +runner.Title("Preconditions " .. full_app_id_supported) +-- Stop SDL if process is still running, delete local policy table and log files +runner.Step("Clean environment", common.preconditions) +runner.Step("Set UseFullAppID to true", actions.setSDLIniParameter, {"UseFullAppID", full_app_id_supported}) +-- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP +runner.Step("Start SDL, HMI, connect Mobile", common.start) +-- Pring in terminal build options(RC status and policy slow) +runner.Step("SDL Configuration", common.printSDLConfig) + +runner.Title("Test " .. full_app_id_supported) +-- create mobile session, register application, perform PTU wit PT +runner.Step("RAI, PTU", common.raiPTU) +-- Check that PTU is performed successful +runner.Step("Check Status", common.checkPTUStatus) + +runner.Title("Postconditions " .. full_app_id_supported) +runner.Step("Restore ini and stop SDL", common.postconditions) diff --git a/test_scripts/SDL4_6/FullAppID/002_PTU_full_app_ID_false.lua b/test_scripts/SDL4_6/FullAppID/002_PTU_full_app_ID_false.lua new file mode 100644 index 0000000000..0f84a95359 --- /dev/null +++ b/test_scripts/SDL4_6/FullAppID/002_PTU_full_app_ID_false.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------- +-- Script verifies that a PT snapshot contains the correct full_app_id_supported flag +-- Supports PROPRIETARY +--------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonPreconditions = require("user_modules/shared_testcases/commonPreconditions") +local mobile_session = require("mobile_session") +local actions = require("user_modules/sequences/actions") +local json = require("modules/json") +local atf_logger = require("atf_logger") +local sdl = require("SDL") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +local common = require("test_scripts/SDL4_6/FullAppID/common") + +local full_app_id_supported = "false" + +-- This is the id in the policy table +common.policy_app_id = config.application1.registerAppInterfaceParams.fullAppID + +-- copy the fullAppID field to appID and remove full app id +config.application1.registerAppInterfaceParams.appID = config.application1.registerAppInterfaceParams.fullAppID +config.application1.registerAppInterfaceParams.fullAppID = nil + + +runner.Title("Preconditions " .. full_app_id_supported) +-- Stop SDL if process is still running, delete local policy table and log files +runner.Step("Clean environment", common.preconditions) +runner.Step("Set UseFullAppID to true", actions.setSDLIniParameter, {"UseFullAppID", full_app_id_supported}) +-- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP +runner.Step("Start SDL, HMI, connect Mobile", common.start) +-- Pring in terminal build options(RC status and policy slow) +runner.Step("SDL Configuration", common.printSDLConfig) + +runner.Title("Test " .. full_app_id_supported) +-- create mobile session, register application, perform PTU wit PT +runner.Step("RAI, PTU", common.raiPTU) +-- Check that PTU is performed successful +runner.Step("Check Status", common.checkPTUStatus) + +runner.Title("Postconditions " .. full_app_id_supported) +runner.Step("Restore ini and stop SDL", common.postconditions) diff --git a/test_scripts/SDL4_6/FullAppID/common.lua b/test_scripts/SDL4_6/FullAppID/common.lua new file mode 100644 index 0000000000..e6fdd5bcc3 --- /dev/null +++ b/test_scripts/SDL4_6/FullAppID/common.lua @@ -0,0 +1,293 @@ +--------------------------------------------------------------------------------------------- +-- Script verifies that a PT snapshot contains the correct full_app_id_supported flag +-- Supports PROPRIETARY +--------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonPreconditions = require("user_modules/shared_testcases/commonPreconditions") +local mobile_session = require("mobile_session") +local actions = require("user_modules/sequences/actions") +local json = require("modules/json") +local atf_logger = require("atf_logger") +local sdl = require("SDL") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +--[[ Local Variables ]] + +local m = commonSteps + +--[[ Local Functions ]] +function m.preconditions() + -- Stop SDL if process is still running + commonFunctions:SDLForceStop() + -- Remove Local Policy Update + commonSteps:DeletePolicyTable() + -- Delete log files + commonSteps:DeleteLogsFiles() +end + +-- Allow device from HMI +local function allowSDL(self) + -- sending notification OnAllowSDLFunctionality from HMI to allow connected device + self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", + { allowed = true, source = "GUI", device = { id = commonSmoke.getDeviceMAC(), name = commonSmoke.getDeviceName() }}) +end + +-- Start SDL and HMI, establish connection between SDL and HMI, open mobile connection via TCP +function m.start(self) + self:runSDL() + commonFunctions:waitForSDLStart(self) + :Do(function() + self:initHMI(self) + :Do(function() + commonFunctions:userPrint(35, "HMI initialized") + self:initHMI_onReady() + :Do(function() + commonFunctions:userPrint(35, "HMI is ready") + self:connectMobile() + :Do(function() + commonFunctions:userPrint(35, "Mobile connected") + allowSDL(self) + end) + end) + end) + end) +end + +-- Loging messages in terminal +local function log(...) + local str = "[" .. atf_logger.formated_time(true) .. "]" + for i, p in pairs({...}) do + local delimiter = "\t" + if i == 1 then delimiter = " " end + str = str .. delimiter .. p + end + commonFunctions:userPrint(35, str) +end + +-- Convert snapshot form json to table +-- @tparam file pts_f snapshot file +local function ptsToTable(pts_f) + local f = io.open(pts_f, "r") + local content = f:read("*all") + f:close() + return json.decode(content) +end + +-- Creation policy table from snapshot +-- @tparam table ptu snapshot table +local function getPTUFromPTS(ptu) + -- remove messages in consumer_friendly_messages + ptu.policy_table.consumer_friendly_messages.messages = nil + -- remove device_data + ptu.policy_table.device_data = nil + -- remove module_meta + ptu.policy_table.module_meta = nil + -- remove usage_and_error_counts + ptu.policy_table.usage_and_error_counts = nil + -- write empty struct in "DataConsent-2".rpcs + ptu.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + -- remove preloaded_pt + ptu.policy_table.module_config.preloaded_pt = nil + -- remove preloaded_date + ptu.policy_table.module_config.preloaded_date = nil + -- Create structure in app_policies related to registered application + ptu.policy_table.app_policies[m.policy_app_id] = { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE" + } + -- Added permissions for registered app from "Base-4", "Base-6" groups + ptu.policy_table.app_policies[m.policy_app_id]["groups"] = { + "Base-4", "Base-6" + } +end + +-- Save created PT in file +-- @tparam table ptu PT table +-- @tparam string ptu_file_name file name +local function storePTUInFile(ptu, ptu_file_name) + local f = io.open(ptu_file_name, "w") + f:write(json.encode(ptu)) + f:close() +end + +-- Check that PT is sent as binary data in OnSystem request +-- @tparam table bin_data binary data +local function checkIfPTSIsSentAsBinary(bin_data, self) + -- decode binary data to table depending on policy flow + local pt = nil + if bin_data ~= nil and string.len(bin_data) > 0 then + pt = json.decode(bin_data).HTTPRequest.body + pt = json.decode(pt) + end + -- Check presence of policy_table in decoded PT + if pt == nil or not pt.policy_table then + self:FailTestCase("PTS was not sent to Mobile as binary data in payload of OnSystemRequest") + end + -- Check that full_app_id_supported is correctly passed along + local pt_full_id_support = tostring(pt.policy_table.module_config.full_app_id_supported) + local ini_full_id_support = commonFunctions:read_parameter_from_smart_device_link_ini("UseFullAppID") + if pt_full_id_support ~= ini_full_id_support then + log("expected: " .. pt_full_id_support .. " recieved: " .. ini_full_id_support) + self:FailTestCase(".ini full app ID support does not match PT snapshot given") + end + +end + +-- Policy table update with Proprietary flow +-- @tparam table ptu_table PT table +local function ptuProprietary(ptu_table, self) + -- Get path to snapshot + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" + .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + -- create ptu_file_name as tmp file + local ptu_file_name = os.tmpname() + -- Send GetURLS request from HMI to SDL with service 7 + local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) + log("HMI->SDL: RQ: SDL.GetURLS") + -- Expect response GetURLS on HMI side + EXPECT_HMIRESPONSE(requestId) + :Do(function() + log("SDL->HMI: RS: SDL.GetURLS") + -- After receiving GetURLS response send OnSystemRequest notification from HMI + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", + { requestType = "PROPRIETARY", fileName = pts_file_name }) + log("HMI->SDL: N: BC.OnSystemRequest") + -- Prepare PT for update + getPTUFromPTS(ptu_table) + log("HMI->SDL:get ptu") + + -- Save created PT for update in tmp file + storePTUInFile(ptu_table, ptu_file_name) + log("HMI->SDL:store ptu") + + -- Expect receiving of OnSystemRequest notification with snapshot on mobile side + self.mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) + :Do(function(_, d) + -- After receiving OnSystemRequest notification on mobile side check that + -- data in notification was sent as binary data + checkIfPTSIsSentAsBinary(d.binaryData, self) + log("SDL->MOB: N: OnSystemRequest") + -- Send SystemRequest request with PT for update from mobile side + local corIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", + { requestType = "PROPRIETARY" }, ptu_file_name) + log("MOB->SDL: RQ: SystemRequest") + -- Expect SystemRequest request on HMI side + EXPECT_HMICALL("BasicCommunication.SystemRequest") + :Do(function(_, dd) + log("SDL->HMI: RQ: BC.SystemRequest") + -- Send SystemRequest response form HMI with resultCode SUCCESS + self.hmiConnection:SendResponse(dd.id, dd.method, "SUCCESS", { }) + log("HMI->SDL: RS: SUCCESS: BC.SystemRequest") + -- Send OnReceivedPolicyUpdate notification from HMI + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", + { policyfile = dd.params.fileName }) + log("HMI->SDL: N: SDL.OnReceivedPolicyUpdate") + end) + -- Expect SystemRequest response with resultCode SUCCESS on mobile side + self.mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS"}) + -- remove tmp PT file after receiving SystemRequest response on mobile side + :Do(function() os.remove(ptu_file_name) end) + log("SDL->MOB: RS: SUCCESS: SystemRequest") + end) + end) +end + +-- Expect 3 OnStatusUpdate notification on HMI side during PTU +local function expOnStatusUpdate() + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", + { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, {status = "UP_TO_DATE" }) + :Do(function(_, d) + log("SDL->HMI: N: SDL.OnStatusUpdate", d.params.status) + end) + :Times(3) +end + +-- Fail test cases by incorrect PTU +-- @tparam string pRequestName request name of RPC that is failed expectations +local function failInCaseIncorrectPTU(pRequestName, self) + self:FailTestCase(pRequestName .. " was sent more than once (PTU update was incorrect)") +end + +-- Registration of application with policy table update +function m.raiPTU(self) + expOnStatusUpdate() -- temp solution due to issue in SDL: + -- SDL.OnStatusUpdate(UPDATE_NEEDED) notification is sent before BC.OnAppRegistered (EXTERNAL_PROPRIETARY flow) + + -- creation mobile session + self.mobileSession = mobile_session.MobileSession(self, self.mobileConnection) + -- open RPC service in created session + self.mobileSession:StartService(7) + :Do(function() + -- Send RegisterAppInterface request from mobile application + local corId = self.mobileSession:SendRPC("RegisterAppInterface", config.application1.registerAppInterfaceParams) + log("MOB->SDL: RQ: RegisterAppInterface") + -- Expect OnAppRegistered on HMI side from SDL + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config.application1.registerAppInterfaceParams.appName } }) + :Do(function() + log("SDL->HMI: N: BC.OnAppRegistered") + -- Expect PolicyUpdate request on HMI side + EXPECT_HMICALL("BasicCommunication.PolicyUpdate") + :Do(function(e, d) + if e.occurences == 1 then -- SDL send BC.PolicyUpdate more than once if PTU update was incorrect + log("SDL->HMI: RQ: BC.PolicyUpdate") + -- Create PT form snapshot + local ptu_table = ptsToTable(d.params.file) + -- Sending PolicyUpdate request from HMI with resultCode SUCCESS + self.hmiConnection:SendResponse(d.id, d.method, "SUCCESS", { }) + log("HMI->SDL: RS: BC.PolicyUpdate") + -- PTU proprietary flow + ptuProprietary(ptu_table, self) + else + failInCaseIncorrectPTU("BC.PolicyUpdate", self) + end + end) + end) + -- Expect RegisterAppInterface response on mobile side with resultCode SUCCESS + self.mobileSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + log("SDL->MOB: RS: RegisterAppInterface") + -- Expect OnHMIStatus with hmiLevel NONE on mobile side form SDL + self.mobileSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Do(function(_, d) + log("SDL->MOB: N: OnHMIStatus", d.payload.hmiLevel) + end) + -- Expect OnPermissionsChange on mobile side form SDL + self.mobileSession:ExpectNotification("OnPermissionsChange") + :Do(function() + log("SDL->MOB: N: OnPermissionsChange") + end) + :Times(2) + end) + end) +end + +-- Check update status +function m.checkPTUStatus(self) + -- Send GetStatusUpdate form HMI to SDL + local reqId = self.hmiConnection:SendRequest("SDL.GetStatusUpdate") + log("HMI->SDL: RQ: SDL.GetStatusUpdate") + -- Expect GetStatusUpdate response from SDL to HMI with update status + EXPECT_HMIRESPONSE(reqId, { result = { status = "UP_TO_DATE" }}) + :Do(function(_, d) + log("HMI->SDL: RS: SDL.GetStatusUpdate", tostring(d.result.status)) + end) +end + +-- Pring in terminal build options(RC status and policy slow) +function m.printSDLConfig() + commonFunctions:printTable(sdl.buildOptions) +end + +function m.postconditions() + actions.restoreSDLIniParameters() + StopSDL() +end + +return m diff --git a/user_modules/sequences/actions.lua b/user_modules/sequences/actions.lua index df68d17476..d53f09c71c 100644 --- a/user_modules/sequences/actions.lua +++ b/user_modules/sequences/actions.lua @@ -434,7 +434,7 @@ end --! @parameters: none --! @return: none --]] -local function restoreSDLIniParameters() +function m.restoreSDLIniParameters() for pParamName, pParamValue in pairs(originalValuesInSDLIni) do commonFunctions:write_parameter_to_smart_device_link_ini(pParamName, pParamValue) end @@ -446,7 +446,7 @@ end --]] function m.postconditions() StopSDL() - restoreSDLIniParameters() + self.restoreSDLIniParameters() end --[[ @getAppsCount: provide count of registered applications From 1624c046389fb5942cc09477734602a6803a5ed6 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 23 Jul 2018 14:12:38 +0300 Subject: [PATCH 530/681] Add initial scripts to check issue 2405 --- test_scripts/Defects/4_6/2405/001.lua | 35 ++++++++ test_scripts/Defects/4_6/2405/002.lua | 35 ++++++++ test_scripts/Defects/4_6/2405/003.lua | 35 ++++++++ test_scripts/Defects/4_6/2405/004.lua | 35 ++++++++ test_scripts/Defects/4_6/2405/005.lua | 35 ++++++++ test_scripts/Defects/4_6/2405/006.lua | 35 ++++++++ test_scripts/Defects/4_6/2405/007.lua | 35 ++++++++ test_scripts/Defects/4_6/2405/008.lua | 35 ++++++++ test_scripts/Defects/4_6/2405/009.lua | 35 ++++++++ test_scripts/Defects/4_6/2405/common.lua | 104 +++++++++++++++++++++++ 10 files changed, 419 insertions(+) create mode 100644 test_scripts/Defects/4_6/2405/001.lua create mode 100644 test_scripts/Defects/4_6/2405/002.lua create mode 100644 test_scripts/Defects/4_6/2405/003.lua create mode 100644 test_scripts/Defects/4_6/2405/004.lua create mode 100644 test_scripts/Defects/4_6/2405/005.lua create mode 100644 test_scripts/Defects/4_6/2405/006.lua create mode 100644 test_scripts/Defects/4_6/2405/007.lua create mode 100644 test_scripts/Defects/4_6/2405/008.lua create mode 100644 test_scripts/Defects/4_6/2405/009.lua create mode 100644 test_scripts/Defects/4_6/2405/common.lua diff --git a/test_scripts/Defects/4_6/2405/001.lua b/test_scripts/Defects/4_6/2405/001.lua new file mode 100644 index 0000000000..68b67a7a59 --- /dev/null +++ b/test_scripts/Defects/4_6/2405/001.lua @@ -0,0 +1,35 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2405 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/4_6/2405/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local tc = { + grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = nil }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = nil } + }, + resultCode = "SUCCESS", + success = true +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) + +runner.Title("Test") +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) +runner.Step("Consent Groups", common.consentGroups, { tc }) +runner.Step("Send GetVehicleData", common.getVD, { tc }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/4_6/2405/002.lua b/test_scripts/Defects/4_6/2405/002.lua new file mode 100644 index 0000000000..20a42ba925 --- /dev/null +++ b/test_scripts/Defects/4_6/2405/002.lua @@ -0,0 +1,35 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2405 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/4_6/2405/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local tc = { + grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = nil }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = common.EMPTY_ARRAY } + }, + resultCode = "SUCCESS", + success = true +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) + +runner.Title("Test") +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) +runner.Step("Consent Groups", common.consentGroups, { tc }) +runner.Step("Send GetVehicleData", common.getVD, { tc }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/4_6/2405/003.lua b/test_scripts/Defects/4_6/2405/003.lua new file mode 100644 index 0000000000..916be2d712 --- /dev/null +++ b/test_scripts/Defects/4_6/2405/003.lua @@ -0,0 +1,35 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2405 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/4_6/2405/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local tc = { + grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = nil }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = { "speed" } } + }, + resultCode = "SUCCESS", + success = true +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) + +runner.Title("Test") +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) +runner.Step("Consent Groups", common.consentGroups, { tc }) +runner.Step("Send GetVehicleData", common.getVD, { tc }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/4_6/2405/004.lua b/test_scripts/Defects/4_6/2405/004.lua new file mode 100644 index 0000000000..25a063c59d --- /dev/null +++ b/test_scripts/Defects/4_6/2405/004.lua @@ -0,0 +1,35 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2405 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/4_6/2405/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local tc = { + grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = common.EMPTY_ARRAY }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = nil } + }, + resultCode = "SUCCESS", + success = true +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) + +runner.Title("Test") +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) +runner.Step("Consent Groups", common.consentGroups, { tc }) +runner.Step("Send GetVehicleData", common.getVD, { tc }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/4_6/2405/005.lua b/test_scripts/Defects/4_6/2405/005.lua new file mode 100644 index 0000000000..034920683d --- /dev/null +++ b/test_scripts/Defects/4_6/2405/005.lua @@ -0,0 +1,35 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2405 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/4_6/2405/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local tc = { + grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = common.EMPTY_ARRAY }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = common.EMPTY_ARRAY } + }, + resultCode = "USER_DISALLOWED", + success = false +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) + +runner.Title("Test") +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) +runner.Step("Consent Groups", common.consentGroups, { tc }) +runner.Step("Send GetVehicleData", common.getVD, { tc }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/4_6/2405/006.lua b/test_scripts/Defects/4_6/2405/006.lua new file mode 100644 index 0000000000..1254796017 --- /dev/null +++ b/test_scripts/Defects/4_6/2405/006.lua @@ -0,0 +1,35 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2405 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/4_6/2405/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local tc = { + grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = common.EMPTY_ARRAY }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = { "speed" } } + }, + resultCode = "SUCCESS", + success = true +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) + +runner.Title("Test") +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) +runner.Step("Consent Groups", common.consentGroups, { tc }) +runner.Step("Send GetVehicleData", common.getVD, { tc }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/4_6/2405/007.lua b/test_scripts/Defects/4_6/2405/007.lua new file mode 100644 index 0000000000..5a2691f685 --- /dev/null +++ b/test_scripts/Defects/4_6/2405/007.lua @@ -0,0 +1,35 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2405 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/4_6/2405/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local tc = { + grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = { "speed" } }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = nil } + }, + resultCode = "SUCCESS", + success = true +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) + +runner.Title("Test") +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) +runner.Step("Consent Groups", common.consentGroups, { tc }) +runner.Step("Send GetVehicleData", common.getVD, { tc }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/4_6/2405/008.lua b/test_scripts/Defects/4_6/2405/008.lua new file mode 100644 index 0000000000..a76728d11b --- /dev/null +++ b/test_scripts/Defects/4_6/2405/008.lua @@ -0,0 +1,35 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2405 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/4_6/2405/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local tc = { + grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = { "speed" } }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = common.EMPTY_ARRAY } + }, + resultCode = "SUCCESS", + success = true +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) + +runner.Title("Test") +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) +runner.Step("Consent Groups", common.consentGroups, { tc }) +runner.Step("Send GetVehicleData", common.getVD, { tc }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/4_6/2405/009.lua b/test_scripts/Defects/4_6/2405/009.lua new file mode 100644 index 0000000000..5a063fd806 --- /dev/null +++ b/test_scripts/Defects/4_6/2405/009.lua @@ -0,0 +1,35 @@ +--------------------------------------------------------------------------------------------------- +-- Issue: https://github.com/smartdevicelink/sdl_core/issues/2405 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/4_6/2405/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local tc = { + grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = { "speed" } }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = { "speed" } } + }, + resultCode = "SUCCESS", + success = true +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) + +runner.Title("Test") +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) +runner.Step("Consent Groups", common.consentGroups, { tc }) +runner.Step("Send GetVehicleData", common.getVD, { tc }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/4_6/2405/common.lua b/test_scripts/Defects/4_6/2405/common.lua new file mode 100644 index 0000000000..c991403d52 --- /dev/null +++ b/test_scripts/Defects/4_6/2405/common.lua @@ -0,0 +1,104 @@ +--------------------------------------------------------------------------------------------------- +-- Common module +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('user_modules/sequences/actions') +local utils = require("user_modules/utils") +local hmi_values = require('user_modules/hmi_values') +local json = require("modules/json") + +local m = common + +m.EMPTY_ARRAY = json.EMPTY_ARRAY + +function m.getHMIValues() + local params = hmi_values.getDefaultHMITable() + params.RC = nil + return params +end + +local ptuOrig = common.policyTableUpdate + +function m.policyTableUpdate(pTC) + local dfltGrpData = { + rpcs = { + GetVehicleData = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED" } + } + } + } + local function ptUpdate(pTbl) + local fg = pTbl.policy_table.functional_groupings + for i = 1, #pTC.grp do + fg[pTC.grp[i].name] = utils.cloneTable(dfltGrpData) + fg[pTC.grp[i].name].user_consent_prompt = pTC.grp[i].prompt + fg[pTC.grp[i].name].rpcs.GetVehicleData.parameters = pTC.grp[i].params + end + pTbl.policy_table.app_policies[common.getConfigAppParams().appID].groups = { "Base-4", pTC.grp[1].name, pTC.grp[2].name } + end + ptuOrig(ptUpdate) +end + +local function getGroupId(pData, pGrpName) + for i = 1, #pData.result.allowedFunctions do + if(pData.result.allowedFunctions[i].name == pGrpName) then + return pData.result.allowedFunctions[i].id + end + end +end + +function m.getListOfPermissions(pTC) + local rid = common.getHMIConnection():SendRequest("SDL.GetListOfPermissions") + common.getHMIConnection():ExpectResponse(rid) + :Do(function(_,data) + for i = 1, #pTC.grp do + pTC.grp[i].id = getGroupId(data, pTC.grp[i].prompt) + print("Grp " .. i .. " Id: ", tostring(pTC.grp[i].id)) + end + end) +end + +local function consentGroupsByAFewMsg(pTC) + for i = 1, #pTC.grp do + common.getHMIConnection():SendNotification("SDL.OnAppPermissionConsent", { + appID = common.getHMIAppId, + source = "GUI", + consentedFunctions = {{ name = pTC.grp[i].prompt, id = pTC.grp[i].id, allowed = true }} + }) + end + common.getMobileSession():ExpectNotification("OnPermissionsChange") + :Times(#pTC.grp) +end + +local function consentGroupsBySingleMsg(pTC) + local consentedFunctions = {} + for i = 1, #pTC.grp do + table.insert(consentedFunctions, { name = pTC.grp[i].prompt, id = pTC.grp[i].id, allowed = true }) + end + common.getHMIConnection():SendNotification("SDL.OnAppPermissionConsent", { + appID = common.getHMIAppId, + source = "GUI", + consentedFunctions = consentedFunctions + }) + common.getMobileSession():ExpectNotification("OnPermissionsChange") +end + +function m.consentGroups(pTC) + consentGroupsByAFewMsg(pTC) +end + +function m.getVD(pTC) + local cid = common.getMobileSession():SendRPC("GetVehicleData", { speed = true }) + if pTC.success == true then + common.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData") + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { speed = 1.11 }) + end) + end + common.getMobileSession():ExpectResponse(cid, { success = pTC.success, resultCode = pTC.resultCode }) + :Do(function(_, data) + utils.printTable(data.payload) + end) +end + +return m From 261a8a4e6303f5d89fd16dfc8f31fbfbddc515e7 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 10 Aug 2018 11:31:40 +0300 Subject: [PATCH 531/681] Rename scripts --- .../2405/001.lua => 5_0/2405/001_omitted_omitted_SUCCESS.lua} | 2 +- .../2405/002.lua => 5_0/2405/002_omitted_empty_SUCCESS.lua} | 2 +- .../2405/003.lua => 5_0/2405/003_omitted_param_SUCCESS.lua} | 2 +- .../2405/004.lua => 5_0/2405/004_empty_omitted_SUCCESS.lua} | 2 +- .../005.lua => 5_0/2405/005_empty_empty_USER_DISALLOWED.lua} | 2 +- .../{4_6/2405/006.lua => 5_0/2405/006_empty_param_SUCCESS.lua} | 2 +- .../2405/007.lua => 5_0/2405/007_param_omitted_SUCCESS.lua} | 2 +- .../{4_6/2405/008.lua => 5_0/2405/008_param_empty_SUCCESS.lua} | 2 +- .../{4_6/2405/009.lua => 5_0/2405/009_param_param_SUCCESS.lua} | 2 +- test_scripts/Defects/{4_6 => 5_0}/2405/common.lua | 0 10 files changed, 9 insertions(+), 9 deletions(-) rename test_scripts/Defects/{4_6/2405/001.lua => 5_0/2405/001_omitted_omitted_SUCCESS.lua} (95%) rename test_scripts/Defects/{4_6/2405/002.lua => 5_0/2405/002_omitted_empty_SUCCESS.lua} (95%) rename test_scripts/Defects/{4_6/2405/003.lua => 5_0/2405/003_omitted_param_SUCCESS.lua} (95%) rename test_scripts/Defects/{4_6/2405/004.lua => 5_0/2405/004_empty_omitted_SUCCESS.lua} (95%) rename test_scripts/Defects/{4_6/2405/005.lua => 5_0/2405/005_empty_empty_USER_DISALLOWED.lua} (95%) rename test_scripts/Defects/{4_6/2405/006.lua => 5_0/2405/006_empty_param_SUCCESS.lua} (95%) rename test_scripts/Defects/{4_6/2405/007.lua => 5_0/2405/007_param_omitted_SUCCESS.lua} (95%) rename test_scripts/Defects/{4_6/2405/008.lua => 5_0/2405/008_param_empty_SUCCESS.lua} (95%) rename test_scripts/Defects/{4_6/2405/009.lua => 5_0/2405/009_param_param_SUCCESS.lua} (95%) rename test_scripts/Defects/{4_6 => 5_0}/2405/common.lua (100%) diff --git a/test_scripts/Defects/4_6/2405/001.lua b/test_scripts/Defects/5_0/2405/001_omitted_omitted_SUCCESS.lua similarity index 95% rename from test_scripts/Defects/4_6/2405/001.lua rename to test_scripts/Defects/5_0/2405/001_omitted_omitted_SUCCESS.lua index 68b67a7a59..fb57f27515 100644 --- a/test_scripts/Defects/4_6/2405/001.lua +++ b/test_scripts/Defects/5_0/2405/001_omitted_omitted_SUCCESS.lua @@ -3,7 +3,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Defects/4_6/2405/common') +local common = require('test_scripts/Defects/5_0/2405/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Defects/4_6/2405/002.lua b/test_scripts/Defects/5_0/2405/002_omitted_empty_SUCCESS.lua similarity index 95% rename from test_scripts/Defects/4_6/2405/002.lua rename to test_scripts/Defects/5_0/2405/002_omitted_empty_SUCCESS.lua index 20a42ba925..06922cfa44 100644 --- a/test_scripts/Defects/4_6/2405/002.lua +++ b/test_scripts/Defects/5_0/2405/002_omitted_empty_SUCCESS.lua @@ -3,7 +3,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Defects/4_6/2405/common') +local common = require('test_scripts/Defects/5_0/2405/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Defects/4_6/2405/003.lua b/test_scripts/Defects/5_0/2405/003_omitted_param_SUCCESS.lua similarity index 95% rename from test_scripts/Defects/4_6/2405/003.lua rename to test_scripts/Defects/5_0/2405/003_omitted_param_SUCCESS.lua index 916be2d712..837a1dc2e4 100644 --- a/test_scripts/Defects/4_6/2405/003.lua +++ b/test_scripts/Defects/5_0/2405/003_omitted_param_SUCCESS.lua @@ -3,7 +3,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Defects/4_6/2405/common') +local common = require('test_scripts/Defects/5_0/2405/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Defects/4_6/2405/004.lua b/test_scripts/Defects/5_0/2405/004_empty_omitted_SUCCESS.lua similarity index 95% rename from test_scripts/Defects/4_6/2405/004.lua rename to test_scripts/Defects/5_0/2405/004_empty_omitted_SUCCESS.lua index 25a063c59d..4c4e39fda1 100644 --- a/test_scripts/Defects/4_6/2405/004.lua +++ b/test_scripts/Defects/5_0/2405/004_empty_omitted_SUCCESS.lua @@ -3,7 +3,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Defects/4_6/2405/common') +local common = require('test_scripts/Defects/5_0/2405/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Defects/4_6/2405/005.lua b/test_scripts/Defects/5_0/2405/005_empty_empty_USER_DISALLOWED.lua similarity index 95% rename from test_scripts/Defects/4_6/2405/005.lua rename to test_scripts/Defects/5_0/2405/005_empty_empty_USER_DISALLOWED.lua index 034920683d..6d1e9ba29c 100644 --- a/test_scripts/Defects/4_6/2405/005.lua +++ b/test_scripts/Defects/5_0/2405/005_empty_empty_USER_DISALLOWED.lua @@ -3,7 +3,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Defects/4_6/2405/common') +local common = require('test_scripts/Defects/5_0/2405/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Defects/4_6/2405/006.lua b/test_scripts/Defects/5_0/2405/006_empty_param_SUCCESS.lua similarity index 95% rename from test_scripts/Defects/4_6/2405/006.lua rename to test_scripts/Defects/5_0/2405/006_empty_param_SUCCESS.lua index 1254796017..8708ee14cc 100644 --- a/test_scripts/Defects/4_6/2405/006.lua +++ b/test_scripts/Defects/5_0/2405/006_empty_param_SUCCESS.lua @@ -3,7 +3,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Defects/4_6/2405/common') +local common = require('test_scripts/Defects/5_0/2405/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Defects/4_6/2405/007.lua b/test_scripts/Defects/5_0/2405/007_param_omitted_SUCCESS.lua similarity index 95% rename from test_scripts/Defects/4_6/2405/007.lua rename to test_scripts/Defects/5_0/2405/007_param_omitted_SUCCESS.lua index 5a2691f685..de580fcad5 100644 --- a/test_scripts/Defects/4_6/2405/007.lua +++ b/test_scripts/Defects/5_0/2405/007_param_omitted_SUCCESS.lua @@ -3,7 +3,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Defects/4_6/2405/common') +local common = require('test_scripts/Defects/5_0/2405/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Defects/4_6/2405/008.lua b/test_scripts/Defects/5_0/2405/008_param_empty_SUCCESS.lua similarity index 95% rename from test_scripts/Defects/4_6/2405/008.lua rename to test_scripts/Defects/5_0/2405/008_param_empty_SUCCESS.lua index a76728d11b..b5ca60bfef 100644 --- a/test_scripts/Defects/4_6/2405/008.lua +++ b/test_scripts/Defects/5_0/2405/008_param_empty_SUCCESS.lua @@ -3,7 +3,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Defects/4_6/2405/common') +local common = require('test_scripts/Defects/5_0/2405/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Defects/4_6/2405/009.lua b/test_scripts/Defects/5_0/2405/009_param_param_SUCCESS.lua similarity index 95% rename from test_scripts/Defects/4_6/2405/009.lua rename to test_scripts/Defects/5_0/2405/009_param_param_SUCCESS.lua index 5a063fd806..69e5ee3b97 100644 --- a/test_scripts/Defects/4_6/2405/009.lua +++ b/test_scripts/Defects/5_0/2405/009_param_param_SUCCESS.lua @@ -3,7 +3,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Defects/4_6/2405/common') +local common = require('test_scripts/Defects/5_0/2405/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/Defects/4_6/2405/common.lua b/test_scripts/Defects/5_0/2405/common.lua similarity index 100% rename from test_scripts/Defects/4_6/2405/common.lua rename to test_scripts/Defects/5_0/2405/common.lua From 7e8a7f0b38f2dbd3037a3f6bd201067328b7a1ea Mon Sep 17 00:00:00 2001 From: Conlain Kelly Date: Fri, 10 Aug 2018 13:28:15 -0400 Subject: [PATCH 532/681] Update tests --- test_scripts/SDL4_6/FullAppID/common.lua | 4 ++++ user_modules/sequences/actions.lua | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/test_scripts/SDL4_6/FullAppID/common.lua b/test_scripts/SDL4_6/FullAppID/common.lua index e6fdd5bcc3..6a123556e5 100644 --- a/test_scripts/SDL4_6/FullAppID/common.lua +++ b/test_scripts/SDL4_6/FullAppID/common.lua @@ -18,6 +18,8 @@ local commonSmoke = require('test_scripts/Smoke/commonSmoke') local m = commonSteps +local preloadedPT = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + --[[ Local Functions ]] function m.preconditions() -- Stop SDL if process is still running @@ -26,6 +28,8 @@ function m.preconditions() commonSteps:DeletePolicyTable() -- Delete log files commonSteps:DeleteLogsFiles() + commonPreconditions:BackupFile(preloadedPT) + commonSmoke.updatePreloadedPT() end -- Allow device from HMI diff --git a/user_modules/sequences/actions.lua b/user_modules/sequences/actions.lua index d53f09c71c..e3aefea20f 100644 --- a/user_modules/sequences/actions.lua +++ b/user_modules/sequences/actions.lua @@ -446,7 +446,7 @@ end --]] function m.postconditions() StopSDL() - self.restoreSDLIniParameters() + m.restoreSDLIniParameters() end --[[ @getAppsCount: provide count of registered applications From 7f5016ca609c71b1dd5cd7616468baf44a0c9590 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 13 Aug 2018 16:01:12 +0300 Subject: [PATCH 533/681] Add additional parameter in all scripts to cover more cases --- .../5_0/2405/001_omitted_omitted_SUCCESS.lua | 21 ++-- .../5_0/2405/002_omitted_empty_SUCCESS.lua | 21 ++-- .../5_0/2405/003_omitted_param_SUCCESS.lua | 21 ++-- .../5_0/2405/004_empty_omitted_SUCCESS.lua | 21 ++-- .../2405/005_empty_empty_USER_DISALLOWED.lua | 21 ++-- .../5_0/2405/006_empty_param_SUCCESS.lua | 21 ++-- .../5_0/2405/007_param_omitted_SUCCESS.lua | 21 ++-- .../5_0/2405/008_param_empty_SUCCESS.lua | 21 ++-- .../5_0/2405/009_param_param_SUCCESS.lua | 21 ++-- test_scripts/Defects/5_0/2405/common.lua | 96 ++++++++++--------- 10 files changed, 132 insertions(+), 153 deletions(-) diff --git a/test_scripts/Defects/5_0/2405/001_omitted_omitted_SUCCESS.lua b/test_scripts/Defects/5_0/2405/001_omitted_omitted_SUCCESS.lua index fb57f27515..479a453aee 100644 --- a/test_scripts/Defects/5_0/2405/001_omitted_omitted_SUCCESS.lua +++ b/test_scripts/Defects/5_0/2405/001_omitted_omitted_SUCCESS.lua @@ -9,27 +9,24 @@ local common = require('test_scripts/Defects/5_0/2405/common') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local tc = { - grp = { - [1] = { name = "Dummy-1", prompt = "Dummy_1", params = nil }, - [2] = { name = "Dummy-2", prompt = "Dummy_2", params = nil } - }, - resultCode = "SUCCESS", - success = true +local grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = nil }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = nil } } --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { grp }) runner.Title("Test") -runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) -runner.Step("Consent Groups", common.consentGroups, { tc }) -runner.Step("Send GetVehicleData", common.getVD, { tc }) +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { grp }) +runner.Step("Consent Groups", common.consentGroups, { grp }) +runner.Step("Send GetVehicleData speed", common.getVD, { "speed", "SUCCESS", true }) +runner.Step("Send GetVehicleData rpm", common.getVD, { "rpm", "SUCCESS", true }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/5_0/2405/002_omitted_empty_SUCCESS.lua b/test_scripts/Defects/5_0/2405/002_omitted_empty_SUCCESS.lua index 06922cfa44..1e50423ac8 100644 --- a/test_scripts/Defects/5_0/2405/002_omitted_empty_SUCCESS.lua +++ b/test_scripts/Defects/5_0/2405/002_omitted_empty_SUCCESS.lua @@ -9,27 +9,24 @@ local common = require('test_scripts/Defects/5_0/2405/common') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local tc = { - grp = { - [1] = { name = "Dummy-1", prompt = "Dummy_1", params = nil }, - [2] = { name = "Dummy-2", prompt = "Dummy_2", params = common.EMPTY_ARRAY } - }, - resultCode = "SUCCESS", - success = true +local grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = nil }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = common.EMPTY_ARRAY } } --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { grp }) runner.Title("Test") -runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) -runner.Step("Consent Groups", common.consentGroups, { tc }) -runner.Step("Send GetVehicleData", common.getVD, { tc }) +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { grp }) +runner.Step("Consent Groups", common.consentGroups, { grp }) +runner.Step("Send GetVehicleData speed", common.getVD, { "speed", "SUCCESS", true }) +runner.Step("Send GetVehicleData rpm", common.getVD, { "rpm", "SUCCESS", true }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/5_0/2405/003_omitted_param_SUCCESS.lua b/test_scripts/Defects/5_0/2405/003_omitted_param_SUCCESS.lua index 837a1dc2e4..223eb81da9 100644 --- a/test_scripts/Defects/5_0/2405/003_omitted_param_SUCCESS.lua +++ b/test_scripts/Defects/5_0/2405/003_omitted_param_SUCCESS.lua @@ -9,27 +9,24 @@ local common = require('test_scripts/Defects/5_0/2405/common') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local tc = { - grp = { - [1] = { name = "Dummy-1", prompt = "Dummy_1", params = nil }, - [2] = { name = "Dummy-2", prompt = "Dummy_2", params = { "speed" } } - }, - resultCode = "SUCCESS", - success = true +local grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = nil }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = { "speed" } } } --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { grp }) runner.Title("Test") -runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) -runner.Step("Consent Groups", common.consentGroups, { tc }) -runner.Step("Send GetVehicleData", common.getVD, { tc }) +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { grp }) +runner.Step("Consent Groups", common.consentGroups, { grp }) +runner.Step("Send GetVehicleData speed", common.getVD, { "speed", "SUCCESS", true }) +runner.Step("Send GetVehicleData rpm", common.getVD, { "rpm", "SUCCESS", true }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/5_0/2405/004_empty_omitted_SUCCESS.lua b/test_scripts/Defects/5_0/2405/004_empty_omitted_SUCCESS.lua index 4c4e39fda1..01af379f57 100644 --- a/test_scripts/Defects/5_0/2405/004_empty_omitted_SUCCESS.lua +++ b/test_scripts/Defects/5_0/2405/004_empty_omitted_SUCCESS.lua @@ -9,27 +9,24 @@ local common = require('test_scripts/Defects/5_0/2405/common') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local tc = { - grp = { - [1] = { name = "Dummy-1", prompt = "Dummy_1", params = common.EMPTY_ARRAY }, - [2] = { name = "Dummy-2", prompt = "Dummy_2", params = nil } - }, - resultCode = "SUCCESS", - success = true +local grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = common.EMPTY_ARRAY }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = nil } } --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { grp }) runner.Title("Test") -runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) -runner.Step("Consent Groups", common.consentGroups, { tc }) -runner.Step("Send GetVehicleData", common.getVD, { tc }) +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { grp }) +runner.Step("Consent Groups", common.consentGroups, { grp }) +runner.Step("Send GetVehicleData speed", common.getVD, { "speed", "SUCCESS", true }) +runner.Step("Send GetVehicleData rpm", common.getVD, { "rpm", "SUCCESS", true }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/5_0/2405/005_empty_empty_USER_DISALLOWED.lua b/test_scripts/Defects/5_0/2405/005_empty_empty_USER_DISALLOWED.lua index 6d1e9ba29c..dff9274da2 100644 --- a/test_scripts/Defects/5_0/2405/005_empty_empty_USER_DISALLOWED.lua +++ b/test_scripts/Defects/5_0/2405/005_empty_empty_USER_DISALLOWED.lua @@ -9,27 +9,24 @@ local common = require('test_scripts/Defects/5_0/2405/common') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local tc = { - grp = { - [1] = { name = "Dummy-1", prompt = "Dummy_1", params = common.EMPTY_ARRAY }, - [2] = { name = "Dummy-2", prompt = "Dummy_2", params = common.EMPTY_ARRAY } - }, - resultCode = "USER_DISALLOWED", - success = false +local grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = common.EMPTY_ARRAY }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = common.EMPTY_ARRAY } } --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { grp }) runner.Title("Test") -runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) -runner.Step("Consent Groups", common.consentGroups, { tc }) -runner.Step("Send GetVehicleData", common.getVD, { tc }) +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { grp }) +runner.Step("Consent Groups", common.consentGroups, { grp }) +runner.Step("Send GetVehicleData speed", common.getVD, { "speed", "USER_DISALLOWED", false }) +runner.Step("Send GetVehicleData rpm", common.getVD, { "rpm", "USER_DISALLOWED", false }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/5_0/2405/006_empty_param_SUCCESS.lua b/test_scripts/Defects/5_0/2405/006_empty_param_SUCCESS.lua index 8708ee14cc..0b62b105fc 100644 --- a/test_scripts/Defects/5_0/2405/006_empty_param_SUCCESS.lua +++ b/test_scripts/Defects/5_0/2405/006_empty_param_SUCCESS.lua @@ -9,27 +9,24 @@ local common = require('test_scripts/Defects/5_0/2405/common') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local tc = { - grp = { - [1] = { name = "Dummy-1", prompt = "Dummy_1", params = common.EMPTY_ARRAY }, - [2] = { name = "Dummy-2", prompt = "Dummy_2", params = { "speed" } } - }, - resultCode = "SUCCESS", - success = true +local grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = common.EMPTY_ARRAY }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = { "speed" } } } --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { grp }) runner.Title("Test") -runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) -runner.Step("Consent Groups", common.consentGroups, { tc }) -runner.Step("Send GetVehicleData", common.getVD, { tc }) +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { grp }) +runner.Step("Consent Groups", common.consentGroups, { grp }) +runner.Step("Send GetVehicleData speed", common.getVD, { "speed", "SUCCESS", true }) +runner.Step("Send GetVehicleData rpm", common.getVD, { "rpm", "DISALLOWED", false }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/5_0/2405/007_param_omitted_SUCCESS.lua b/test_scripts/Defects/5_0/2405/007_param_omitted_SUCCESS.lua index de580fcad5..bd75281add 100644 --- a/test_scripts/Defects/5_0/2405/007_param_omitted_SUCCESS.lua +++ b/test_scripts/Defects/5_0/2405/007_param_omitted_SUCCESS.lua @@ -9,27 +9,24 @@ local common = require('test_scripts/Defects/5_0/2405/common') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local tc = { - grp = { - [1] = { name = "Dummy-1", prompt = "Dummy_1", params = { "speed" } }, - [2] = { name = "Dummy-2", prompt = "Dummy_2", params = nil } - }, - resultCode = "SUCCESS", - success = true +local grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = { "speed" } }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = nil } } --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { grp }) runner.Title("Test") -runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) -runner.Step("Consent Groups", common.consentGroups, { tc }) -runner.Step("Send GetVehicleData", common.getVD, { tc }) +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { grp }) +runner.Step("Consent Groups", common.consentGroups, { grp }) +runner.Step("Send GetVehicleData speed", common.getVD, { "speed", "SUCCESS", true }) +runner.Step("Send GetVehicleData rpm", common.getVD, { "rpm", "SUCCESS", true }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/5_0/2405/008_param_empty_SUCCESS.lua b/test_scripts/Defects/5_0/2405/008_param_empty_SUCCESS.lua index b5ca60bfef..d42dda8311 100644 --- a/test_scripts/Defects/5_0/2405/008_param_empty_SUCCESS.lua +++ b/test_scripts/Defects/5_0/2405/008_param_empty_SUCCESS.lua @@ -9,27 +9,24 @@ local common = require('test_scripts/Defects/5_0/2405/common') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local tc = { - grp = { - [1] = { name = "Dummy-1", prompt = "Dummy_1", params = { "speed" } }, - [2] = { name = "Dummy-2", prompt = "Dummy_2", params = common.EMPTY_ARRAY } - }, - resultCode = "SUCCESS", - success = true +local grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = { "speed" } }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = common.EMPTY_ARRAY } } --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { grp }) runner.Title("Test") -runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) -runner.Step("Consent Groups", common.consentGroups, { tc }) -runner.Step("Send GetVehicleData", common.getVD, { tc }) +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { grp }) +runner.Step("Consent Groups", common.consentGroups, { grp }) +runner.Step("Send GetVehicleData speed", common.getVD, { "speed", "SUCCESS", true }) +runner.Step("Send GetVehicleData rpm", common.getVD, { "rpm", "DISALLOWED", false }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/5_0/2405/009_param_param_SUCCESS.lua b/test_scripts/Defects/5_0/2405/009_param_param_SUCCESS.lua index 69e5ee3b97..9083c8a776 100644 --- a/test_scripts/Defects/5_0/2405/009_param_param_SUCCESS.lua +++ b/test_scripts/Defects/5_0/2405/009_param_param_SUCCESS.lua @@ -9,27 +9,24 @@ local common = require('test_scripts/Defects/5_0/2405/common') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local tc = { - grp = { - [1] = { name = "Dummy-1", prompt = "Dummy_1", params = { "speed" } }, - [2] = { name = "Dummy-2", prompt = "Dummy_2", params = { "speed" } } - }, - resultCode = "SUCCESS", - success = true +local grp = { + [1] = { name = "Dummy-1", prompt = "Dummy_1", params = { "speed" } }, + [2] = { name = "Dummy-2", prompt = "Dummy_2", params = { "rpm" } } } --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { common.getHMIValues() }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register App", common.registerApp) runner.Step("Activate App", common.activateApp) -runner.Step("PolicyTableUpdate", common.policyTableUpdate, { tc }) +runner.Step("PolicyTableUpdate", common.policyTableUpdate, { grp }) runner.Title("Test") -runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { tc }) -runner.Step("Consent Groups", common.consentGroups, { tc }) -runner.Step("Send GetVehicleData", common.getVD, { tc }) +runner.Step("Send GetListOfPermissions", common.getListOfPermissions, { grp }) +runner.Step("Consent Groups", common.consentGroups, { grp }) +runner.Step("Send GetVehicleData speed", common.getVD, { "speed", "SUCCESS", true }) +runner.Step("Send GetVehicleData rpm", common.getVD, { "rpm", "SUCCESS", true }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Defects/5_0/2405/common.lua b/test_scripts/Defects/5_0/2405/common.lua index c991403d52..92e2c8b2a5 100644 --- a/test_scripts/Defects/5_0/2405/common.lua +++ b/test_scripts/Defects/5_0/2405/common.lua @@ -1,40 +1,39 @@ --------------------------------------------------------------------------------------------------- -- Common module --------------------------------------------------------------------------------------------------- +config.defaultProtocolVersion = 2 + --[[ Required Shared libraries ]] local common = require('user_modules/sequences/actions') local utils = require("user_modules/utils") -local hmi_values = require('user_modules/hmi_values') local json = require("modules/json") local m = common m.EMPTY_ARRAY = json.EMPTY_ARRAY -function m.getHMIValues() - local params = hmi_values.getDefaultHMITable() - params.RC = nil - return params -end - local ptuOrig = common.policyTableUpdate - -function m.policyTableUpdate(pTC) - local dfltGrpData = { - rpcs = { - GetVehicleData = { - hmi_levels = { "BACKGROUND", "FULL", "LIMITED" } +function m.policyTableUpdate(pGrp) + local function ptUpdate(pTbl) + local dfltGrpData = { + rpcs = { + GetVehicleData = { + hmi_levels = { "BACKGROUND", "FULL", "LIMITED" } + } } } - } - local function ptUpdate(pTbl) local fg = pTbl.policy_table.functional_groupings - for i = 1, #pTC.grp do - fg[pTC.grp[i].name] = utils.cloneTable(dfltGrpData) - fg[pTC.grp[i].name].user_consent_prompt = pTC.grp[i].prompt - fg[pTC.grp[i].name].rpcs.GetVehicleData.parameters = pTC.grp[i].params + local appId = common.getConfigAppParams().appID + if not pTbl.policy_table.app_policies[appId] then + pTbl.policy_table.app_policies[appId] = utils.cloneTable(pTbl.policy_table.app_policies.default) + end + pTbl.policy_table.app_policies[appId].groups = { "Base-4" } + for i = 1, #pGrp do + fg[pGrp[i].name] = utils.cloneTable(dfltGrpData) + fg[pGrp[i].name].user_consent_prompt = pGrp[i].prompt + fg[pGrp[i].name].rpcs.GetVehicleData.parameters = pGrp[i].params + table.insert(pTbl.policy_table.app_policies[appId].groups, pGrp[i].name) end - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].groups = { "Base-4", pTC.grp[1].name, pTC.grp[2].name } end ptuOrig(ptUpdate) end @@ -47,33 +46,39 @@ local function getGroupId(pData, pGrpName) end end -function m.getListOfPermissions(pTC) +function m.getListOfPermissions(pGrp) local rid = common.getHMIConnection():SendRequest("SDL.GetListOfPermissions") common.getHMIConnection():ExpectResponse(rid) :Do(function(_,data) - for i = 1, #pTC.grp do - pTC.grp[i].id = getGroupId(data, pTC.grp[i].prompt) - print("Grp " .. i .. " Id: ", tostring(pTC.grp[i].id)) + for i = 1, #pGrp do + pGrp[i].id = getGroupId(data, pGrp[i].prompt) + print(pGrp[i].name .. ":", tostring(pGrp[i].id)) end end) end -local function consentGroupsByAFewMsg(pTC) - for i = 1, #pTC.grp do - common.getHMIConnection():SendNotification("SDL.OnAppPermissionConsent", { - appID = common.getHMIAppId, - source = "GUI", - consentedFunctions = {{ name = pTC.grp[i].prompt, id = pTC.grp[i].id, allowed = true }} - }) +local function consentGroupsByAFewMsg(pGrp) + local count = 0 + for i = 1, #pGrp do + if pGrp[i].id then + count = count + 1 + common.getHMIConnection():SendNotification("SDL.OnAppPermissionConsent", { + appID = common.getHMIAppId, + source = "GUI", + consentedFunctions = {{ name = pGrp[i].prompt, id = pGrp[i].id, allowed = true }} + }) + end end common.getMobileSession():ExpectNotification("OnPermissionsChange") - :Times(#pTC.grp) + :Times(count) end -local function consentGroupsBySingleMsg(pTC) +local function consentGroupsBySingleMsg(pGrp) local consentedFunctions = {} - for i = 1, #pTC.grp do - table.insert(consentedFunctions, { name = pTC.grp[i].prompt, id = pTC.grp[i].id, allowed = true }) + for i = 1, #pGrp do + if pGrp[i].id then + table.insert(consentedFunctions, { name = pGrp[i].prompt, id = pGrp[i].id, allowed = true }) + end end common.getHMIConnection():SendNotification("SDL.OnAppPermissionConsent", { appID = common.getHMIAppId, @@ -83,22 +88,23 @@ local function consentGroupsBySingleMsg(pTC) common.getMobileSession():ExpectNotification("OnPermissionsChange") end -function m.consentGroups(pTC) - consentGroupsByAFewMsg(pTC) +function m.consentGroups(pGrp) + consentGroupsBySingleMsg(pGrp) end -function m.getVD(pTC) - local cid = common.getMobileSession():SendRPC("GetVehicleData", { speed = true }) - if pTC.success == true then +function m.getVD(pParam, pResultCode, pSuccess) + local valMap = { + speed = 1.11, + rpm = 222 + } + local cid = common.getMobileSession():SendRPC("GetVehicleData", { [pParam] = true }) + if pSuccess == true then common.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData") :Do(function(_,data) - common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { speed = 1.11 }) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { [pParam] = valMap[pParam] }) end) end - common.getMobileSession():ExpectResponse(cid, { success = pTC.success, resultCode = pTC.resultCode }) - :Do(function(_, data) - utils.printTable(data.payload) - end) + common.getMobileSession():ExpectResponse(cid, { success = pSuccess, resultCode = pResultCode }) end return m From 5500d4e40fac8b74cc65d6b56b61fff65aca2f3f Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 13 Aug 2018 16:02:39 +0300 Subject: [PATCH 534/681] Rename scripts --- ...y_param_SUCCESS.lua => 006_empty_param_SUCCESS_DISALLOWED.lua} | 0 ...m_empty_SUCCESS.lua => 008_param_empty_SUCCESS_DISALLOWED.lua} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename test_scripts/Defects/5_0/2405/{006_empty_param_SUCCESS.lua => 006_empty_param_SUCCESS_DISALLOWED.lua} (100%) rename test_scripts/Defects/5_0/2405/{008_param_empty_SUCCESS.lua => 008_param_empty_SUCCESS_DISALLOWED.lua} (100%) diff --git a/test_scripts/Defects/5_0/2405/006_empty_param_SUCCESS.lua b/test_scripts/Defects/5_0/2405/006_empty_param_SUCCESS_DISALLOWED.lua similarity index 100% rename from test_scripts/Defects/5_0/2405/006_empty_param_SUCCESS.lua rename to test_scripts/Defects/5_0/2405/006_empty_param_SUCCESS_DISALLOWED.lua diff --git a/test_scripts/Defects/5_0/2405/008_param_empty_SUCCESS.lua b/test_scripts/Defects/5_0/2405/008_param_empty_SUCCESS_DISALLOWED.lua similarity index 100% rename from test_scripts/Defects/5_0/2405/008_param_empty_SUCCESS.lua rename to test_scripts/Defects/5_0/2405/008_param_empty_SUCCESS_DISALLOWED.lua From f4a42b249b7f1f34ea29141230c898a5f9272a67 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Mon, 13 Aug 2018 14:39:31 -0400 Subject: [PATCH 535/681] Update PTS to accept full_app_id_supported --- .../shared_testcases/testCasesForPolicyTableSnapshot.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua b/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua index e0be2c392f..bfd0c980d5 100644 --- a/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua +++ b/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua @@ -135,6 +135,7 @@ function testCasesForPolicyTableSnapshot:verify_PTS(is_created, app_IDs, device_ { name = "module_config.vehicle_model", elem_required = "optional"}, { name = "module_config.vehicle_year", elem_required = "optional"}, { name = "module_config.display_order", elem_required = "optional"}, + { name = "module_config.full_app_id_supported", elem_required = "required"}, { name = "consumer_friendly_messages.version", elem_required = "required"}, From 0fd769042bd016db1eba974e96dc7f41823aa839 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Mon, 13 Aug 2018 14:59:54 -0400 Subject: [PATCH 536/681] Fix test script to check for correct parameter --- ...egister_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/Policies/build_options/095_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua b/test_scripts/Policies/build_options/095_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua index 5f85517a80..ac28d6dfcf 100644 --- a/test_scripts/Policies/build_options/095_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/095_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua @@ -155,7 +155,7 @@ function Test:TestStep_CheckThatAppID_Present_In_DataBase() if r[1] then wait = false end end - local sql = table.concat({"SELECT 1 FROM application WHERE id = '", tostring(registerAppInterfaceParams.fullAppID), "'"}) + local sql = table.concat({"SELECT 1 FROM application WHERE id = '", tostring(registerAppInterfaceParams.appID), "'"}) print(sql) local r_actual = commonFunctions:get_data_policy_sql(PolicyDBPath, sql) if r_actual[1] == nil then From 7691dc455453dcdf5c2f946260f67c91e5f727a8 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Mon, 13 Aug 2018 15:09:42 -0400 Subject: [PATCH 537/681] Update script to check for correct parameter --- ...ister_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_scripts/Policies/build_options/114_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua b/test_scripts/Policies/build_options/114_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua index 9e88403dc9..e2b4ea7925 100644 --- a/test_scripts/Policies/build_options/114_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/114_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua @@ -125,8 +125,8 @@ function Test:TestStep_CheckThatAppID_Present_In_DataBase() commonFunctions:userPrint(31, "policy.sqlite file is not found") self:FailTestCase("PolicyTable is not avaliable " .. tostring(PolicyDBPath)) end - local select_value = "SELECT id FROM application WHERE id = '"..tostring(registerAppInterfaceParams.fullAppID).."'" - local result = commonFunctions:is_db_contains(PolicyDBPath, select_value, {tostring(registerAppInterfaceParams.fullAppID)}) + local select_value = "SELECT id FROM application WHERE id = '"..tostring(registerAppInterfaceParams.appID).."'" + local result = commonFunctions:is_db_contains(PolicyDBPath, select_value, {tostring(registerAppInterfaceParams.appID)}) if result == false then self:FailTestCase("DB doesn't contain special id") end From ac790d2c76aad7cc9962360adcc3e00180a70c18 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Mon, 13 Aug 2018 19:48:26 -0400 Subject: [PATCH 538/681] Fix common file to not update preloaded_pt --- test_scripts/SDL4_6/FullAppID/common.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/SDL4_6/FullAppID/common.lua b/test_scripts/SDL4_6/FullAppID/common.lua index 6a123556e5..ada76ac053 100644 --- a/test_scripts/SDL4_6/FullAppID/common.lua +++ b/test_scripts/SDL4_6/FullAppID/common.lua @@ -29,7 +29,6 @@ function m.preconditions() -- Delete log files commonSteps:DeleteLogsFiles() commonPreconditions:BackupFile(preloadedPT) - commonSmoke.updatePreloadedPT() end -- Allow device from HMI @@ -292,6 +291,7 @@ end function m.postconditions() actions.restoreSDLIniParameters() StopSDL() + commonPreconditions:RestoreFile(preloadedPT) end return m From 184febe59fae67a215dffe25da347f172d08bd31 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 14 Aug 2018 14:39:43 +0300 Subject: [PATCH 539/681] Changes regarding 'Revise Updating DOP value range' --- .../003_GetVD_gps_mandatory_parameters.lua | 100 +++++++++++++++ .../004_OnVD_gps_mandatory_parameters.lua | 115 ++++++++++++++++++ .../API/VehicleData/commonVehicleData.lua | 18 +-- test_sets/VehicleData.txt | 2 + 4 files changed, 226 insertions(+), 9 deletions(-) create mode 100644 test_scripts/API/VehicleData/GetVehicleData/003_GetVD_gps_mandatory_parameters.lua create mode 100644 test_scripts/API/VehicleData/OnVehicleData/004_OnVD_gps_mandatory_parameters.lua diff --git a/test_scripts/API/VehicleData/GetVehicleData/003_GetVD_gps_mandatory_parameters.lua b/test_scripts/API/VehicleData/GetVehicleData/003_GetVD_gps_mandatory_parameters.lua new file mode 100644 index 0000000000..fec6e7ca75 --- /dev/null +++ b/test_scripts/API/VehicleData/GetVehicleData/003_GetVD_gps_mandatory_parameters.lua @@ -0,0 +1,100 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TO ADD !!! +-- Use case: TO ADD !!! +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [GetVehicleData] As a mobile app wants to send a request to get the details of the vehicle data +-- +-- Description: +-- In case: +-- mobile application sends valid GetVehicleData to SDL and this request is allowed by Policies +-- SDL must: +-- 1) Transfer this request to HMI +-- 2) After successful response from hmi with all mandatory parameters +-- respond SUCCESS, success:true and resend parameter values received from HMI to mobile application +-- 3) After response from HMI with missed mandatory parameters +-- respond success:false, GENERIC_ERROR +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') + +--[[ Local Variables ]] +local rpc = { + name = "GetVehicleData", + params = { + gps = true + } +} + +local vehicleDataValues = { + allData = { + longitudeDegrees = 10, + latitudeDegrees = 20, + utcYear = 2010, + utcMonth = 1, + utcDay = 2, + utcHours = 3, + utcMinutes = 4, + utcSeconds = 5, + compassDirection = "NORTH", + actual = true, + satellites = 6, + dimension = "2D", + altitude = 7, + heading = 8, + speed = 9, + pdop = 10, + hdop = 11, + vdop = 12 + }, + mandatoryOnly = { + longitudeDegrees = 10, + latitudeDegrees = 20 + } +} + +local vehicleDataValuesMissedMandatory = { + missedAll = { utcYear = 2010 }, + missedLongitude = { latitudeDegrees = 20 }, + missedLatitude = { longitudeDegrees = 10 } +} + +--[[ Local Functions ]] +local function processRPC(pParams, isSuccess, self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc.name, rpc.params) + EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { gps = pParams }) + end) + if isSuccess == true then + local responseParams = {} + responseParams.gps = pParams + responseParams.success = true + responseParams.resultCode = "SUCCESS" + mobileSession:ExpectResponse(cid, responseParams) + else + mobileSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Invalid message received from vehicle" }) + end +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for key, value in pairs(vehicleDataValues) do + runner.Step("RPC GetVehicleData gps " .. key, processRPC, { value, true }) +end +for key, value in pairs(vehicleDataValuesMissedMandatory) do + runner.Step("RPC GetVehicleData gps " .. key, processRPC, { value, false }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/VehicleData/OnVehicleData/004_OnVD_gps_mandatory_parameters.lua b/test_scripts/API/VehicleData/OnVehicleData/004_OnVD_gps_mandatory_parameters.lua new file mode 100644 index 0000000000..2cfe745fb0 --- /dev/null +++ b/test_scripts/API/VehicleData/OnVehicleData/004_OnVD_gps_mandatory_parameters.lua @@ -0,0 +1,115 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TO ADD !!! +-- Use case: TO ADD !!! +-- Item: Use Case 1: TO ADD!!! +-- +-- Requirement summary: +-- [OnVehicleData] As a mobile app is subscribed for VI parameter +-- and received notification about this parameter change from hmi +-- +-- Description: +-- In case: +-- 1) If application is subscribed to get vehicle data with 'engineOilLife' parameter +-- 2) Notification about changes with mandatory parameters is received from hmi +-- 3) Notification about changes without mandatory parameters is received from hmi +-- SDL must: +-- 1) Forward this notification to mobile application +-- 2) Not forward this notification to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') + +--[[ Local Variables ]] +local rpc1 = { + name = "SubscribeVehicleData", + params = { + gps = true + } +} + +local vehicleDataResults = { + engineOilLife = { + dataType = "VEHICLEDATA_GPS", + resultCode = "SUCCESS" + } +} + +local vehicleDataValues = { + allData = { + longitudeDegrees = 10, + latitudeDegrees = 20, + utcYear = 2010, + utcMonth = 1, + utcDay = 2, + utcHours = 3, + utcMinutes = 4, + utcSeconds = 5, + compassDirection = "NORTH", + actual = true, + satellites = 6, + dimension = "2D", + altitude = 7, + heading = 8, + speed = 9, + pdop = 10, + hdop = 11, + vdop = 12 + }, + mandatoryOnly = { + longitudeDegrees = 10, + latitudeDegrees = 20 + } +} + +local vehicleDataValuesMissedMandatory = { + missedAll = { utcYear = 2010 }, + missedLongitude = { latitudeDegrees = 20 }, + missedLatitude = { longitudeDegrees = 10 } +} + +--[[ Local Functions ]] +local function processRPCSubscribeSuccess(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc1.name, rpc1.params) + EXPECT_HMICALL("VehicleInfo." .. rpc1.name, rpc1.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", vehicleDataResults) + end) + + local responseParams = vehicleDataResults + responseParams.success = true + responseParams.resultCode = "SUCCESS" + mobileSession:ExpectResponse(cid, responseParams) +end + +local function checkNotification(pParams, isNotificationExpect, self) + local mobileSession = common.getMobileSession(self, 1) + self.hmiConnection:SendNotification("VehicleInfo.OnVehicleData", { gps = pParams }) + if isNotificationExpect == true then + mobileSession:ExpectNotification("OnVehicleData", { gps = pParams }) + else + mobileSession:ExpectNotification("OnVehicleData") + :Times(0) + end +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU) +runner.Step("Activate App", common.activateApp) +runner.Step("SubscribeVehicleData gps", processRPCSubscribeSuccess) + +runner.Title("Test") +for key, value in pairs(vehicleDataValues) do + runner.Step("RPC OnVehicleData gps " .. key, checkNotification, { value, true }) +end +for key, value in pairs(vehicleDataValuesMissedMandatory) do + runner.Step("RPC OnVehicleData gps " .. key, checkNotification, { value, false }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/VehicleData/commonVehicleData.lua b/test_scripts/API/VehicleData/commonVehicleData.lua index 10ad54554e..d91a8a69d3 100644 --- a/test_scripts/API/VehicleData/commonVehicleData.lua +++ b/test_scripts/API/VehicleData/commonVehicleData.lua @@ -56,7 +56,6 @@ local function jsonFileToTable(file_name) return json.decode(content) end - local function addParamToRPC(tbl, functional_grouping, rpc, param) local is_found = false local params = tbl.policy_table.functional_groupings[functional_grouping].rpcs[rpc].parameters @@ -87,13 +86,14 @@ local function ptu(self, app_id, ptu_update_func) self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = pts_file_name }) getPTUFromPTS(ptu_table) - local function updatePTU(tbl) + local function updatePTU(tbl) for rpc in pairs(tbl.policy_table.functional_groupings["Emergency-1"].rpcs) do addParamToRPC(tbl, "Emergency-1", rpc, "engineOilLife") addParamToRPC(tbl, "Emergency-1", rpc, "fuelRange") addParamToRPC(tbl, "Emergency-1", rpc, "tirePressure") addParamToRPC(tbl, "Emergency-1", rpc, "electronicParkBrakeStatus") addParamToRPC(tbl, "Emergency-1", rpc, "turnSignal") + addParamToRPC(tbl, "Emergency-1", rpc, "gps") end tbl.policy_table.app_policies[commonVehicleData.getMobileAppId(app_id)] = commonVehicleData.getGetVehicleDataConfig() end @@ -260,13 +260,13 @@ end local function allowSDL(self) self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { - allowed = true, - source = "GUI", - device = { - id = commonVehicleData.getDeviceMAC(), - name = commonVehicleData.getDeviceName() - } - }) + allowed = true, + source = "GUI", + device = { + id = commonVehicleData.getDeviceMAC(), + name = commonVehicleData.getDeviceName() + } + }) end function commonVehicleData.start(pHMIParams, self) diff --git a/test_sets/VehicleData.txt b/test_sets/VehicleData.txt index 47082138a0..8f55f8df92 100644 --- a/test_sets/VehicleData.txt +++ b/test_sets/VehicleData.txt @@ -1,8 +1,10 @@ ./test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua ./test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +./test_scripts/API/VehicleData/GetVehicleData/003_GetVD_gps_mandatory_parameters.lua ./test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua ./test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua ;./test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua +./test_scripts/API/VehicleData/OnVehicleData/004_OnVD_gps_mandatory_parameters.lua ./test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua ;./test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua ;./test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua From 6c926ddeffd1860f092eb4e1b04d415b5fa968fb Mon Sep 17 00:00:00 2001 From: Jacob Keeler Date: Tue, 14 Aug 2018 15:59:17 -0400 Subject: [PATCH 540/681] Fix copy-paste error --- .../OnVehicleData/004_OnVD_gps_mandatory_parameters.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_scripts/API/VehicleData/OnVehicleData/004_OnVD_gps_mandatory_parameters.lua b/test_scripts/API/VehicleData/OnVehicleData/004_OnVD_gps_mandatory_parameters.lua index 2cfe745fb0..eb26ec9251 100644 --- a/test_scripts/API/VehicleData/OnVehicleData/004_OnVD_gps_mandatory_parameters.lua +++ b/test_scripts/API/VehicleData/OnVehicleData/004_OnVD_gps_mandatory_parameters.lua @@ -9,7 +9,7 @@ -- -- Description: -- In case: --- 1) If application is subscribed to get vehicle data with 'engineOilLife' parameter +-- 1) If application is subscribed to get vehicle data with 'gps' parameter -- 2) Notification about changes with mandatory parameters is received from hmi -- 3) Notification about changes without mandatory parameters is received from hmi -- SDL must: @@ -30,7 +30,7 @@ local rpc1 = { } local vehicleDataResults = { - engineOilLife = { + gps = { dataType = "VEHICLEDATA_GPS", resultCode = "SUCCESS" } From 307bfb7137029bd4ebc3e3de689fc83abb9f5e1f Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 14 Aug 2018 17:27:04 -0400 Subject: [PATCH 541/681] Fix for 031_ATF_Register_App_Interface_App_Unauthorized.lua --- files/jsons/Policies/appID_Management/ptu_0.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/files/jsons/Policies/appID_Management/ptu_0.json b/files/jsons/Policies/appID_Management/ptu_0.json index 2456b913b7..5d5f53f468 100644 --- a/files/jsons/Policies/appID_Management/ptu_0.json +++ b/files/jsons/Policies/appID_Management/ptu_0.json @@ -4,9 +4,9 @@ "0000001": "default", "123_xyz": { "groups": ["Base-6"], - "keep_context": false, + "keep_context": false, "steal_focus": false, - "default_hmi": "NONE", + "default_hmi": "NONE", "priority": "NONE", "nicknames": ["Media Application", "MediaApp"] }, @@ -15,7 +15,9 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [], + "RequestSubType": [] }, "device": { "keep_context": false, From 24c71b509fd1ab9698207b4eb5b86e1d4d7418b5 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 14 Aug 2018 17:55:08 -0400 Subject: [PATCH 542/681] Fix for 043_ATF_HMI_Status_Appid_Gets_Null_In_Case_Of_PTU.lua --- .../Policies/appID_Management/ptu_013_1.json | 10 ++- ..._Status_Appid_Gets_Null_In_Case_Of_PTU.lua | 82 ++++++++++--------- 2 files changed, 50 insertions(+), 42 deletions(-) diff --git a/files/jsons/Policies/appID_Management/ptu_013_1.json b/files/jsons/Policies/appID_Management/ptu_013_1.json index 326edc245a..4294db548d 100644 --- a/files/jsons/Policies/appID_Management/ptu_013_1.json +++ b/files/jsons/Policies/appID_Management/ptu_013_1.json @@ -4,17 +4,19 @@ "0000001": { "groups": ["Base-4", "Base-6"], "priority": "NONE", - "keep_context": false, + "keep_context": false, "steal_focus": false, - "default_hmi": "NONE", - "nicknames": ["App1"] + "default_hmi": "NONE", + "nicknames": ["App1"] }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [], + "RequestSubType": [] }, "device": { "keep_context": false, diff --git a/test_scripts/Policies/appID_Management/043_ATF_HMI_Status_Appid_Gets_Null_In_Case_Of_PTU.lua b/test_scripts/Policies/appID_Management/043_ATF_HMI_Status_Appid_Gets_Null_In_Case_Of_PTU.lua index 0560979f8c..6ed7757972 100644 --- a/test_scripts/Policies/appID_Management/043_ATF_HMI_Status_Appid_Gets_Null_In_Case_Of_PTU.lua +++ b/test_scripts/Policies/appID_Management/043_ATF_HMI_Status_Appid_Gets_Null_In_Case_Of_PTU.lua @@ -84,44 +84,50 @@ function Test:TestStep_UpdatePolicy() local file = "files/jsons/Policies/appID_Management/ptu_013_2.json" local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATING" }, { status = "UP_TO_DATE" }):Times(2) - local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(requestId) - :Do(function() - - self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }) - - local request_received = false - - -- Steps in case OnSystemRequest is sent to application 1 - self.mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }):Times(Between(0,1)) - :Do(function() - print("OnSystemRequest for App1 is received") - if(request_received == true) then - self:FailTestCase("OnSystemRequest already received for application 2") - end - request_received = true - local corIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }, file) - self.mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS"}) - end) - - -- Steps in case OnSystemRequest is sent to application 2 - self.mobileSession2:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }):Times(Between(0,1)) - :Do(function() - print("OnSystemRequest for App2 is received") - if(request_received == true) then - self:FailTestCase("OnSystemRequest already received for application 1") - end - request_received = true - local corIdSystemRequest = self.mobileSession2:SendRPC("SystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }, file) - self.mobileSession2:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS"}) - end) - - EXPECT_HMICALL("BasicCommunication.SystemRequest",{requestType = "PROPRIETARY", fileName = policy_file_path.."/"..policy_file_name },file) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, "BasicCommunication.SystemRequest", "SUCCESS", {}) - self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = policy_file_path.."/"..policy_file_name} ) - end) + EXPECT_HMICALL("BasicCommunication.PolicyUpdate", + { + file = "/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json" + }) + :Do(function(_, data1) + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATING" }, { status = "UP_TO_DATE" }):Times(2) + self.hmiConnection:SendResponse(data1.id, data1.method, "SUCCESS", {}) + local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) + EXPECT_HMIRESPONSE(requestId) + :Do(function() + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }) + + local request_received = false + + -- Steps in case OnSystemRequest is sent to application 1 + self.mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }):Times(Between(0,1)) + :Do(function() + print("OnSystemRequest for App1 is received") + if(request_received == true) then + self:FailTestCase("OnSystemRequest already received for application 2") + end + request_received = true + local corIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }, file) + self.mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS"}) + end) + + -- Steps in case OnSystemRequest is sent to application 2 + self.mobileSession2:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }):Times(Between(0,1)) + :Do(function() + print("OnSystemRequest for App2 is received") + if(request_received == true) then + self:FailTestCase("OnSystemRequest already received for application 1") + end + request_received = true + local corIdSystemRequest = self.mobileSession2:SendRPC("SystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }, file) + self.mobileSession2:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS"}) + end) + + EXPECT_HMICALL("BasicCommunication.SystemRequest",{requestType = "PROPRIETARY", fileName = policy_file_path.."/"..policy_file_name },file) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, "BasicCommunication.SystemRequest", "SUCCESS", {}) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = policy_file_path.."/"..policy_file_name} ) + end) + end) end) EXPECT_HMINOTIFICATION("SDL.OnAppPermissionChanged", { appID = HMIAppID, appRevoked = true}) From f25462869ada5f2b299c4a5ec0dc806eae0712fa Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 14 Aug 2018 19:43:16 -0400 Subject: [PATCH 543/681] Remove wrong RPC expectation App is activated by means of SDL.ActivateApp request from the HMI instead. --- user_modules/shared_testcases/testCasesForPolicyTable.lua | 3 --- 1 file changed, 3 deletions(-) diff --git a/user_modules/shared_testcases/testCasesForPolicyTable.lua b/user_modules/shared_testcases/testCasesForPolicyTable.lua index 39b16bb851..1138340a11 100644 --- a/user_modules/shared_testcases/testCasesForPolicyTable.lua +++ b/user_modules/shared_testcases/testCasesForPolicyTable.lua @@ -1047,9 +1047,6 @@ function testCasesForPolicyTable:trigger_getting_device_consent(self, app_name, end) end) - EXPECT_HMICALL("BasicCommunication.ActivateApp") - :Do(function(_,data) self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) end) - EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "FULL", systemContext = "MAIN"}) end From 98133e2a45edff53c7609ca244ce1fc5e61b10d5 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 14 Aug 2018 20:00:20 -0400 Subject: [PATCH 544/681] Update Activate App expectation --- user_modules/shared_testcases/testCasesForPolicyTable.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/user_modules/shared_testcases/testCasesForPolicyTable.lua b/user_modules/shared_testcases/testCasesForPolicyTable.lua index 1138340a11..c180ef1826 100644 --- a/user_modules/shared_testcases/testCasesForPolicyTable.lua +++ b/user_modules/shared_testcases/testCasesForPolicyTable.lua @@ -1046,6 +1046,8 @@ function testCasesForPolicyTable:trigger_getting_device_consent(self, app_name, self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) end) + EXPECT_HMICALL("BasicCommunication.ActivateApp"):Times(Between(0,1)) + :Do(function(_,data) self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) end) EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "FULL", systemContext = "MAIN"}) end From 10e1c782646a2ad3a98f4993c5c246cdf86089c4 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 14 Aug 2018 20:05:13 -0400 Subject: [PATCH 545/681] Update policy table to contain requestType --- .../jsons/Policies/Policy_Table_Update/endpoints_appId.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/files/jsons/Policies/Policy_Table_Update/endpoints_appId.json b/files/jsons/Policies/Policy_Table_Update/endpoints_appId.json index ca979ea968..ef216abf0a 100644 --- a/files/jsons/Policies/Policy_Table_Update/endpoints_appId.json +++ b/files/jsons/Policies/Policy_Table_Update/endpoints_appId.json @@ -14,7 +14,7 @@ "endpoints": { "0x07": { "default": ["http://policies.telematics.ford.com/api/policies"], - "0000001": ["http://policies.telematics.ford.com/api/test_apllication"] + "0000001": ["http://policies.telematics.ford.com/api/test_apllication"] }, "0x04": { "default": ["http://ivsu.software.ford.com/api/getsoftwareupdates"] @@ -2246,7 +2246,9 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [], + "RequestSubType": [] }, "device": { "keep_context": false, From 178e2c045a94e445f6e2ff220ec780765823cca8 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 14 Aug 2018 20:13:35 -0400 Subject: [PATCH 546/681] Add projection notification --- .../shared_testcases/testCasesForPolicyTableSnapshot.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua b/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua index bfd0c980d5..372188aea0 100644 --- a/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua +++ b/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua @@ -130,6 +130,7 @@ function testCasesForPolicyTableSnapshot:verify_PTS(is_created, app_IDs, device_ { name = "module_config.notifications_per_minute_by_priority.COMMUNICATION", elem_required = "required"}, { name = "module_config.notifications_per_minute_by_priority.NORMAL", elem_required = "required"}, { name = "module_config.notifications_per_minute_by_priority.NONE", elem_required = "required"}, + { name = "module_config.notifications_per_minute_by_priority.PROJECTION", elem_required = "required"}, { name = "module_config.certificate", elem_required = "optional"}, { name = "module_config.vehicle_make", elem_required = "optional"}, { name = "module_config.vehicle_model", elem_required = "optional"}, From fc9621f63ee483a910868c7e49ec446ce466b60e Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 14 Aug 2018 20:26:45 -0400 Subject: [PATCH 547/681] Fix for 145_ATF_PTU_Merge_Into_LPT.lua --- .../ptu_file_with_full_app_id_supported.json | 987 ++++++++++++++++++ .../145_ATF_PTU_Merge_Into_LPT.lua | 3 +- 2 files changed, 989 insertions(+), 1 deletion(-) create mode 100644 files/jsons/Policies/Policy_Table_Update/ptu_file_with_full_app_id_supported.json diff --git a/files/jsons/Policies/Policy_Table_Update/ptu_file_with_full_app_id_supported.json b/files/jsons/Policies/Policy_Table_Update/ptu_file_with_full_app_id_supported.json new file mode 100644 index 0000000000..ce6100a0f8 --- /dev/null +++ b/files/jsons/Policies/Policy_Table_Update/ptu_file_with_full_app_id_supported.json @@ -0,0 +1,987 @@ +{ + "policy_table": { + "app_policies": { + "0000001": { + "keep_context": true, + "steal_focus": true, + "priority": "NONE", + "default_hmi": "NONE", + "groups": ["Base-4", "Base-6"], + "heart_beat_timeout_ms": 0, + "memory_kb": 0, + "nicknames": ["Test Application"] + }, + "default": { + "keep_context": false, + "steal_focus": false, + "priority": "NONE", + "default_hmi": "NONE", + "groups": ["Base-4"] + }, + "device": { + "keep_context": false, + "steal_focus": false, + "priority": "NONE", + "default_hmi": "NONE", + "groups": ["DataConsent-2"] + }, + "pre_DataConsent": { + "keep_context": false, + "steal_focus": false, + "priority": "NONE", + "default_hmi": "NONE", + "groups": ["BaseBeforeDataConsent"] + } + }, + "functional_groupings": { + "BackgroundAPT": { + "rpcs": { + "EndAudioPassThru": { + "hmi_levels": [ + "BACKGROUND" + ] + }, + "OnAudioPassThru": { + "hmi_levels": [ + "BACKGROUND" + ] + }, + "PerformAudioPassThru": { + "hmi_levels": [ + "BACKGROUND" + ] + } + } + }, + "Base-4": { + "rpcs": { + "AddCommand": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "AddSubMenu": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "OnHMIStatus": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnSystemRequest": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + } + } + }, + "Base-6": { + "rpcs": { + "AddCommand": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "AddSubMenu": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "Alert": { + "hmi_levels": [ + "FULL", + "LIMITED" + ] + }, + "ChangeRegistration": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "CreateInteractionChoiceSet": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "DeleteCommand": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "DeleteFile": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "DeleteInteractionChoiceSet": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "DeleteSubMenu": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "EncodedSyncPData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "EndAudioPassThru": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "GenericResponse": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "ListFiles": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnAppInterfaceUnregistered": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnAudioPassThru": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "OnButtonEvent": { + "hmi_levels": [ + "FULL", + "LIMITED" + ] + }, + "OnButtonPress": { + "hmi_levels": [ + "FULL", + "LIMITED" + ] + }, + "OnCommand": { + "hmi_levels": [ + "FULL", + "LIMITED" + ] + }, + "OnDriverDistraction": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "OnEncodedSyncPData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnHMIStatus": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnLanguageChange": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnPermissionsChange": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnSyncPData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnTBTClientState": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "PerformAudioPassThru": { + "hmi_levels": [ + "FULL", + "LIMITED" + ] + }, + "PerformInteraction": { + "hmi_levels": [ + "FULL", + "LIMITED" + ] + }, + "PutFile": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "RegisterAppInterface": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "ResetGlobalProperties": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "ScrollableMessage": { + "hmi_levels": [ + "FULL" + ] + }, + "SetAppIcon": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "SetDisplayLayout": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "SetGlobalProperties": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "SetMediaClockTimer": { + "hmi_levels": [ + "FULL" + ] + }, + "Show": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "Slider": { + "hmi_levels": [ + "FULL" + ] + }, + "Speak": { + "hmi_levels": [ + "FULL", + "LIMITED" + ] + }, + "SubscribeButton": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "SyncPData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "UnregisterAppInterface": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "UnsubscribeButton": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + } + } + }, + "BaseBeforeDataConsent": { + "rpcs": { + "ChangeRegistration": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "DeleteFile": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "EncodedSyncPData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "ListFiles": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnAppInterfaceUnregistered": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnEncodedSyncPData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnHMIStatus": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnHashChange": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnLanguageChange": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnPermissionsChange": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "OnSystemRequest": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "PutFile": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "RegisterAppInterface": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "ResetGlobalProperties": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "SetAppIcon": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "SetDisplayLayout": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "SetGlobalProperties": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "SystemRequest": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "UnregisterAppInterface": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + } + } + }, + "DataConsent-2": { + "rpcs": null, + "user_consent_prompt": "DataConsent" + }, + "DiagnosticMessageOnly": { + "rpcs": { + "DiagnosticMessage": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + } + } + }, + "DrivingCharacteristics-3": { + "rpcs": { + "GetVehicleData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ], + "parameters": [ + "accPedalPosition", + "beltStatus", + "driverBraking", + "myKey", + "prndl", + "rpm", + "steeringWheelAngle" + ] + }, + "OnVehicleData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ], + "parameters": [ + "accPedalPosition", + "beltStatus", + "driverBraking", + "myKey", + "prndl", + "rpm", + "steeringWheelAngle" + ] + }, + "SubscribeVehicleData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ], + "parameters": [ + "accPedalPosition", + "beltStatus", + "driverBraking", + "myKey", + "prndl", + "rpm", + "steeringWheelAngle" + ] + }, + "UnsubscribeVehicleData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ], + "parameters": [ + "accPedalPosition", + "beltStatus", + "driverBraking", + "myKey", + "prndl", + "rpm", + "steeringWheelAngle" + ] + } + }, + "user_consent_prompt": "DrivingCharacteristics" + }, + "Emergency-1": { + "rpcs": { + "GetVehicleData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ], + "parameters": [ + "airbagStatus", + "clusterModeStatus", + "eCallInfo", + "emergencyEvent" + ] + }, + "OnVehicleData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ], + "parameters": [ + "airbagStatus", + "clusterModeStatus", + "eCallInfo", + "emergencyEvent" + ] + }, + "SubscribeVehicleData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ], + "parameters": [ + "airbagStatus", + "clusterModeStatus", + "eCallInfo", + "emergencyEvent" + ] + }, + "UnsubscribeVehicleData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ], + "parameters": [ + "airbagStatus", + "clusterModeStatus", + "eCallInfo", + "emergencyEvent" + ] + } + } + }, + "Location-1": { + "rpcs": { + "GetVehicleData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ], + "parameters": [ + "gps", + "speed" + ] + }, + "OnVehicleData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ], + "parameters": [ + "gps", + "speed" + ] + }, + "SubscribeVehicleData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ], + "parameters": [ + "gps", + "speed" + ] + }, + "UnsubscribeVehicleData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ], + "parameters": [ + "gps", + "speed" + ] + } + }, + "user_consent_prompt": "Location" + }, + "Navigation-1": { + "rpcs": { + "AlertManeuver": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "ShowConstantTBT": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "UpdateTurnList": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + } + } + }, + "Notifications": { + "rpcs": { + "Alert": { + "hmi_levels": [ + "BACKGROUND" + ] + } + }, + "user_consent_prompt": "Notifications" + }, + "OnKeyboardInputOnlyGroup": { + "rpcs": { + "OnKeyboardInput": { + "hmi_levels": [ + "FULL" + ] + } + } + }, + "OnTouchEventOnlyGroup": { + "rpcs": { + "OnTouchEvent": { + "hmi_levels": [ + "FULL" + ] + } + } + }, + "PropriataryData-1": { + "rpcs": { + "DiagnosticMessage": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "GetDTCs": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "ReadDID": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + } + } + }, + "PropriataryData-2": { + "rpcs": { + "DiagnosticMessage": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "GetDTCs": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "ReadDID": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + } + } + }, + "ProprietaryData-3": { + "rpcs": { + "GetDTCs": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + }, + "ReadDID": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + } + } + }, + "SendLocation": { + "rpcs": { + "SendLocation": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ] + } + } + }, + "VehicleInfo-3": { + "rpcs": { + "GetVehicleData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ], + "parameters": [ + "bodyInformation", + "deviceStatus", + "engineTorque", + "externalTemperature", + "fuelLevel", + "fuelLevel_State", + "headLampStatus", + "instantFuelConsumption", + "odometer", + "tirePressure", + "vin", + "wiperStatus" + ] + }, + "OnVehicleData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ], + "parameters": [ + "bodyInformation", + "deviceStatus", + "engineTorque", + "externalTemperature", + "fuelLevel", + "fuelLevel_State", + "headLampStatus", + "instantFuelConsumption", + "odometer", + "tirePressure", + "vin", + "wiperStatus" + ] + }, + "SubscribeVehicleData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ], + "parameters": [ + "bodyInformation", + "deviceStatus", + "engineTorque", + "externalTemperature", + "fuelLevel", + "fuelLevel_State", + "headLampStatus", + "instantFuelConsumption", + "odometer", + "tirePressure", + "wiperStatus" + ] + }, + "UnsubscribeVehicleData": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED" + ], + "parameters": [ + "bodyInformation", + "deviceStatus", + "engineTorque", + "externalTemperature", + "fuelLevel", + "fuelLevel_State", + "headLampStatus", + "instantFuelConsumption", + "odometer", + "tirePressure", + "wiperStatus" + ] + } + }, + "user_consent_prompt": "VehicleInfo" + } + }, + "module_config": { + "endpoints": { + "Updated_endpoints": { + "default": [ + "http://i.imgur.com/QwZ9uKG.png" + ] + } + }, + "exchange_after_x_ignition_cycles": 100, + "exchange_after_x_kilometers": 1800, + "exchange_after_x_days": 30, + "timeout_after_x_seconds": 60, + "notifications_per_minute_by_priority": { + "COMMUNICATION": 5, + "EMERGENCY": 5, + "NAVIGATION": 5, + "NONE": 5, + "NORMAL": 5, + "VOICECOM": 5 + }, + "seconds_between_retries": [ + 5, + 5, + 5, + 5, + 5 + ], + "full_app_id_supported": true + } + } +} + diff --git a/test_scripts/Policies/Policy_Table_Update/145_ATF_PTU_Merge_Into_LPT.lua b/test_scripts/Policies/Policy_Table_Update/145_ATF_PTU_Merge_Into_LPT.lua index 3eb7089885..6c84b7052d 100644 --- a/test_scripts/Policies/Policy_Table_Update/145_ATF_PTU_Merge_Into_LPT.lua +++ b/test_scripts/Policies/Policy_Table_Update/145_ATF_PTU_Merge_Into_LPT.lua @@ -32,6 +32,7 @@ local utils = require ('user_modules/utils') local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") local policy_file_name = "PolicyTableUpdate" local ptu_file = "files/jsons/Policies/Policy_Table_Update/ptu_18190.json" +local pts_file_with_full_app_id_supported = "files/jsons/Policies/Policy_Table_Update/ptu_file_with_full_app_id_supported.json" --"files/ptu_general.json") --[[ Local Functions ]] @@ -155,7 +156,7 @@ end function Test:TestStep_ValidateResult() local pts = json_to_table(policy_file_path .. "/sdl_snapshot.json") - local ptu = json_to_table(ptu_file) + local ptu = json_to_table(pts_file_with_full_app_id_supported) -- Reconcile expected vs actual ptu.policy_table.module_config.preloaded_pt = false ptu.policy_table.app_policies["0000002"] = "default" From bba129dbf54ac94934d76d59c09750cb8dfda9d1 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 14 Aug 2018 20:50:32 -0400 Subject: [PATCH 548/681] Update ptu to contain requestType --- files/PTU_NewPermissionsForUserConsent.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/files/PTU_NewPermissionsForUserConsent.json b/files/PTU_NewPermissionsForUserConsent.json index c05e831112..ff75660faa 100644 --- a/files/PTU_NewPermissionsForUserConsent.json +++ b/files/PTU_NewPermissionsForUserConsent.json @@ -2293,7 +2293,9 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [], + "RequestSubType": [] }, "device": { "keep_context": false, From 83fbecb25ba1355123aa51ad048c6b836e63eaa6 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 14 Aug 2018 21:04:35 -0400 Subject: [PATCH 549/681] Add request type to policy tables --- .../OnAppPermissionConsent_1.json | 24 ++++++++++--------- ...preloaded_pt_AlertOnlyNotifications_1.json | 6 +++-- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/files/jsons/Policies/user_consent/OnAppPermissionConsent_1.json b/files/jsons/Policies/user_consent/OnAppPermissionConsent_1.json index 544ec9c408..c07854a8c4 100644 --- a/files/jsons/Policies/user_consent/OnAppPermissionConsent_1.json +++ b/files/jsons/Policies/user_consent/OnAppPermissionConsent_1.json @@ -297,7 +297,7 @@ "LIMITED", "NONE"] }, - "DiagnosticMessage": { + "DiagnosticMessage": { "hmi_levels": ["BACKGROUND", "FULL", "LIMITED"] @@ -2243,21 +2243,23 @@ } }, "app_policies": { - "0000001": { - "keep_context": false, - "steal_focus": false, - "priority": "NONE", - "default_hmi": "NONE", - "groups": [ - "Base-4", "Notifications", "Location-1" - ] - }, + "0000001": { + "keep_context": false, + "steal_focus": false, + "priority": "NONE", + "default_hmi": "NONE", + "groups": [ + "Base-4", "Notifications", "Location-1" + ] + }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [], + "RequestSubType": [] }, "device": { "keep_context": false, diff --git a/files/sdl_preloaded_pt_AlertOnlyNotifications_1.json b/files/sdl_preloaded_pt_AlertOnlyNotifications_1.json index e9418c7f5a..3cecb6a16d 100644 --- a/files/sdl_preloaded_pt_AlertOnlyNotifications_1.json +++ b/files/sdl_preloaded_pt_AlertOnlyNotifications_1.json @@ -294,7 +294,7 @@ "Alert": { "hmi_levels": ["BACKGROUND"] }, - "DiagnosticMessage": { + "DiagnosticMessage": { "hmi_levels": ["BACKGROUND", "FULL", "LIMITED"] @@ -2252,7 +2252,9 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", - "groups": ["Base-4"] + "groups": ["Base-4"], + "RequestType": [], + "RequestSubType": [] }, "device": { "keep_context": false, From 820e2ffb628a24b153e81220adcc2626cf3df6ce Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 15 Aug 2018 10:02:53 +0300 Subject: [PATCH 550/681] Description updated, added additional step in script with partially RPC processing --- .../LowVoltage/001_Low_Voltage_and_Wake_Up.lua | 2 +- ...05_Low_Voltage_and_Wake_Up_RPC_in_progress.lua | 15 +++++++++++++-- ...evel_without_disconnect_before_low_voltage.lua | 2 +- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/test_scripts/LowVoltage/001_Low_Voltage_and_Wake_Up.lua b/test_scripts/LowVoltage/001_Low_Voltage_and_Wake_Up.lua index 1361dbf987..fa38332a5b 100644 --- a/test_scripts/LowVoltage/001_Low_Voltage_and_Wake_Up.lua +++ b/test_scripts/LowVoltage/001_Low_Voltage_and_Wake_Up.lua @@ -9,7 +9,7 @@ -- 3) All apps have some data that can be resumed -- 4) SDL get LOW_VOLTAGE signal -- 5) And then SDL get WAKE_UP signal --- 6) All apps are registered with the same hashID +-- 6) All apps are registered with their corresponding hashIDs -- SDL does: -- 1) after 4th step: -- Stop all read write activities diff --git a/test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua b/test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua index ae3aed5cff..8766a905f2 100644 --- a/test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua +++ b/test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua @@ -17,6 +17,7 @@ runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local cid = nil +local hmiId --[[ Local Functions ]] local function checkResumptionData() @@ -24,6 +25,13 @@ local function checkResumptionData() :Times(0) end +local function showResponseDuringWakeUp() + common.sendWakeUpSignal() + common.getHMIConnection():SendResponse(hmiId, "UI.Show", "SUCCESS", {}) + common.getMobileSession():ExpectResponse(cid) -- check absence of response + :Times(0) +end + local function checkResumptionHMILevel() common.getHMIConnection():ExpectRequest("BasicCommunication.ActivateApp", { appID = common.getHMIAppId(1) }) :Do(function(_, data) @@ -43,6 +51,9 @@ local function processRPCPartially() } cid = common.getMobileSession():SendRPC("Show", params) EXPECT_HMICALL("UI.Show") + :Do(function(_, data) + hmiId = data.id + end) end local function checkAppId(pAppId, pData) @@ -64,8 +75,8 @@ runner.Title("Test") runner.Step("Wait until Resumption Data is stored" , common.waitUntilResumptionDataIsStored) runner.Step("RPC Show partially", processRPCPartially) runner.Step("Send LOW_VOLTAGE signal", common.sendLowVoltageSignal) -runner.Step("Close mobile connection", common.cleanSessions) -runner.Step("Send WAKE_UP signal", common.sendWakeUpSignal) +runner.Step("Send WAKE_UP signal and absence Show response on mobile app", showResponseDuringWakeUp) +runner.Step("Clean sessions", common.cleanSessions) runner.Step("Re-connect Mobile", common.connectMobile) runner.Step("Re-register App, check resumption data and HMI level", common.reRegisterApp, { 1, checkAppId, checkResumptionData, checkResumptionHMILevel, "SUCCESS", 11000 diff --git a/test_scripts/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua b/test_scripts/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua index 6cda0a3e65..235c505a2e 100644 --- a/test_scripts/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua +++ b/test_scripts/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua @@ -34,7 +34,7 @@ local function checkAppId(pAppId, pData) end local function checkResumptionHMILevel() - common.getMobileSession(1):ExpectNotification("OnHMIStatus", + common.getMobileSession(1):ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", systemContext = "MAIN", audioStreamingState = "NOT_AUDIBLE" }, { hmiLevel = "LIMITED", systemContext = "MAIN", audioStreamingState = "AUDIBLE" }) :Times(2) From f4f42576ceb8a596706049ad5913b293444f41e8 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Wed, 15 Aug 2018 13:43:40 -0400 Subject: [PATCH 551/681] Update based on comments --- .../VersionNegotiation/001_register_legacy_app.lua | 6 +++--- test_sets/mobile_api_versioning.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua index a00b033824..510a82171a 100644 --- a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua +++ b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua @@ -64,7 +64,7 @@ local requestParams = { } } -local function SetNotificationParams() +local function GetNotificationParams() local notificationParams = { application = {} } @@ -86,7 +86,7 @@ local function SetNotificationParams() end --[[ Local Functions ]] -local function unregisterAppInterface(self) +local function UnregisterAppInterface(self) local cid = self.mobileSession1:SendRPC("UnregisterAppInterface", { }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = commonSmoke.getHMIAppId(), unexpectedDisconnect = false }) @@ -95,7 +95,7 @@ end local function RegisterAppInterface(self) local CorIdRAI = self.mobileSession1:SendRPC("RegisterAppInterface", requestParams) - local notificationParams = SetNotificationParams() + local notificationParams = GetNotificationParams() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", notificationParams) self.mobileSession1:ExpectResponse(CorIdRAI, { success = true, resultCode = "SUCCESS", syncMsgVersion = requestParams.syncMsgVersion}) self.mobileSession1:ExpectNotification("OnHMIStatus", diff --git a/test_sets/mobile_api_versioning.txt b/test_sets/mobile_api_versioning.txt index b16d29000c..7345b1b7ae 100644 --- a/test_sets/mobile_api_versioning.txt +++ b/test_sets/mobile_api_versioning.txt @@ -1,2 +1,2 @@ ./test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua -./test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua \ No newline at end of file +./test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua From ed9da3fa0bfc8ed096b88f00f42c19e932b87e22 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Wed, 15 Aug 2018 14:04:27 -0400 Subject: [PATCH 552/681] Update based on comments --- .../VersionNegotiation/001_register_legacy_app.lua | 2 +- .../002_register_app_on_legacy_module.lua | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua index 510a82171a..38ce594bc3 100644 --- a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua +++ b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua @@ -109,7 +109,7 @@ runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) -runner.Step("UnregisterAppInterface Positive Case", unregisterAppInterface) +runner.Step("UnregisterAppInterface Positive Case", UnregisterAppInterface) runner.Title("Test") runner.Step("RegisterAppInterface Legacy App Case", RegisterAppInterface) diff --git a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua index 1a63954e9a..936d00abca 100644 --- a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua +++ b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua @@ -70,7 +70,7 @@ local responseSyncMsgVersion = { patchVersion = 0 } -local function SetNotificationParams() +local function GetNotificationParams() local notificationParams = { application = {} } @@ -92,7 +92,7 @@ local function SetNotificationParams() end --[[ Local Functions ]] -local function unregisterAppInterface(self) +local function UnregisterAppInterface(self) local cid = self.mobileSession1:SendRPC("UnregisterAppInterface", { }) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = commonSmoke.getHMIAppId(), unexpectedDisconnect = false }) @@ -101,7 +101,7 @@ end local function RegisterAppInterface(self) local CorIdRAI = self.mobileSession1:SendRPC("RegisterAppInterface", requestParams) - local notificationParams = SetNotificationParams() + local notificationParams = GetNotificationParams() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", notificationParams) self.mobileSession1:ExpectResponse(CorIdRAI, { success = true, resultCode = "SUCCESS", syncMsgVersion = responseSyncMsgVersion}) self.mobileSession1:ExpectNotification("OnHMIStatus", @@ -115,7 +115,7 @@ runner.Step("Clean environment", commonSmoke.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) runner.Step("RAI", commonSmoke.registerApp) runner.Step("Activate App", commonSmoke.activateApp) -runner.Step("UnregisterAppInterface Positive Case", unregisterAppInterface) +runner.Step("UnregisterAppInterface Positive Case", UnregisterAppInterface) runner.Title("Test") runner.Step("RegisterAppInterface New App on Legacy Module Positive Case", RegisterAppInterface) From f1ef7365b5a6203f72b93439ae4f68788f9ea8d6 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Wed, 15 Aug 2018 16:31:40 -0400 Subject: [PATCH 553/681] Get most recent version from mobile_api --- .../002_register_app_on_legacy_module.lua | 7 ++--- user_modules/mobile_api.lua | 27 +++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 user_modules/mobile_api.lua diff --git a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua index 936d00abca..0920132c47 100644 --- a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua +++ b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua @@ -29,6 +29,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonSmoke = require('test_scripts/Smoke/commonSmoke') +local mobileAPI = require('user_modules/mobile_api') --[[ Local Variables ]] local requestParams = { @@ -64,11 +65,7 @@ local requestParams = { } } -local responseSyncMsgVersion = { - majorVersion = 5, - minorVersion = 0, - patchVersion = 0 -} +local responseSyncMsgVersion = mobileAPI.GetVersion() local function GetNotificationParams() local notificationParams = { diff --git a/user_modules/mobile_api.lua b/user_modules/mobile_api.lua new file mode 100644 index 0000000000..cf32ec34df --- /dev/null +++ b/user_modules/mobile_api.lua @@ -0,0 +1,27 @@ +local xml = require('xml') + +local api_doc = xml.open("data/MOBILE_API.xml") + +local mobileAPI = {} + +function mobileAPI.GetVersion() + local interface = api_doc:xpath("//interface") + local version_str = "" + for _, s in ipairs(interface) do + version_str = s:attr("version") + local version_arr = {0,0,0} + local index = 0 + for i in string.gmatch(version_str, "([^.]+)") do + version_arr[index] = i + index = index + 1 + end + local minVersion = { + majorVersion = version_arr[0], + minorVersion = version_arr[1], + patchVersion = version_arr[2] + } + return minVersion + end +end + +return mobileAPI \ No newline at end of file From 70fe37bcae344d7e41cd293a9bd275016ab01aed Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 16 Aug 2018 10:51:47 +0300 Subject: [PATCH 554/681] Added majorVersion=5 in common files for scripts with functionality for version 5 --- .../Expanded_proprietary_data_exchange/commonDataExchange.lua | 1 + test_scripts/MobileProjection/Phase1/common.lua | 2 ++ test_scripts/MobileProjection/Phase2/common.lua | 2 ++ test_scripts/RC/OnRCStatus/commonOnRCStatus.lua | 2 ++ test_scripts/RC/SEAT/commonRC.lua | 2 ++ test_scripts/SDL4_6/TTSChunks/common.lua | 1 + 6 files changed, 10 insertions(+) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua b/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua index 1bacea67b6..90120dbc41 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua @@ -10,6 +10,7 @@ local json = require("modules/json") --[[ General configuration parameters ]] config.defaultProtocolVersion = 2 +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 local m = actions local ptuTable = {} diff --git a/test_scripts/MobileProjection/Phase1/common.lua b/test_scripts/MobileProjection/Phase1/common.lua index 01dc1bead4..b7fdf9f4ba 100644 --- a/test_scripts/MobileProjection/Phase1/common.lua +++ b/test_scripts/MobileProjection/Phase1/common.lua @@ -3,6 +3,8 @@ --------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 +config.application2.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 --[[ Required Shared libraries ]] local actions = require("user_modules/sequences/actions") diff --git a/test_scripts/MobileProjection/Phase2/common.lua b/test_scripts/MobileProjection/Phase2/common.lua index d5bd4b8f4b..7c75f01fa6 100644 --- a/test_scripts/MobileProjection/Phase2/common.lua +++ b/test_scripts/MobileProjection/Phase2/common.lua @@ -3,6 +3,8 @@ --------------------------------------------------------------------------------------------------- --[[ General configuration parameters ]] config.defaultProtocolVersion = 3 +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 +config.application2.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 --[[ Required Shared libraries ]] local actions = require("user_modules/sequences/actions") diff --git a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua index a4378561c0..5ef39ddfa6 100644 --- a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua +++ b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua @@ -6,6 +6,8 @@ config.defaultProtocolVersion = 2 config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.checkAllValidations = true +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 +config.application2.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 --[[ Required Shared libraries ]] local commonRC = require('test_scripts/RC/commonRC') diff --git a/test_scripts/RC/SEAT/commonRC.lua b/test_scripts/RC/SEAT/commonRC.lua index 91d96be2d6..8ea05d1c18 100644 --- a/test_scripts/RC/SEAT/commonRC.lua +++ b/test_scripts/RC/SEAT/commonRC.lua @@ -7,6 +7,8 @@ config.defaultProtocolVersion = 2 config.ValidateSchema = false config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 +config.application2.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 --[[ Required Shared libraries ]] local initialCommon = require('test_scripts/RC/commonRC') diff --git a/test_scripts/SDL4_6/TTSChunks/common.lua b/test_scripts/SDL4_6/TTSChunks/common.lua index b2772ea258..1f3e8d6a59 100644 --- a/test_scripts/SDL4_6/TTSChunks/common.lua +++ b/test_scripts/SDL4_6/TTSChunks/common.lua @@ -4,6 +4,7 @@ --[[ General configuration parameters ]] config.mobileHost = "127.0.0.1" config.defaultProtocolVersion = 2 +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 --[[ Required Shared libraries ]] local actions = require("user_modules/sequences/actions") From 7c4c350b643634986d513c889cb84031a292a076 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Thu, 16 Aug 2018 13:06:18 -0400 Subject: [PATCH 555/681] Update test script to use load_schema.mob_api --- .../002_register_app_on_legacy_module.lua | 5 ++-- user_modules/mobile_api.lua | 27 ------------------- 2 files changed, 3 insertions(+), 29 deletions(-) delete mode 100644 user_modules/mobile_api.lua diff --git a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua index 0920132c47..3628536f40 100644 --- a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua +++ b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua @@ -29,7 +29,8 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonSmoke = require('test_scripts/Smoke/commonSmoke') -local mobileAPI = require('user_modules/mobile_api') +local load_schema = require('load_schema') +local mob_api_version = load_schema.mob_api_version --[[ Local Variables ]] local requestParams = { @@ -65,7 +66,7 @@ local requestParams = { } } -local responseSyncMsgVersion = mobileAPI.GetVersion() +local responseSyncMsgVersion = mob_api_version local function GetNotificationParams() local notificationParams = { diff --git a/user_modules/mobile_api.lua b/user_modules/mobile_api.lua deleted file mode 100644 index cf32ec34df..0000000000 --- a/user_modules/mobile_api.lua +++ /dev/null @@ -1,27 +0,0 @@ -local xml = require('xml') - -local api_doc = xml.open("data/MOBILE_API.xml") - -local mobileAPI = {} - -function mobileAPI.GetVersion() - local interface = api_doc:xpath("//interface") - local version_str = "" - for _, s in ipairs(interface) do - version_str = s:attr("version") - local version_arr = {0,0,0} - local index = 0 - for i in string.gmatch(version_str, "([^.]+)") do - version_arr[index] = i - index = index + 1 - end - local minVersion = { - majorVersion = version_arr[0], - minorVersion = version_arr[1], - patchVersion = version_arr[2] - } - return minVersion - end -end - -return mobileAPI \ No newline at end of file From 7aa78a3b9f045ff4258d5342bfa8a689740c94e7 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Thu, 16 Aug 2018 13:21:14 -0400 Subject: [PATCH 556/681] Add new line --- test_sets/mobile_api_versioning.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test_sets/mobile_api_versioning.txt b/test_sets/mobile_api_versioning.txt index 238631db85..d0c44d0d86 100644 --- a/test_sets/mobile_api_versioning.txt +++ b/test_sets/mobile_api_versioning.txt @@ -5,3 +5,4 @@ ./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/001_create_interaction_choice_success_legacy_app.lua ./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/002_create_interaction_choice_invalid_data_legacy_app.lua ./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/003_perform_interaction_success_legacy_app.lua + From 61d75e8b2fcfb0701fa6a4cc62996e3b499870ad Mon Sep 17 00:00:00 2001 From: JackLivio Date: Thu, 16 Aug 2018 15:54:11 -0400 Subject: [PATCH 557/681] Update verision to 4.5 --- .../VersionNegotiation/001_register_legacy_app.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua index 38ce594bc3..f1b94cb13b 100644 --- a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua +++ b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua @@ -33,8 +33,8 @@ local commonSmoke = require('test_scripts/Smoke/commonSmoke') --[[ Local Variables ]] local requestParams = { syncMsgVersion = { - majorVersion = 2, - minorVersion = 2, + majorVersion = 4, + minorVersion = 5, }, appName = "SyncProxyTester", ttsName = { From 1b386886f3aa19280eb92dc772c615a68784a30b Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 17 Aug 2018 12:54:10 +0300 Subject: [PATCH 558/681] Remove redundant new line from mobile versioning set --- test_sets/mobile_api_versioning.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/test_sets/mobile_api_versioning.txt b/test_sets/mobile_api_versioning.txt index d0c44d0d86..238631db85 100644 --- a/test_sets/mobile_api_versioning.txt +++ b/test_sets/mobile_api_versioning.txt @@ -5,4 +5,3 @@ ./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/001_create_interaction_choice_success_legacy_app.lua ./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/002_create_interaction_choice_invalid_data_legacy_app.lua ./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/003_perform_interaction_success_legacy_app.lua - From 931c698e7166ca2759e0274ca837c1a0fce54582 Mon Sep 17 00:00:00 2001 From: "Ira Lytvynenko (GitHub)" Date: Fri, 18 May 2018 12:32:28 +0300 Subject: [PATCH 559/681] Scripts for new RC modules --- .../001_Success_flow.lua | 35 + .../002_Disallow_flow_by_policy_AUDIO.lua | 44 ++ .../003_Disallow_flow_by_policy_LIGHT.lua | 44 ++ ...4_Disallow_flow_by_policy_HMI_SETTINGS.lua | 44 ++ ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 56 ++ .../006_RPC_parameters_values.lua | 113 ++++ ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 60 ++ ..._in_case_HMI_respond_with_invalid_data.lua | 90 +++ ...se_moduleType_is_an_empty_array_in_LPT.lua | 45 ++ ...ow_in_case_moduleType_is_absent_in_LPT.lua | 48 ++ ...ROR_in_case_HMI_respond_with_READ_ONLY.lua | 60 ++ ...ransfering_of_HMI_resultCode_to_mobile.lua | 95 +++ ...ut_response_from_HMI_with_isSubscribed.lua | 80 +++ ...ase_of_2nd_Subscription_UnSubscription.lua | 104 +++ ...response_from_HMI_without_isSubscribed.lua | 86 +++ .../001_Consent_true_SIVD.lua | 62 ++ .../002_Consent_false_SIVD.lua | 64 ++ .../003_TIMED_OUT_from_HMI_SIVD.lua | 78 +++ .../004_HMI_no_response_SIVD.lua | 76 +++ .../005_HMI_invalid_response_SIVD.lua | 78 +++ .../GetSystemCapability/001_Success_flow.lua | 62 ++ ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 48 ++ ...CE_in_case_RC_interface_is_unavailable.lua | 59 ++ .../001_Success_flow.lua | 63 ++ .../002_Disallow_flow_by_policy_AUDIO.lua | 45 ++ .../003_Disallow_flow_by_policy_LIGHT.lua | 45 ++ ...4_Disallow_flow_by_policy_HMI_SETTINGS.lua | 45 ++ ...ribing_with_isSubscribe_false_from_HMI.lua | 70 ++ ...cribing_with_isSubscribe_true_from_HMI.lua | 75 +++ ...bscribing_without_isSubscribe_from_HMI.lua | 75 +++ ...bscribing_without_isSubscribe_from_HMI.lua | 81 +++ .../001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua | 63 ++ ...002_REJECTED_in_case_nonFULL_HMI_level.lua | 67 ++ ...003_Allowed_true_accessMode_AUTO_ALLOW.lua | 57 ++ .../004_Allowed_true_accessMode_AUTO_DENY.lua | 61 ++ ...005_Allowed_true_accessMode_ASK_DRIVER.lua | 64 ++ .../006_Default_accessMode.lua | 53 ++ .../001_Success_flow.lua | 41 ++ .../002_Disallow_flow_by_policy_CLIMATE.lua | 55 ++ .../003_Disallow_flow_by_policy_AUDIO.lua | 55 ++ .../004_Disallow_flow_by_policy_LIGHT.lua | 55 ++ ...5_Disallow_flow_by_policy_HMI_SETTINGS.lua | 55 ++ ...se_moduleType_is_an_empty_array_in_LPT.lua | 67 ++ ...ow_in_case_moduleType_is_absent_in_LPT.lua | 57 ++ ...cle_data_if_read_only_params_requested.lua | 45 ++ .../009_Change_audio_source_in_FULL.lua | 73 ++ .../010_Change_audio_source_in_BACKGROUND.lua | 75 +++ .../010_Change_audio_source_in_LIMITED.lua | 83 +++ .../011_Change_audio_source_in_BACKGROUND.lua | 75 +++ ..._audio_source_in_FULL_rc_non_media_app.lua | 67 ++ ...ce_from_MOBILE_APP_without_keepContext.lua | 86 +++ ..._audio_source_in_FULL_rc_non_media_app.lua | 67 ++ ...urce_from_MOBILE_APP_keepContext_false.lua | 86 +++ ...ce_from_MOBILE_APP_without_keepContext.lua | 86 +++ ...urce_from_MOBILE_APP_keepContext_false.lua | 86 +++ ..._from_MOBILE_APP_keepContext_true_FULL.lua | 86 +++ ..._from_MOBILE_APP_keepContext_true_FULL.lua | 86 +++ ...om_MOBILE_APP_keepContext_true_LIMITED.lua | 96 +++ ...om_MOBILE_APP_keepContext_true_LIMITED.lua | 96 +++ ...ype_except_MOBILE_APP_keepContext_true.lua | 88 +++ ...ype_except_MOBILE_APP_keepContext_true.lua | 88 +++ .../commonRCmodules.lua | 625 ++++++++++++++++++ .../025_IN_USE_in_case_3_requests.lua | 224 +++++++ test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt | 54 ++ test_sets/rc_CLIMATE_RADIO.txt | 1 + user_modules/hmi_values.lua | 50 +- 66 files changed, 5101 insertions(+), 2 deletions(-) create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/001_Success_flow.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/004_HMI_no_response_SIVD.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/005_HMI_invalid_response_SIVD.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/001_Success_flow.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/003_UNSUPPORTED_RESOURCE_in_case_RC_interface_is_unavailable.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/001_Success_flow.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/004_Allowed_true_accessMode_AUTO_DENY.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/005_Allowed_true_accessMode_ASK_DRIVER.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/006_Default_accessMode.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/001_Success_flow.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/008_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_BACKGROUND.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_FULL_rc_non_media_app.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_from_MOBILE_APP_without_keepContext.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_keepContext_false.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_without_keepContext.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_false.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/025_IN_USE_in_case_3_requests.lua create mode 100644 test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/001_Success_flow.lua new file mode 100644 index 0000000000..324d99b869 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/001_Success_flow.lua @@ -0,0 +1,35 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: TRS: GetInteriorVehicleData, #3 +-- In case: +-- 1) RC app sends valid and allowed by policies GetInteriorvehicleData_request +-- 2) and SDL received GetInteriorVehicledata_response with successful result code and current module data from HMI +-- SDL must: +-- 1) transfer GetInteriorVehicleData_response with provided from HMI current module data for allowed module and control items +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData " .. mod, common.subscribeToModule, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua new file mode 100644 index 0000000000..f2e9b53c5b --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received GetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local mod = "AUDIO" + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, self) + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType + }) + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { PTUfunc }) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua new file mode 100644 index 0000000000..61c949c8aa --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received GetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local mod = "LIGHT" + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, self) + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType + }) + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { PTUfunc }) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua new file mode 100644 index 0000000000..b52f650aeb --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received GetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local mod = "HMI_SETTINGS" + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, self) + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType + }) + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { PTUfunc }) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua new file mode 100644 index 0000000000..ca593e5567 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Alternative flow 1 +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) Non remote-control application is registered on SDL +-- 2) and SDL received GetInteriorVehicleData request from this App +-- SDL must: +-- 1) Disallow remote-control RPCs for this app (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Functions ]] +local function getDataForModule(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType + }) + EXPECT_HMICALL("RC.GetInteriorVehicleData") + :Times(0) + mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + local appId = config.application1.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua new file mode 100644 index 0000000000..d6a6351f97 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua @@ -0,0 +1,113 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Exceptions: 2.1 +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with invalid parameters +-- - invalid parameter name +-- - invalid parameter type +-- - missing mandatory parameter +-- SDL must: +-- 1) Do not transfer request to HMI +-- 2) Respond with success:false, "INVALID_DATA" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function invalidParamName(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + modduleType = pModuleType, -- invalid name of parameter + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function invalidParamType(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = 17 -- invalid type of parameter + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function missingMandatoryParam() + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + -- moduleType = "CLIMATE", -- mandatory parameter absent + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function fakeParam(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + fakeParam = 7, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = true + }) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + isSubscribed = true, + moduleData = common.getModuleControlDataForResponse(pModuleType) + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod .. " invalid name of parameter", invalidParamName, { mod }) + runner.Step("GetInteriorVehicleData " .. mod .. " invalid type of parameter", invalidParamType, { mod }) + runner.Step("GetInteriorVehicleData " .. mod .. " fake parameter", fakeParam, { mod }) +end + +runner.Step("GetInteriorVehicleData mandatory parameter absent", missingMandatoryParam) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua new file mode 100644 index 0000000000..6701c0a2c1 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -0,0 +1,60 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Exceptions: 5.1 +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with valid parameters +-- 2) and HMI didn't respond within default timeout +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function getDataForModule(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, _) + -- HMI does not respond + end) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod .. " HMI does not respond", getDataForModule, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua new file mode 100644 index 0000000000..23891efbfc --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -0,0 +1,90 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Exceptions: 5.1 +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with valid parameters +-- 2) and HMI responds with invalid data: +-- - invalid type of parameter +-- - missing mandatory parameter +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function invalidParamType(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlData(pModuleType), + isSubscribed = "yes" -- invalid type of parameter + }) + end) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +local function missingMandatoryParam(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + local moduleData = common.getModuleControlData(pModuleType) + moduleData.moduleType = nil -- missing mandatory parameter + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = moduleData, + isSubscribed = true + }) + end) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod .. " Invalid response from HMI-Invalid type of parameter", invalidParamType, { mod }) + runner.Step("GetInteriorVehicleData " .. mod .. " Invalid response from HMI-Missing mandatory parameter", missingMandatoryParam, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua new file mode 100644 index 0000000000..f0b8482268 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has an empty array +-- 2) and RC app sends GetInteriorVehicleData request with valid parameters +-- SDL must: +-- 1) Allow this RPC to be processed +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local json = require('modules/json') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +local function PTUfunc(tbl) + common.AddOnRCStatusToPT(tbl) + local appId = config.application1.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId] = common.getRCAppConfig() + tbl.policy_table.app_policies[appId].moduleType = json.EMPTY_ARRAY +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData " .. mod, common.rpcAllowed, { mod, 1, "GetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua new file mode 100644 index 0000000000..533450f5cf --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) "moduleType" does not exist in app's assigned policies +-- 2) and RC app sends GetInteriorVehicleData request with valid parameters +-- SDL must: +-- 1) Disallow this RPC to be processed (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } + +local function PTUfunc(tbl) + common.AddOnRCStatusToPT(tbl) + local appId = config.application1.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod, common.rpcDenied, { mod, 1, "GetInteriorVehicleData", "DISALLOWED" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua new file mode 100644 index 0000000000..bd2a47fef8 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -0,0 +1,60 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with valid parameters +-- 2) and SDL gets response (resultCode: READ_ONLY) from HMI +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function getDataForModule(module_type) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = module_type, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = module_type, + subscribe = true + }) + :Do(function(_, data) + common.getHMIconnection():SendError(data.id, data.method, "READ_ONLY", "Info message") + end) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Info message" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua new file mode 100644 index 0000000000..fcef64b4dd --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua @@ -0,0 +1,95 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Exceptions: 5.2 +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) RC app sends valid and allowed by policies GetInteriorvehicleData request +-- 2) and SDL received GetInteriorVehicledata response with successful result code and current module data from HMI +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with provided from HMI current module data for allowed module and control items +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } +local success_codes = { "WARNINGS" } +local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } + +--[[ Local Functions ]] +local function stepSuccessfull(pModuleType, pResultCode) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, pResultCode, { + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = false + }) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = pResultCode, + isSubscribed = false, + moduleData = common.getModuleControlDataForResponse(pModuleType) + }) +end + +local function stepUnsuccessfull(pModuleType, pResultCode) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + common.getHMIconnection():SendError(data.id, data.method, pResultCode, "Error error") + end) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = pResultCode}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + for _, code in pairs(success_codes) do + runner.Step("GetInteriorVehicleData " .. mod .. " with " .. code .. " resultCode", stepSuccessfull, { mod, code }) + end +end + +for _, mod in pairs(modules) do + for _, code in pairs(error_codes) do + runner.Step("GetInteriorVehicleData " .. mod .. " with " .. code .. " resultCode", stepUnsuccessfull, { mod, code }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua new file mode 100644 index 0000000000..105350555b --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -0,0 +1,80 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: TRS: GetInteriorVehicleData, #2 +-- In case: +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData_request without "subscribe" parameter +-- 2) and SDL gets GetInteriorVehicleData_response with resultCode: <"any-result"> +-- 3) and with "isSubscribed" parameter from HMI +-- SDL must: +-- 1) transfer GetInteriorVehicleData_response with resultCode: <"any-result"> +-- and without "isSubscribed" param to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, isSubscriptionActive) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType + -- no subscribe parameter + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = isSubscriptionActive -- return current value of subscription + }) + end) + :ValidIf(function(_, data) -- no subscribe parameter + if data.params.subscribe == nil then + return true + end + return false, 'Parameter "subscribe" is transfered with to HMI value: ' .. tostring(data.params.subscribe) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = common.getModuleControlDataForResponse(pModuleType) + }) + :ValidIf(function(_, data) -- no isSubscribed parameter + if data.payload.isSubscribed == nil then + return true + end + return false, 'Parameter "isSubscribed" is transfered to App with value: ' .. tostring(data.payload.isSubscribed) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription", getDataForModule, { mod, false }) +end + +for _, mod in pairs(common.modules) do + runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) + runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua new file mode 100644 index 0000000000..5cbd7c6b4c --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua @@ -0,0 +1,104 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: TRS: GetInteriorVehicleData, #12 +-- In case: +-- 1) RC app is subscribed to "" +-- 2) and sends valid and allowed-by-policies GetInteriorVehicleData request +-- 3) with "subscribe:true" parameter for the same "" +-- SDL must: +-- 1) Forward request to HMI without "subscribe:true" parameter +-- 2) not change the subscription status of the app +-- 3) transfer HMI's response with added "isSubscribed: true" to the app +-- +-- Description: TRS: GetInteriorVehicleData, #13 +-- In case: +-- 1) RC app is not subscribed to "" +-- 2) and sends valid and allowed-by-policies GetInteriorVehicleData request +-- 3) with "subscribe:false" parameter for the same "" +-- SDL must: +-- 1) Forward request to HMI without "subscribe:false" parameter +-- 2) not change the subscription status of the app +-- 3) transfer HMI's response with added "isSubscribed: false" to the app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function subscriptionToModule(pModuleType, pSubscribe) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = pSubscribe + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = pSubscribe + }) + end) + :ValidIf(function(_, data) + if data.params.subscribe == nil then + return true + end + return false, 'Parameter "subscribe" is transfered to HMI with value: ' .. tostring(data.params.subscribe) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = pSubscribe + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + -- app has not subscribed yet + runner.Step("Unsubscribe app to " .. mod, subscriptionToModule, { mod, false }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", common.isUnsubscribed, + { mod }) + + -- subscribe to module 1st time + runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", common.isSubscribed, + { mod }) + + -- subscribe to module 2nd time + runner.Step("Subscribe 2nd time app to " .. mod, subscriptionToModule, { mod, true }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", common.isSubscribed, + { mod }) + + -- unsubscribe to module 1st time + runner.Step("Unsubscribe app to " .. mod, common.unSubscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", common.isUnsubscribed, + { mod }) + + -- unsubscribe to module 2nd time + runner.Step("Unsubscribe 2nd time app to " .. mod, subscriptionToModule, { mod, false }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", common.isUnsubscribed, + { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua new file mode 100644 index 0000000000..6df7c061c8 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -0,0 +1,86 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: TRS: GetInteriorVehicleData, #1 +-- In case: +-- 1) RC app sends valid and allowed by policies GetInteriorvehicleData_request with "subscribe" parameter +-- 2) and SDL received GetInteriorVehicledata_response with resultCode: <"any_not_erroneous_result"> +-- 3) and without "isSubscribed" parameter from HMI +-- SDL must: +-- 1) transfer GetInteriorVehicleData_response with resultCode:<"any_not_erroneous_result"> +-- and with added isSubscribed: <"current_subscription_status"> to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = pSubscribe + }) + + local pSubscribeHMI = pSubscribe + if isSubscriptionActive == pSubscribe then + pSubscribeHMI = nil + end + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlDataForResponse(pModuleType), + -- no isSubscribed parameter + }) + end) + :ValidIf(function(_, data) + if data.params.subscribe == pSubscribeHMI then + return true + end + return false, 'Parameter "subscribe" is transfered to HMI with value: ' .. tostring(data.params.subscribe) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + isSubscribed = isSubscriptionActive, -- return current value of subscription + moduleData = common.getModuleControlDataForResponse(pModuleType) + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription_subscribe", getDataForModule, + { mod, false, true }) + runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription_unsubscribe", getDataForModule, + { mod, false, false }) +end + +for _, mod in pairs(common.modules) do + runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) + runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, + { mod, true, true }) + runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_unsubscribe", getDataForModule, + { mod, true, false }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua new file mode 100644 index 0000000000..0751bc5bf9 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua @@ -0,0 +1,62 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Alternative flow 2 +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #1 +-- In case: +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and user allowed access to RC module for requested application +-- SDL must: +-- 1) allocate access to RC module to requested application +-- 2) process control request from this application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function PTUfunc(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App1", common.activateApp) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Activate App2", common.activateApp, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", common.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: allowed:true + runner.Step("App2 SetInteriorVehicleData 1st SUCCESS", common.rpcAllowedWithConsent, + { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 SetInteriorVehicleData 2nd SUCCESS", common.rpcAllowed, + { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua new file mode 100644 index 0000000000..9f7f5ad3d6 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua @@ -0,0 +1,64 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Alternative flow 2.1 +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #4 +-- In case: +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and user disallowed access to RC module for the requested application +-- SDL must: +-- 1) respond on control request to RC application with result code REJECTED, success:false, +-- info: "The resource is in use and the driver disallows this remote control RPC" +-- 2) not allocate access for remote control module to the requested application +-- (meaning SDL must leave control of remote control module without changes) +-- Note: All further requests from this application to the same module in case +-- if it is still under control of another application must be rejected by SDL without initiating consent prompts +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function PTUfunc(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App1", common.activateApp) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Activate App2", common.activateApp, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", common.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: allowed:false + runner.Step("App2 SetInteriorVehicleData 1st REJECTED", common.rpcRejectWithConsent, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 SetInteriorVehicleData 2nd REJECTED", common.rpcRejectWithoutConsent, { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua new file mode 100644 index 0000000000..fd5a6cbd86 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua @@ -0,0 +1,78 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Alternative flow 2.2 +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #2 +-- In case: +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and user did not provide the answer during default timeout +-- 5) and SDL received in response from HMI GetInteriorVehicleDataConsent (TIMED_OUT) +-- SDL must: +-- 1) respond on control request to RC application with result code TIMED_OUT, success:false, +-- info: "The resource is in use and the driver did not respond in time" +-- 2) not allocate access for remote control module to the requested application +-- (meaning SDL must leave control of remote control module without changes) +-- Note: SDL must initiate user prompt in case of consequent control request for the same module from this application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function PTUfunc(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +local function rpcTimedOutHMIResponse(pModuleType, pAppId, pRPC) + local info = "The resource is in use and the driver did not respond in time" + local consentRPC = "GetInteriorVehicleDataConsent" + local mobSession = common.getMobileSession(pAppId) + local cid = mobSession:SendRPC(common.getAppEventName(pRPC), common.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(common.getHMIEventName(consentRPC), common.getHMIRequestParams(consentRPC, pModuleType, pAppId)) + :Do(function(_, data) + common.getHMIconnection():SendError(data.id, data.method, "TIMED_OUT", info) + EXPECT_HMICALL(common.getHMIEventName(pRPC)):Times(0) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "TIMED_OUT", info = info }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App1", common.activateApp) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Activate App2", common.activateApp, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", common.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: TIMED_OUT + runner.Step("App2 SetInteriorVehicleData 1st TIMED_OUT", rpcTimedOutHMIResponse, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 SetInteriorVehicleData 2nd SUCCESS", common.rpcAllowedWithConsent, + { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/004_HMI_no_response_SIVD.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/004_HMI_no_response_SIVD.lua new file mode 100644 index 0000000000..163c0b43db --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/004_HMI_no_response_SIVD.lua @@ -0,0 +1,76 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 2.1 +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #3 +-- In case: +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and HMI did not respond during default timeout or response is invalid or erroneous +-- SDL must: +-- 1) respond on control request to RC application with result code GENERIC_ERROR, success:false +-- 2) not allocate access for remote control module to the requested application +-- (meaning SDL must leave control of remote control module without changes) +-- Note: SDL must initiate user prompt in case of consequent control request for the same module from this application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function PTUfunc(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +local function rpcNoHMIResponse(pModuleType, pAppId, pRPC) + local consentRPC = "GetInteriorVehicleDataConsent" + local mobSession = common.getMobileSession(pAppId) + local cid = mobSession:SendRPC(common.getAppEventName(pRPC), common.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(common.getHMIEventName(consentRPC), common.getHMIRequestParams(consentRPC, pModuleType, pAppId)) + :Do(function(_, _) + -- HMI does not respond + EXPECT_HMICALL(common.getHMIEventName(pRPC)):Times(0) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App1", common.activateApp) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Activate App2", common.activateApp, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", common.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: doesn't respond + runner.Step("App2 SetInteriorVehicleData 1st GENERIC_ERROR", rpcNoHMIResponse, + { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 SetInteriorVehicleData 2nd SUCCESS", common.rpcAllowedWithConsent, + { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/005_HMI_invalid_response_SIVD.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/005_HMI_invalid_response_SIVD.lua new file mode 100644 index 0000000000..9172322770 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/005_HMI_invalid_response_SIVD.lua @@ -0,0 +1,78 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 2.1 +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #3 +-- In case: +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and HMI did not respond during default timeout or response is invalid or erroneous +-- SDL must: +-- 1) respond on control request to RC application with result code GENERIC_ERROR, success:false +-- 2) not allocate access for remote control module to the requested application +-- (meaning SDL must leave control of remote control module without changes) +-- Note: SDL must initiate user prompt in case of consequent control request for the same module from this application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function PTUfunc(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +local function rpcInvalidHMIResponse(pModuleType, pAppId, pRPC) + local consentRPC = "GetInteriorVehicleDataConsent" + local mobSession = common.getMobileSession(pAppId) + local cid = mobSession:SendRPC(common.getAppEventName(pRPC), common.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(common.getHMIEventName(consentRPC), common.getHMIRequestParams(consentRPC, pModuleType, pAppId)) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + allowed = "aaa" -- invalid type of parameter + }) + EXPECT_HMICALL(common.getHMIEventName(pRPC)):Times(0) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App1", common.activateApp) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Activate App2", common.activateApp, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", common.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: response with invalid data + runner.Step("App2 SetInteriorVehicleData 1st GENERIC_ERROR", rpcInvalidHMIResponse, + { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 SetInteriorVehicleData 2nd SUCCESS", common.rpcAllowedWithConsent, + { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/001_Success_flow.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/001_Success_flow.lua new file mode 100644 index 0000000000..15570f87d5 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/001_Success_flow.lua @@ -0,0 +1,62 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/RC/detailed_info_GetSystemCapability.md +-- Item: Use Case 2: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- 1) App is RC +-- 2) App tries to get RC capabilities +-- SDL must: +-- 1) Transfer RC capabilities to mobiles +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local capParams = {} +for _, v in pairs(common.modules) do capParams[v] = common.DEFAULT end -- HMI has all posible RC capabilities +local hmiRcCapabilities = common.buildHmiRcCapabilities(capParams) + +--[[ Local Functions ]] +local function rpcSuccess() + local rcCapabilities = hmiRcCapabilities.RC.GetCapabilities.params.remoteControlCapability + local cid = common.getMobileSession():SendRPC("GetSystemCapability", { systemCapabilityType = "REMOTE_CONTROL" }) + common.getMobileSession():ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS", + systemCapability = { + remoteControlCapability = { + climateControlCapabilities = rcCapabilities.climateControlCapabilities, + radioControlCapabilities = rcCapabilities.radioControlCapabilities, + audioControlCapabilities = rcCapabilities.audioControlCapabilities, + hmiSettingsControlCapabilities = rcCapabilities.hmiSettingsControlCapabilities, + lightControlCapabilities = rcCapabilities.lightControlCapabilities, + buttonCapabilities = rcCapabilities.buttonCapabilities + } + } + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Backup HMI capabilities file", common.backupHMICapabilities) +runner.Step("Update HMI capabilities file", common.updateDefaultCapabilities, { common.modules }) +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { hmiRcCapabilities }) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("GetSystemCapability Positive Case", rpcSuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) +runner.Step("Restore HMI capabilities file", common.restoreHMICapabilities) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua new file mode 100644 index 0000000000..4687c71312 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/RC/detailed_info_GetSystemCapability.md +-- Item: Use Case 2: Exception 2.1 +-- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- 1) App is Non-RC +-- 2) App tries to get RC capabilities +-- SDL must: +-- 1) Reply with DISALLOWED to App +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Functions ]] +local function ptUpdateFunc(pTbl) + local appId = config.application1.registerAppInterfaceParams.appID + pTbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } +end + +local function rpcDissallowed() + local cid = common.getMobileSession():SendRPC("GetSystemCapability", { systemCapabilityType = "REMOTE_CONTROL" }) + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { ptUpdateFunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("GetSystemCapability DISALLOWED", rpcDissallowed) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/003_UNSUPPORTED_RESOURCE_in_case_RC_interface_is_unavailable.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/003_UNSUPPORTED_RESOURCE_in_case_RC_interface_is_unavailable.lua new file mode 100644 index 0000000000..48fac27d27 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/003_UNSUPPORTED_RESOURCE_in_case_RC_interface_is_unavailable.lua @@ -0,0 +1,59 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/RC/detailed_info_GetSystemCapability.md +-- Item: Use Case 2: Exception 5.1 +-- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- 1) RC interface is not available on HMI (RC.IsReady=false) +-- 2) App is RC +-- 3) App tries to get RC capabilities +-- SDL must: +-- 1) Reply with UNSUPPORTED_RESOURCE (success=false) to App +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local hmi_values = require('user_modules/hmi_values') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.checkAllValidations = true + +--[[ Local Functions ]] +local function getHMIParams() + local params = hmi_values.getDefaultHMITable() + params.RC.IsReady.params.available = false -- RC interface is unavailable + params.RC.GetCapabilities.params = { } + params.RC.GetCapabilities.occurrence = 0 + return params +end + +local function rpcUnsupportedResource() + local cid = common.getMobileSession():SendRPC("GetSystemCapability", { systemCapabilityType = "REMOTE_CONTROL" }) + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) + :ValidIf(function(_, data) + if data.payload.systemCapability then + return false, "Capabilities are transferred to mobile application" + end + return true + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { getHMIParams() }) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("GetSystemCapability_UNSUPPORTED_RESOURCE", rpcUnsupportedResource) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/001_Success_flow.lua new file mode 100644 index 0000000000..d7caa7dbb1 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/001_Success_flow.lua @@ -0,0 +1,63 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/4 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/subscription_on_module_status_change_notification.md +-- Item: Use Case 1: Main Flow +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification +-- +-- Description: TRS: GetInteriorVehicleData, #4 +-- In case: +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter +-- 2) and SDL received GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS" from HMI +-- 3) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Internally subscribe this application for requested +-- 2) Transfer GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS", "success:true" to the related app +-- 3) Re-send OnInteriorVehicleData notification to the related app +-- +-- [SDL_RC] Unsubscribe from RC module change notifications +-- +-- Description: TRS: GetInteriorVehicleData, #8 +-- In case: +-- 1) RC app is subscribed to "" +-- 2) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS" from HMI +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Internally un-subscribe this application for requested +-- 2) Transfer GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS", "success:true" to the related app +-- 3) Does not re-send OnInteriorVehicleData notification to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", common.isSubscribed, { mod }) +end + +for _, mod in pairs(common.modules) do + runner.Step("Unsubscribe app to " .. mod, common.unSubscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is unsubscribed", common.isUnsubscribed, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua new file mode 100644 index 0000000000..2eb4921573 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Exceptions: 5.1 +-- +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) A set of module(s) is defined in policies for particular RC app +-- 2) and this RC app is subscribed to one of the module from the list +-- 3) and then SDL received OnInteriorVehicleData notification for module not in list +-- SDL must: +-- 1) Does not re-send OnInteriorVehicleData notification to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local mod = "AUDIO" + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { mod } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData " .. mod, common.subscribeToModule, { mod }) +runner.Step("OnInteriorVehicleData " .. mod, common.isUnsubscribed, { "RADIO" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua new file mode 100644 index 0000000000..e88dd60fb1 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Exceptions: 5.1 +-- +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) A set of module(s) is defined in policies for particular RC app +-- 2) and this RC app is subscribed to one of the module from the list +-- 3) and then SDL received OnInteriorVehicleData notification for module not in list +-- SDL must: +-- 1) Does not re-send OnInteriorVehicleData notification to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local mod = "LIGHT" + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { mod } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData " .. mod, common.subscribeToModule, { mod }) +runner.Step("OnInteriorVehicleData " .. mod, common.isUnsubscribed, { "RADIO" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua new file mode 100644 index 0000000000..6ef489705b --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Exceptions: 5.1 +-- +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) A set of module(s) is defined in policies for particular RC app +-- 2) and this RC app is subscribed to one of the module from the list +-- 3) and then SDL received OnInteriorVehicleData notification for module not in list +-- SDL must: +-- 1) Does not re-send OnInteriorVehicleData notification to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local mod = "HMI_SETTINGS" + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { mod } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData " .. mod, common.subscribeToModule, { mod }) +runner.Step("OnInteriorVehicleData " .. mod, common.isUnsubscribed, { "RADIO" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua new file mode 100644 index 0000000000..63c1de1647 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/4 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/subscription_on_module_status_change_notification.md +-- Use Case 1: Alternative flow 1 +-- +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification +-- +-- Description: TRS: GetInteriorVehicleData, #5 +-- In case: +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter +-- 2) and SDL received GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS" from HMI +-- 3) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS", "success:true" to the related app +-- 2) Does not re-send OnInteriorVehicleData notification to the app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function subscriptionToModule(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = false -- not subscribe + }) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = false + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, subscriptionToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", common.isUnsubscribed, + { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua new file mode 100644 index 0000000000..4ca483025f --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua @@ -0,0 +1,75 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Alternative flow 1 +-- +-- Requirement summary: +-- [SDL_RC] Unsubscribe from RC module change notifications +-- +-- Description: TRS: GetInteriorVehicleData, #9 +-- In case: +-- 1) RC app is subscribed to "" +-- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS" from HMI +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS", "success:true" to the related app +-- 2) Re-send OnInteriorVehicleData notification to the app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function unSubscriptionToModule(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = false + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = false + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = true -- HMI responds with true + }) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = true + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", common.isSubscribed, { mod }) +end + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, unSubscriptionToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App still subscribed", common.isSubscribed, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua new file mode 100644 index 0000000000..0ba691b995 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -0,0 +1,75 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Alternative flow 2 +-- +-- Requirement summary: +-- [SDL_RC] Unsubscribe from RC module change notifications +-- +-- Description: TRS: GetInteriorVehicleData, #10 +-- In case: +-- 1) RC app is subscribed to "" +-- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response without "isSubscribed" parameter, "resultCode: SUCCESS" from HMI +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS", "success:true" to the related app +-- 2) Re-send OnInteriorVehicleData notification to the app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function unSubscriptionToModule(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = false + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = false + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlDataForResponse(pModuleType), + -- no isSubscribed parameter + }) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = true + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", common.isSubscribed, { mod }) +end + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, unSubscriptionToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App still subscribed", common.isSubscribed, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua new file mode 100644 index 0000000000..23193d50e3 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -0,0 +1,81 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Alternative flow 3 +-- +-- Requirement summary: +-- [SDL_RC] Unsubscribe from RC module change notifications +-- +-- Description: TRS: GetInteriorVehicleData, #11 +-- In case: +-- 1) RC app is subscribed to "" +-- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response with "resultCode: " from HMI +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "resultCode: " +-- and without "isSubscribed" param to the related app +-- 2) Re-send OnInteriorVehicleData notification to the app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } +local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } + +--[[ Local Functions ]] +local function unSubscriptionToModule(pModuleType, pResultCode) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = false + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = false + }) + :Do(function(_, data) + common.getHMIconnection():SendError(data.id, data.method, pResultCode, "Error error") + -- no isSubscribed parameter + end) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = pResultCode }) + :ValidIf(function(_, data) -- no isSubscribed parameter + if data.payload.isSubscribed == nil then + return true + end + return false, 'Parameter "isSubscribed" is transfered to App with value: ' .. tostring(data.payload.isSubscribed) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App subscribed", common.isSubscribed, { mod }) +end + +runner.Title("Test") + +for _, mod in pairs(modules) do + for _, err in pairs(error_codes) do + runner.Step("Unsubscribe app to " .. mod .. " (" .. err .. " from HMI)", unSubscriptionToModule, { mod, err }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App still subscribed", common.isSubscribed, + { mod }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua new file mode 100644 index 0000000000..57bedf68d7 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua @@ -0,0 +1,63 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #1 +-- In case: +-- 1) SDL received OnRemoteControlSettings notification from HMI with allowed:true +-- 2) and "accessMode" = "AUTO_ALLOW" or without "accessMode" parameter at all +-- 3) and RC_module on HMI is alreay in control by RC-application +-- SDL must: +-- 1) provide access to RC_module for the second RC_application in HMILevel FULL after it sends control RPC +-- (either SetInteriorVehicleData or ButtonPress) for the same RC_module without asking a driver +-- 2) process the request from the second RC_application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } +local access_modes = { nil, "AUTO_ALLOW" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) +runner.Step("RAI2", common.raiN, { 2 }) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + for i = 1, #access_modes do + runner.Title("Access mode: " .. tostring(access_modes[i])) + -- set control for App1 + runner.Step("Activate App1", common.activateApp) + runner.Step("App1 SetInteriorVehicleData", common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set RA mode + runner.Step("Set RA mode", common.defineRAMode, { true, access_modes[i] }) + -- set control for App2 --> Allowed + runner.Step("Activate App2", common.activateApp, { 2 }) + runner.Step("App2 SetInteriorVehicleData", common.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua new file mode 100644 index 0000000000..43a66a26dd --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua @@ -0,0 +1,67 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 1 +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #2 +-- In case: +-- 1) SDL received OnRemoteControlSettings notification from HMI with allowed:true +-- 2) and with any "accessMode" or without "accessMode" parameter at all +-- 3) and RC_module on HMI is alreay in control by RC-application_1 +-- 4) and another RC_application_2 is in HMILevel other than FULL (either LIMITED or BACKGROUND) +-- SDL must: +-- 1) deny access to RC_module for another RC_application_2 after it sends control RPC +-- (either SetInteriorVehicleData or ButtonPress) for the same RC_module without asking a driver +-- 2) not process the request from RC_application_2 and respond with result code REJECTED, success:false +-- 3) leave RC_application_1 in control of the RC_module +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } +local access_modes = { nil, "AUTO_ALLOW", "AUTO_DENY", "ASK_DRIVER" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) +runner.Step("Activate App1", common.activateApp) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Activate App2", common.activateApp, { 2 }) + +-- App's HMI levels: 1 - BACKGROUND, 2 - FULL + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App2 + runner.Step("App2 SetInteriorVehicleData", common.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + for i = 1, #access_modes do + runner.Title("Access mode: " .. tostring(access_modes[i])) + -- set RA mode + runner.Step("Set RA mode", common.defineRAMode, { true, access_modes[i] }) + -- try to set control for App1 --> Denied + runner.Step("App1 SetInteriorVehicleData", common.rpcDenied, { mod, 1, "SetInteriorVehicleData", "REJECTED" }) + -- try to set control for App2 --> Allowed + runner.Step("App2 SetInteriorVehicleData", common.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua new file mode 100644 index 0000000000..9c65480feb --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md +-- Item: Use Case 2: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- RC_functionality is disabled on HMI and HMI sends notification OnRemoteControlSettings (allowed:true, ) +-- +-- SDL must: +-- 1) store RC state allowed:true and received from HMI internally +-- 2) allow RC functionality for applications with REMOTE_CONTROL appHMIType +-- +-- Case: accessMode = "AUTO_ALLOW" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +local function disableRcFromHmi() + common.defineRAMode(false, nil) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Disable RC from HMI", disableRcFromHmi) + +runner.Title("Test") +runner.Step("Enable RC from HMI with AUTO_ALLOW access mode", common.defineRAMode, { true, "AUTO_ALLOW"}) +for _, mod in pairs(modules) do + runner.Step("Activate App1", common.activateApp) + runner.Step("Check module " .. mod .." App1 SetInteriorVehicleData allowed", common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + runner.Step("Activate App2", common.activateApp, { 2 }) + runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed", common.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/004_Allowed_true_accessMode_AUTO_DENY.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/004_Allowed_true_accessMode_AUTO_DENY.lua new file mode 100644 index 0000000000..95f253c0a8 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/004_Allowed_true_accessMode_AUTO_DENY.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md +-- Item: Use Case 2: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- RC_functionality is disabled on HMI and HMI sends notification OnRemoteControlSettings (allowed:true, ) +-- +-- SDL must: +-- 1) store RC state allowed:true and received from HMI internally +-- 2) allow RC functionality for applications with REMOTE_CONTROL appHMIType +-- +-- Case: accessMode = "AUTO_DENY" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +local function disableRcFromHmi(self) + common.defineRAMode(false, nil, self) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Disable RC from HMI", disableRcFromHmi) + +runner.Title("Test") +runner.Step("Enable RC from HMI with AUTO_DENY access mode", common.defineRAMode, { true, "AUTO_DENY"}) +for _, mod in pairs(modules) do + runner.Step("Activate App1", common.activateApp) + runner.Step("Check module " .. mod .." App1 SetInteriorVehicleData allowed", common.rpcAllowed, + { mod, 1, "SetInteriorVehicleData" }) + runner.Step("Activate App2", common.activateApp, { 2 }) + runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData denied", common.rpcDenied, + { mod, 2, "SetInteriorVehicleData", "IN_USE" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/005_Allowed_true_accessMode_ASK_DRIVER.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/005_Allowed_true_accessMode_ASK_DRIVER.lua new file mode 100644 index 0000000000..6dc084f042 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/005_Allowed_true_accessMode_ASK_DRIVER.lua @@ -0,0 +1,64 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md +-- Item: Use Case 2: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- RC_functionality is disabled on HMI and HMI sends notification OnRemoteControlSettings (allowed:true, ) +-- +-- SDL must: +-- 1) store RC state allowed:true and received from HMI internally +-- 2) allow RC functionality for applications with REMOTE_CONTROL appHMIType +-- +-- Case: accessMode = "ASK_DRIVER" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +local function disableRcFromHmi(self) + common.defineRAMode(false, nil, self) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Disable RC from HMI", disableRcFromHmi) + +runner.Title("Test") +runner.Step("Enable RC from HMI with ASK_DRIVER access mode", common.defineRAMode, { true, "ASK_DRIVER"}) +runner.Step("Activate App2", common.activateApp, { 2 }) +for _, mod in pairs(modules) do + runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed", common.rpcAllowed, + { mod, 2, "SetInteriorVehicleData" }) + runner.Step("Activate App1", common.activateApp) + runner.Step("Check module " .. mod .." App1 SetInteriorVehicleData allowed with driver consent", + common.rpcAllowedWithConsent, { mod, 1, "SetInteriorVehicleData" }) + runner.Step("Activate App2", common.activateApp, { 2 }) + runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed with driver consent", + common.rpcAllowedWithConsent, { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/006_Default_accessMode.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/006_Default_accessMode.lua new file mode 100644 index 0000000000..6387d63b7e --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/006_Default_accessMode.lua @@ -0,0 +1,53 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- HMI didn't send OnRemoteControlSettings notifications on systems start +-- +-- SDL must: +-- use default value allowed:true and accessMode = "AUTO_ALLOW" for all registered REMOTE_CONTROL applications +-- until OnRemoteControlSettings notification with other settings is received +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) +runner.Step("RAI2", common.raiN, { 2 }) + +runner.Title("Test") +for _, mod in pairs(modules) do + runner.Step("Activate App2", common.activateApp, { 2 }) + runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed", + common.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("Activate App1", common.activateApp) + runner.Step("Check module " .. mod .." App1 SetInteriorVehicleData allowed", + common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/001_Success_flow.lua new file mode 100644 index 0000000000..ff43ad2714 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/001_Success_flow.lua @@ -0,0 +1,41 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) and sends valid SetInteriorVehicleData RPC with valid parameters +-- SDL must: +-- 1) Transfer this request to HMI +-- 2) Respond with received from HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod, common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua new file mode 100644 index 0000000000..2530721fbc --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 4.1 +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received SetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local mod = "CLIMATE" + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = common.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua new file mode 100644 index 0000000000..18c29a6e63 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 4.1 +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received SetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local mod = "AUDIO" + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = common.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua new file mode 100644 index 0000000000..c3fa95671d --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 4.1 +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received SetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local mod = "LIGHT" + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = common.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua new file mode 100644 index 0000000000..00202d0464 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 4.1 +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received SetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local mod = "HMI_SETTINGS" + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = common.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua new file mode 100644 index 0000000000..0e92caf8e1 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -0,0 +1,67 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has an empty array +-- 2) and RC app sends SetInteriorVehicleData request with valid parameters +-- SDL must: +-- 1) Allow this RPC to be processed +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local json = require('modules/json') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = common.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = common.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getSettableModuleControlData(pModuleType) + }) + end) + + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua new file mode 100644 index 0000000000..87ffb43115 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) "moduleType" does not exist in app's assigned policies +-- 2) and RC app sends SetInteriorVehicleData request with valid parameters +-- SDL must: +-- 1) Disallow this RPC to be processed (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = common.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/008_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/008_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua new file mode 100644 index 0000000000..21831a0a1a --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/008_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 7.1 +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- +-- Description: +-- In case: +-- application sends valid SetInteriorVehicleData with just read-only parameters in "radioControlData" struct for muduleType: RADIO +-- SDL must +-- respond with "resultCode: READ_ONLY, success:false" to this application and do not process this RPC. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local module_data_radio = common.getReadOnlyParamsByModule("RADIO") + +--[[ Local Functions ]] +local function setVehicleData(module_data) + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", {moduleData = module_data}) + + EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) + + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "READ_ONLY" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test: SDL respond with READ_ONLY if SetInteriorVehicleData is sent with read_only params") +runner.Step("Send SetInteriorVehicleData with read only sisData", setVehicleData, {module_data_radio}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua new file mode 100644 index 0000000000..077918a2af --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua @@ -0,0 +1,73 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source between various audio sources several times +-- SDL must: +-- 1) Change audio source successfully as many times as defined +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "RADIO_TUNER" +} + +--[[ Local Functions ]] +local function setVehicleData(pSource) + audioData.audioControlData.source = pSource + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, source in pairs(audioSources) do + runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_BACKGROUND.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_BACKGROUND.lua new file mode 100644 index 0000000000..da6953ec1c --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_BACKGROUND.lua @@ -0,0 +1,75 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in NONE or BACKGROUND HMI level +-- 3) App tries to change audio source +-- SDL must: +-- 1) Not change audio source +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true +config.application2.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "RADIO_TUNER" +} + +--[[ Local Functions ]] +local function setVehicleData(pSource) + audioData.audioControlData.source = pSource + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = audioData }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = common.getHMIAppId(), moduleData = audioData }) + :Do(function(_, data) + common.getHMIconnection():SendError(data.id, data.method, "REJECTED", "Error") + end) + + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "REJECTED", info = "Error" }) +end + +local function BringAppToBACKGROUND() + common.activateApp(2) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU App1", common.raiPTUn) +runner.Step("RAI App2", common.raiN, {2}) +runner.Step("Activate App1", common.activateApp) +runner.Step("Set App1 to BACKGROUND HMI level", BringAppToBACKGROUND) + +runner.Title("Test") +for _, source in pairs(audioSources) do + runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua new file mode 100644 index 0000000000..1d372b1222 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua @@ -0,0 +1,83 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in LIMITED HMI level +-- 3) App tries to change audio source between various audio sources several times +-- SDL must: +-- 1) Change audio source successfully as many times as defined +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "RADIO_TUNER" +} + +--[[ Local Functions ]] +local function setVehicleData(pSource) + audioData.audioControlData.source = pSource + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function bringAppToLIMITED() + common.getHMIconnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(), + reason = "GENERAL" + }) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("Set App to LIMITED HMI level", bringAppToLIMITED) + +runner.Title("Test") +for _, source in pairs(audioSources) do + runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua new file mode 100644 index 0000000000..da6953ec1c --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua @@ -0,0 +1,75 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in NONE or BACKGROUND HMI level +-- 3) App tries to change audio source +-- SDL must: +-- 1) Not change audio source +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true +config.application2.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "RADIO_TUNER" +} + +--[[ Local Functions ]] +local function setVehicleData(pSource) + audioData.audioControlData.source = pSource + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = audioData }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = common.getHMIAppId(), moduleData = audioData }) + :Do(function(_, data) + common.getHMIconnection():SendError(data.id, data.method, "REJECTED", "Error") + end) + + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "REJECTED", info = "Error" }) +end + +local function BringAppToBACKGROUND() + common.activateApp(2) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU App1", common.raiPTUn) +runner.Step("RAI App2", common.raiN, {2}) +runner.Step("Activate App1", common.activateApp) +runner.Step("Set App1 to BACKGROUND HMI level", BringAppToBACKGROUND) + +runner.Title("Test") +for _, source in pairs(audioSources) do + runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_FULL_rc_non_media_app.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_FULL_rc_non_media_app.lua new file mode 100644 index 0000000000..5c9c76218d --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_FULL_rc_non_media_app.lua @@ -0,0 +1,67 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Non-Media +-- 2) App in any HMI level +-- 3) App tries to change audio source +-- SDL must: +-- 1) Not change audio source +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = false + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "RADIO_TUNER" +} + +--[[ Local Functions ]] +local function setVehicleData(pSource) + audioData.audioControlData.source = pSource + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + -- Confirmation nedded, not clear what resultCode must be + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, source in pairs(audioSources) do + runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_from_MOBILE_APP_without_keepContext.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_from_MOBILE_APP_without_keepContext.lua new file mode 100644 index 0000000000..4d1c5d8d74 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_from_MOBILE_APP_without_keepContext.lua @@ -0,0 +1,86 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source from MOBILE_APP with keepContext = false +-- SDL must: +-- 1) Change audio source successfully +-- 2) Change HMI level of App to BACKGROUND +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") + +--[[ Local Functions ]] +local function setVehicleDataMobileApp() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "MOBILE_APP" + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function setVehicleData() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "USB" + audioData.audioControlData.keepContext = nil + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) + +runner.Title("Test") +runner.Step("Change audio source from MOBILE_APP without keepContext", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua new file mode 100644 index 0000000000..5c9c76218d --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua @@ -0,0 +1,67 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Non-Media +-- 2) App in any HMI level +-- 3) App tries to change audio source +-- SDL must: +-- 1) Not change audio source +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = false + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "RADIO_TUNER" +} + +--[[ Local Functions ]] +local function setVehicleData(pSource) + audioData.audioControlData.source = pSource + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + -- Confirmation nedded, not clear what resultCode must be + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, source in pairs(audioSources) do + runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_keepContext_false.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_keepContext_false.lua new file mode 100644 index 0000000000..b5942647c3 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_keepContext_false.lua @@ -0,0 +1,86 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source from MOBILE_APP without keepContext parameter defined +-- SDL must: +-- 1) Change audio source successfully +-- 2) Change HMI level of App to BACKGROUND +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") + +--[[ Local Functions ]] +local function setVehicleDataMobileApp() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "MOBILE_APP" + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function setVehicleData() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "USB" + audioData.audioControlData.keepContext = false + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) + +runner.Title("Test") +runner.Step("Change audio source from MOBILE_APP keepContext is false", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_without_keepContext.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_without_keepContext.lua new file mode 100644 index 0000000000..4d1c5d8d74 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_without_keepContext.lua @@ -0,0 +1,86 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source from MOBILE_APP with keepContext = false +-- SDL must: +-- 1) Change audio source successfully +-- 2) Change HMI level of App to BACKGROUND +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") + +--[[ Local Functions ]] +local function setVehicleDataMobileApp() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "MOBILE_APP" + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function setVehicleData() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "USB" + audioData.audioControlData.keepContext = nil + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) + +runner.Title("Test") +runner.Step("Change audio source from MOBILE_APP without keepContext", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_false.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_false.lua new file mode 100644 index 0000000000..b5942647c3 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_false.lua @@ -0,0 +1,86 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source from MOBILE_APP without keepContext parameter defined +-- SDL must: +-- 1) Change audio source successfully +-- 2) Change HMI level of App to BACKGROUND +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") + +--[[ Local Functions ]] +local function setVehicleDataMobileApp() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "MOBILE_APP" + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function setVehicleData() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "USB" + audioData.audioControlData.keepContext = false + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) + +runner.Title("Test") +runner.Step("Change audio source from MOBILE_APP keepContext is false", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua new file mode 100644 index 0000000000..f4f5afd6d0 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua @@ -0,0 +1,86 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1)App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source from MOBILE_APP with keepContext = true +-- SDL must: +-- 1) Change audio source successfully +-- 2) Not change HMI level, but change audioStreamingState to "NOT_AUDIBLE" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") + +--[[ Local Functions ]] +local function setVehicleDataMobileApp() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "MOBILE_APP" + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function setVehicleData() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "USB" + audioData.audioControlData.keepContext = true + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) + +runner.Title("Test") +runner.Step("Change audio source from MOBILE_APP keepContext is true", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua new file mode 100644 index 0000000000..f4f5afd6d0 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua @@ -0,0 +1,86 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1)App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source from MOBILE_APP with keepContext = true +-- SDL must: +-- 1) Change audio source successfully +-- 2) Not change HMI level, but change audioStreamingState to "NOT_AUDIBLE" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") + +--[[ Local Functions ]] +local function setVehicleDataMobileApp() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "MOBILE_APP" + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function setVehicleData() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "USB" + audioData.audioControlData.keepContext = true + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) + +runner.Title("Test") +runner.Step("Change audio source from MOBILE_APP keepContext is true", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua new file mode 100644 index 0000000000..e7b1e7728b --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua @@ -0,0 +1,96 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1)App is RC and Media +-- 2) App in LIMITED HMI level +-- 3) App tries to change audio source from MOBILE_APP with keepContext = true +-- SDL must: +-- 1) Change audio source successfully +-- 2) Change HMI level to BACKGROUND and change audioStreamingState to "NOT_AUDIBLE" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") + +--[[ Local Functions ]] +local function setVehicleDataMobileApp() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "MOBILE_APP" + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function setVehicleData() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "USB" + audioData.audioControlData.keepContext = true + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +local function bringAppToLIMITED() + common.getHMIconnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(), + reason = "GENERAL" + }) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("Set App to LIMITED HMI level", bringAppToLIMITED) +runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) + +runner.Title("Test") +runner.Step("Change audio source from MOBILE_APP keepContext is true", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua new file mode 100644 index 0000000000..e7b1e7728b --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua @@ -0,0 +1,96 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1)App is RC and Media +-- 2) App in LIMITED HMI level +-- 3) App tries to change audio source from MOBILE_APP with keepContext = true +-- SDL must: +-- 1) Change audio source successfully +-- 2) Change HMI level to BACKGROUND and change audioStreamingState to "NOT_AUDIBLE" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") + +--[[ Local Functions ]] +local function setVehicleDataMobileApp() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "MOBILE_APP" + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function setVehicleData() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "USB" + audioData.audioControlData.keepContext = true + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +local function bringAppToLIMITED() + common.getHMIconnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(), + reason = "GENERAL" + }) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("Set App to LIMITED HMI level", bringAppToLIMITED) +runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) + +runner.Title("Test") +runner.Step("Change audio source from MOBILE_APP keepContext is true", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua new file mode 100644 index 0000000000..68e6e2b82f --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua @@ -0,0 +1,88 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source from any type except of MOBILE_APP and with any value of keepContext parameter or event without it +-- SDL must: +-- 1) Change audio source successfully +-- 2) Not change HMI level +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "RADIO_TUNER" +} + +local keepContext = { + false, + true, + "empty" +} + +--[[ Local Functions ]] +local function setVehicleData(pSource,pKeepContext) + local mobSession = common.getMobileSession() + audioData.audioControlData.source = pSource + if "empty" == pKeepContext then + audioData.audioControlData.keepContext = nil + else + audioData.audioControlData.keepContext = pKeepContext + end + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, source in pairs(audioSources) do + for _, keepContextValue in pairs(keepContext) do + runner.Step("Change audio source from " .. source .. " source with keepContext is " .. + tostring(keepContextValue), setVehicleData, { source, keepContextValue }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua new file mode 100644 index 0000000000..68e6e2b82f --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua @@ -0,0 +1,88 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source from any type except of MOBILE_APP and with any value of keepContext parameter or event without it +-- SDL must: +-- 1) Change audio source successfully +-- 2) Not change HMI level +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "RADIO_TUNER" +} + +local keepContext = { + false, + true, + "empty" +} + +--[[ Local Functions ]] +local function setVehicleData(pSource,pKeepContext) + local mobSession = common.getMobileSession() + audioData.audioControlData.source = pSource + if "empty" == pKeepContext then + audioData.audioControlData.keepContext = nil + else + audioData.audioControlData.keepContext = pKeepContext + end + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, source in pairs(audioSources) do + for _, keepContextValue in pairs(keepContext) do + runner.Step("Change audio source from " .. source .. " source with keepContext is " .. + tostring(keepContextValue), setVehicleData, { source, keepContextValue }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua new file mode 100644 index 0000000000..a0aa23083b --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua @@ -0,0 +1,625 @@ +--------------------------------------------------------------------------------------------------- +-- RC common module for AUDIO, LIGHT, HMI_SETTINGS modules +--------------------------------------------------------------------------------------------------- +config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } + +--[[ Required Shared libraries ]] +local commonRC = require("test_scripts/RC/commonRC") +local test = require("user_modules/dummy_connecttest") +local hmi_values = require("user_modules/hmi_values") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') + +--[[ Local Variables ]] +local c = {} +c.modules = { "RADIO", "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } +c.capMap = { + ["RADIO"] = "radioControlCapabilities", + ["CLIMATE"] = "climateControlCapabilities", + ["AUDIO"] = "audioControlCapabilities", + ["LIGHT"] = "lightControlCapabilities", + ["HMI_SETTINGS"] = "hmiSettingsControlCapabilities" +} + +c.backupHMICapabilities = commonRC.backupHMICapabilities +c.restoreHMICapabilities = commonRC.restoreHMICapabilities +c.DEFAULT = commonRC.DEFAULT + +function c.preconditions() + commonRC.preconditions() +end + +function c.start(pHMIParams) + commonRC.start(pHMIParams, test) +end + +local function audibleState(pAppId) + if not pAppId then pAppId = 1 end + local appParams = config["application" .. pAppId].registerAppInterfaceParams + local audibleState + if appParams.isMediaApplication == true then + audibleState = "AUDIBLE" + else + audibleState = "NOT_AUDIBLE" + end + return audibleState +end + +function c.AddOnRCStatusToPT(tbl) + tbl.policy_table.functional_groupings.RemoteControl.rpcs.OnRCStatus = { + hmi_levels = { "NONE", "BACKGROUND", "FULL", "LIMITED" } + } +end + +function c.getRCAppConfig() + local struct = commonRC.getRCAppConfig() + struct.moduleType = c.modules + return struct +end + +local function PTUfunc(tbl) + c.AddOnRCStatusToPT(tbl) + local appId = config.application1.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId] = c.getRCAppConfig() +end + +function c.raiPTUn(pPTUfunc, pAppId) + if not pAppId then pAppId = 1 end + if not pPTUfunc then + pPTUfunc = PTUfunc + end + commonRC.rai_ptu_n(pAppId, pPTUfunc, test) +end + +function c.raiN(pAppId) + commonRC.rai_n(pAppId, test) +end + +function c.getHMIAppId(pAppId) + local appId = commonRC.getHMIAppId(pAppId) + return appId +end + +function c.getModuleControlData(pModuleType) + local struct = {} + if "CLIMATE" == pModuleType then + struct.moduleType = "CLIMATE" + struct.climateControlData = {} + struct.climateControlData.heatedSteeringWheelEnable = true + struct.climateControlData.heatedWindshieldEnable = true + struct.climateControlData.heatedRearWindowEnable = true + struct.climateControlData.heatedMirrorsEnable = true + elseif "RADIO" == pModuleType then + struct.moduleType = "RADIO" + struct.radioControlData = {} + struct.radioControlData.sisData = { + stationShortName = "Name1", + stationIDNumber = { + countryCode = 100, + fccFacilityId = 100 + }, + stationLongName = "RadioStationLongName", + stationLocation = { + longitudeDegrees = 0.1, + latitudeDegrees = 0.1, + altitudeMeters = 0.1 + }, + stationMessage = "station message" + } + elseif "AUDIO" == pModuleType then + struct.moduleType = "AUDIO" + struct.audioControlData = { + source = "RADIO_TUNER", + keepContext = false, + volume = 50, + equalizerSettings = { + { + channelId = 10, + channelName = "Channel 1", + channelSetting = 50 + } + } + } + elseif "LIGHT" == pModuleType then + struct.moduleType = "LIGHT" + struct.lightControlData = { + lightState = { + { + id = "FRONT_LEFT_HIGH_BEAM", + status = "ON", + density = 0.2, + sRGBColor = { + red = 50, + green = 150, + blue = 200 + } + } + } + } + elseif "HMI_SETTINGS" == pModuleType then + struct.moduleType = "HMI_SETTINGS" + struct.hmiSettingsControlData = { + displayMode = "DAY", + temperatureUnit = "CELSIUS", + distanceUnit = "KILOMETERS" + } + end + return struct +end + +function c.getAnotherModuleControlData(pModuleType) + local struct = {} + if "CLIMATE" == pModuleType then + struct.moduleType = "CLIMATE" + struct.climateControlData = {} + struct.climateControlData.heatedSteeringWheelEnable = false + struct.climateControlData.heatedWindshieldEnable = false + struct.climateControlData.heatedRearWindowEnable = false + struct.climateControlData.heatedMirrorsEnable = false + elseif "RADIO" == pModuleType then + struct.moduleType = "RADIO" + struct.radioControlData = {} + struct.radioControlData.sisData = { + stationShortName = "Name2", + stationIDNumber = { + countryCode = 200, + fccFacilityId = 200 + }, + stationLongName = "RadioStationLongName2", + stationLocation = { + longitudeDegrees = 20.1, + latitudeDegrees = 20.1, + altitudeMeters = 20.1 + }, + stationMessage = "station message 2" + } + elseif "AUDIO" == pModuleType then + struct.moduleType = "AUDIO" + struct.audioControlData = { + source = "USB", + keepContext = true, + volume = 20, + equalizerSettings = { + { + channelId = 20, + channelName = "Channel 2", + channelSetting = 20 + } + } + } + elseif "LIGHT" == pModuleType then + struct.moduleType = "LIGHT" + struct.lightControlData = { + lightState = { + { + id = "READING_LIGHTS", + status = "ON", + density = 0.5, + sRGBColor = { + red = 150, + green = 200, + blue = 250 + } + } + } + } + elseif "HMI_SETTINGS" == pModuleType then + struct.moduleType = "HMI_SETTINGS" + struct.hmiSettingsControlData = { + displayMode = "NIGHT", + temperatureUnit = "FAHRENHEIT", + distanceUnit = "MILES" + } + end + return struct +end + +function c.getModuleParams(pModuleData) + if pModuleData.moduleType == "RADIO" then + if not pModuleData.radioControlData then + pModuleData.radioControlData = { } + end + return pModuleData.radioControlData + elseif pModuleData.moduleType == "AUDIO" then + if not pModuleData.audioControlData then + pModuleData.audioControlData = { } + end + return pModuleData.audioControlData + end +end + +function c.getReadOnlyParamsByModule(pModuleType) + local out = { moduleType = pModuleType } + if pModuleType == "RADIO" then + out.radioControlData = { + sisData = { + stationShortName = "Name2", + stationIDNumber = { + countryCode = 200, + fccFacilityId = 200 + }, + stationLongName = "RadioStationLongName2", + stationLocation = { + longitudeDegrees = 20.1, + latitudeDegrees = 20.1, + altitudeMeters = 20.1 + }, + stationMessage = "station message 2" + } + } + elseif pModuleType == "AUDIO" then + out.audioControlData = { + equalizerSettings = { { channelName = "Channel 1" } } + } + end + return out +end + +function c.getSettableModuleControlData(pModuleType) + local out = c.getModuleControlData(pModuleType) + local params_read_only = c.getModuleParams(c.getReadOnlyParamsByModule(pModuleType)) + if params_read_only then + for p_read_only, p_read_only_value in pairs(params_read_only) do + if pModuleType == "AUDIO" then + for sub_read_only_key, sub_read_only_value in pairs(p_read_only_value) do + for sub_read_only_name in pairs(sub_read_only_value) do + c.getModuleParams(out)[p_read_only][sub_read_only_key][sub_read_only_name] = nil + end + end + else + c.getModuleParams(out)[p_read_only] = nil + end + end + end + return out +end + +-- RC RPCs structure +local rcRPCs = { + GetInteriorVehicleData = { + appEventName = "GetInteriorVehicleData", + hmiEventName = "RC.GetInteriorVehicleData", + requestParams = function(pModuleType, pSubscribe) + return { + moduleType = pModuleType, + subscribe = pSubscribe + } + end, + hmiRequestParams = function(pModuleType, pAppId, pSubscribe) + return { + appID = c.getHMIAppId(pAppId), + moduleType = pModuleType, + subscribe = pSubscribe + } + end, + hmiResponseParams = function(pModuleType, pSubscribe) + local GetInteriorVDModuleData = c.getModuleControlData(pModuleType) + if GetInteriorVDModuleData.audioControlData then + GetInteriorVDModuleData.audioControlData.keepContext = nil + end + return { + moduleData = GetInteriorVDModuleData, + isSubscribed = pSubscribe + } + end, + responseParams = function(success, resultCode, pModuleType, pSubscribe) + local GetInteriorVDModuleData = c.getModuleControlData(pModuleType) + if GetInteriorVDModuleData.audioControlData then + GetInteriorVDModuleData.audioControlData.keepContext = nil + end + return { + success = success, + resultCode = resultCode, + moduleData = GetInteriorVDModuleData, + isSubscribed = pSubscribe + } + end + }, + SetInteriorVehicleData = { + appEventName = "SetInteriorVehicleData", + hmiEventName = "RC.SetInteriorVehicleData", + requestParams = function(pModuleType) + return { + moduleData = c.getSettableModuleControlData(pModuleType) + } + end, + hmiRequestParams = function(pModuleType, pAppId) + return { + appID = c.getHMIAppId(pAppId), + moduleData = c.getSettableModuleControlData(pModuleType) + } + end, + hmiResponseParams = function(pModuleType) + return { + moduleData = c.getSettableModuleControlData(pModuleType) + } + end, + responseParams = function(success, resultCode, pModuleType) + return { + success = success, + resultCode = resultCode, + moduleData = c.getSettableModuleControlData(pModuleType) + } + end + }, + ButtonPress = { + appEventName = "ButtonPress", + hmiEventName = "Buttons.ButtonPress", + requestParams = function(pModuleType) + return { + moduleType = pModuleType, + buttonName = c.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + } + end, + hmiRequestParams = function(pModuleType, pAppId) + return { + appID = c.getHMIAppId(pAppId), + moduleType = pModuleType, + buttonName = c.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + } + end, + hmiResponseParams = function() + return {} + end, + responseParams = function(success, resultCode) + return { + success = success, + resultCode = resultCode + } + end + }, + GetInteriorVehicleDataConsent = { + hmiEventName = "RC.GetInteriorVehicleDataConsent", + hmiRequestParams = function(pModuleType, pAppId) + return { + appID = c.getHMIAppId(pAppId), + moduleType = pModuleType + } + end, + hmiResponseParams = function(pAllowed) + return { + allowed = pAllowed + } + end, + }, + OnInteriorVehicleData = { + appEventName = "OnInteriorVehicleData", + hmiEventName = "RC.OnInteriorVehicleData", + hmiResponseParams = function(pModuleType) + local OnInteriorVDModuleData = c.getAnotherModuleControlData(pModuleType) + if OnInteriorVDModuleData.audioControlData then + OnInteriorVDModuleData.audioControlData.keepContext = nil + end + return { + moduleData = OnInteriorVDModuleData + } + end, + responseParams = function(pModuleType) + local OnInteriorVDModuleData = c.getAnotherModuleControlData(pModuleType) + if OnInteriorVDModuleData.audioControlData then + OnInteriorVDModuleData.audioControlData.keepContext = nil + end + return { + moduleData = OnInteriorVDModuleData + } + end + }, + OnRemoteControlSettings = { + hmiEventName = "RC.OnRemoteControlSettings", + hmiResponseParams = function(pAllowed, pAccessMode) + return { + allowed = pAllowed, + accessMode = pAccessMode + } + end + } +} + +function c.getAppEventName(pRPC) + return rcRPCs[pRPC].appEventName +end + +function c.getHMIEventName(pRPC) + return rcRPCs[pRPC].hmiEventName +end + +function c.getAppRequestParams(pRPC, ...) + return rcRPCs[pRPC].requestParams(...) +end + +function c.getAppResponseParams(pRPC, ...) + return rcRPCs[pRPC].responseParams(...) +end + +function c.getHMIRequestParams(pRPC, ...) + return rcRPCs[pRPC].hmiRequestParams(...) +end + +function c.getHMIResponseParams(pRPC, ...) + return rcRPCs[pRPC].hmiResponseParams(...) +end + +function c.getMobileSession(pAppId) + if not pAppId then pAppId = 1 end + return test["mobileSession" .. pAppId] +end + +function c.getHMIconnection() + return test.hmiConnection +end + +function c.subscribeToModule(pModuleType, pAppId) + if not pAppId then pAppId = 1 end + local rpc = "GetInteriorVehicleData" + local subscribe = true + local mobSession = c.getMobileSession(pAppId) + local cid = mobSession:SendRPC(c.getAppEventName(rpc), c.getAppRequestParams(rpc, pModuleType, subscribe)) + EXPECT_HMICALL(c.getHMIEventName(rpc), c.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe)) + :Do(function(_, data) + test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + c.getHMIResponseParams(rpc, pModuleType, subscribe)) + end) + mobSession:ExpectResponse(cid, c.getAppResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) + :ValidIf(function(_,data) + if "AUDIO" == pModuleType and + nil ~= data.payload.moduleData.audioControlData.keepContext then + return false, "Mobile response GetInteriorVehicleData contains unexpected keepContext parameter" + end + return true + end) +end + +function c.unSubscribeToModule(pModuleType, pAppId) + local rpc = "GetInteriorVehicleData" + local subscribe = false + local mobSession = c.getMobileSession(pAppId) + local cid = mobSession:SendRPC(c.getAppEventName(rpc), c.getAppRequestParams(rpc, pModuleType, subscribe)) + EXPECT_HMICALL(c.getHMIEventName(rpc), c.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe)) + :Do(function(_, data) + test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + c.getHMIResponseParams(rpc, pModuleType, subscribe)) + end) + mobSession:ExpectResponse(cid, c.getAppResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) + :ValidIf(function(_,data) + if "AUDIO" == pModuleType and + nil ~= data.payload.moduleData.audioControlData.keepContext then + return false, "Mobile response GetInteriorVehicleData contains unexpected keepContext parameter" + end + return true + end) +end + +function c.activateApp(pAppId) + if not pAppId then pAppId = 1 end + local pHMIAppId = c.getHMIAppId(pAppId) + local mobSession = c.getMobileSession(pAppId) + local requestId = test.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + EXPECT_HMIRESPONSE(requestId) + mobSession:ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = audibleState(), + systemContext = "MAIN" }) +end + +function c.defineRAMode(pAllowed, pAccessMode) + commonRC.defineRAMode(pAllowed, pAccessMode, test) +end + +function c.rpcAllowed(pModuleType, pAppId, pRPC) + local mobSession = c.getMobileSession(pAppId) + local cid = mobSession:SendRPC(c.getAppEventName(pRPC), c.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(c.getHMIEventName(pRPC), c.getHMIRequestParams(pRPC, pModuleType, pAppId)) + :Do(function(_, data) + test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", c.getHMIResponseParams(pRPC, pModuleType)) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +function c.rpcAllowedWithConsent(pModuleType, pAppId, pRPC) + local mobSession = c.getMobileSession(pAppId) + local cid = mobSession:SendRPC(c.getAppEventName(pRPC), c.getAppRequestParams(pRPC, pModuleType)) + local consentRPC = "GetInteriorVehicleDataConsent" + EXPECT_HMICALL(c.getHMIEventName(consentRPC), c.getHMIRequestParams(consentRPC, pModuleType, pAppId)) + :Do(function(_, data) + test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", c.getHMIResponseParams(consentRPC, true)) + EXPECT_HMICALL(c.getHMIEventName(pRPC), c.getHMIRequestParams(pRPC, pModuleType, pAppId)) + :Do(function(_, data2) + test.hmiConnection:SendResponse(data2.id, data2.method, "SUCCESS", c.getHMIResponseParams(pRPC, pModuleType)) + end) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +function c.isSubscribed(pModuleType, pAppId) + local mobSession = c.getMobileSession(pAppId) + local rpc = "OnInteriorVehicleData" + test.hmiConnection:SendNotification(c.getHMIEventName(rpc), c.getHMIResponseParams(rpc, pModuleType)) + mobSession:ExpectNotification(c.getAppEventName(rpc), c.getAppResponseParams(rpc, pModuleType)) + :ValidIf(function(_,data) + if "AUDIO" == pModuleType and + nil ~= data.payload.moduleData.audioControlData.keepContext then + return false, "Mobile notification OnInteriorVehicleData contains unexpected keepContext parameter" + end + return true + end) +end + +function c.isUnsubscribed(pModuleType, pAppId) + local mobSession = c.getMobileSession(pAppId) + local rpc = "OnInteriorVehicleData" + test.hmiConnection:SendNotification(c.getHMIEventName(rpc), c.getHMIResponseParams(rpc, pModuleType)) + mobSession:ExpectNotification(c.getAppEventName(rpc), {}):Times(0) +end + +function c.rpcDenied(pModuleType, pAppId, pRPC, pResultCode) + local mobSession = c.getMobileSession(pAppId) + local cid = mobSession:SendRPC(c.getAppEventName(pRPC), c.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(c.getHMIEventName(pRPC), {}):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = pResultCode }) +end + +function c.rpcRejectWithConsent(pModuleType, pAppId, pRPC) + local info = "The resource is in use and the driver disallows this remote control RPC" + local consentRPC = "GetInteriorVehicleDataConsent" + local mobSession = c.getMobileSession(pAppId) + local cid = mobSession:SendRPC(c.getAppEventName(pRPC), c.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(c.getHMIEventName(consentRPC), c.getHMIRequestParams(consentRPC, pModuleType, pAppId)) + :Do(function(_, data) + test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", c.getHMIResponseParams(consentRPC, false)) + EXPECT_HMICALL(c.getHMIEventName(pRPC)):Times(0) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED", info = info }) +end + +function c.rpcRejectWithoutConsent(pModuleType, pAppId, pRPC) + local mobSession = c.getMobileSession( pAppId) + local cid = mobSession:SendRPC(c.getAppEventName(pRPC), c.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(c.getHMIEventName("GetInteriorVehicleDataConsent")):Times(0) + EXPECT_HMICALL(c.getHMIEventName(pRPC)):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) +end + +function c.postconditions() + commonRC.postconditions() +end + +function c.buildHmiRcCapabilities(pCapabilities) + local hmiParams = hmi_values.getDefaultHMITable() + hmiParams.RC.IsReady.params.available = true + local capParams = hmiParams.RC.GetCapabilities.params.remoteControlCapability + for k, v in pairs(c.capMap) do + if pCapabilities[k] then + if pCapabilities[k] ~= commonRC.DEFAULT then + capParams[v] = pCapabilities[v] + end + else + capParams[v] = nil + end + end + return hmiParams +end + +function c.updateDefaultCapabilities(pDisabledModuleTypes) + local hmiCapabilitiesFile = commonPreconditions:GetPathToSDL() + .. commonFunctions:read_parameter_from_smart_device_link_ini("HMICapabilities") + local hmiCapTbl = commonRC.jsonFileToTable(hmiCapabilitiesFile) + local rcCapTbl = hmiCapTbl.UI.systemCapabilities.remoteControlCapability + for _, pDisabledModuleType in pairs(pDisabledModuleTypes) do + local buttonId = commonRC.getButtonIdByName( + rcCapTbl.buttonCapabilities, commonRC.getButtonNameByModule(pDisabledModuleType)) + table.remove(rcCapTbl.buttonCapabilities, buttonId) + rcCapTbl[c.capMap[pDisabledModuleType]] = nil + end + commonRC.tableToJsonFile(hmiCapTbl, hmiCapabilitiesFile) +end + +function c.getModuleControlDataForResponse(pModuleType) + local moduleData = c.getModuleControlData(pModuleType) + if moduleData.audioControlData then + moduleData.audioControlData.keepContext = nil + end + return moduleData +end + +return c diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/025_IN_USE_in_case_3_requests.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/025_IN_USE_in_case_3_requests.lua new file mode 100644 index 0000000000..1a8ca84562 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/025_IN_USE_in_case_3_requests.lua @@ -0,0 +1,224 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 2 +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/9 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/button_press_emulation.md +-- Item: Use Case 1: Exception 1.5 +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exception 6.1 +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #3 +-- In case: +-- 1) SDL received OnRemoteControlSettings notification from HMI with allowed:true +-- 2) and "accessMode" = "AUTO_ALLOW" or without "accessMode" parameter at all +-- 3) and RC_module on HMI is alreay in control by RC-application_1 +-- 4) and RC_module is currently executing request by RC_application_1 +-- 5) and another RC_application_2 in HMILevel LIMITED sends control RPC (either SetInteriorVehicleData or ButtonPress) +-- 6) and another RC_application_3 in HMILevel FULL sends control RPC (either SetInteriorVehicleData or ButtonPress) +-- SDL must: +-- 1) deny access to RC_module for RC_application_2, RC_application_3 without asking a driver +-- 2) not process the request from RC_application_2, RC_application_3 and respond with result code IN_USE, success:false +-- 3) leave RC_application_1 in control of the RC_module +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local mobile_session = require("mobile_session") + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local access_modes = { nil, "AUTO_ALLOW" } +local hmiAppIds = { } + +local app1Params = config.application1.registerAppInterfaceParams +local app2Params = config.application2.registerAppInterfaceParams +local app3Params = config.application3.registerAppInterfaceParams + +app1Params.isMediaApplication = false +app1Params.appHMIType = { "NAVIGATION", "REMOTE_CONTROL" } +app2Params.isMediaApplication = true +app2Params.appHMIType = { "DEFAULT", "REMOTE_CONTROL" } +app3Params.isMediaApplication = false +app3Params.appHMIType = { "DEFAULT", "REMOTE_CONTROL" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[app1Params.appID].AppHMIType = app1Params.appHMIType + tbl.policy_table.app_policies[app2Params.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[app2Params.appID].AppHMIType = app2Params.appHMIType + tbl.policy_table.app_policies[app3Params.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[app3Params.appID].AppHMIType = app3Params.appHMIType +end + +local function step(pModuleType, pRPC1, pRPC2, self) + local cid1 + if pRPC1 == "SetInteriorVehicleData" then + cid1 = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, data) + local function hmiRespond() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + end + RUN_AFTER(hmiRespond, 4000) + end) + elseif pRPC1 == "ButtonPress" then + cid1 = self.mobileSession1:SendRPC("ButtonPress", { + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + EXPECT_HMICALL("Buttons.ButtonPress", { + appID = commonRC.getHMIAppId(1), + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + :Do(function(_, data) + local function hmiRespond() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + RUN_AFTER(hmiRespond, 4000) + end) + end + self.mobileSession1:ExpectResponse(cid1, { success = true, resultCode = "SUCCESS" }) + + local req3_func = function() + local cid3 + local pRPC3 = pRPC2 + if pRPC3 == "SetInteriorVehicleData" then + cid3 = self.mobileSession3:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + elseif pRPC3 == "ButtonPress" then + cid3 = self.mobileSession3:SendRPC("ButtonPress", { + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + end + self.mobileSession3:ExpectResponse(cid3, { success = false, resultCode = "IN_USE" }) + end + + local req2_func = function() + local cid2 + if pRPC2 == "SetInteriorVehicleData" then + cid2 = self.mobileSession2:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + elseif pRPC2 == "ButtonPress" then + cid2 = self.mobileSession2:SendRPC("ButtonPress", { + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + end + self.mobileSession2:ExpectResponse(cid2, { success = false, resultCode = "IN_USE" }) + :Do(function() + req3_func() + end) + end + + RUN_AFTER(req2_func, 1000) +end + +local function rai_n(id, self) + self, id = commonRC.getSelfAndParams(id, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC("RegisterAppInterface", + config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + end) + end) +end + +local function activate_app(pAppId, pOnHMIStatusFunc, self) + self, pAppId = commonRC.getSelfAndParams(pAppId, self) + if not pAppId then pAppId = 1 end + local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + local mobSession = commonRC.getMobileSession(self, pAppId) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + EXPECT_HMIRESPONSE(requestId) + if not pOnHMIStatusFunc then + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + else + pOnHMIStatusFunc(self) + end +end + +local function OnHMIStatus2Apps(self) + self.mobileSession2:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) +end + +local function OnHMIStatus3Apps(self) + self.mobileSession3:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + self.mobileSession1:ExpectNotification("OnHMIStatus") + :Times(0) + self.mobileSession2:ExpectNotification("OnHMIStatus", + { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", rai_n, { 2 }) +runner.Step("Activate App2", activate_app, { 2, OnHMIStatus2Apps }) +runner.Step("RAI3", rai_n, { 3 }) +runner.Step("Activate App3", activate_app, { 3, OnHMIStatus3Apps }) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + for i = 1, #access_modes do + runner.Title("Access mode: " .. tostring(access_modes[i])) + -- set RA mode + runner.Step("Set RA mode", commonRC.defineRAMode, { true, access_modes[i] }) + -- try to set control for App2 while request for App1 is executing + local rpcs = { "SetInteriorVehicleData", "ButtonPress" } + for _, rpc1 in pairs(rpcs) do + for _, rpc2 in pairs(rpcs) do + runner.Step("App1 " .. rpc1 .. " App2_App3_" .. rpc2, step, { mod, rpc1, rpc2 }) + end + end + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt b/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt new file mode 100644 index 0000000000..d7d8732a00 --- /dev/null +++ b/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt @@ -0,0 +1,54 @@ +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/004_HMI_no_response_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/005_HMI_invalid_response_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/001_Success_flow.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/003_UNSUPPORTED_RESOURCE_in_case_RC_interface_is_unavailable.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/004_Allowed_true_accessMode_AUTO_DENY.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/005_Allowed_true_accessMode_ASK_DRIVER.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/006_Default_accessMode.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/008_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_without_keepContext.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_false.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua diff --git a/test_sets/rc_CLIMATE_RADIO.txt b/test_sets/rc_CLIMATE_RADIO.txt index d960cea13e..d39912361e 100644 --- a/test_sets/rc_CLIMATE_RADIO.txt +++ b/test_sets/rc_CLIMATE_RADIO.txt @@ -89,6 +89,7 @@ ./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua ./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua ./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/025_IN_USE_in_case_3_requests.lua ./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/001_Success_flow.lua ./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua ./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index 163c2ad830..6793089132 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -346,7 +346,11 @@ function module.getDefaultHMITable() ventilationModeAvailable = true, ventilationMode = { "UPPER", "LOWER", "BOTH", "NONE" - } + }, + heatedSteeringWheelAvailable = true, + heatedWindshieldAvailable = true, + heatedRearWindowAvailable = true, + heatedMirrorsAvailable = true } }, radioControlCapabilities = { @@ -360,7 +364,17 @@ function module.getDefaultHMITable() availableHDsAvailable = true, stateAvailable = true, signalStrengthAvailable = true, - signalChangeThresholdAvailable = true + signalChangeThresholdAvailable = true, + sisDataAvailable = true + } + }, + audioControlCapabilities = { + { + moduleName = "Audio", + sourceAvailable = true, + volumeAvailable = true, + equalizerAvailable = true, + equalizerMaxChannelId = 100 } }, seatControlCapabilities = { @@ -383,6 +397,38 @@ function module.getDefaultHMITable() memoryAvailable = true } }, + hmiSettingsControlCapabilities = { + moduleName = "HmiSettings", + distanceUnitAvailable = true, + temperatureUnitAvailable = true, + displayModeUnitAvailable = true + }, + lightControlCapabilities = { + moduleName = "Light", + supportedLights = (function() + local lights = { "FRONT_LEFT_HIGH_BEAM", "FRONT_RIGHT_HIGH_BEAM", "FRONT_LEFT_LOW_BEAM", + "FRONT_RIGHT_LOW_BEAM", "FRONT_LEFT_PARKING_LIGHT", "FRONT_RIGHT_PARKING_LIGHT", + "FRONT_LEFT_FOG_LIGHT", "FRONT_RIGHT_FOG_LIGHT", "FRONT_LEFT_DAYTIME_RUNNING_LIGHT", + "FRONT_RIGHT_DAYTIME_RUNNING_LIGHT", "FRONT_LEFT_TURN_LIGHT", "FRONT_RIGHT_TURN_LIGHT", + "REAR_LEFT_FOG_LIGHT", "REAR_RIGHT_FOG_LIGHT", "REAR_LEFT_TAIL_LIGHT", "REAR_RIGHT_TAIL_LIGHT", + "REAR_LEFT_BREAK_LIGHT", "REAR_RIGHT_BREAK_LIGHT", "REAR_LEFT_TURN_LIGHT", "REAR_RIGHT_TURN_LIGHT", + "REAR_REGISTRATION_PLATE_LIGHT", "HIGH_BEAMS", "LOW_BEAMS", "FOG_LIGHTS", "RUNNING_LIGHTS", + "PARKING_LIGHTS", "BRAKE_LIGHTS", "REAR_REVERSING_LIGHTS", "SIDE_MARKER_LIGHTS", "LEFT_TURN_LIGHTS", + "RIGHT_TURN_LIGHTS", "HAZARD_LIGHTS", "AMBIENT_LIGHTS", "OVERHEAD_LIGHTS", "READING_LIGHTS", + "TRUNK_LIGHTS", "EXTERIOR_FRONT_LIGHTS", "EXTERIOR_REAR_LIGHTS", "EXTERIOR_LEFT_LIGHTS", + "EXTERIOR_RIGHT_LIGHTS" } + local out = { } + for _, name in pairs(lights) do + local item = { + name = name, + densityAvailable = true, + sRGBColorSpaceAvailable = true + } + table.insert(out, item) + end + return out + end)() + }, buttonCapabilities = (function() local buttons = { -- climate From a5ec9c410b2afe8541e4326cc95219e6641e4498 Mon Sep 17 00:00:00 2001 From: "Ira Lytvynenko (GitHub)" Date: Wed, 30 May 2018 16:40:06 +0300 Subject: [PATCH 560/681] Add new parameter keepContextAvailable to hmi capabilities --- user_modules/hmi_values.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index 6793089132..9443a5d9d3 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -372,6 +372,7 @@ function module.getDefaultHMITable() { moduleName = "Audio", sourceAvailable = true, + keepContextAvailable = true, volumeAvailable = true, equalizerAvailable = true, equalizerMaxChannelId = 100 From a5eb32225662a2c36760f030e202d7edebe80ded Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 25 Jul 2018 11:29:37 +0300 Subject: [PATCH 561/681] Remove duplicate scripts with wrong numbering --- .../010_Change_audio_source_in_BACKGROUND.lua | 75 --------------- ..._audio_source_in_FULL_rc_non_media_app.lua | 67 ------------- ...ce_from_MOBILE_APP_without_keepContext.lua | 86 ----------------- ...urce_from_MOBILE_APP_keepContext_false.lua | 86 ----------------- ..._from_MOBILE_APP_keepContext_true_FULL.lua | 86 ----------------- ...om_MOBILE_APP_keepContext_true_LIMITED.lua | 96 ------------------- ...ype_except_MOBILE_APP_keepContext_true.lua | 88 ----------------- 7 files changed, 584 deletions(-) delete mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_BACKGROUND.lua delete mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_FULL_rc_non_media_app.lua delete mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_from_MOBILE_APP_without_keepContext.lua delete mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_keepContext_false.lua delete mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua delete mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua delete mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_BACKGROUND.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_BACKGROUND.lua deleted file mode 100644 index da6953ec1c..0000000000 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_BACKGROUND.lua +++ /dev/null @@ -1,75 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- User story: TBD --- Use case: TBD --- --- Requirement summary: --- TBD --- --- Description: --- In case: --- 1) App is RC and Media --- 2) App in NONE or BACKGROUND HMI level --- 3) App tries to change audio source --- SDL must: --- 1) Not change audio source ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ General configuration parameters ]] -config.application1.registerAppInterfaceParams.isMediaApplication = true -config.application2.registerAppInterfaceParams.isMediaApplication = true - ---[[ Local Variables ]] -local audioData = common.getSettableModuleControlData("AUDIO") -local audioSources = { - "NO_SOURCE_SELECTED", - "CD", - "BLUETOOTH_STEREO_BTST", - "USB", - "USB2", - "LINE_IN", - "IPOD", - "MOBILE_APP", - "RADIO_TUNER" -} - ---[[ Local Functions ]] -local function setVehicleData(pSource) - audioData.audioControlData.source = pSource - local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = audioData }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = common.getHMIAppId(), moduleData = audioData }) - :Do(function(_, data) - common.getHMIconnection():SendError(data.id, data.method, "REJECTED", "Error") - end) - - common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "REJECTED", info = "Error" }) -end - -local function BringAppToBACKGROUND() - common.activateApp(2) - common.getMobileSession():ExpectNotification("OnHMIStatus", - { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU App1", common.raiPTUn) -runner.Step("RAI App2", common.raiN, {2}) -runner.Step("Activate App1", common.activateApp) -runner.Step("Set App1 to BACKGROUND HMI level", BringAppToBACKGROUND) - -runner.Title("Test") -for _, source in pairs(audioSources) do - runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) -end - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_FULL_rc_non_media_app.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_FULL_rc_non_media_app.lua deleted file mode 100644 index 5c9c76218d..0000000000 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_FULL_rc_non_media_app.lua +++ /dev/null @@ -1,67 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- User story: TBD --- Use case: TBD --- --- Requirement summary: --- TBD --- --- Description: --- In case: --- 1) App is RC and Non-Media --- 2) App in any HMI level --- 3) App tries to change audio source --- SDL must: --- 1) Not change audio source ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ General configuration parameters ]] -config.application1.registerAppInterfaceParams.isMediaApplication = false - ---[[ Local Variables ]] -local audioData = common.getSettableModuleControlData("AUDIO") -local audioSources = { - "NO_SOURCE_SELECTED", - "CD", - "BLUETOOTH_STEREO_BTST", - "USB", - "USB2", - "LINE_IN", - "IPOD", - "MOBILE_APP", - "RADIO_TUNER" -} - ---[[ Local Functions ]] -local function setVehicleData(pSource) - audioData.audioControlData.source = pSource - local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) - - -- Confirmation nedded, not clear what resultCode must be - common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) -runner.Step("Activate App", common.activateApp) - -runner.Title("Test") -for _, source in pairs(audioSources) do - runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) -end - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_from_MOBILE_APP_without_keepContext.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_from_MOBILE_APP_without_keepContext.lua deleted file mode 100644 index 4d1c5d8d74..0000000000 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_from_MOBILE_APP_without_keepContext.lua +++ /dev/null @@ -1,86 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- User story: TBD --- Use case: TBD --- --- Requirement summary: --- TBD --- --- Description: --- In case: --- 1) App is RC and Media --- 2) App in FULL HMI level --- 3) App tries to change audio source from MOBILE_APP with keepContext = false --- SDL must: --- 1) Change audio source successfully --- 2) Change HMI level of App to BACKGROUND ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ General configuration parameters ]] -config.application1.registerAppInterfaceParams.isMediaApplication = true - ---[[ Local Variables ]] -local audioData = common.getSettableModuleControlData("AUDIO") - ---[[ Local Functions ]] -local function setVehicleDataMobileApp() - local mobSession = common.getMobileSession() - audioData.audioControlData.source = "MOBILE_APP" - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - -local function setVehicleData() - local mobSession = common.getMobileSession() - audioData.audioControlData.source = "USB" - audioData.audioControlData.keepContext = nil - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { - eventName = "AUDIO_SOURCE", - isActive = true - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) - mobSession:ExpectNotification("OnHMIStatus", - { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) -runner.Step("Activate App", common.activateApp) -runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) - -runner.Title("Test") -runner.Step("Change audio source from MOBILE_APP without keepContext", setVehicleData) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_keepContext_false.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_keepContext_false.lua deleted file mode 100644 index b5942647c3..0000000000 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_keepContext_false.lua +++ /dev/null @@ -1,86 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- User story: TBD --- Use case: TBD --- --- Requirement summary: --- TBD --- --- Description: --- In case: --- 1) App is RC and Media --- 2) App in FULL HMI level --- 3) App tries to change audio source from MOBILE_APP without keepContext parameter defined --- SDL must: --- 1) Change audio source successfully --- 2) Change HMI level of App to BACKGROUND ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ General configuration parameters ]] -config.application1.registerAppInterfaceParams.isMediaApplication = true - ---[[ Local Variables ]] -local audioData = common.getSettableModuleControlData("AUDIO") - ---[[ Local Functions ]] -local function setVehicleDataMobileApp() - local mobSession = common.getMobileSession() - audioData.audioControlData.source = "MOBILE_APP" - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - -local function setVehicleData() - local mobSession = common.getMobileSession() - audioData.audioControlData.source = "USB" - audioData.audioControlData.keepContext = false - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { - eventName = "AUDIO_SOURCE", - isActive = true - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) - mobSession:ExpectNotification("OnHMIStatus", - { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) -runner.Step("Activate App", common.activateApp) -runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) - -runner.Title("Test") -runner.Step("Change audio source from MOBILE_APP keepContext is false", setVehicleData) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua deleted file mode 100644 index f4f5afd6d0..0000000000 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua +++ /dev/null @@ -1,86 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- User story: TBD --- Use case: TBD --- --- Requirement summary: --- TBD --- --- Description: --- In case: --- 1)App is RC and Media --- 2) App in FULL HMI level --- 3) App tries to change audio source from MOBILE_APP with keepContext = true --- SDL must: --- 1) Change audio source successfully --- 2) Not change HMI level, but change audioStreamingState to "NOT_AUDIBLE" ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ General configuration parameters ]] -config.application1.registerAppInterfaceParams.isMediaApplication = true - ---[[ Local Variables ]] -local audioData = common.getSettableModuleControlData("AUDIO") - ---[[ Local Functions ]] -local function setVehicleDataMobileApp() - local mobSession = common.getMobileSession() - audioData.audioControlData.source = "MOBILE_APP" - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - -local function setVehicleData() - local mobSession = common.getMobileSession() - audioData.audioControlData.source = "USB" - audioData.audioControlData.keepContext = true - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { - eventName = "AUDIO_SOURCE", - isActive = true - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) - mobSession:ExpectNotification("OnHMIStatus", - { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) -runner.Step("Activate App", common.activateApp) -runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) - -runner.Title("Test") -runner.Step("Change audio source from MOBILE_APP keepContext is true", setVehicleData) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua deleted file mode 100644 index e7b1e7728b..0000000000 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua +++ /dev/null @@ -1,96 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- User story: TBD --- Use case: TBD --- --- Requirement summary: --- TBD --- --- Description: --- In case: --- 1)App is RC and Media --- 2) App in LIMITED HMI level --- 3) App tries to change audio source from MOBILE_APP with keepContext = true --- SDL must: --- 1) Change audio source successfully --- 2) Change HMI level to BACKGROUND and change audioStreamingState to "NOT_AUDIBLE" ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ General configuration parameters ]] -config.application1.registerAppInterfaceParams.isMediaApplication = true - ---[[ Local Variables ]] -local audioData = common.getSettableModuleControlData("AUDIO") - ---[[ Local Functions ]] -local function setVehicleDataMobileApp() - local mobSession = common.getMobileSession() - audioData.audioControlData.source = "MOBILE_APP" - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - -local function setVehicleData() - local mobSession = common.getMobileSession() - audioData.audioControlData.source = "USB" - audioData.audioControlData.keepContext = true - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { - eventName = "AUDIO_SOURCE", - isActive = true - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) - mobSession:ExpectNotification("OnHMIStatus", - { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) -end - -local function bringAppToLIMITED() - common.getHMIconnection():SendNotification("BasicCommunication.OnAppDeactivated", { - appID = common.getHMIAppId(), - reason = "GENERAL" - }) - common.getMobileSession():ExpectNotification("OnHMIStatus", - { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) -runner.Step("Activate App", common.activateApp) -runner.Step("Set App to LIMITED HMI level", bringAppToLIMITED) -runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) - -runner.Title("Test") -runner.Step("Change audio source from MOBILE_APP keepContext is true", setVehicleData) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua deleted file mode 100644 index 68e6e2b82f..0000000000 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua +++ /dev/null @@ -1,88 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- User story: TBD --- Use case: TBD --- --- Requirement summary: --- TBD --- --- Description: --- In case: --- 1) App is RC and Media --- 2) App in FULL HMI level --- 3) App tries to change audio source from any type except of MOBILE_APP and with any value of keepContext parameter or event without it --- SDL must: --- 1) Change audio source successfully --- 2) Not change HMI level ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ General configuration parameters ]] -config.application1.registerAppInterfaceParams.isMediaApplication = true - ---[[ Local Variables ]] -local audioData = common.getSettableModuleControlData("AUDIO") -local audioSources = { - "NO_SOURCE_SELECTED", - "CD", - "BLUETOOTH_STEREO_BTST", - "USB", - "USB2", - "LINE_IN", - "IPOD", - "RADIO_TUNER" -} - -local keepContext = { - false, - true, - "empty" -} - ---[[ Local Functions ]] -local function setVehicleData(pSource,pKeepContext) - local mobSession = common.getMobileSession() - audioData.audioControlData.source = pSource - if "empty" == pKeepContext then - audioData.audioControlData.keepContext = nil - else - audioData.audioControlData.keepContext = pKeepContext - end - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) - mobSession:ExpectNotification("OnHMIStatus") - :Times(0) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) -runner.Step("Activate App", common.activateApp) - -runner.Title("Test") -for _, source in pairs(audioSources) do - for _, keepContextValue in pairs(keepContext) do - runner.Step("Change audio source from " .. source .. " source with keepContext is " .. - tostring(keepContextValue), setVehicleData, { source, keepContextValue }) - end -end - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) From 1435a46a53c05e3e6e05c47160099f03ff7c87b2 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 14 Aug 2018 13:00:58 +0300 Subject: [PATCH 562/681] Changes regarding 'Revise New remote control modules' --- .../016_RADIO_GPSdata_in_HMI_response.lua | 128 ++++++++++++++++++ .../commonRCmodules.lua | 11 +- test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt | 1 + user_modules/hmi_values.lua | 2 +- 4 files changed, 136 insertions(+), 6 deletions(-) create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua new file mode 100644 index 0000000000..08131ad97b --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua @@ -0,0 +1,128 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0099-new-remote-control-modules-and-parameters.md +-- User story: TBD +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with valid parameters +-- 2) and SDL gets response (resultCode: SUCCESS) and data from GPSData struct in stationLocation from HMI +-- SDL must: +-- 1) Respond to App with success:true, "SUCCESS" and resend values received from HMI in case all values are valid and all mandatory parameters are present +-- S) Respond to App with success:false, "GENERIC_ERROR" in case mandatry parameters are missed +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local moduleName = "RADIO" + +local paramsForPositiveCase = { + mandatoryOnly = { + longitudeDegrees = 20.1, + latitudeDegrees = 20.1 + }, + mandatoryWithAltitude = { + longitudeDegrees = 20.1, + latitudeDegrees = 20.1, + altitude = 20.1 + }, + allGPSdata = { + longitudeDegrees = 20.1, + latitudeDegrees = 20.1, + altitude = 20.1, + utcYear = 2020, + utcMonth = 5, + utcDay = 15, + utcHours = 5, + utcMinutes = 30, + utcSeconds = 30, + compassDirection = "NORTH", + pdop = 5, + hdop = 5, + vdop = 5, + actual = true, + satellites = 5, + dimension = "NO_FIX", + heading = 10.1, + speed = 15 + } +} + +local paramsMissingMandatory = { + onlyLongitude = { + longitudeDegrees = 20.1 + }, + onlyLatitude = { + latitudeDegrees = 20.1 + } +} + +--[[ Local Functions ]] +local function getRadioParams(pStationLocationParams) + local radioParams = { + moduleType = moduleName, + radioControlData = { + sisData = { + stationShortName = "Name2", + stationIDNumber = { + countryCode = 200, + fccFacilityId = 200 + }, + stationLongName = "RadioStationLongName2", + stationLocation = pStationLocationParams, + stationMessage = "station message 2" + } + } + } + return radioParams +end + +local function getDataForModule(pStationLocationParams, isSuccess) + local radioParams = getRadioParams(pStationLocationParams) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = moduleName + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = moduleName + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = radioParams }) + end) + if isSuccess == true then + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = radioParams }) + else + mobileSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Invalid message received from vehicle" }) + end + +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for key, value in pairs(paramsForPositiveCase) do + runner.Step("GetInteriorVehicleData stationLocation " .. key, getDataForModule, { value, true }) +end +for key, value in pairs(paramsMissingMandatory) do + runner.Step("GetInteriorVehicleData stationLocation " .. key, getDataForModule, { value, false }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua index a0aa23083b..2eec208345 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua @@ -3,6 +3,7 @@ --------------------------------------------------------------------------------------------------- config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 --[[ Required Shared libraries ]] local commonRC = require("test_scripts/RC/commonRC") @@ -103,7 +104,7 @@ function c.getModuleControlData(pModuleType) stationLocation = { longitudeDegrees = 0.1, latitudeDegrees = 0.1, - altitudeMeters = 0.1 + altitude = 0.1 }, stationMessage = "station message" } @@ -129,7 +130,7 @@ function c.getModuleControlData(pModuleType) id = "FRONT_LEFT_HIGH_BEAM", status = "ON", density = 0.2, - sRGBColor = { + color = { red = 50, green = 150, blue = 200 @@ -170,7 +171,7 @@ function c.getAnotherModuleControlData(pModuleType) stationLocation = { longitudeDegrees = 20.1, latitudeDegrees = 20.1, - altitudeMeters = 20.1 + altitude = 20.1 }, stationMessage = "station message 2" } @@ -196,7 +197,7 @@ function c.getAnotherModuleControlData(pModuleType) id = "READING_LIGHTS", status = "ON", density = 0.5, - sRGBColor = { + color = { red = 150, green = 200, blue = 250 @@ -243,7 +244,7 @@ function c.getReadOnlyParamsByModule(pModuleType) stationLocation = { longitudeDegrees = 20.1, latitudeDegrees = 20.1, - altitudeMeters = 20.1 + altitude = 20.1 }, stationMessage = "station message 2" } diff --git a/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt b/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt index d7d8732a00..9de99a0870 100644 --- a/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt +++ b/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt @@ -13,6 +13,7 @@ ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index 9443a5d9d3..e7b97175cf 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -423,7 +423,7 @@ function module.getDefaultHMITable() local item = { name = name, densityAvailable = true, - sRGBColorSpaceAvailable = true + RGBColorSpaceAvailable = true } table.insert(out, item) end From 1d23608d34b23f4be20682442f368c291faa36e8 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 15 Aug 2018 18:31:47 +0300 Subject: [PATCH 563/681] Rename parameter RGBColorSpaceAvailable --- user_modules/hmi_values.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index e7b97175cf..63514c2257 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -423,7 +423,7 @@ function module.getDefaultHMITable() local item = { name = name, densityAvailable = true, - RGBColorSpaceAvailable = true + rgbColorSpaceAvailable = true } table.insert(out, item) end From 923babcb640bbe7f80d30ba8a84a50ce66ce7843 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 16 Aug 2018 11:12:12 +0300 Subject: [PATCH 564/681] Update BREAK_LIGHT to BRAKE_LIGHT --- user_modules/hmi_values.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index 63514c2257..84ad02b7e8 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -412,7 +412,7 @@ function module.getDefaultHMITable() "FRONT_LEFT_FOG_LIGHT", "FRONT_RIGHT_FOG_LIGHT", "FRONT_LEFT_DAYTIME_RUNNING_LIGHT", "FRONT_RIGHT_DAYTIME_RUNNING_LIGHT", "FRONT_LEFT_TURN_LIGHT", "FRONT_RIGHT_TURN_LIGHT", "REAR_LEFT_FOG_LIGHT", "REAR_RIGHT_FOG_LIGHT", "REAR_LEFT_TAIL_LIGHT", "REAR_RIGHT_TAIL_LIGHT", - "REAR_LEFT_BREAK_LIGHT", "REAR_RIGHT_BREAK_LIGHT", "REAR_LEFT_TURN_LIGHT", "REAR_RIGHT_TURN_LIGHT", + "REAR_LEFT_BRAKE_LIGHT", "REAR_RIGHT_BRAKE_LIGHT", "REAR_LEFT_TURN_LIGHT", "REAR_RIGHT_TURN_LIGHT", "REAR_REGISTRATION_PLATE_LIGHT", "HIGH_BEAMS", "LOW_BEAMS", "FOG_LIGHTS", "RUNNING_LIGHTS", "PARKING_LIGHTS", "BRAKE_LIGHTS", "REAR_REVERSING_LIGHTS", "SIDE_MARKER_LIGHTS", "LEFT_TURN_LIGHTS", "RIGHT_TURN_LIGHTS", "HAZARD_LIGHTS", "AMBIENT_LIGHTS", "OVERHEAD_LIGHTS", "READING_LIGHTS", From fe67713a4ee2d27086700ba7b9ece55704977450 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 16 Aug 2018 16:17:24 +0300 Subject: [PATCH 565/681] Added majorVersion=5 in common files --- test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua | 1 + test_scripts/RC/commonRC.lua | 2 ++ 2 files changed, 3 insertions(+) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua index 2eec208345..28cf34198e 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua @@ -4,6 +4,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 +config.application2.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 --[[ Required Shared libraries ]] local commonRC = require("test_scripts/RC/commonRC") diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 3526622f57..875bceed55 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -7,6 +7,8 @@ config.defaultProtocolVersion = 2 config.ValidateSchema = false config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 +config.application2.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") From 7fe538e99367fafc1e194dec8d2415e8d057f651 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 16 Aug 2018 18:46:40 +0300 Subject: [PATCH 566/681] Update according to review comments --- ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 4 ++-- ...se_moduleType_is_an_empty_array_in_LPT.lua | 20 +------------------ 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 4687c71312..719ae038f9 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -29,7 +29,7 @@ local function ptUpdateFunc(pTbl) pTbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } end -local function rpcDissallowed() +local function rpcDisallowed() local cid = common.getMobileSession():SendRPC("GetSystemCapability", { systemCapabilityType = "REMOTE_CONTROL" }) common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) end @@ -42,7 +42,7 @@ runner.Step("RAI, PTU", common.raiPTUn, { ptUpdateFunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") -runner.Step("GetSystemCapability DISALLOWED", rpcDissallowed) +runner.Step("GetSystemCapability DISALLOWED", rpcDisallowed) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 0e92caf8e1..149fa6aa4c 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -27,24 +27,6 @@ runner.testSettings.isSelfIncluded = false local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } --[[ Local Functions ]] -local function setVehicleData(pModuleType) - local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { - moduleData = common.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = common.getSettableModuleControlData(pModuleType) - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = common.getSettableModuleControlData(pModuleType) - }) - end) - - common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY @@ -60,7 +42,7 @@ runner.Step("Activate App", common.activateApp) runner.Title("Test") for _, mod in pairs(modules) do - runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) + runner.Step("SetInteriorVehicleData " .. mod, common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) end runner.Title("Postconditions") From 83d658c79fa89f822bab9929117eaa2cd46ba5c5 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 16 Aug 2018 19:48:35 +0300 Subject: [PATCH 567/681] Added majorVersion=5 in common file for app3 --- test_scripts/RC/commonRC.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 875bceed55..b7069fa35b 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -9,6 +9,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 config.application2.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 +config.application3.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") From 011e90294d93e6bff07651477594ca05a110a1b7 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 16 Aug 2018 23:08:34 +0300 Subject: [PATCH 568/681] Use rpcDenied in disallowed cases --- .../002_Disallow_flow_by_policy_CLIMATE.lua | 14 ++------------ .../003_Disallow_flow_by_policy_AUDIO.lua | 14 ++------------ .../004_Disallow_flow_by_policy_LIGHT.lua | 14 ++------------ .../005_Disallow_flow_by_policy_HMI_SETTINGS.lua | 14 ++------------ 4 files changed, 8 insertions(+), 48 deletions(-) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 2530721fbc..d2fccf2c44 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -23,19 +23,9 @@ runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local mod = "CLIMATE" +local rpc = "SetInteriorVehicleData" --[[ Local Functions ]] -local function setVehicleData(pModuleType) - local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { - moduleData = common.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) - - common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } @@ -49,7 +39,7 @@ runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") -runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +runner.Step("SetInteriorVehicleData " .. mod, common.rpcDenied, {mod, 1, rpc, "DISALLOWED"}) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua index 18c29a6e63..4b252fc5a1 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua @@ -23,19 +23,9 @@ runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local mod = "AUDIO" +local rpc = "SetInteriorVehicleData" --[[ Local Functions ]] -local function setVehicleData(pModuleType) - local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { - moduleData = common.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) - - common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } @@ -49,7 +39,7 @@ runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") -runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +runner.Step("SetInteriorVehicleData " .. mod, common.rpcDenied, {mod, 1, rpc, "DISALLOWED"}) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua index c3fa95671d..71bc5c0a7f 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua @@ -23,19 +23,9 @@ runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local mod = "LIGHT" +local rpc = "SetInteriorVehicleData" --[[ Local Functions ]] -local function setVehicleData(pModuleType) - local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { - moduleData = common.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) - - common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } @@ -49,7 +39,7 @@ runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") -runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +runner.Step("SetInteriorVehicleData " .. mod, common.rpcDenied, {mod, 1, rpc, "DISALLOWED"}) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua index 00202d0464..08b9b014fd 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua @@ -23,19 +23,9 @@ runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local mod = "HMI_SETTINGS" +local rpc = "SetInteriorVehicleData" --[[ Local Functions ]] -local function setVehicleData(pModuleType) - local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { - moduleData = common.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) - - common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } @@ -49,7 +39,7 @@ runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") -runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +runner.Step("SetInteriorVehicleData " .. mod, common.rpcDenied, {mod, 1, rpc, "DISALLOWED"}) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) From 94ac99ffb975b3b9a6f08e3eab58aa31b705de07 Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Thu, 16 Aug 2018 17:27:03 -0400 Subject: [PATCH 569/681] Reduce redundant code --- .../002_Disallow_flow_by_policy_AUDIO.lua | 12 +----------- .../003_Disallow_flow_by_policy_LIGHT.lua | 12 +----------- .../004_Disallow_flow_by_policy_HMI_SETTINGS.lua | 12 +----------- ...ow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua | 13 +------------ ...ow_flow_in_case_moduleType_is_absent_in_LPT.lua | 14 +------------- 5 files changed, 5 insertions(+), 58 deletions(-) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua index f2e9b53c5b..30c648ab1f 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua @@ -16,16 +16,6 @@ local commonRC = require('test_scripts/RC/commonRC') --[[ Local Variables ]] local mod = "AUDIO" ---[[ Local Functions ]] -local function getDataForModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType - }) - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } end @@ -38,7 +28,7 @@ runner.Step("RAI, PTU", commonRC.rai_ptu, { PTUfunc }) runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") -runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +runner.Step("GetInteriorVehicleData " .. mod, commonRC.rpcDenied, { mod, 1, "GetInteriorVehicleData", "DISALLOWED" }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua index 61c949c8aa..95d9065102 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua @@ -16,16 +16,6 @@ local commonRC = require('test_scripts/RC/commonRC') --[[ Local Variables ]] local mod = "LIGHT" ---[[ Local Functions ]] -local function getDataForModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType - }) - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } end @@ -38,7 +28,7 @@ runner.Step("RAI, PTU", commonRC.rai_ptu, { PTUfunc }) runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") -runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +runner.Step("GetInteriorVehicleData " .. mod, commonRC.rpcDenied, { mod, 1, "GetInteriorVehicleData", "DISALLOWED" }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua index b52f650aeb..5e84b4e2f1 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua @@ -16,16 +16,6 @@ local commonRC = require('test_scripts/RC/commonRC') --[[ Local Variables ]] local mod = "HMI_SETTINGS" ---[[ Local Functions ]] -local function getDataForModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType - }) - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } end @@ -38,7 +28,7 @@ runner.Step("RAI, PTU", commonRC.rai_ptu, { PTUfunc }) runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") -runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +runner.Step("GetInteriorVehicleData " .. mod, commonRC.rpcDenied, { mod, 1, "GetInteriorVehicleData", "DISALLOWED" }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index ca593e5567..aca8d87025 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -23,17 +23,6 @@ runner.testSettings.isSelfIncluded = false --[[ General configuration parameters ]] config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } ---[[ Local Functions ]] -local function getDataForModule(pModuleType) - local mobileSession = common.getMobileSession() - local cid = mobileSession:SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType - }) - EXPECT_HMICALL("RC.GetInteriorVehicleData") - :Times(0) - mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) local appId = config.application1.registerAppInterfaceParams.appID tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } @@ -49,7 +38,7 @@ runner.Step("Activate App", common.activateApp) runner.Title("Test") for _, mod in pairs(common.modules) do - runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) + runner.Step("GetInteriorVehicleData " .. mod, common.rpcDenied, { mod, 1, "GetInteriorVehicleData", "DISALLOWED" }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 87ffb43115..2aee29a21b 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -25,18 +25,6 @@ runner.testSettings.isSelfIncluded = false --modules array does not contain "RADIO" because "RADIO" module has read only parameters local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } ---[[ Local Functions ]] -local function setVehicleData(pModuleType) - local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { - moduleData = common.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) - - common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil end @@ -50,7 +38,7 @@ runner.Step("Activate App", common.activateApp) runner.Title("Test") for _, mod in pairs(modules) do - runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) + runner.Step("SetInteriorVehicleData " .. mod, common.rpcDenied, { mod, 1, "SetInteriorVehicleData", "DISALLOWED" }) end runner.Title("Postconditions") From d836343d9cb46ffde717d3ad1fa2f08a37d90185 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 17 Aug 2018 15:32:26 +0300 Subject: [PATCH 570/681] Expand common file with new module values for OnRCStatus --- .../RC/OnRCStatus/commonOnRCStatus.lua | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua index 5ef39ddfa6..c11690c73e 100644 --- a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua +++ b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua @@ -24,7 +24,7 @@ local m = {} local getRCAppConfigOrigin = commonRC.getRCAppConfig function commonRC.getRCAppConfig(tbl) local rcAppConfig = getRCAppConfigOrigin(tbl) - rcAppConfig.moduleType = { "RADIO", "CLIMATE", "SEAT" } + rcAppConfig.moduleType = { "RADIO", "CLIMATE", "SEAT", "AUDIO", "LIGHT", "HMI_SETTINGS" } return rcAppConfig end @@ -106,6 +106,35 @@ function commonRC.getModuleControlData(module_type) action = "SAVE" } } + elseif module_type == "AUDIO" then + out.moduleType = "AUDIO" + out.audioControlData = { + source = "RADIO_TUNER", + volume = 50 + } + elseif module_type == "LIGHT" then + out.moduleType = "LIGHT" + out.lightControlData = { + lightState = { + { + id = "FRONT_LEFT_HIGH_BEAM", + status = "ON", + density = 0.2, + color = { + red = 50, + green = 150, + blue = 200 + } + } + } + } + elseif module_type == "HMI_SETTINGS" then + out.moduleType = "HMI_SETTINGS" + out.hmiSettingsControlData = { + displayMode = "DAY", + temperatureUnit = "CELSIUS", + distanceUnit = "KILOMETERS" + } else out = origGetModuleControlData(module_type) end @@ -122,7 +151,7 @@ function m.getModules() end function m.getAllModules() - return commonFunctions:cloneTable({ "RADIO", "CLIMATE", "SEAT" }) + return commonFunctions:cloneTable({ "RADIO", "CLIMATE", "SEAT", "AUDIO", "LIGHT", "HMI_SETTINGS" }) end function m.getRCAppConfig() From dbebf27ff4ae7830aa5de06221fe172f417ea1ff Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 6 Jun 2018 16:25:10 +0300 Subject: [PATCH 571/681] Initial scripts for feature Radio parameter update --- .../GetSystemCapability/001_Success_flow.lua | 82 +++++++++++++++++++ ..._RESOURCE_hdRadioEnableAvailable_false.lua | 39 +++++++++ ...ESOURCE_hdRadioEnableAvailable_omitted.lua | 39 +++++++++ .../018_Success_flow_band_setting.lua | 59 +++++++++++++ ..._RESOURCE_siriusxmRadioAvailable_false.lua | 53 ++++++++++++ ...ESOURCE_siriusxmRadioAvailable_omitted.lua | 53 ++++++++++++ ..._in_case_invalid_data_in_hdRadioEnable.lua | 49 +++++++++++ ...022_availableHDs_hdChannel_upper_bound.lua | 69 ++++++++++++++++ ...ilableHDs_hdChannel_out_of_upper_bound.lua | 62 ++++++++++++++ test_scripts/RC/commonRC.lua | 6 +- test_sets/rc_radio_parameter_update.txt | 12 +++ user_modules/hmi_values.lua | 10 ++- 12 files changed, 528 insertions(+), 5 deletions(-) create mode 100644 test_scripts/RC/CLIMATE_RADIO/GetSystemCapability/001_Success_flow.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/016_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_false.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/017_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_omitted.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/018_Success_flow_band_setting.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/019_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_false.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/020_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_omitted.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/021_INVALID_DATA_in_case_invalid_data_in_hdRadioEnable.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/022_availableHDs_hdChannel_upper_bound.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/023_availableHDs_hdChannel_out_of_upper_bound.lua create mode 100644 test_sets/rc_radio_parameter_update.txt diff --git a/test_scripts/RC/CLIMATE_RADIO/GetSystemCapability/001_Success_flow.lua b/test_scripts/RC/CLIMATE_RADIO/GetSystemCapability/001_Success_flow.lua new file mode 100644 index 0000000000..df9ad82807 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/GetSystemCapability/001_Success_flow.lua @@ -0,0 +1,82 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/RC/detailed_info_GetSystemCapability.md +-- Item: Use Case 2: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- 1) App is RC +-- 2) App tries to get RC capabilities +-- SDL must: +-- 1) Transfer RC capabilities to mobiles +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/commonRC') +local hmi_values = require("user_modules/hmi_values") + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local capMap = { + ["RADIO"] = "radioControlCapabilities", + ["CLIMATE"] = "climateControlCapabilities" +} +local capabParams = {} +for _, v in pairs(modules) do capabParams[v] = common.DEFAULT end -- HMI has all posible RC capabilities + +--[[ Local Functions ]] +local function buildHmiRcCapabilities(pCapabilities) + local hmiParams = hmi_values.getDefaultHMITable() + hmiParams.RC.IsReady.params.available = true + local capParams = hmiParams.RC.GetCapabilities.params.remoteControlCapability + for k, v in pairs(capMap) do + if pCapabilities[k] then + if pCapabilities[k] ~= common.DEFAULT then + capParams[v] = pCapabilities[v] + end + else + capParams[v] = nil + end + end + return hmiParams +end + +local hmiRcCapabilities = buildHmiRcCapabilities(capabParams) + +local function rpcSuccess(self) + local rcCapabilities = hmiRcCapabilities.RC.GetCapabilities.params.remoteControlCapability + local cid = common.getMobileSession(self):SendRPC("GetSystemCapability", { systemCapabilityType = "REMOTE_CONTROL" }) + common.getMobileSession(self):ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS", + systemCapability = { + remoteControlCapability = { + climateControlCapabilities = rcCapabilities.climateControlCapabilities, + radioControlCapabilities = rcCapabilities.radioControlCapabilities, + audioControlCapabilities = rcCapabilities.audioControlCapabilities, + hmiSettingsControlCapabilities = rcCapabilities.hmiSettingsControlCapabilities, + lightControlCapabilities = rcCapabilities.lightControlCapabilities, + buttonCapabilities = rcCapabilities.buttonCapabilities + } + } + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Backup HMI capabilities file", common.backupHMICapabilities) +runner.Step("Update HMI capabilities file", common.updateDefaultCapabilities, { modules }) +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { hmiRcCapabilities }) +runner.Step("RAI, PTU", common.rai_ptu) +runner.Step("Activate App", common.activate_app) + +runner.Title("Test") +runner.Step("GetSystemCapability Positive Case", rpcSuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) +runner.Step("Restore HMI capabilities file", common.restoreHMICapabilities) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/016_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_false.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/016_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_false.lua new file mode 100644 index 0000000000..ac17e3d581 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/016_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_false.lua @@ -0,0 +1,39 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0160-rc-radio-parameter-update.md +-- User story: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) RC.GetCapabilities received with hdRadioEnableAvailable = false from HMI +-- 2) Application is registered with REMOTE_CONTROL appHMIType +-- 3) and sends valid SetInteriorVehicleData RPC with hdRadioEnable +-- SDL must: +-- 1) Respond with UNSUPPORTED_RESOURCE result code, success = false to mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local hmi_values = require("user_modules/hmi_values") + +--[[ Local Variables ]] +local Module = "RADIO" +local hmiValues = hmi_values.getDefaultHMITable() +hmiValues.RC.GetCapabilities.params.remoteControlCapability.radioControlCapabilities[1].hdRadioEnableAvailable = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { hmiValues }) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") + +runner.Step("SetInteriorVehicleData UNSUPPORTED_RESOURCE in case hdRadioEnableAvailable false", commonRC.rpcDenied, + {Module, 1, "SetInteriorVehicleData", "UNSUPPORTED_RESOURCE"}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/017_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_omitted.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/017_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_omitted.lua new file mode 100644 index 0000000000..4898ffc5c8 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/017_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_omitted.lua @@ -0,0 +1,39 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0160-rc-radio-parameter-update.md +-- User story: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) RC.GetCapabilities received without hdRadioEnableAvailable from HMI +-- 2) Application is registered with REMOTE_CONTROL appHMIType +-- 3) and sends valid SetInteriorVehicleData RPC with hdRadioEnable +-- SDL must: +-- 1) Respond with UNSUPPORTED_RESOURCE result code, success = false to mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local hmi_values = require("user_modules/hmi_values") + +--[[ Local Variables ]] +local Module = "RADIO" +local hmiValues = hmi_values.getDefaultHMITable() +hmiValues.RC.GetCapabilities.params.remoteControlCapability.radioControlCapabilities[1].hdRadioEnableAvailable = nil + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { hmiValues }) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") + +runner.Step("SetInteriorVehicleData UNSUPPORTED_RESOURCE in case hdRadioEnableAvailable omitted", commonRC.rpcDenied, + {Module, 1, "SetInteriorVehicleData", "UNSUPPORTED_RESOURCE"}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/018_Success_flow_band_setting.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/018_Success_flow_band_setting.lua new file mode 100644 index 0000000000..31ddc6e2d6 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/018_Success_flow_band_setting.lua @@ -0,0 +1,59 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0160-rc-radio-parameter-update.md +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) and sends valid SetInteriorVehicleData RPC with valid parameters +-- SDL must: +-- 1) Transfer this request to HMI +-- 2) Respond with received from HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local Module = "RADIO" + +--[[ Local Functions ]] +local function setVehicleData(self) + local requestParams = commonRC.getSettableModuleControlData(Module) + requestParams.radioControlData.band = "XM" + + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + moduleData = requestParams + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = requestParams + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = requestParams + }) + end) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") + +runner.Step("SetInteriorVehicleData with band XM", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/019_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_false.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/019_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_false.lua new file mode 100644 index 0000000000..4b9ff3af77 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/019_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_false.lua @@ -0,0 +1,53 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0160-rc-radio-parameter-update.md +-- User story: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) RC.GetCapabilities received with siriusxmRadioAvailable = false from HMI +-- 2) Application is registered with REMOTE_CONTROL appHMIType +-- 3) and sends valid SetInteriorVehicleData RPC with band = XM +-- SDL must: +-- 1) Respond with UNSUPPORTED_RESOURCE result code, success = false to mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local hmi_values = require("user_modules/hmi_values") + +--[[ Local Variables ]] +local Module = "RADIO" +local hmiValues = hmi_values.getDefaultHMITable() +hmiValues.RC.GetCapabilities.params.remoteControlCapability.radioControlCapabilities[1].siriusxmRadioAvailable = false + +--[[ Local Functions ]] +local function rpcDenied(self) + local requestParams = commonRC.getSettableModuleControlData(Module) + requestParams.radioControlData.band = "XM" + + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + moduleData = requestParams + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { hmiValues }) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") + +runner.Step("SetInteriorVehicleData UNSUPPORTED_RESOURCE in case siriusxmRadioAvailable false", rpcDenied) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/020_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_omitted.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/020_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_omitted.lua new file mode 100644 index 0000000000..df7b251869 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/020_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_omitted.lua @@ -0,0 +1,53 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0160-rc-radio-parameter-update.md +-- User story: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) RC.GetCapabilities received without siriusxmRadioAvailable from HMI +-- 2) Application is registered with REMOTE_CONTROL appHMIType +-- 3) and sends valid SetInteriorVehicleData RPC with band = XM +-- SDL must: +-- 1) Respond with UNSUPPORTED_RESOURCE result code, success = false to mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local hmi_values = require("user_modules/hmi_values") + +--[[ Local Variables ]] +local Module = "RADIO" +local hmiValues = hmi_values.getDefaultHMITable() +hmiValues.RC.GetCapabilities.params.remoteControlCapability.radioControlCapabilities[1].siriusxmRadioAvailable = nil + +--[[ Local Functions ]] +local function rpcDenied(self) + local requestParams = commonRC.getSettableModuleControlData(Module) + requestParams.radioControlData.band = "XM" + + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + moduleData = requestParams + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { hmiValues }) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") + +runner.Step("SetInteriorVehicleData UNSUPPORTED_RESOURCE in case siriusxmRadioAvailable omitted", rpcDenied) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/021_INVALID_DATA_in_case_invalid_data_in_hdRadioEnable.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/021_INVALID_DATA_in_case_invalid_data_in_hdRadioEnable.lua new file mode 100644 index 0000000000..b79c3e24d6 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/021_INVALID_DATA_in_case_invalid_data_in_hdRadioEnable.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0160-rc-radio-parameter-update.md +-- User story: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) and sends valid SetInteriorVehicleData RPC with invalid value in hdRadioEnable +-- SDL must: +-- 1) Respond with INVALID_DATA result code, success = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local Module = "RADIO" + +--[[ Local Functions ]] +local function rpcInvalidData(self) + local requestParams = commonRC.getSettableModuleControlData(Module) + requestParams.radioControlData.hdRadioEnable = "ENABLE" + + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + moduleData = requestParams + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") + +runner.Step("SetInteriorVehicleData INVALID_DATA", rpcInvalidData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/022_availableHDs_hdChannel_upper_bound.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/022_availableHDs_hdChannel_upper_bound.lua new file mode 100644 index 0000000000..e5d236b9d2 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/022_availableHDs_hdChannel_upper_bound.lua @@ -0,0 +1,69 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0160-rc-radio-parameter-update.md +-- User story: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) and sends valid SetInteriorVehicleData RPC with max value for hdChannel +-- 3) HMI sends OnInteriorVehicleData with max value for availableHDs +-- SDL must: +-- 1) Transfer this request to HMI +-- 2) Respond with received from HMI +-- 3) Transfer notification to mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local Module = "RADIO" + +--[[ Local Functions ]] +local function setVehicleData(self) + local requestParams = commonRC.getSettableModuleControlData(Module) + requestParams.radioControlData.hdChannel = 7 + + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + moduleData = requestParams + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = requestParams + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = requestParams + }) + end) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function onVehicleData(self) + local notificationParams = commonRC.getHMIResponseParams("OnInteriorVehicleData", Module) + notificationParams.moduleData.radioControlData.availableHDs = 7 + + self.hmiConnection:SendNotification(commonRC.getHMIEventName("OnInteriorVehicleData"), notificationParams) + self.mobileSession1:ExpectNotification(commonRC.getAppEventName("OnInteriorVehicleData"), notificationParams) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) +runner.Step("Subscribe app to " .. Module, commonRC.subscribeToModule, { Module }) + +runner.Title("Test") + +runner.Step("SetInteriorVehicleData with max value for hdChannel", setVehicleData) +runner.Step("OnInteriorVehicleData with max value for availableHDs", onVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/023_availableHDs_hdChannel_out_of_upper_bound.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/023_availableHDs_hdChannel_out_of_upper_bound.lua new file mode 100644 index 0000000000..0602f54a58 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/023_availableHDs_hdChannel_out_of_upper_bound.lua @@ -0,0 +1,62 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0160-rc-radio-parameter-update.md +-- User story: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) and sends valid SetInteriorVehicleData RPC with out of upper bound value for hdChannel +-- 3) HMI sends OnInteriorVehicleData with out of upper bound value for availableHDs +-- SDL must: +-- 1) Respond with INVALID_DATA result code, success = false to mobile application +-- 3) not transfer notification to mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local Module = "RADIO" + +--[[ Local Functions ]] +local function setVehicleData(self) + local requestParams = commonRC.getSettableModuleControlData(Module) + requestParams.radioControlData.hdChannel = 8 + + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + moduleData = requestParams + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) +end + +local function onVehicleData(self) + local notificationParams = commonRC.getHMIResponseParams("OnInteriorVehicleData", Module) + notificationParams.moduleData.radioControlData.availableHDs = 8 + + self.hmiConnection:SendNotification(commonRC.getHMIEventName("OnInteriorVehicleData"), notificationParams) + self.mobileSession1:ExpectNotification(commonRC.getAppEventName("OnInteriorVehicleData")) + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) +runner.Step("Subscribe app to " .. Module, commonRC.subscribeToModule, { Module }) + +runner.Title("Test") + +runner.Step("SetInteriorVehicleData with out of upper bound value for hdChannel", setVehicleData) +runner.Step("OnInteriorVehicleData with out of upper bound value for availableHDs", onVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index b7069fa35b..427e03d25c 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -325,7 +325,8 @@ function commonRC.getModuleControlData(module_type) signalStrength = 5, signalChangeThreshold = 10, radioEnable = true, - state = "ACQUIRING" + state = "ACQUIRING", + hdRadioEnable = true } end return out @@ -372,7 +373,8 @@ function commonRC.getAnotherModuleControlData(module_type) signalStrength = 5, signalChangeThreshold = 20, radioEnable = true, - state = "ACQUIRING" + state = "ACQUIRING", + hdRadioEnable = false } end return out diff --git a/test_sets/rc_radio_parameter_update.txt b/test_sets/rc_radio_parameter_update.txt new file mode 100644 index 0000000000..94cfc7314d --- /dev/null +++ b/test_sets/rc_radio_parameter_update.txt @@ -0,0 +1,12 @@ +./test_scripts/RC/CLIMATE_RADIO/GetSystemCapability/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/016_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_false.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/017_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_omitted.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/018_Success_flow_band_setting.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/019_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_false.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/020_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_omitted.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/021_INVALID_DATA_in_case_invalid_data_in_hdRadioEnable.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/022_availableHDs_hdChannel_upper_bound.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/023_availableHDs_hdChannel_out_of_upper_bound.lua diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index 84ad02b7e8..aa97eefd25 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -365,7 +365,9 @@ function module.getDefaultHMITable() stateAvailable = true, signalStrengthAvailable = true, signalChangeThresholdAvailable = true, - sisDataAvailable = true + sisDataAvailable = true, + hdRadioEnableAvailable = true, + siriusxmRadioAvailable = true } }, audioControlCapabilities = { @@ -375,7 +377,9 @@ function module.getDefaultHMITable() keepContextAvailable = true, volumeAvailable = true, equalizerAvailable = true, - equalizerMaxChannelId = 100 + equalizerMaxChannelId = 100, + hdRadioEnableAvailable = true, + siriusxmRadioAvailable = true } }, seatControlCapabilities = { @@ -397,7 +401,7 @@ function module.getDefaultHMITable() massageCushionFirmnessAvailable = true, memoryAvailable = true } - }, + }, hmiSettingsControlCapabilities = { moduleName = "HmiSettings", distanceUnitAvailable = true, From 492e80e002c6b5be036f437b19ddaf8671cbb3f9 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 17 Aug 2018 12:06:59 +0300 Subject: [PATCH 572/681] Remove redundant capabilities from audioControlCapabilities --- user_modules/hmi_values.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index aa97eefd25..26b454421c 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -377,9 +377,7 @@ function module.getDefaultHMITable() keepContextAvailable = true, volumeAvailable = true, equalizerAvailable = true, - equalizerMaxChannelId = 100, - hdRadioEnableAvailable = true, - siriusxmRadioAvailable = true + equalizerMaxChannelId = 100 } }, seatControlCapabilities = { From 7f06254c357e2db90feb285943844debc30a0bec Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 24 Jul 2018 18:14:29 +0300 Subject: [PATCH 573/681] Replace the RADIO_TUNER with four enumeration elements AM, FM, XM and DAB --- .../017_Success_audio_source_values.lua | 61 +++++++++++++++++++ .../009_Success_audio_source_values.lua | 56 +++++++++++++++++ .../009_Change_audio_source_in_FULL.lua | 13 +--- .../010_Change_audio_source_in_LIMITED.lua | 13 +--- .../011_Change_audio_source_in_BACKGROUND.lua | 13 +--- ..._audio_source_in_FULL_rc_non_media_app.lua | 13 +--- ...ype_except_MOBILE_APP_keepContext_true.lua | 5 +- .../commonRCmodules.lua | 17 +++++- test_sets/audio_source_am_fm_xm.txt | 9 +++ test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt | 2 + 10 files changed, 152 insertions(+), 50 deletions(-) create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua create mode 100644 test_sets/audio_source_am_fm_xm.txt diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua new file mode 100644 index 0000000000..ea7f9614bc --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0182-audio-source-am-fm-xm.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1) Mobile app sends GetInteriorVehicleData request with moduleType=AUDIO +-- 2) SDL transfers this request to HMI +-- 3) HMI responds with source from PrimaryAudioSource enum +-- SDL must: +-- 1) Process this response and transfer it to mobile +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function subscribeToModule(pAudioSources) + local rpc = "GetInteriorVehicleData" + local subscribe = nil + local moduleType = "AUDIO" + local mobSession = common.getMobileSession(1) + local hmiResponseParams = common.getHMIResponseParams(rpc, moduleType, subscribe) + hmiResponseParams.moduleData.audioControlData.source = pAudioSources + local mobileResponseParams = common.getAppResponseParams(rpc, true, "SUCCESS", moduleType, subscribe) + mobileResponseParams.moduleData.audioControlData.source = pAudioSources + local cid = mobSession:SendRPC(common.getAppEventName(rpc), common.getAppRequestParams(rpc, moduleType, subscribe)) + EXPECT_HMICALL(common.getHMIEventName(rpc), common.getHMIRequestParams(rpc, moduleType, 1, subscribe)) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", hmiResponseParams) + end) + mobSession:ExpectResponse(cid, mobileResponseParams) + :ValidIf(function(_,data) + if nil ~= data.payload.moduleData.audioControlData.keepContext then + return false, "Mobile response GetInteriorVehicleData contains unexpected keepContext parameter" + end + return true + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, source in pairs(common.audioSources) do + runner.Step("GetInteriorVehicleData source " .. source, subscribeToModule, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua new file mode 100644 index 0000000000..51d44aacd3 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0182-audio-source-am-fm-xm.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app is subscribed to get interior vehicle data for module AUDIO +-- 2) HMI sends OnInteriorVehicleData with source from PrimaryAudioSource enum +-- SDL must: +-- 1) Process this notification and transfer it to mobile +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function isSubscribed(pAudioSources) + local moduleType = "AUDIO" + local mobSession = common.getMobileSession(1) + local rpc = "OnInteriorVehicleData" + local hmiParams = common.getHMIResponseParams(rpc, moduleType) + hmiParams.moduleData.audioControlData.source = pAudioSources + local mobileParams = common.getAppResponseParams(rpc, moduleType) + mobileParams.moduleData.audioControlData.source = pAudioSources + common.getHMIconnection():SendNotification(common.getHMIEventName(rpc), hmiParams) + mobSession:ExpectNotification(common.getAppEventName(rpc), mobileParams) + :ValidIf(function(_,data) + if nil ~= data.payload.moduleData.audioControlData.keepContext then + return false, "Mobile notification OnInteriorVehicleData contains unexpected keepContext parameter" + end + return true + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("Subscribe app to AUDIO", common.subscribeToModule, { "AUDIO" }) + +runner.Title("Test") + +for _, source in pairs(common.audioSources) do + runner.Step("Send notification OnInteriorVehicleData " .. source .. ". App is subscribed", isSubscribed, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua index 077918a2af..744f56c4a2 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua @@ -25,17 +25,6 @@ config.application1.registerAppInterfaceParams.isMediaApplication = true --[[ Local Variables ]] local audioData = common.getSettableModuleControlData("AUDIO") -local audioSources = { - "NO_SOURCE_SELECTED", - "CD", - "BLUETOOTH_STEREO_BTST", - "USB", - "USB2", - "LINE_IN", - "IPOD", - "MOBILE_APP", - "RADIO_TUNER" -} --[[ Local Functions ]] local function setVehicleData(pSource) @@ -65,7 +54,7 @@ runner.Step("RAI, PTU", common.raiPTUn) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, source in pairs(audioSources) do +for _, source in pairs(common.audioSources) do runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua index 1d372b1222..e45271edb0 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua @@ -25,17 +25,6 @@ config.application1.registerAppInterfaceParams.isMediaApplication = true --[[ Local Variables ]] local audioData = common.getSettableModuleControlData("AUDIO") -local audioSources = { - "NO_SOURCE_SELECTED", - "CD", - "BLUETOOTH_STEREO_BTST", - "USB", - "USB2", - "LINE_IN", - "IPOD", - "MOBILE_APP", - "RADIO_TUNER" -} --[[ Local Functions ]] local function setVehicleData(pSource) @@ -75,7 +64,7 @@ runner.Step("Activate App", common.activateApp) runner.Step("Set App to LIMITED HMI level", bringAppToLIMITED) runner.Title("Test") -for _, source in pairs(audioSources) do +for _, source in pairs(common.audioSources) do runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua index da6953ec1c..e10ad08462 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua @@ -26,17 +26,6 @@ config.application2.registerAppInterfaceParams.isMediaApplication = true --[[ Local Variables ]] local audioData = common.getSettableModuleControlData("AUDIO") -local audioSources = { - "NO_SOURCE_SELECTED", - "CD", - "BLUETOOTH_STEREO_BTST", - "USB", - "USB2", - "LINE_IN", - "IPOD", - "MOBILE_APP", - "RADIO_TUNER" -} --[[ Local Functions ]] local function setVehicleData(pSource) @@ -67,7 +56,7 @@ runner.Step("Activate App1", common.activateApp) runner.Step("Set App1 to BACKGROUND HMI level", BringAppToBACKGROUND) runner.Title("Test") -for _, source in pairs(audioSources) do +for _, source in pairs(common.audioSources) do runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua index 5c9c76218d..751921cb50 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua @@ -25,17 +25,6 @@ config.application1.registerAppInterfaceParams.isMediaApplication = false --[[ Local Variables ]] local audioData = common.getSettableModuleControlData("AUDIO") -local audioSources = { - "NO_SOURCE_SELECTED", - "CD", - "BLUETOOTH_STEREO_BTST", - "USB", - "USB2", - "LINE_IN", - "IPOD", - "MOBILE_APP", - "RADIO_TUNER" -} --[[ Local Functions ]] local function setVehicleData(pSource) @@ -59,7 +48,7 @@ runner.Step("RAI, PTU", common.raiPTUn) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, source in pairs(audioSources) do +for _, source in pairs(common.audioSources) do runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua index 68e6e2b82f..4006803660 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua @@ -34,7 +34,10 @@ local audioSources = { "USB2", "LINE_IN", "IPOD", - "RADIO_TUNER" + "AM", + "FM", + "XM", + "DAB" } local keepContext = { diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua index 28cf34198e..cb3d3e39ac 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua @@ -24,6 +24,21 @@ c.capMap = { ["HMI_SETTINGS"] = "hmiSettingsControlCapabilities" } +c.audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "AM", + "FM", + "XM", + "DAB" +} + c.backupHMICapabilities = commonRC.backupHMICapabilities c.restoreHMICapabilities = commonRC.restoreHMICapabilities c.DEFAULT = commonRC.DEFAULT @@ -112,7 +127,7 @@ function c.getModuleControlData(pModuleType) elseif "AUDIO" == pModuleType then struct.moduleType = "AUDIO" struct.audioControlData = { - source = "RADIO_TUNER", + source = "AM", keepContext = false, volume = 50, equalizerSettings = { diff --git a/test_sets/audio_source_am_fm_xm.txt b/test_sets/audio_source_am_fm_xm.txt new file mode 100644 index 0000000000..eb023c98e0 --- /dev/null +++ b/test_sets/audio_source_am_fm_xm.txt @@ -0,0 +1,9 @@ +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua +./test_scripts/API/VehicleData/GetVehicleData/003_Success_deviceStatus_primaryAudioSource.lua +./test_scripts/API/VehicleData/OnVehicleData/004_Success_flow_deviceStatus_primaryAudioSource.lua diff --git a/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt b/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt index 9de99a0870..faae0fd39d 100644 --- a/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt +++ b/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt @@ -14,6 +14,7 @@ ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua @@ -30,6 +31,7 @@ ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua From 60a1835983f2c28ec9d7716d5166849af1108d35 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 24 Jul 2018 18:19:42 +0300 Subject: [PATCH 574/681] Replace the RADIO_TUNER with four enumeration elements for VehicleData --- ...uccess_deviceStatus_primaryAudioSource.lua | 78 +++++++++++++++ ...s_flow_deviceStatus_primaryAudioSource.lua | 95 +++++++++++++++++++ .../API/VehicleData/commonVehicleData.lua | 2 +- test_sets/VehicleData.txt | 2 + 4 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 test_scripts/API/VehicleData/GetVehicleData/004_Success_deviceStatus_primaryAudioSource.lua create mode 100644 test_scripts/API/VehicleData/OnVehicleData/005_Success_flow_deviceStatus_primaryAudioSource.lua diff --git a/test_scripts/API/VehicleData/GetVehicleData/004_Success_deviceStatus_primaryAudioSource.lua b/test_scripts/API/VehicleData/GetVehicleData/004_Success_deviceStatus_primaryAudioSource.lua new file mode 100644 index 0000000000..4cc3aca1ed --- /dev/null +++ b/test_scripts/API/VehicleData/GetVehicleData/004_Success_deviceStatus_primaryAudioSource.lua @@ -0,0 +1,78 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0182-audio-source-am-fm-xm.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1) Mobile app sends GetVehicleData request with deviceStatus=true +-- 2) SDL transfers this request to HMI +-- 3) HMI responds with value from PrimaryAudioSource enum in deviceStatus.primaryAudioSource +-- SDL must: +-- 1) Process GetVehicleData response and transfer it to mobile +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') +local utils = require("user_modules/utils") + +--[[ Local Variables ]] +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "AM", + "FM", + "XM", + "DAB" +} + +local rpc = { + name = "GetVehicleData", + params = { + deviceStatus = true + } +} + +--[[ Local Functions ]] +local function processRPCSuccess(pAudioSource, self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc.name, rpc.params) + local vehicleDataValues = { + deviceStatus = { + primaryAudioSource = pAudioSource + } + } + EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", vehicleDataValues ) + end) + local responseParams = vehicleDataValues + responseParams.success = true + responseParams.resultCode = "SUCCESS" + mobileSession:ExpectResponse(cid, responseParams) + utils.wait(300) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, source in pairs(audioSources) do + runner.Step("RPC " .. rpc.name .. " source " .. source, processRPCSuccess, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/VehicleData/OnVehicleData/005_Success_flow_deviceStatus_primaryAudioSource.lua b/test_scripts/API/VehicleData/OnVehicleData/005_Success_flow_deviceStatus_primaryAudioSource.lua new file mode 100644 index 0000000000..76ea62041f --- /dev/null +++ b/test_scripts/API/VehicleData/OnVehicleData/005_Success_flow_deviceStatus_primaryAudioSource.lua @@ -0,0 +1,95 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0182-audio-source-am-fm-xm.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1) Mobile app is subscribed to get deviceStatus vehicle data +-- 2) HMI sends OnVehicleData with value from PrimaryAudioSource enum in deviceStatus.primaryAudioSource +-- SDL must: +-- 1) Process OnVehicleData notification and transfer it to mobile +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') + +--[[ Local Variables ]] +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "AM", + "FM", + "XM", + "DAB" +} + +local rpc1 = { + name = "SubscribeVehicleData", + params = { + deviceStatus = true + } +} + +local vehicleDataResults = { + deviceStatus = { + dataType = "VEHICLEDATA_DEVICESTATUS", + resultCode = "SUCCESS" + } +} + +local rpc2 = { + name = "OnVehicleData", + params = { + deviceStatus = { + primaryAudioSource = "CD" + } + } +} + +--[[ Local Functions ]] +local function processRPCSubscribeSuccess(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc1.name, rpc1.params) + EXPECT_HMICALL("VehicleInfo." .. rpc1.name, rpc1.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", vehicleDataResults) + end) + + local responseParams = vehicleDataResults + responseParams.success = true + responseParams.resultCode = "SUCCESS" + mobileSession:ExpectResponse(cid, responseParams) +end + +local function checkNotificationSuccess(pAudioSource, self) + rpc2.params.deviceStatus.primaryAudioSource = pAudioSource + local mobileSession = common.getMobileSession(self, 1) + self.hmiConnection:SendNotification("VehicleInfo." .. rpc2.name, rpc2.params) + mobileSession:ExpectNotification("OnVehicleData", rpc2.params) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("RPC " .. rpc1.name, processRPCSubscribeSuccess) +for _, source in pairs(audioSources) do + runner.Step("RPC " .. rpc2.name .. " source " .. source, checkNotificationSuccess, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/VehicleData/commonVehicleData.lua b/test_scripts/API/VehicleData/commonVehicleData.lua index d91a8a69d3..778ca63bda 100644 --- a/test_scripts/API/VehicleData/commonVehicleData.lua +++ b/test_scripts/API/VehicleData/commonVehicleData.lua @@ -35,7 +35,7 @@ function commonVehicleData.getGetVehicleDataConfig() steal_focus = false, priority = "NONE", default_hmi = "NONE", - groups = { "Base-4", "Emergency-1" } + groups = { "Base-4", "Emergency-1", "VehicleInfo-3" } } end diff --git a/test_sets/VehicleData.txt b/test_sets/VehicleData.txt index 8f55f8df92..105559f2a9 100644 --- a/test_sets/VehicleData.txt +++ b/test_sets/VehicleData.txt @@ -1,10 +1,12 @@ ./test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua ./test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua ./test_scripts/API/VehicleData/GetVehicleData/003_GetVD_gps_mandatory_parameters.lua +./test_scripts/API/VehicleData/GetVehicleData/004_Success_deviceStatus_primaryAudioSource.lua ./test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua ./test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua ;./test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua ./test_scripts/API/VehicleData/OnVehicleData/004_OnVD_gps_mandatory_parameters.lua +./test_scripts/API/VehicleData/OnVehicleData/005_Success_flow_deviceStatus_primaryAudioSource.lua ./test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua ;./test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua ;./test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua From f491abb344fb9a44a3a445e37a8b13685a2efeaa Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 17 Aug 2018 19:30:34 +0300 Subject: [PATCH 575/681] Fix links to scripts in test set --- test_sets/audio_source_am_fm_xm.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_sets/audio_source_am_fm_xm.txt b/test_sets/audio_source_am_fm_xm.txt index eb023c98e0..8e8a16b590 100644 --- a/test_sets/audio_source_am_fm_xm.txt +++ b/test_sets/audio_source_am_fm_xm.txt @@ -5,5 +5,5 @@ ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua -./test_scripts/API/VehicleData/GetVehicleData/003_Success_deviceStatus_primaryAudioSource.lua -./test_scripts/API/VehicleData/OnVehicleData/004_Success_flow_deviceStatus_primaryAudioSource.lua +./test_scripts/API/VehicleData/GetVehicleData/004_Success_deviceStatus_primaryAudioSource.lua +./test_scripts/API/VehicleData/OnVehicleData/005_Success_flow_deviceStatus_primaryAudioSource.lua From ecea504ef82d876e58286fdfeb1773622b381d0c Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Mon, 20 Aug 2018 13:45:58 +0300 Subject: [PATCH 576/681] Update RADIO_TUNER to AM in common for OnRCStatus --- test_scripts/RC/OnRCStatus/commonOnRCStatus.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua index c11690c73e..80826e10d5 100644 --- a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua +++ b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua @@ -109,7 +109,7 @@ function commonRC.getModuleControlData(module_type) elseif module_type == "AUDIO" then out.moduleType = "AUDIO" out.audioControlData = { - source = "RADIO_TUNER", + source = "AM", volume = 50 } elseif module_type == "LIGHT" then From b566945afb86043479095db53d0585b7485039cb Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 21 Aug 2018 11:40:32 -0400 Subject: [PATCH 577/681] Send version 2.2, expect version 4.5 --- .../VersionNegotiation/001_register_legacy_app.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua index f1b94cb13b..04be8b9469 100644 --- a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua +++ b/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua @@ -33,8 +33,8 @@ local commonSmoke = require('test_scripts/Smoke/commonSmoke') --[[ Local Variables ]] local requestParams = { syncMsgVersion = { - majorVersion = 4, - minorVersion = 5, + majorVersion = 2, + minorVersion = 2, }, appName = "SyncProxyTester", ttsName = { @@ -97,7 +97,10 @@ local function RegisterAppInterface(self) local CorIdRAI = self.mobileSession1:SendRPC("RegisterAppInterface", requestParams) local notificationParams = GetNotificationParams() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", notificationParams) - self.mobileSession1:ExpectResponse(CorIdRAI, { success = true, resultCode = "SUCCESS", syncMsgVersion = requestParams.syncMsgVersion}) + self.mobileSession1:ExpectResponse(CorIdRAI, { success = true, resultCode = "SUCCESS", syncMsgVersion = { + majorVersion = 4, + minorVersion = 5, + }}) self.mobileSession1:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) self.mobileSession1:ExpectNotification("OnPermissionsChange") From f11ebf78bff79779568e3fa093ffd5425fb2091e Mon Sep 17 00:00:00 2001 From: JackLivio Date: Wed, 22 Aug 2018 14:18:50 -0400 Subject: [PATCH 578/681] Fix conflicts --- .../ATF_Expanded_smoke_test_Genivi.lua | 81 ++----------------- 1 file changed, 7 insertions(+), 74 deletions(-) diff --git a/test_scripts/ATF_Expanded_smoke_test_Genivi.lua b/test_scripts/ATF_Expanded_smoke_test_Genivi.lua index ff3439aa6f..9b7feacc72 100644 --- a/test_scripts/ATF_Expanded_smoke_test_Genivi.lua +++ b/test_scripts/ATF_Expanded_smoke_test_Genivi.lua @@ -20,51 +20,9 @@ os.execute("cp -f files/SmokeTest_genivi_pt.json " .. commonPreconditions:GetPat Test = require('connecttest') require('cardinalities') require('user_modules/AppTypes') -<<<<<<< HEAD -local SDLConfig = require ('user_modules/shared_testcases/SmartDeviceLinkConfigurations') -config.SDLStoragePath = config.pathToSDL .. "storage/" -config.sharedMemoryPath = "" -local dif_fileType = {{typeV = "GRAPHIC_BMP", file = "files/PutFile/bmp_6kb.bmp" }, {typeV = "GRAPHIC_JPEG", file = "files/PutFile/jpeg_4kb.jpg" }, {typeV = "GRAPHIC_PNG", file = "files/PutFile/icon.png" }, {typeV = "AUDIO_WAVE", file = "files/PutFile/WAV_6kb.wav" }, {typeV = "AUDIO_MP3", file = "files/PutFile/MP3_123kb.mp3" }, {typeV = "AUDIO_AAC", file = "files/PutFile/Alarm.aac" }, {typeV = "BINARY", file = "files/PutFile/binaryFile" }, {typeV = "JSON", file = "files/PutFile/luxoftPT.json" }} - -local ButtonArray = {"OK","PLAY_PAUSE","SEEKLEFT", "SEEKRIGHT", "TUNEUP", "TUNEDOWN", "PRESET_0", "PRESET_1", "PRESET_2", "PRESET_3", "PRESET_4", "PRESET_5", "PRESET_6", "PRESET_7", "PRESET_8", "PRESET_9"} -======= ->>>>>>> origin/develop --[[ Local Variables ]]------------------------------------------------------------------------------------------------ local applicationName = config.application1.registerAppInterfaceParams.appName -<<<<<<< HEAD -Test.spaceAvailable = tonumber(SDLConfig:GetValue("AppDirectoryQuota")) -Test.InitialSpaceAvailable = tonumber(SDLConfig:GetValue("AppDirectoryQuota")) -config.deviceMAC = "12ca17b49af2289436f303e0166030a21e525d266e209267433801a8fd4071a0" -local iTimeout = 5000 -local PathToAppFolder = config.pathToSDL .. SDLConfig:GetValue("AppStorageFolder") .. "/" .. tostring(config.application1.registerAppInterfaceParams.appID .. "_" .. tostring(config.deviceMAC) .. "/") -local updateModeNotRequireStartEndTime = {"PAUSE", "RESUME", "CLEAR"} -local updateMode = {"COUNTUP", "COUNTDOWN", "PAUSE", "RESUME", "CLEAR"} -local updateModeCountUpDown = {"COUNTUP", "COUNTDOWN"} -local buttonName = {"OK","PLAY_PAUSE","SEEKLEFT","SEEKRIGHT","TUNEUP","TUNEDOWN", "PRESET_0","PRESET_1","PRESET_2","PRESET_3","PRESET_4","PRESET_5","PRESET_6","PRESET_7","PRESET_8"} -local PositiveChoiceSets -local textPromtValue = {"Please speak one of the following commands," ,"Please say a command,"} - -local NavigationType = false -if Test.appHMITypes["NAVIGATION"] == true then - NavigationType = true -end - ---------------------------------------------------------------------------------------------- ------------------------------------------ Functions Used ------------------------------------ ---------------------------------------------------------------------------------------------- - - --Common functions - ------------------------------------------------------------------------------------------ - - function DelayedExp(timeout) - local event = events.Event() - event.matches = function(self, e) return self == e end - EXPECT_EVENT(event, "Delayed event") - RUN_AFTER(function() - RAISE_EVENT(event, event) - end, timeout) -======= local pathToAppFolder = commonPreconditions:GetPathToSDL() .. SDLConfig:GetValue("AppStorageFolder") .. "/" .. tostring(config.application1.registerAppInterfaceParams.appID .. "_" .. tostring(config.deviceMAC) .. "/") local spaceAvailable = tonumber(SDLConfig:GetValue("AppDirectoryQuota")) @@ -78,7 +36,7 @@ local fileTypes = { { typeV = "BINARY", file = "files/PutFile/binaryFile" }, { typeV = "JSON", file = "files/PutFile/luxoftPT.json" } } -local buttonArray = { "OK", "SEEKLEFT", "SEEKRIGHT", "TUNEUP", "TUNEDOWN", "PRESET_0", "PRESET_1", "PRESET_2", "PRESET_3", +local buttonArray = { "OK", "PLAY_PAUSE", "SEEKLEFT", "SEEKRIGHT", "TUNEUP", "TUNEDOWN", "PRESET_0", "PRESET_1", "PRESET_2", "PRESET_3", "PRESET_4", "PRESET_5", "PRESET_6", "PRESET_7", "PRESET_8", "PRESET_9" } local updateModeNotRequireStartEndTime = { "PAUSE", "RESUME", "CLEAR" } local updateMode = { "COUNTUP", "COUNTDOWN", "PAUSE", "RESUME", "CLEAR" } @@ -108,7 +66,6 @@ local blockId = 1 name = name .. string.rep(filler, strLen - string.len(name)) Test[name] = function() end blockId = blockId + 1 ->>>>>>> origin/develop end -- Sending OnSystemContext notification @@ -6432,20 +6389,12 @@ local blockId = 1 EXPECT_NOTIFICATION("OnHashChange") else -<<<<<<< HEAD if - ButtonArray[i] == "PLAY_PAUSE" or - ButtonArray[i] == "SEEKLEFT" or - ButtonArray[i] == "SEEKRIGHT" or - ButtonArray[i] == "TUNEUP" or - ButtonArray[i] == "TUNEDOWN" then -======= - if - buttonArray[i] == "SEEKLEFT" or + buttonArray[i] == "PLAY_PAUSE" or + buttonArray[i] == "SEEKLEFT" or buttonArray[i] == "SEEKRIGHT" or buttonArray[i] == "TUNEUP" or buttonArray[i] == "TUNEDOWN" then ->>>>>>> origin/develop --mobile side: expect SubscribeButton response self.mobileSession:ExpectResponse(CorIdSubscribeButtonAllPAramsVD, { success = false, resultCode = "REJECTED"}) @@ -6509,20 +6458,12 @@ local blockId = 1 --mobile side: expect SubscribeButton response self.mobileSession:ExpectResponse(cid, { success = false, resultCode = "IGNORED"}) else -<<<<<<< HEAD if - ButtonArray[i] == "PLAY_PAUSE" or - ButtonArray[i] == "SEEKLEFT" or - ButtonArray[i] == "SEEKRIGHT" or - ButtonArray[i] == "TUNEUP" or - ButtonArray[i] == "TUNEDOWN" then -======= - if - buttonArray[i] == "SEEKLEFT" or + buttonArray[i] == "PLAY_PAUSE" or + buttonArray[i] == "SEEKLEFT" or buttonArray[i] == "SEEKRIGHT" or buttonArray[i] == "TUNEUP" or buttonArray[i] == "TUNEDOWN" then ->>>>>>> origin/develop --mobile side: expect SubscribeButton response self.mobileSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED"}) else @@ -6583,20 +6524,12 @@ local blockId = 1 EXPECT_NOTIFICATION("OnHashChange") else -<<<<<<< HEAD if - ButtonArray[i] == "PLAY_PAUSE" or - ButtonArray[i] == "SEEKLEFT" or - ButtonArray[i] == "SEEKRIGHT" or - ButtonArray[i] == "TUNEUP" or - ButtonArray[i] == "TUNEDOWN" then -======= - if - buttonArray[i] == "SEEKLEFT" or + buttonArray[i] == "PLAY_PAUSE" or + buttonArray[i] == "SEEKLEFT" or buttonArray[i] == "SEEKRIGHT" or buttonArray[i] == "TUNEUP" or buttonArray[i] == "TUNEDOWN" then ->>>>>>> origin/develop --mobile side: expect SubscribeButton response self.mobileSession:ExpectResponse(CorIdUnSubscribeButton, { success = false, resultCode = "IGNORED"}) From 7eb585c40b54ee07819cb329cf540b796536c9aa Mon Sep 17 00:00:00 2001 From: JackLivio Date: Wed, 22 Aug 2018 16:00:22 -0400 Subject: [PATCH 579/681] Add mobile versioning tests for play_pause --- files/hmi_capabilities_SearchButton.json | 6 ++ files/hmi_capabilities_Without_PRESET9.json | 6 ++ .../001_play_pause_v5_allowed.lua | 80 +++++++++++++++++++ .../002_play_pause_v4_invalid_data.lua | 70 ++++++++++++++++ user_modules/connecttest_initHMI.lua | 1 + user_modules/hmi_values.lua | 1 + 6 files changed, 164 insertions(+) create mode 100644 test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/001_play_pause_v5_allowed.lua create mode 100644 test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua diff --git a/files/hmi_capabilities_SearchButton.json b/files/hmi_capabilities_SearchButton.json index ae107c8236..e9c77ffca4 100644 --- a/files/hmi_capabilities_SearchButton.json +++ b/files/hmi_capabilities_SearchButton.json @@ -373,6 +373,12 @@ "longPressAvailable": true, "upDownAvailable": true }, + { + "name": "PLAY_PAUSE", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, { "name":"PLAY_PAUSE", "shortPressAvailable": true, diff --git a/files/hmi_capabilities_Without_PRESET9.json b/files/hmi_capabilities_Without_PRESET9.json index 6f19019fa0..12051caf74 100644 --- a/files/hmi_capabilities_Without_PRESET9.json +++ b/files/hmi_capabilities_Without_PRESET9.json @@ -367,6 +367,12 @@ "longPressAvailable": true, "upDownAvailable": true }, + { + "name": "PLAY_PAUSE", + "shortPressAvailable": true, + "longPressAvailable": true, + "upDownAvailable": true + }, { "name":"PLAY_PAUSE", "shortPressAvailable": true, diff --git a/test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/001_play_pause_v5_allowed.lua b/test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/001_play_pause_v5_allowed.lua new file mode 100644 index 0000000000..75ea47c74b --- /dev/null +++ b/test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/001_play_pause_v5_allowed.lua @@ -0,0 +1,80 @@ +--------------------------------------------------------------------------------------------------- +-- User story: MobileVersioning +-- Use case: SubscribeButton +-- Item: Happy path +-- +-- Requirement summary: +-- [SubscribeButton] SUCCESS: getting SUCCESS:SubscribeButton() +-- +-- Description: +-- Mobile application sends valid SubscribeButton request and gets SubscribeButton "SUCCESS" response from SDL + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests SubscribeButton with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if Buttons interface is available on HMI +-- SDL checks if SubscribeButton is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL sends the Buttons notificaton to HMI +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + + +config.application1.registerAppInterfaceParams.syncMsgVersion = { + majorVersion = 5, + minorVersion = 0 +} + +--[[ Local Variables ]] +local buttonName = { + "OK", + "PLAY_PAUSE", + "SEEKLEFT", + "SEEKRIGHT", + "TUNEUP", + "TUNEDOWN", + "PRESET_0", + "PRESET_1", + "PRESET_2", + "PRESET_3", + "PRESET_4", + "PRESET_5", + "PRESET_6", + "PRESET_7", + "PRESET_8" +} + +--[[ Local Functions ]] +local function subscribeButton(pButName, self) + local cid = self.mobileSession1:SendRPC("SubscribeButton", { buttonName = pButName }) + local appIDvalue = commonSmoke.getHMIAppId() + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", { appID = appIDvalue, name = pButName, isSubscribed = true }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI", commonSmoke.registerApp) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") +for _, v in pairs(buttonName) do + runner.Step("SubscribeButton " .. v .. " Positive Case", subscribeButton, { v }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) \ No newline at end of file diff --git a/test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua b/test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua new file mode 100644 index 0000000000..6a823ff310 --- /dev/null +++ b/test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- User story: Smoke +-- Use case: SubscribeButton +-- Item: Happy path +-- +-- Requirement summary: +-- [SubscribeButton] SUCCESS: getting SUCCESS:SubscribeButton() +-- +-- Description: +-- Mobile application sends valid SubscribeButton request and gets SubscribeButton "SUCCESS" response from SDL + +-- Pre-conditions: +-- a. HMI and SDL are started +-- b. appID is registered and activated on SDL +-- c. appID is currently in Background, Full or Limited HMI level + +-- Steps: +-- appID requests SubscribeButton with valid parameters + +-- Expected: +-- SDL validates parameters of the request +-- SDL checks if Buttons interface is available on HMI +-- SDL checks if SubscribeButton is allowed by Policies +-- SDL checks if all parameters are allowed by Policies +-- SDL sends the Buttons notificaton to HMI +-- SDL responds with (resultCode: SUCCESS, success:true) to mobile application +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonSmoke = require('test_scripts/Smoke/commonSmoke') + +config.application1.registerAppInterfaceParams.syncMsgVersion = { + majorVersion = 4, + minorVersion = 5 +} + +--[[ Local Functions ]] +local function subscribeButtonSuccess(pButName, self) + local cid = self.mobileSession1:SendRPC("SubscribeButton", { buttonName = pButName }) + local appIDvalue = commonSmoke.getHMIAppId() + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", { appID = appIDvalue, name = pButName, isSubscribed = true }) + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + self.mobileSession1:ExpectNotification("OnHashChange") +end + +local function subscribeButtonInvalidData(pButName, self) + local cid = self.mobileSession1:SendRPC("SubscribeButton", { buttonName = pButName }) + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription") + :Times(0) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) + self.mobileSession1:ExpectNotification("OnHashChange") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonSmoke.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonSmoke.start) +runner.Step("RAI", commonSmoke.registerApp) +runner.Step("Activate App", commonSmoke.activateApp) + +runner.Title("Test") + +runner.Step("SubscribeButton " .. "OK" .. " Positive Case", subscribeButtonSuccess, { "OK" }) + +runner.Step("SubscribeButton " .. "PLAY_PAUSE" .. " Invalid Data Case", subscribeButtonInvalidData, { "PLAY_PAUSE" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonSmoke.postconditions) \ No newline at end of file diff --git a/user_modules/connecttest_initHMI.lua b/user_modules/connecttest_initHMI.lua index df5319efaf..9059fc8510 100644 --- a/user_modules/connecttest_initHMI.lua +++ b/user_modules/connecttest_initHMI.lua @@ -460,6 +460,7 @@ function module:initHMI_onReady() button_capability("PRESET_8"), button_capability("PRESET_9"), button_capability("OK", true, false, true), + button_capability("PLAY_PAUSE", true, false, true), button_capability("SEEKLEFT"), button_capability("SEEKRIGHT"), button_capability("TUNEUP"), diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index 163c2ad830..546911bcdb 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -312,6 +312,7 @@ function module.getDefaultHMITable() module.createButtonCapability("PRESET_8"), module.createButtonCapability("PRESET_9"), module.createButtonCapability("OK", true, false, true), + module.createButtonCapability("PLAY_PAUSE", true, false, true), module.createButtonCapability("SEEKLEFT"), module.createButtonCapability("SEEKRIGHT"), module.createButtonCapability("TUNEUP"), From ddd9e1221ddef2db51eb14db0ee0b287854a28e1 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Wed, 22 Aug 2018 16:24:50 -0400 Subject: [PATCH 580/681] Add play_pause to smoke test rpcs --- .../Smoke/API/022_SubscribeButton_PositiveCase_SUCCESS.lua | 1 + .../Smoke/API/023_UnsubscribeButton_PositiveCase_SUCCESS.lua | 1 + .../API/042_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua | 1 + .../API/043_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua | 1 + 4 files changed, 4 insertions(+) diff --git a/test_scripts/Smoke/API/022_SubscribeButton_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/022_SubscribeButton_PositiveCase_SUCCESS.lua index 01b1341ea8..1dfc139554 100644 --- a/test_scripts/Smoke/API/022_SubscribeButton_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/022_SubscribeButton_PositiveCase_SUCCESS.lua @@ -33,6 +33,7 @@ local commonSmoke = require('test_scripts/Smoke/commonSmoke') --[[ Local Variables ]] local buttonName = { "OK", + "PLAY_PAUSE", "SEEKLEFT", "SEEKRIGHT", "TUNEUP", diff --git a/test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase_SUCCESS.lua index 91f8bfe97a..f8babcd204 100644 --- a/test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/023_UnsubscribeButton_PositiveCase_SUCCESS.lua @@ -33,6 +33,7 @@ local commonSmoke = require('test_scripts/Smoke/commonSmoke') --[[ Local Variables ]] local buttonName = { "OK", + "PLAY_PAUSE", "SEEKLEFT", "SEEKRIGHT", "TUNEUP", diff --git a/test_scripts/Smoke/API/042_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/042_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua index f39ff5c893..850a2ee4c0 100644 --- a/test_scripts/Smoke/API/042_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/042_SubscribeButton_Non_Media_PositiveCase_SUCCESS.lua @@ -48,6 +48,7 @@ local buttonName = { } local mediaButtonName = { + "PLAY_PAUSE", "SEEKLEFT", "SEEKRIGHT", "TUNEUP", diff --git a/test_scripts/Smoke/API/043_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua b/test_scripts/Smoke/API/043_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua index 028c7c7c97..fba825717a 100644 --- a/test_scripts/Smoke/API/043_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua +++ b/test_scripts/Smoke/API/043_UnsubscribeButton_Non_Media_PositiveCase_SUCCESS.lua @@ -48,6 +48,7 @@ local buttonName = { } local mediaButtonName = { + "PLAY_PAUSE", "SEEKLEFT", "SEEKRIGHT", "TUNEUP", From 7c1aed7d136ac24253f589d3ef6ac264d6830978 Mon Sep 17 00:00:00 2001 From: "Ira Lytvynenko (GitHub)" Date: Fri, 18 May 2018 12:32:28 +0300 Subject: [PATCH 581/681] Scripts for new RC modules --- .../001_Success_flow.lua | 35 + .../002_Disallow_flow_by_policy_AUDIO.lua | 44 ++ .../003_Disallow_flow_by_policy_LIGHT.lua | 44 ++ ...4_Disallow_flow_by_policy_HMI_SETTINGS.lua | 44 ++ ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 56 ++ .../006_RPC_parameters_values.lua | 113 ++++ ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 60 ++ ..._in_case_HMI_respond_with_invalid_data.lua | 90 +++ ...se_moduleType_is_an_empty_array_in_LPT.lua | 45 ++ ...ow_in_case_moduleType_is_absent_in_LPT.lua | 48 ++ ...ROR_in_case_HMI_respond_with_READ_ONLY.lua | 60 ++ ...ransfering_of_HMI_resultCode_to_mobile.lua | 95 +++ ...ut_response_from_HMI_with_isSubscribed.lua | 80 +++ ...ase_of_2nd_Subscription_UnSubscription.lua | 104 +++ ...response_from_HMI_without_isSubscribed.lua | 86 +++ .../001_Consent_true_SIVD.lua | 62 ++ .../002_Consent_false_SIVD.lua | 64 ++ .../003_TIMED_OUT_from_HMI_SIVD.lua | 78 +++ .../004_HMI_no_response_SIVD.lua | 76 +++ .../005_HMI_invalid_response_SIVD.lua | 78 +++ .../GetSystemCapability/001_Success_flow.lua | 62 ++ ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 48 ++ ...CE_in_case_RC_interface_is_unavailable.lua | 59 ++ .../001_Success_flow.lua | 63 ++ .../002_Disallow_flow_by_policy_AUDIO.lua | 45 ++ .../003_Disallow_flow_by_policy_LIGHT.lua | 45 ++ ...4_Disallow_flow_by_policy_HMI_SETTINGS.lua | 45 ++ ...ribing_with_isSubscribe_false_from_HMI.lua | 70 ++ ...cribing_with_isSubscribe_true_from_HMI.lua | 75 +++ ...bscribing_without_isSubscribe_from_HMI.lua | 75 +++ ...bscribing_without_isSubscribe_from_HMI.lua | 81 +++ .../001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua | 63 ++ ...002_REJECTED_in_case_nonFULL_HMI_level.lua | 67 ++ ...003_Allowed_true_accessMode_AUTO_ALLOW.lua | 57 ++ .../004_Allowed_true_accessMode_AUTO_DENY.lua | 61 ++ ...005_Allowed_true_accessMode_ASK_DRIVER.lua | 64 ++ .../006_Default_accessMode.lua | 53 ++ .../001_Success_flow.lua | 41 ++ .../002_Disallow_flow_by_policy_CLIMATE.lua | 55 ++ .../003_Disallow_flow_by_policy_AUDIO.lua | 55 ++ .../004_Disallow_flow_by_policy_LIGHT.lua | 55 ++ ...5_Disallow_flow_by_policy_HMI_SETTINGS.lua | 55 ++ ...se_moduleType_is_an_empty_array_in_LPT.lua | 67 ++ ...ow_in_case_moduleType_is_absent_in_LPT.lua | 57 ++ ...cle_data_if_read_only_params_requested.lua | 45 ++ .../009_Change_audio_source_in_FULL.lua | 73 ++ .../010_Change_audio_source_in_BACKGROUND.lua | 75 +++ .../010_Change_audio_source_in_LIMITED.lua | 83 +++ .../011_Change_audio_source_in_BACKGROUND.lua | 75 +++ ..._audio_source_in_FULL_rc_non_media_app.lua | 67 ++ ...ce_from_MOBILE_APP_without_keepContext.lua | 86 +++ ..._audio_source_in_FULL_rc_non_media_app.lua | 67 ++ ...urce_from_MOBILE_APP_keepContext_false.lua | 86 +++ ...ce_from_MOBILE_APP_without_keepContext.lua | 86 +++ ...urce_from_MOBILE_APP_keepContext_false.lua | 86 +++ ..._from_MOBILE_APP_keepContext_true_FULL.lua | 86 +++ ..._from_MOBILE_APP_keepContext_true_FULL.lua | 86 +++ ...om_MOBILE_APP_keepContext_true_LIMITED.lua | 96 +++ ...om_MOBILE_APP_keepContext_true_LIMITED.lua | 96 +++ ...ype_except_MOBILE_APP_keepContext_true.lua | 88 +++ ...ype_except_MOBILE_APP_keepContext_true.lua | 88 +++ .../commonRCmodules.lua | 625 ++++++++++++++++++ .../025_IN_USE_in_case_3_requests.lua | 224 +++++++ test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt | 54 ++ test_sets/rc_CLIMATE_RADIO.txt | 1 + user_modules/hmi_values.lua | 50 +- 66 files changed, 5101 insertions(+), 2 deletions(-) create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/001_Success_flow.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/004_HMI_no_response_SIVD.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/005_HMI_invalid_response_SIVD.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/001_Success_flow.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/003_UNSUPPORTED_RESOURCE_in_case_RC_interface_is_unavailable.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/001_Success_flow.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/004_Allowed_true_accessMode_AUTO_DENY.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/005_Allowed_true_accessMode_ASK_DRIVER.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/006_Default_accessMode.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/001_Success_flow.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/008_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_BACKGROUND.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_FULL_rc_non_media_app.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_from_MOBILE_APP_without_keepContext.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_keepContext_false.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_without_keepContext.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_false.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/025_IN_USE_in_case_3_requests.lua create mode 100644 test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/001_Success_flow.lua new file mode 100644 index 0000000000..324d99b869 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/001_Success_flow.lua @@ -0,0 +1,35 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: TRS: GetInteriorVehicleData, #3 +-- In case: +-- 1) RC app sends valid and allowed by policies GetInteriorvehicleData_request +-- 2) and SDL received GetInteriorVehicledata_response with successful result code and current module data from HMI +-- SDL must: +-- 1) transfer GetInteriorVehicleData_response with provided from HMI current module data for allowed module and control items +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData " .. mod, common.subscribeToModule, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua new file mode 100644 index 0000000000..f2e9b53c5b --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received GetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local mod = "AUDIO" + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, self) + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType + }) + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { PTUfunc }) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua new file mode 100644 index 0000000000..61c949c8aa --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received GetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local mod = "LIGHT" + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, self) + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType + }) + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { PTUfunc }) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua new file mode 100644 index 0000000000..b52f650aeb --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received GetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local mod = "HMI_SETTINGS" + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, self) + local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType + }) + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu, { PTUfunc }) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua new file mode 100644 index 0000000000..ca593e5567 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Alternative flow 1 +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) Non remote-control application is registered on SDL +-- 2) and SDL received GetInteriorVehicleData request from this App +-- SDL must: +-- 1) Disallow remote-control RPCs for this app (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Functions ]] +local function getDataForModule(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType + }) + EXPECT_HMICALL("RC.GetInteriorVehicleData") + :Times(0) + mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + local appId = config.application1.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua new file mode 100644 index 0000000000..d6a6351f97 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua @@ -0,0 +1,113 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Exceptions: 2.1 +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with invalid parameters +-- - invalid parameter name +-- - invalid parameter type +-- - missing mandatory parameter +-- SDL must: +-- 1) Do not transfer request to HMI +-- 2) Respond with success:false, "INVALID_DATA" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function invalidParamName(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + modduleType = pModuleType, -- invalid name of parameter + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function invalidParamType(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = 17 -- invalid type of parameter + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function missingMandatoryParam() + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + -- moduleType = "CLIMATE", -- mandatory parameter absent + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) + :Times(0) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) +end + +local function fakeParam(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + fakeParam = 7, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = true + }) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + isSubscribed = true, + moduleData = common.getModuleControlDataForResponse(pModuleType) + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod .. " invalid name of parameter", invalidParamName, { mod }) + runner.Step("GetInteriorVehicleData " .. mod .. " invalid type of parameter", invalidParamType, { mod }) + runner.Step("GetInteriorVehicleData " .. mod .. " fake parameter", fakeParam, { mod }) +end + +runner.Step("GetInteriorVehicleData mandatory parameter absent", missingMandatoryParam) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua new file mode 100644 index 0000000000..6701c0a2c1 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -0,0 +1,60 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Exceptions: 5.1 +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with valid parameters +-- 2) and HMI didn't respond within default timeout +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function getDataForModule(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, _) + -- HMI does not respond + end) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod .. " HMI does not respond", getDataForModule, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua new file mode 100644 index 0000000000..23891efbfc --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -0,0 +1,90 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Exceptions: 5.1 +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with valid parameters +-- 2) and HMI responds with invalid data: +-- - invalid type of parameter +-- - missing mandatory parameter +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function invalidParamType(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlData(pModuleType), + isSubscribed = "yes" -- invalid type of parameter + }) + end) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +local function missingMandatoryParam(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + local moduleData = common.getModuleControlData(pModuleType) + moduleData.moduleType = nil -- missing mandatory parameter + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = moduleData, + isSubscribed = true + }) + end) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod .. " Invalid response from HMI-Invalid type of parameter", invalidParamType, { mod }) + runner.Step("GetInteriorVehicleData " .. mod .. " Invalid response from HMI-Missing mandatory parameter", missingMandatoryParam, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua new file mode 100644 index 0000000000..f0b8482268 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has an empty array +-- 2) and RC app sends GetInteriorVehicleData request with valid parameters +-- SDL must: +-- 1) Allow this RPC to be processed +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local json = require('modules/json') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +local function PTUfunc(tbl) + common.AddOnRCStatusToPT(tbl) + local appId = config.application1.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId] = common.getRCAppConfig() + tbl.policy_table.app_policies[appId].moduleType = json.EMPTY_ARRAY +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData " .. mod, common.rpcAllowed, { mod, 1, "GetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua new file mode 100644 index 0000000000..533450f5cf --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) "moduleType" does not exist in app's assigned policies +-- 2) and RC app sends GetInteriorVehicleData request with valid parameters +-- SDL must: +-- 1) Disallow this RPC to be processed (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } + +local function PTUfunc(tbl) + common.AddOnRCStatusToPT(tbl) + local appId = config.application1.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod, common.rpcDenied, { mod, 1, "GetInteriorVehicleData", "DISALLOWED" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua new file mode 100644 index 0000000000..bd2a47fef8 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -0,0 +1,60 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with valid parameters +-- 2) and SDL gets response (resultCode: READ_ONLY) from HMI +-- SDL must: +-- 1) Respond to App with success:false, "GENERIC_ERROR" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function getDataForModule(module_type) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = module_type, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = module_type, + subscribe = true + }) + :Do(function(_, data) + common.getHMIconnection():SendError(data.id, data.method, "READ_ONLY", "Info message") + end) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Info message" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua new file mode 100644 index 0000000000..fcef64b4dd --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua @@ -0,0 +1,95 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Exceptions: 5.2 +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) RC app sends valid and allowed by policies GetInteriorvehicleData request +-- 2) and SDL received GetInteriorVehicledata response with successful result code and current module data from HMI +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with provided from HMI current module data for allowed module and control items +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } +local success_codes = { "WARNINGS" } +local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } + +--[[ Local Functions ]] +local function stepSuccessfull(pModuleType, pResultCode) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, pResultCode, { + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = false + }) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = pResultCode, + isSubscribed = false, + moduleData = common.getModuleControlDataForResponse(pModuleType) + }) +end + +local function stepUnsuccessfull(pModuleType, pResultCode) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + common.getHMIconnection():SendError(data.id, data.method, pResultCode, "Error error") + end) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = pResultCode}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + for _, code in pairs(success_codes) do + runner.Step("GetInteriorVehicleData " .. mod .. " with " .. code .. " resultCode", stepSuccessfull, { mod, code }) + end +end + +for _, mod in pairs(modules) do + for _, code in pairs(error_codes) do + runner.Step("GetInteriorVehicleData " .. mod .. " with " .. code .. " resultCode", stepUnsuccessfull, { mod, code }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua new file mode 100644 index 0000000000..105350555b --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -0,0 +1,80 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: TRS: GetInteriorVehicleData, #2 +-- In case: +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData_request without "subscribe" parameter +-- 2) and SDL gets GetInteriorVehicleData_response with resultCode: <"any-result"> +-- 3) and with "isSubscribed" parameter from HMI +-- SDL must: +-- 1) transfer GetInteriorVehicleData_response with resultCode: <"any-result"> +-- and without "isSubscribed" param to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, isSubscriptionActive) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType + -- no subscribe parameter + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = isSubscriptionActive -- return current value of subscription + }) + end) + :ValidIf(function(_, data) -- no subscribe parameter + if data.params.subscribe == nil then + return true + end + return false, 'Parameter "subscribe" is transfered with to HMI value: ' .. tostring(data.params.subscribe) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = common.getModuleControlDataForResponse(pModuleType) + }) + :ValidIf(function(_, data) -- no isSubscribed parameter + if data.payload.isSubscribed == nil then + return true + end + return false, 'Parameter "isSubscribed" is transfered to App with value: ' .. tostring(data.payload.isSubscribed) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription", getDataForModule, { mod, false }) +end + +for _, mod in pairs(common.modules) do + runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) + runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua new file mode 100644 index 0000000000..5cbd7c6b4c --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua @@ -0,0 +1,104 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: TRS: GetInteriorVehicleData, #12 +-- In case: +-- 1) RC app is subscribed to "" +-- 2) and sends valid and allowed-by-policies GetInteriorVehicleData request +-- 3) with "subscribe:true" parameter for the same "" +-- SDL must: +-- 1) Forward request to HMI without "subscribe:true" parameter +-- 2) not change the subscription status of the app +-- 3) transfer HMI's response with added "isSubscribed: true" to the app +-- +-- Description: TRS: GetInteriorVehicleData, #13 +-- In case: +-- 1) RC app is not subscribed to "" +-- 2) and sends valid and allowed-by-policies GetInteriorVehicleData request +-- 3) with "subscribe:false" parameter for the same "" +-- SDL must: +-- 1) Forward request to HMI without "subscribe:false" parameter +-- 2) not change the subscription status of the app +-- 3) transfer HMI's response with added "isSubscribed: false" to the app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function subscriptionToModule(pModuleType, pSubscribe) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = pSubscribe + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = pSubscribe + }) + end) + :ValidIf(function(_, data) + if data.params.subscribe == nil then + return true + end + return false, 'Parameter "subscribe" is transfered to HMI with value: ' .. tostring(data.params.subscribe) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = pSubscribe + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + -- app has not subscribed yet + runner.Step("Unsubscribe app to " .. mod, subscriptionToModule, { mod, false }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", common.isUnsubscribed, + { mod }) + + -- subscribe to module 1st time + runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", common.isSubscribed, + { mod }) + + -- subscribe to module 2nd time + runner.Step("Subscribe 2nd time app to " .. mod, subscriptionToModule, { mod, true }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", common.isSubscribed, + { mod }) + + -- unsubscribe to module 1st time + runner.Step("Unsubscribe app to " .. mod, common.unSubscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", common.isUnsubscribed, + { mod }) + + -- unsubscribe to module 2nd time + runner.Step("Unsubscribe 2nd time app to " .. mod, subscriptionToModule, { mod, false }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", common.isUnsubscribed, + { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua new file mode 100644 index 0000000000..6df7c061c8 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -0,0 +1,86 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/2 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: TRS: GetInteriorVehicleData, #1 +-- In case: +-- 1) RC app sends valid and allowed by policies GetInteriorvehicleData_request with "subscribe" parameter +-- 2) and SDL received GetInteriorVehicledata_response with resultCode: <"any_not_erroneous_result"> +-- 3) and without "isSubscribed" parameter from HMI +-- SDL must: +-- 1) transfer GetInteriorVehicleData_response with resultCode:<"any_not_erroneous_result"> +-- and with added isSubscribed: <"current_subscription_status"> to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = pSubscribe + }) + + local pSubscribeHMI = pSubscribe + if isSubscriptionActive == pSubscribe then + pSubscribeHMI = nil + end + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlDataForResponse(pModuleType), + -- no isSubscribed parameter + }) + end) + :ValidIf(function(_, data) + if data.params.subscribe == pSubscribeHMI then + return true + end + return false, 'Parameter "subscribe" is transfered to HMI with value: ' .. tostring(data.params.subscribe) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + isSubscribed = isSubscriptionActive, -- return current value of subscription + moduleData = common.getModuleControlDataForResponse(pModuleType) + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription_subscribe", getDataForModule, + { mod, false, true }) + runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription_unsubscribe", getDataForModule, + { mod, false, false }) +end + +for _, mod in pairs(common.modules) do + runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) + runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, + { mod, true, true }) + runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_unsubscribe", getDataForModule, + { mod, true, false }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua new file mode 100644 index 0000000000..0751bc5bf9 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua @@ -0,0 +1,62 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Alternative flow 2 +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #1 +-- In case: +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and user allowed access to RC module for requested application +-- SDL must: +-- 1) allocate access to RC module to requested application +-- 2) process control request from this application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function PTUfunc(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App1", common.activateApp) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Activate App2", common.activateApp, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", common.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: allowed:true + runner.Step("App2 SetInteriorVehicleData 1st SUCCESS", common.rpcAllowedWithConsent, + { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 SetInteriorVehicleData 2nd SUCCESS", common.rpcAllowed, + { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua new file mode 100644 index 0000000000..9f7f5ad3d6 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua @@ -0,0 +1,64 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Alternative flow 2.1 +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #4 +-- In case: +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and user disallowed access to RC module for the requested application +-- SDL must: +-- 1) respond on control request to RC application with result code REJECTED, success:false, +-- info: "The resource is in use and the driver disallows this remote control RPC" +-- 2) not allocate access for remote control module to the requested application +-- (meaning SDL must leave control of remote control module without changes) +-- Note: All further requests from this application to the same module in case +-- if it is still under control of another application must be rejected by SDL without initiating consent prompts +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function PTUfunc(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App1", common.activateApp) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Activate App2", common.activateApp, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", common.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: allowed:false + runner.Step("App2 SetInteriorVehicleData 1st REJECTED", common.rpcRejectWithConsent, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 SetInteriorVehicleData 2nd REJECTED", common.rpcRejectWithoutConsent, { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua new file mode 100644 index 0000000000..fd5a6cbd86 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua @@ -0,0 +1,78 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Alternative flow 2.2 +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #2 +-- In case: +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and user did not provide the answer during default timeout +-- 5) and SDL received in response from HMI GetInteriorVehicleDataConsent (TIMED_OUT) +-- SDL must: +-- 1) respond on control request to RC application with result code TIMED_OUT, success:false, +-- info: "The resource is in use and the driver did not respond in time" +-- 2) not allocate access for remote control module to the requested application +-- (meaning SDL must leave control of remote control module without changes) +-- Note: SDL must initiate user prompt in case of consequent control request for the same module from this application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function PTUfunc(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +local function rpcTimedOutHMIResponse(pModuleType, pAppId, pRPC) + local info = "The resource is in use and the driver did not respond in time" + local consentRPC = "GetInteriorVehicleDataConsent" + local mobSession = common.getMobileSession(pAppId) + local cid = mobSession:SendRPC(common.getAppEventName(pRPC), common.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(common.getHMIEventName(consentRPC), common.getHMIRequestParams(consentRPC, pModuleType, pAppId)) + :Do(function(_, data) + common.getHMIconnection():SendError(data.id, data.method, "TIMED_OUT", info) + EXPECT_HMICALL(common.getHMIEventName(pRPC)):Times(0) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "TIMED_OUT", info = info }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App1", common.activateApp) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Activate App2", common.activateApp, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", common.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: TIMED_OUT + runner.Step("App2 SetInteriorVehicleData 1st TIMED_OUT", rpcTimedOutHMIResponse, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 SetInteriorVehicleData 2nd SUCCESS", common.rpcAllowedWithConsent, + { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/004_HMI_no_response_SIVD.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/004_HMI_no_response_SIVD.lua new file mode 100644 index 0000000000..163c0b43db --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/004_HMI_no_response_SIVD.lua @@ -0,0 +1,76 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 2.1 +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #3 +-- In case: +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and HMI did not respond during default timeout or response is invalid or erroneous +-- SDL must: +-- 1) respond on control request to RC application with result code GENERIC_ERROR, success:false +-- 2) not allocate access for remote control module to the requested application +-- (meaning SDL must leave control of remote control module without changes) +-- Note: SDL must initiate user prompt in case of consequent control request for the same module from this application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function PTUfunc(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +local function rpcNoHMIResponse(pModuleType, pAppId, pRPC) + local consentRPC = "GetInteriorVehicleDataConsent" + local mobSession = common.getMobileSession(pAppId) + local cid = mobSession:SendRPC(common.getAppEventName(pRPC), common.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(common.getHMIEventName(consentRPC), common.getHMIRequestParams(consentRPC, pModuleType, pAppId)) + :Do(function(_, _) + -- HMI does not respond + EXPECT_HMICALL(common.getHMIEventName(pRPC)):Times(0) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App1", common.activateApp) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Activate App2", common.activateApp, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", common.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: doesn't respond + runner.Step("App2 SetInteriorVehicleData 1st GENERIC_ERROR", rpcNoHMIResponse, + { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 SetInteriorVehicleData 2nd SUCCESS", common.rpcAllowedWithConsent, + { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/005_HMI_invalid_response_SIVD.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/005_HMI_invalid_response_SIVD.lua new file mode 100644 index 0000000000..9172322770 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/005_HMI_invalid_response_SIVD.lua @@ -0,0 +1,78 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 2.1 +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #5; TRS: GetInteriorVehicleDataConsent, #3 +-- In case: +-- 1) SDL received OnRemoteControlSettings notification from HMI with "ASK_DRIVER" access mode +-- 2) and RC application (in HMILevel FULL) requested access to remote control module +-- that is already allocated to another RC application +-- 3) and SDL requested user consent from HMI via GetInteriorVehicleDataConsent +-- 4) and HMI did not respond during default timeout or response is invalid or erroneous +-- SDL must: +-- 1) respond on control request to RC application with result code GENERIC_ERROR, success:false +-- 2) not allocate access for remote control module to the requested application +-- (meaning SDL must leave control of remote control module without changes) +-- Note: SDL must initiate user prompt in case of consequent control request for the same module from this application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function PTUfunc(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +local function rpcInvalidHMIResponse(pModuleType, pAppId, pRPC) + local consentRPC = "GetInteriorVehicleDataConsent" + local mobSession = common.getMobileSession(pAppId) + local cid = mobSession:SendRPC(common.getAppEventName(pRPC), common.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(common.getHMIEventName(consentRPC), common.getHMIRequestParams(consentRPC, pModuleType, pAppId)) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + allowed = "aaa" -- invalid type of parameter + }) + EXPECT_HMICALL(common.getHMIEventName(pRPC)):Times(0) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App1", common.activateApp) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Activate App2", common.activateApp, { 2 }) + +runner.Title("Test") +runner.Step("Set RA mode: ASK_DRIVER", common.defineRAMode, { true, "ASK_DRIVER" }) + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set control for App2 --> Ask driver --> HMI: response with invalid data + runner.Step("App2 SetInteriorVehicleData 1st GENERIC_ERROR", rpcInvalidHMIResponse, + { mod, 2, "SetInteriorVehicleData" }) + runner.Step("App2 SetInteriorVehicleData 2nd SUCCESS", common.rpcAllowedWithConsent, + { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/001_Success_flow.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/001_Success_flow.lua new file mode 100644 index 0000000000..15570f87d5 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/001_Success_flow.lua @@ -0,0 +1,62 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/RC/detailed_info_GetSystemCapability.md +-- Item: Use Case 2: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- 1) App is RC +-- 2) App tries to get RC capabilities +-- SDL must: +-- 1) Transfer RC capabilities to mobiles +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local capParams = {} +for _, v in pairs(common.modules) do capParams[v] = common.DEFAULT end -- HMI has all posible RC capabilities +local hmiRcCapabilities = common.buildHmiRcCapabilities(capParams) + +--[[ Local Functions ]] +local function rpcSuccess() + local rcCapabilities = hmiRcCapabilities.RC.GetCapabilities.params.remoteControlCapability + local cid = common.getMobileSession():SendRPC("GetSystemCapability", { systemCapabilityType = "REMOTE_CONTROL" }) + common.getMobileSession():ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS", + systemCapability = { + remoteControlCapability = { + climateControlCapabilities = rcCapabilities.climateControlCapabilities, + radioControlCapabilities = rcCapabilities.radioControlCapabilities, + audioControlCapabilities = rcCapabilities.audioControlCapabilities, + hmiSettingsControlCapabilities = rcCapabilities.hmiSettingsControlCapabilities, + lightControlCapabilities = rcCapabilities.lightControlCapabilities, + buttonCapabilities = rcCapabilities.buttonCapabilities + } + } + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Backup HMI capabilities file", common.backupHMICapabilities) +runner.Step("Update HMI capabilities file", common.updateDefaultCapabilities, { common.modules }) +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { hmiRcCapabilities }) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("GetSystemCapability Positive Case", rpcSuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) +runner.Step("Restore HMI capabilities file", common.restoreHMICapabilities) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua new file mode 100644 index 0000000000..4687c71312 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/RC/detailed_info_GetSystemCapability.md +-- Item: Use Case 2: Exception 2.1 +-- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- 1) App is Non-RC +-- 2) App tries to get RC capabilities +-- SDL must: +-- 1) Reply with DISALLOWED to App +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } + +--[[ Local Functions ]] +local function ptUpdateFunc(pTbl) + local appId = config.application1.registerAppInterfaceParams.appID + pTbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } +end + +local function rpcDissallowed() + local cid = common.getMobileSession():SendRPC("GetSystemCapability", { systemCapabilityType = "REMOTE_CONTROL" }) + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { ptUpdateFunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("GetSystemCapability DISALLOWED", rpcDissallowed) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/003_UNSUPPORTED_RESOURCE_in_case_RC_interface_is_unavailable.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/003_UNSUPPORTED_RESOURCE_in_case_RC_interface_is_unavailable.lua new file mode 100644 index 0000000000..48fac27d27 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/003_UNSUPPORTED_RESOURCE_in_case_RC_interface_is_unavailable.lua @@ -0,0 +1,59 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/RC/detailed_info_GetSystemCapability.md +-- Item: Use Case 2: Exception 5.1 +-- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- 1) RC interface is not available on HMI (RC.IsReady=false) +-- 2) App is RC +-- 3) App tries to get RC capabilities +-- SDL must: +-- 1) Reply with UNSUPPORTED_RESOURCE (success=false) to App +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local hmi_values = require('user_modules/hmi_values') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.checkAllValidations = true + +--[[ Local Functions ]] +local function getHMIParams() + local params = hmi_values.getDefaultHMITable() + params.RC.IsReady.params.available = false -- RC interface is unavailable + params.RC.GetCapabilities.params = { } + params.RC.GetCapabilities.occurrence = 0 + return params +end + +local function rpcUnsupportedResource() + local cid = common.getMobileSession():SendRPC("GetSystemCapability", { systemCapabilityType = "REMOTE_CONTROL" }) + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) + :ValidIf(function(_, data) + if data.payload.systemCapability then + return false, "Capabilities are transferred to mobile application" + end + return true + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { getHMIParams() }) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("GetSystemCapability_UNSUPPORTED_RESOURCE", rpcUnsupportedResource) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/001_Success_flow.lua new file mode 100644 index 0000000000..d7caa7dbb1 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/001_Success_flow.lua @@ -0,0 +1,63 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/4 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/subscription_on_module_status_change_notification.md +-- Item: Use Case 1: Main Flow +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification +-- +-- Description: TRS: GetInteriorVehicleData, #4 +-- In case: +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter +-- 2) and SDL received GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS" from HMI +-- 3) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Internally subscribe this application for requested +-- 2) Transfer GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS", "success:true" to the related app +-- 3) Re-send OnInteriorVehicleData notification to the related app +-- +-- [SDL_RC] Unsubscribe from RC module change notifications +-- +-- Description: TRS: GetInteriorVehicleData, #8 +-- In case: +-- 1) RC app is subscribed to "" +-- 2) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS" from HMI +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Internally un-subscribe this application for requested +-- 2) Transfer GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS", "success:true" to the related app +-- 3) Does not re-send OnInteriorVehicleData notification to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", common.isSubscribed, { mod }) +end + +for _, mod in pairs(common.modules) do + runner.Step("Unsubscribe app to " .. mod, common.unSubscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is unsubscribed", common.isUnsubscribed, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua new file mode 100644 index 0000000000..2eb4921573 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Exceptions: 5.1 +-- +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) A set of module(s) is defined in policies for particular RC app +-- 2) and this RC app is subscribed to one of the module from the list +-- 3) and then SDL received OnInteriorVehicleData notification for module not in list +-- SDL must: +-- 1) Does not re-send OnInteriorVehicleData notification to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local mod = "AUDIO" + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { mod } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData " .. mod, common.subscribeToModule, { mod }) +runner.Step("OnInteriorVehicleData " .. mod, common.isUnsubscribed, { "RADIO" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua new file mode 100644 index 0000000000..e88dd60fb1 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Exceptions: 5.1 +-- +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) A set of module(s) is defined in policies for particular RC app +-- 2) and this RC app is subscribed to one of the module from the list +-- 3) and then SDL received OnInteriorVehicleData notification for module not in list +-- SDL must: +-- 1) Does not re-send OnInteriorVehicleData notification to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local mod = "LIGHT" + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { mod } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData " .. mod, common.subscribeToModule, { mod }) +runner.Step("OnInteriorVehicleData " .. mod, common.isUnsubscribed, { "RADIO" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua new file mode 100644 index 0000000000..6ef489705b --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Exceptions: 5.1 +-- +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) A set of module(s) is defined in policies for particular RC app +-- 2) and this RC app is subscribed to one of the module from the list +-- 3) and then SDL received OnInteriorVehicleData notification for module not in list +-- SDL must: +-- 1) Does not re-send OnInteriorVehicleData notification to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local mod = "HMI_SETTINGS" + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { mod } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData " .. mod, common.subscribeToModule, { mod }) +runner.Step("OnInteriorVehicleData " .. mod, common.isUnsubscribed, { "RADIO" }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua new file mode 100644 index 0000000000..63c1de1647 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -0,0 +1,70 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/4 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/subscription_on_module_status_change_notification.md +-- Use Case 1: Alternative flow 1 +-- +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification +-- +-- Description: TRS: GetInteriorVehicleData, #5 +-- In case: +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter +-- 2) and SDL received GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS" from HMI +-- 3) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS", "success:true" to the related app +-- 2) Does not re-send OnInteriorVehicleData notification to the app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function subscriptionToModule(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = true + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = true + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = false -- not subscribe + }) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = false + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, subscriptionToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", common.isUnsubscribed, + { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua new file mode 100644 index 0000000000..4ca483025f --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua @@ -0,0 +1,75 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Alternative flow 1 +-- +-- Requirement summary: +-- [SDL_RC] Unsubscribe from RC module change notifications +-- +-- Description: TRS: GetInteriorVehicleData, #9 +-- In case: +-- 1) RC app is subscribed to "" +-- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS" from HMI +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS", "success:true" to the related app +-- 2) Re-send OnInteriorVehicleData notification to the app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function unSubscriptionToModule(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = false + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = false + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = true -- HMI responds with true + }) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = true + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", common.isSubscribed, { mod }) +end + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, unSubscriptionToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App still subscribed", common.isSubscribed, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua new file mode 100644 index 0000000000..0ba691b995 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -0,0 +1,75 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Alternative flow 2 +-- +-- Requirement summary: +-- [SDL_RC] Unsubscribe from RC module change notifications +-- +-- Description: TRS: GetInteriorVehicleData, #10 +-- In case: +-- 1) RC app is subscribed to "" +-- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response without "isSubscribed" parameter, "resultCode: SUCCESS" from HMI +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS", "success:true" to the related app +-- 2) Re-send OnInteriorVehicleData notification to the app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function unSubscriptionToModule(pModuleType) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = false + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = false + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlDataForResponse(pModuleType), + -- no isSubscribed parameter + }) + end) + + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = true + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", common.isSubscribed, { mod }) +end + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, unSubscriptionToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App still subscribed", common.isSubscribed, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua new file mode 100644 index 0000000000..23193d50e3 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -0,0 +1,81 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Alternative flow 3 +-- +-- Requirement summary: +-- [SDL_RC] Unsubscribe from RC module change notifications +-- +-- Description: TRS: GetInteriorVehicleData, #11 +-- In case: +-- 1) RC app is subscribed to "" +-- 2) and RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response with "resultCode: " from HMI +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Transfer GetInteriorVehicleData response with "resultCode: " +-- and without "isSubscribed" param to the related app +-- 2) Re-send OnInteriorVehicleData notification to the app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } +local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } + +--[[ Local Functions ]] +local function unSubscriptionToModule(pModuleType, pResultCode) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType, + subscribe = false + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = pModuleType, + subscribe = false + }) + :Do(function(_, data) + common.getHMIconnection():SendError(data.id, data.method, pResultCode, "Error error") + -- no isSubscribed parameter + end) + + mobileSession:ExpectResponse(cid, { success = false, resultCode = pResultCode }) + :ValidIf(function(_, data) -- no isSubscribed parameter + if data.payload.isSubscribed == nil then + return true + end + return false, 'Parameter "isSubscribed" is transfered to App with value: ' .. tostring(data.payload.isSubscribed) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +for _, mod in pairs(modules) do + runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App subscribed", common.isSubscribed, { mod }) +end + +runner.Title("Test") + +for _, mod in pairs(modules) do + for _, err in pairs(error_codes) do + runner.Step("Unsubscribe app to " .. mod .. " (" .. err .. " from HMI)", unSubscriptionToModule, { mod, err }) + runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App still subscribed", common.isSubscribed, + { mod }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua new file mode 100644 index 0000000000..57bedf68d7 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua @@ -0,0 +1,63 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #1 +-- In case: +-- 1) SDL received OnRemoteControlSettings notification from HMI with allowed:true +-- 2) and "accessMode" = "AUTO_ALLOW" or without "accessMode" parameter at all +-- 3) and RC_module on HMI is alreay in control by RC-application +-- SDL must: +-- 1) provide access to RC_module for the second RC_application in HMILevel FULL after it sends control RPC +-- (either SetInteriorVehicleData or ButtonPress) for the same RC_module without asking a driver +-- 2) process the request from the second RC_application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } +local access_modes = { nil, "AUTO_ALLOW" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) +runner.Step("RAI2", common.raiN, { 2 }) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + for i = 1, #access_modes do + runner.Title("Access mode: " .. tostring(access_modes[i])) + -- set control for App1 + runner.Step("Activate App1", common.activateApp) + runner.Step("App1 SetInteriorVehicleData", common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + -- set RA mode + runner.Step("Set RA mode", common.defineRAMode, { true, access_modes[i] }) + -- set control for App2 --> Allowed + runner.Step("Activate App2", common.activateApp, { 2 }) + runner.Step("App2 SetInteriorVehicleData", common.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua new file mode 100644 index 0000000000..43a66a26dd --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua @@ -0,0 +1,67 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 1 +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #2 +-- In case: +-- 1) SDL received OnRemoteControlSettings notification from HMI with allowed:true +-- 2) and with any "accessMode" or without "accessMode" parameter at all +-- 3) and RC_module on HMI is alreay in control by RC-application_1 +-- 4) and another RC_application_2 is in HMILevel other than FULL (either LIMITED or BACKGROUND) +-- SDL must: +-- 1) deny access to RC_module for another RC_application_2 after it sends control RPC +-- (either SetInteriorVehicleData or ButtonPress) for the same RC_module without asking a driver +-- 2) not process the request from RC_application_2 and respond with result code REJECTED, success:false +-- 3) leave RC_application_1 in control of the RC_module +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } +local access_modes = { nil, "AUTO_ALLOW", "AUTO_DENY", "ASK_DRIVER" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) +runner.Step("Activate App1", common.activateApp) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Activate App2", common.activateApp, { 2 }) + +-- App's HMI levels: 1 - BACKGROUND, 2 - FULL + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App2 + runner.Step("App2 SetInteriorVehicleData", common.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + for i = 1, #access_modes do + runner.Title("Access mode: " .. tostring(access_modes[i])) + -- set RA mode + runner.Step("Set RA mode", common.defineRAMode, { true, access_modes[i] }) + -- try to set control for App1 --> Denied + runner.Step("App1 SetInteriorVehicleData", common.rpcDenied, { mod, 1, "SetInteriorVehicleData", "REJECTED" }) + -- try to set control for App2 --> Allowed + runner.Step("App2 SetInteriorVehicleData", common.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua new file mode 100644 index 0000000000..9c65480feb --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md +-- Item: Use Case 2: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- RC_functionality is disabled on HMI and HMI sends notification OnRemoteControlSettings (allowed:true, ) +-- +-- SDL must: +-- 1) store RC state allowed:true and received from HMI internally +-- 2) allow RC functionality for applications with REMOTE_CONTROL appHMIType +-- +-- Case: accessMode = "AUTO_ALLOW" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +local function disableRcFromHmi() + common.defineRAMode(false, nil) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Disable RC from HMI", disableRcFromHmi) + +runner.Title("Test") +runner.Step("Enable RC from HMI with AUTO_ALLOW access mode", common.defineRAMode, { true, "AUTO_ALLOW"}) +for _, mod in pairs(modules) do + runner.Step("Activate App1", common.activateApp) + runner.Step("Check module " .. mod .." App1 SetInteriorVehicleData allowed", common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + runner.Step("Activate App2", common.activateApp, { 2 }) + runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed", common.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/004_Allowed_true_accessMode_AUTO_DENY.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/004_Allowed_true_accessMode_AUTO_DENY.lua new file mode 100644 index 0000000000..95f253c0a8 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/004_Allowed_true_accessMode_AUTO_DENY.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md +-- Item: Use Case 2: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- RC_functionality is disabled on HMI and HMI sends notification OnRemoteControlSettings (allowed:true, ) +-- +-- SDL must: +-- 1) store RC state allowed:true and received from HMI internally +-- 2) allow RC functionality for applications with REMOTE_CONTROL appHMIType +-- +-- Case: accessMode = "AUTO_DENY" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +local function disableRcFromHmi(self) + common.defineRAMode(false, nil, self) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Disable RC from HMI", disableRcFromHmi) + +runner.Title("Test") +runner.Step("Enable RC from HMI with AUTO_DENY access mode", common.defineRAMode, { true, "AUTO_DENY"}) +for _, mod in pairs(modules) do + runner.Step("Activate App1", common.activateApp) + runner.Step("Check module " .. mod .." App1 SetInteriorVehicleData allowed", common.rpcAllowed, + { mod, 1, "SetInteriorVehicleData" }) + runner.Step("Activate App2", common.activateApp, { 2 }) + runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData denied", common.rpcDenied, + { mod, 2, "SetInteriorVehicleData", "IN_USE" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/005_Allowed_true_accessMode_ASK_DRIVER.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/005_Allowed_true_accessMode_ASK_DRIVER.lua new file mode 100644 index 0000000000..6dc084f042 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/005_Allowed_true_accessMode_ASK_DRIVER.lua @@ -0,0 +1,64 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md +-- Item: Use Case 2: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- RC_functionality is disabled on HMI and HMI sends notification OnRemoteControlSettings (allowed:true, ) +-- +-- SDL must: +-- 1) store RC state allowed:true and received from HMI internally +-- 2) allow RC functionality for applications with REMOTE_CONTROL appHMIType +-- +-- Case: accessMode = "ASK_DRIVER" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +local function disableRcFromHmi(self) + common.defineRAMode(false, nil, self) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) +runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("Disable RC from HMI", disableRcFromHmi) + +runner.Title("Test") +runner.Step("Enable RC from HMI with ASK_DRIVER access mode", common.defineRAMode, { true, "ASK_DRIVER"}) +runner.Step("Activate App2", common.activateApp, { 2 }) +for _, mod in pairs(modules) do + runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed", common.rpcAllowed, + { mod, 2, "SetInteriorVehicleData" }) + runner.Step("Activate App1", common.activateApp) + runner.Step("Check module " .. mod .." App1 SetInteriorVehicleData allowed with driver consent", + common.rpcAllowedWithConsent, { mod, 1, "SetInteriorVehicleData" }) + runner.Step("Activate App2", common.activateApp, { 2 }) + runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed with driver consent", + common.rpcAllowedWithConsent, { mod, 2, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/006_Default_accessMode.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/006_Default_accessMode.lua new file mode 100644 index 0000000000..6387d63b7e --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/006_Default_accessMode.lua @@ -0,0 +1,53 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: +-- In case: +-- HMI didn't send OnRemoteControlSettings notifications on systems start +-- +-- SDL must: +-- use default value allowed:true and accessMode = "AUTO_ALLOW" for all registered REMOTE_CONTROL applications +-- until OnRemoteControlSettings notification with other settings is received +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + common.AddOnRCStatusToPT(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) +runner.Step("RAI2", common.raiN, { 2 }) + +runner.Title("Test") +for _, mod in pairs(modules) do + runner.Step("Activate App2", common.activateApp, { 2 }) + runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed", + common.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("Activate App1", common.activateApp) + runner.Step("Check module " .. mod .." App1 SetInteriorVehicleData allowed", + common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/001_Success_flow.lua new file mode 100644 index 0000000000..ff43ad2714 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/001_Success_flow.lua @@ -0,0 +1,41 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) and sends valid SetInteriorVehicleData RPC with valid parameters +-- SDL must: +-- 1) Transfer this request to HMI +-- 2) Respond with received from HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod, common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua new file mode 100644 index 0000000000..2530721fbc --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 4.1 +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received SetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local mod = "CLIMATE" + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = common.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua new file mode 100644 index 0000000000..18c29a6e63 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 4.1 +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received SetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local mod = "AUDIO" + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = common.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua new file mode 100644 index 0000000000..c3fa95671d --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 4.1 +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received SetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local mod = "LIGHT" + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = common.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua new file mode 100644 index 0000000000..00202d0464 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua @@ -0,0 +1,55 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 4.1 +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has one or more valid values +-- 2) and SDL received SetInteriorVehicleData request from App with moduleType not in list +-- SDL must: +-- 1) Disallow app's remote-control RPCs for this module (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local mod = "HMI_SETTINGS" + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = common.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua new file mode 100644 index 0000000000..0e92caf8e1 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -0,0 +1,67 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) "moduleType" in app's assigned policies has an empty array +-- 2) and RC app sends SetInteriorVehicleData request with valid parameters +-- SDL must: +-- 1) Allow this RPC to be processed +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local json = require('modules/json') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = common.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = common.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getSettableModuleControlData(pModuleType) + }) + end) + + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua new file mode 100644 index 0000000000..87ffb43115 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/7 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/Policy_Support_of_basic_RC_functionality.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- [SDL_RC] Policy support of basic RC functionality +-- +-- Description: +-- In case: +-- 1) "moduleType" does not exist in app's assigned policies +-- 2) and RC app sends SetInteriorVehicleData request with valid parameters +-- SDL must: +-- 1) Disallow this RPC to be processed (success:false, "DISALLOWED") +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +--modules array does not contain "RADIO" because "RADIO" module has read only parameters +local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +--[[ Local Functions ]] +local function setVehicleData(pModuleType) + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = common.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +end + +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, mod in pairs(modules) do + runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/008_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/008_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua new file mode 100644 index 0000000000..21831a0a1a --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/008_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exceptions: 7.1 +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- +-- Description: +-- In case: +-- application sends valid SetInteriorVehicleData with just read-only parameters in "radioControlData" struct for muduleType: RADIO +-- SDL must +-- respond with "resultCode: READ_ONLY, success:false" to this application and do not process this RPC. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local module_data_radio = common.getReadOnlyParamsByModule("RADIO") + +--[[ Local Functions ]] +local function setVehicleData(module_data) + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", {moduleData = module_data}) + + EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) + + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "READ_ONLY" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test: SDL respond with READ_ONLY if SetInteriorVehicleData is sent with read_only params") +runner.Step("Send SetInteriorVehicleData with read only sisData", setVehicleData, {module_data_radio}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua new file mode 100644 index 0000000000..077918a2af --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua @@ -0,0 +1,73 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source between various audio sources several times +-- SDL must: +-- 1) Change audio source successfully as many times as defined +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "RADIO_TUNER" +} + +--[[ Local Functions ]] +local function setVehicleData(pSource) + audioData.audioControlData.source = pSource + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, source in pairs(audioSources) do + runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_BACKGROUND.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_BACKGROUND.lua new file mode 100644 index 0000000000..da6953ec1c --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_BACKGROUND.lua @@ -0,0 +1,75 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in NONE or BACKGROUND HMI level +-- 3) App tries to change audio source +-- SDL must: +-- 1) Not change audio source +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true +config.application2.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "RADIO_TUNER" +} + +--[[ Local Functions ]] +local function setVehicleData(pSource) + audioData.audioControlData.source = pSource + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = audioData }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = common.getHMIAppId(), moduleData = audioData }) + :Do(function(_, data) + common.getHMIconnection():SendError(data.id, data.method, "REJECTED", "Error") + end) + + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "REJECTED", info = "Error" }) +end + +local function BringAppToBACKGROUND() + common.activateApp(2) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU App1", common.raiPTUn) +runner.Step("RAI App2", common.raiN, {2}) +runner.Step("Activate App1", common.activateApp) +runner.Step("Set App1 to BACKGROUND HMI level", BringAppToBACKGROUND) + +runner.Title("Test") +for _, source in pairs(audioSources) do + runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua new file mode 100644 index 0000000000..1d372b1222 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua @@ -0,0 +1,83 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in LIMITED HMI level +-- 3) App tries to change audio source between various audio sources several times +-- SDL must: +-- 1) Change audio source successfully as many times as defined +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "RADIO_TUNER" +} + +--[[ Local Functions ]] +local function setVehicleData(pSource) + audioData.audioControlData.source = pSource + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function bringAppToLIMITED() + common.getHMIconnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(), + reason = "GENERAL" + }) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("Set App to LIMITED HMI level", bringAppToLIMITED) + +runner.Title("Test") +for _, source in pairs(audioSources) do + runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua new file mode 100644 index 0000000000..da6953ec1c --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua @@ -0,0 +1,75 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in NONE or BACKGROUND HMI level +-- 3) App tries to change audio source +-- SDL must: +-- 1) Not change audio source +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true +config.application2.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "RADIO_TUNER" +} + +--[[ Local Functions ]] +local function setVehicleData(pSource) + audioData.audioControlData.source = pSource + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = audioData }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = common.getHMIAppId(), moduleData = audioData }) + :Do(function(_, data) + common.getHMIconnection():SendError(data.id, data.method, "REJECTED", "Error") + end) + + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "REJECTED", info = "Error" }) +end + +local function BringAppToBACKGROUND() + common.activateApp(2) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU App1", common.raiPTUn) +runner.Step("RAI App2", common.raiN, {2}) +runner.Step("Activate App1", common.activateApp) +runner.Step("Set App1 to BACKGROUND HMI level", BringAppToBACKGROUND) + +runner.Title("Test") +for _, source in pairs(audioSources) do + runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_FULL_rc_non_media_app.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_FULL_rc_non_media_app.lua new file mode 100644 index 0000000000..5c9c76218d --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_FULL_rc_non_media_app.lua @@ -0,0 +1,67 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Non-Media +-- 2) App in any HMI level +-- 3) App tries to change audio source +-- SDL must: +-- 1) Not change audio source +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = false + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "RADIO_TUNER" +} + +--[[ Local Functions ]] +local function setVehicleData(pSource) + audioData.audioControlData.source = pSource + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + -- Confirmation nedded, not clear what resultCode must be + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, source in pairs(audioSources) do + runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_from_MOBILE_APP_without_keepContext.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_from_MOBILE_APP_without_keepContext.lua new file mode 100644 index 0000000000..4d1c5d8d74 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_from_MOBILE_APP_without_keepContext.lua @@ -0,0 +1,86 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source from MOBILE_APP with keepContext = false +-- SDL must: +-- 1) Change audio source successfully +-- 2) Change HMI level of App to BACKGROUND +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") + +--[[ Local Functions ]] +local function setVehicleDataMobileApp() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "MOBILE_APP" + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function setVehicleData() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "USB" + audioData.audioControlData.keepContext = nil + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) + +runner.Title("Test") +runner.Step("Change audio source from MOBILE_APP without keepContext", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua new file mode 100644 index 0000000000..5c9c76218d --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua @@ -0,0 +1,67 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Non-Media +-- 2) App in any HMI level +-- 3) App tries to change audio source +-- SDL must: +-- 1) Not change audio source +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = false + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "RADIO_TUNER" +} + +--[[ Local Functions ]] +local function setVehicleData(pSource) + audioData.audioControlData.source = pSource + local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + -- Confirmation nedded, not clear what resultCode must be + common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, source in pairs(audioSources) do + runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_keepContext_false.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_keepContext_false.lua new file mode 100644 index 0000000000..b5942647c3 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_keepContext_false.lua @@ -0,0 +1,86 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source from MOBILE_APP without keepContext parameter defined +-- SDL must: +-- 1) Change audio source successfully +-- 2) Change HMI level of App to BACKGROUND +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") + +--[[ Local Functions ]] +local function setVehicleDataMobileApp() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "MOBILE_APP" + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function setVehicleData() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "USB" + audioData.audioControlData.keepContext = false + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) + +runner.Title("Test") +runner.Step("Change audio source from MOBILE_APP keepContext is false", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_without_keepContext.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_without_keepContext.lua new file mode 100644 index 0000000000..4d1c5d8d74 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_without_keepContext.lua @@ -0,0 +1,86 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source from MOBILE_APP with keepContext = false +-- SDL must: +-- 1) Change audio source successfully +-- 2) Change HMI level of App to BACKGROUND +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") + +--[[ Local Functions ]] +local function setVehicleDataMobileApp() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "MOBILE_APP" + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function setVehicleData() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "USB" + audioData.audioControlData.keepContext = nil + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) + +runner.Title("Test") +runner.Step("Change audio source from MOBILE_APP without keepContext", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_false.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_false.lua new file mode 100644 index 0000000000..b5942647c3 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_false.lua @@ -0,0 +1,86 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source from MOBILE_APP without keepContext parameter defined +-- SDL must: +-- 1) Change audio source successfully +-- 2) Change HMI level of App to BACKGROUND +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") + +--[[ Local Functions ]] +local function setVehicleDataMobileApp() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "MOBILE_APP" + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function setVehicleData() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "USB" + audioData.audioControlData.keepContext = false + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) + +runner.Title("Test") +runner.Step("Change audio source from MOBILE_APP keepContext is false", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua new file mode 100644 index 0000000000..f4f5afd6d0 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua @@ -0,0 +1,86 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1)App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source from MOBILE_APP with keepContext = true +-- SDL must: +-- 1) Change audio source successfully +-- 2) Not change HMI level, but change audioStreamingState to "NOT_AUDIBLE" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") + +--[[ Local Functions ]] +local function setVehicleDataMobileApp() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "MOBILE_APP" + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function setVehicleData() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "USB" + audioData.audioControlData.keepContext = true + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) + +runner.Title("Test") +runner.Step("Change audio source from MOBILE_APP keepContext is true", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua new file mode 100644 index 0000000000..f4f5afd6d0 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua @@ -0,0 +1,86 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1)App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source from MOBILE_APP with keepContext = true +-- SDL must: +-- 1) Change audio source successfully +-- 2) Not change HMI level, but change audioStreamingState to "NOT_AUDIBLE" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") + +--[[ Local Functions ]] +local function setVehicleDataMobileApp() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "MOBILE_APP" + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function setVehicleData() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "USB" + audioData.audioControlData.keepContext = true + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) + +runner.Title("Test") +runner.Step("Change audio source from MOBILE_APP keepContext is true", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua new file mode 100644 index 0000000000..e7b1e7728b --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua @@ -0,0 +1,96 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1)App is RC and Media +-- 2) App in LIMITED HMI level +-- 3) App tries to change audio source from MOBILE_APP with keepContext = true +-- SDL must: +-- 1) Change audio source successfully +-- 2) Change HMI level to BACKGROUND and change audioStreamingState to "NOT_AUDIBLE" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") + +--[[ Local Functions ]] +local function setVehicleDataMobileApp() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "MOBILE_APP" + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function setVehicleData() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "USB" + audioData.audioControlData.keepContext = true + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +local function bringAppToLIMITED() + common.getHMIconnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(), + reason = "GENERAL" + }) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("Set App to LIMITED HMI level", bringAppToLIMITED) +runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) + +runner.Title("Test") +runner.Step("Change audio source from MOBILE_APP keepContext is true", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua new file mode 100644 index 0000000000..e7b1e7728b --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua @@ -0,0 +1,96 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1)App is RC and Media +-- 2) App in LIMITED HMI level +-- 3) App tries to change audio source from MOBILE_APP with keepContext = true +-- SDL must: +-- 1) Change audio source successfully +-- 2) Change HMI level to BACKGROUND and change audioStreamingState to "NOT_AUDIBLE" +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") + +--[[ Local Functions ]] +local function setVehicleDataMobileApp() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "MOBILE_APP" + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function setVehicleData() + local mobSession = common.getMobileSession() + audioData.audioControlData.source = "USB" + audioData.audioControlData.keepContext = true + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + eventName = "AUDIO_SOURCE", + isActive = true + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) +end + +local function bringAppToLIMITED() + common.getHMIconnection():SendNotification("BasicCommunication.OnAppDeactivated", { + appID = common.getHMIAppId(), + reason = "GENERAL" + }) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("Set App to LIMITED HMI level", bringAppToLIMITED) +runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) + +runner.Title("Test") +runner.Step("Change audio source from MOBILE_APP keepContext is true", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua new file mode 100644 index 0000000000..68e6e2b82f --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua @@ -0,0 +1,88 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source from any type except of MOBILE_APP and with any value of keepContext parameter or event without it +-- SDL must: +-- 1) Change audio source successfully +-- 2) Not change HMI level +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "RADIO_TUNER" +} + +local keepContext = { + false, + true, + "empty" +} + +--[[ Local Functions ]] +local function setVehicleData(pSource,pKeepContext) + local mobSession = common.getMobileSession() + audioData.audioControlData.source = pSource + if "empty" == pKeepContext then + audioData.audioControlData.keepContext = nil + else + audioData.audioControlData.keepContext = pKeepContext + end + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, source in pairs(audioSources) do + for _, keepContextValue in pairs(keepContext) do + runner.Step("Change audio source from " .. source .. " source with keepContext is " .. + tostring(keepContextValue), setVehicleData, { source, keepContextValue }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua new file mode 100644 index 0000000000..68e6e2b82f --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua @@ -0,0 +1,88 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) App is RC and Media +-- 2) App in FULL HMI level +-- 3) App tries to change audio source from any type except of MOBILE_APP and with any value of keepContext parameter or event without it +-- SDL must: +-- 1) Change audio source successfully +-- 2) Not change HMI level +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ General configuration parameters ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Variables ]] +local audioData = common.getSettableModuleControlData("AUDIO") +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "RADIO_TUNER" +} + +local keepContext = { + false, + true, + "empty" +} + +--[[ Local Functions ]] +local function setVehicleData(pSource,pKeepContext) + local mobSession = common.getMobileSession() + audioData.audioControlData.source = pSource + if "empty" == pKeepContext then + audioData.audioControlData.keepContext = nil + else + audioData.audioControlData.keepContext = pKeepContext + end + local cid = mobSession:SendRPC("SetInteriorVehicleData", { + moduleData = audioData + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleData = audioData + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = audioData + }) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + mobSession:ExpectNotification("OnHMIStatus") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, source in pairs(audioSources) do + for _, keepContextValue in pairs(keepContext) do + runner.Step("Change audio source from " .. source .. " source with keepContext is " .. + tostring(keepContextValue), setVehicleData, { source, keepContextValue }) + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua new file mode 100644 index 0000000000..a0aa23083b --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua @@ -0,0 +1,625 @@ +--------------------------------------------------------------------------------------------------- +-- RC common module for AUDIO, LIGHT, HMI_SETTINGS modules +--------------------------------------------------------------------------------------------------- +config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } + +--[[ Required Shared libraries ]] +local commonRC = require("test_scripts/RC/commonRC") +local test = require("user_modules/dummy_connecttest") +local hmi_values = require("user_modules/hmi_values") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') + +--[[ Local Variables ]] +local c = {} +c.modules = { "RADIO", "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } +c.capMap = { + ["RADIO"] = "radioControlCapabilities", + ["CLIMATE"] = "climateControlCapabilities", + ["AUDIO"] = "audioControlCapabilities", + ["LIGHT"] = "lightControlCapabilities", + ["HMI_SETTINGS"] = "hmiSettingsControlCapabilities" +} + +c.backupHMICapabilities = commonRC.backupHMICapabilities +c.restoreHMICapabilities = commonRC.restoreHMICapabilities +c.DEFAULT = commonRC.DEFAULT + +function c.preconditions() + commonRC.preconditions() +end + +function c.start(pHMIParams) + commonRC.start(pHMIParams, test) +end + +local function audibleState(pAppId) + if not pAppId then pAppId = 1 end + local appParams = config["application" .. pAppId].registerAppInterfaceParams + local audibleState + if appParams.isMediaApplication == true then + audibleState = "AUDIBLE" + else + audibleState = "NOT_AUDIBLE" + end + return audibleState +end + +function c.AddOnRCStatusToPT(tbl) + tbl.policy_table.functional_groupings.RemoteControl.rpcs.OnRCStatus = { + hmi_levels = { "NONE", "BACKGROUND", "FULL", "LIMITED" } + } +end + +function c.getRCAppConfig() + local struct = commonRC.getRCAppConfig() + struct.moduleType = c.modules + return struct +end + +local function PTUfunc(tbl) + c.AddOnRCStatusToPT(tbl) + local appId = config.application1.registerAppInterfaceParams.appID + tbl.policy_table.app_policies[appId] = c.getRCAppConfig() +end + +function c.raiPTUn(pPTUfunc, pAppId) + if not pAppId then pAppId = 1 end + if not pPTUfunc then + pPTUfunc = PTUfunc + end + commonRC.rai_ptu_n(pAppId, pPTUfunc, test) +end + +function c.raiN(pAppId) + commonRC.rai_n(pAppId, test) +end + +function c.getHMIAppId(pAppId) + local appId = commonRC.getHMIAppId(pAppId) + return appId +end + +function c.getModuleControlData(pModuleType) + local struct = {} + if "CLIMATE" == pModuleType then + struct.moduleType = "CLIMATE" + struct.climateControlData = {} + struct.climateControlData.heatedSteeringWheelEnable = true + struct.climateControlData.heatedWindshieldEnable = true + struct.climateControlData.heatedRearWindowEnable = true + struct.climateControlData.heatedMirrorsEnable = true + elseif "RADIO" == pModuleType then + struct.moduleType = "RADIO" + struct.radioControlData = {} + struct.radioControlData.sisData = { + stationShortName = "Name1", + stationIDNumber = { + countryCode = 100, + fccFacilityId = 100 + }, + stationLongName = "RadioStationLongName", + stationLocation = { + longitudeDegrees = 0.1, + latitudeDegrees = 0.1, + altitudeMeters = 0.1 + }, + stationMessage = "station message" + } + elseif "AUDIO" == pModuleType then + struct.moduleType = "AUDIO" + struct.audioControlData = { + source = "RADIO_TUNER", + keepContext = false, + volume = 50, + equalizerSettings = { + { + channelId = 10, + channelName = "Channel 1", + channelSetting = 50 + } + } + } + elseif "LIGHT" == pModuleType then + struct.moduleType = "LIGHT" + struct.lightControlData = { + lightState = { + { + id = "FRONT_LEFT_HIGH_BEAM", + status = "ON", + density = 0.2, + sRGBColor = { + red = 50, + green = 150, + blue = 200 + } + } + } + } + elseif "HMI_SETTINGS" == pModuleType then + struct.moduleType = "HMI_SETTINGS" + struct.hmiSettingsControlData = { + displayMode = "DAY", + temperatureUnit = "CELSIUS", + distanceUnit = "KILOMETERS" + } + end + return struct +end + +function c.getAnotherModuleControlData(pModuleType) + local struct = {} + if "CLIMATE" == pModuleType then + struct.moduleType = "CLIMATE" + struct.climateControlData = {} + struct.climateControlData.heatedSteeringWheelEnable = false + struct.climateControlData.heatedWindshieldEnable = false + struct.climateControlData.heatedRearWindowEnable = false + struct.climateControlData.heatedMirrorsEnable = false + elseif "RADIO" == pModuleType then + struct.moduleType = "RADIO" + struct.radioControlData = {} + struct.radioControlData.sisData = { + stationShortName = "Name2", + stationIDNumber = { + countryCode = 200, + fccFacilityId = 200 + }, + stationLongName = "RadioStationLongName2", + stationLocation = { + longitudeDegrees = 20.1, + latitudeDegrees = 20.1, + altitudeMeters = 20.1 + }, + stationMessage = "station message 2" + } + elseif "AUDIO" == pModuleType then + struct.moduleType = "AUDIO" + struct.audioControlData = { + source = "USB", + keepContext = true, + volume = 20, + equalizerSettings = { + { + channelId = 20, + channelName = "Channel 2", + channelSetting = 20 + } + } + } + elseif "LIGHT" == pModuleType then + struct.moduleType = "LIGHT" + struct.lightControlData = { + lightState = { + { + id = "READING_LIGHTS", + status = "ON", + density = 0.5, + sRGBColor = { + red = 150, + green = 200, + blue = 250 + } + } + } + } + elseif "HMI_SETTINGS" == pModuleType then + struct.moduleType = "HMI_SETTINGS" + struct.hmiSettingsControlData = { + displayMode = "NIGHT", + temperatureUnit = "FAHRENHEIT", + distanceUnit = "MILES" + } + end + return struct +end + +function c.getModuleParams(pModuleData) + if pModuleData.moduleType == "RADIO" then + if not pModuleData.radioControlData then + pModuleData.radioControlData = { } + end + return pModuleData.radioControlData + elseif pModuleData.moduleType == "AUDIO" then + if not pModuleData.audioControlData then + pModuleData.audioControlData = { } + end + return pModuleData.audioControlData + end +end + +function c.getReadOnlyParamsByModule(pModuleType) + local out = { moduleType = pModuleType } + if pModuleType == "RADIO" then + out.radioControlData = { + sisData = { + stationShortName = "Name2", + stationIDNumber = { + countryCode = 200, + fccFacilityId = 200 + }, + stationLongName = "RadioStationLongName2", + stationLocation = { + longitudeDegrees = 20.1, + latitudeDegrees = 20.1, + altitudeMeters = 20.1 + }, + stationMessage = "station message 2" + } + } + elseif pModuleType == "AUDIO" then + out.audioControlData = { + equalizerSettings = { { channelName = "Channel 1" } } + } + end + return out +end + +function c.getSettableModuleControlData(pModuleType) + local out = c.getModuleControlData(pModuleType) + local params_read_only = c.getModuleParams(c.getReadOnlyParamsByModule(pModuleType)) + if params_read_only then + for p_read_only, p_read_only_value in pairs(params_read_only) do + if pModuleType == "AUDIO" then + for sub_read_only_key, sub_read_only_value in pairs(p_read_only_value) do + for sub_read_only_name in pairs(sub_read_only_value) do + c.getModuleParams(out)[p_read_only][sub_read_only_key][sub_read_only_name] = nil + end + end + else + c.getModuleParams(out)[p_read_only] = nil + end + end + end + return out +end + +-- RC RPCs structure +local rcRPCs = { + GetInteriorVehicleData = { + appEventName = "GetInteriorVehicleData", + hmiEventName = "RC.GetInteriorVehicleData", + requestParams = function(pModuleType, pSubscribe) + return { + moduleType = pModuleType, + subscribe = pSubscribe + } + end, + hmiRequestParams = function(pModuleType, pAppId, pSubscribe) + return { + appID = c.getHMIAppId(pAppId), + moduleType = pModuleType, + subscribe = pSubscribe + } + end, + hmiResponseParams = function(pModuleType, pSubscribe) + local GetInteriorVDModuleData = c.getModuleControlData(pModuleType) + if GetInteriorVDModuleData.audioControlData then + GetInteriorVDModuleData.audioControlData.keepContext = nil + end + return { + moduleData = GetInteriorVDModuleData, + isSubscribed = pSubscribe + } + end, + responseParams = function(success, resultCode, pModuleType, pSubscribe) + local GetInteriorVDModuleData = c.getModuleControlData(pModuleType) + if GetInteriorVDModuleData.audioControlData then + GetInteriorVDModuleData.audioControlData.keepContext = nil + end + return { + success = success, + resultCode = resultCode, + moduleData = GetInteriorVDModuleData, + isSubscribed = pSubscribe + } + end + }, + SetInteriorVehicleData = { + appEventName = "SetInteriorVehicleData", + hmiEventName = "RC.SetInteriorVehicleData", + requestParams = function(pModuleType) + return { + moduleData = c.getSettableModuleControlData(pModuleType) + } + end, + hmiRequestParams = function(pModuleType, pAppId) + return { + appID = c.getHMIAppId(pAppId), + moduleData = c.getSettableModuleControlData(pModuleType) + } + end, + hmiResponseParams = function(pModuleType) + return { + moduleData = c.getSettableModuleControlData(pModuleType) + } + end, + responseParams = function(success, resultCode, pModuleType) + return { + success = success, + resultCode = resultCode, + moduleData = c.getSettableModuleControlData(pModuleType) + } + end + }, + ButtonPress = { + appEventName = "ButtonPress", + hmiEventName = "Buttons.ButtonPress", + requestParams = function(pModuleType) + return { + moduleType = pModuleType, + buttonName = c.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + } + end, + hmiRequestParams = function(pModuleType, pAppId) + return { + appID = c.getHMIAppId(pAppId), + moduleType = pModuleType, + buttonName = c.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + } + end, + hmiResponseParams = function() + return {} + end, + responseParams = function(success, resultCode) + return { + success = success, + resultCode = resultCode + } + end + }, + GetInteriorVehicleDataConsent = { + hmiEventName = "RC.GetInteriorVehicleDataConsent", + hmiRequestParams = function(pModuleType, pAppId) + return { + appID = c.getHMIAppId(pAppId), + moduleType = pModuleType + } + end, + hmiResponseParams = function(pAllowed) + return { + allowed = pAllowed + } + end, + }, + OnInteriorVehicleData = { + appEventName = "OnInteriorVehicleData", + hmiEventName = "RC.OnInteriorVehicleData", + hmiResponseParams = function(pModuleType) + local OnInteriorVDModuleData = c.getAnotherModuleControlData(pModuleType) + if OnInteriorVDModuleData.audioControlData then + OnInteriorVDModuleData.audioControlData.keepContext = nil + end + return { + moduleData = OnInteriorVDModuleData + } + end, + responseParams = function(pModuleType) + local OnInteriorVDModuleData = c.getAnotherModuleControlData(pModuleType) + if OnInteriorVDModuleData.audioControlData then + OnInteriorVDModuleData.audioControlData.keepContext = nil + end + return { + moduleData = OnInteriorVDModuleData + } + end + }, + OnRemoteControlSettings = { + hmiEventName = "RC.OnRemoteControlSettings", + hmiResponseParams = function(pAllowed, pAccessMode) + return { + allowed = pAllowed, + accessMode = pAccessMode + } + end + } +} + +function c.getAppEventName(pRPC) + return rcRPCs[pRPC].appEventName +end + +function c.getHMIEventName(pRPC) + return rcRPCs[pRPC].hmiEventName +end + +function c.getAppRequestParams(pRPC, ...) + return rcRPCs[pRPC].requestParams(...) +end + +function c.getAppResponseParams(pRPC, ...) + return rcRPCs[pRPC].responseParams(...) +end + +function c.getHMIRequestParams(pRPC, ...) + return rcRPCs[pRPC].hmiRequestParams(...) +end + +function c.getHMIResponseParams(pRPC, ...) + return rcRPCs[pRPC].hmiResponseParams(...) +end + +function c.getMobileSession(pAppId) + if not pAppId then pAppId = 1 end + return test["mobileSession" .. pAppId] +end + +function c.getHMIconnection() + return test.hmiConnection +end + +function c.subscribeToModule(pModuleType, pAppId) + if not pAppId then pAppId = 1 end + local rpc = "GetInteriorVehicleData" + local subscribe = true + local mobSession = c.getMobileSession(pAppId) + local cid = mobSession:SendRPC(c.getAppEventName(rpc), c.getAppRequestParams(rpc, pModuleType, subscribe)) + EXPECT_HMICALL(c.getHMIEventName(rpc), c.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe)) + :Do(function(_, data) + test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + c.getHMIResponseParams(rpc, pModuleType, subscribe)) + end) + mobSession:ExpectResponse(cid, c.getAppResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) + :ValidIf(function(_,data) + if "AUDIO" == pModuleType and + nil ~= data.payload.moduleData.audioControlData.keepContext then + return false, "Mobile response GetInteriorVehicleData contains unexpected keepContext parameter" + end + return true + end) +end + +function c.unSubscribeToModule(pModuleType, pAppId) + local rpc = "GetInteriorVehicleData" + local subscribe = false + local mobSession = c.getMobileSession(pAppId) + local cid = mobSession:SendRPC(c.getAppEventName(rpc), c.getAppRequestParams(rpc, pModuleType, subscribe)) + EXPECT_HMICALL(c.getHMIEventName(rpc), c.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe)) + :Do(function(_, data) + test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", + c.getHMIResponseParams(rpc, pModuleType, subscribe)) + end) + mobSession:ExpectResponse(cid, c.getAppResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) + :ValidIf(function(_,data) + if "AUDIO" == pModuleType and + nil ~= data.payload.moduleData.audioControlData.keepContext then + return false, "Mobile response GetInteriorVehicleData contains unexpected keepContext parameter" + end + return true + end) +end + +function c.activateApp(pAppId) + if not pAppId then pAppId = 1 end + local pHMIAppId = c.getHMIAppId(pAppId) + local mobSession = c.getMobileSession(pAppId) + local requestId = test.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + EXPECT_HMIRESPONSE(requestId) + mobSession:ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = audibleState(), + systemContext = "MAIN" }) +end + +function c.defineRAMode(pAllowed, pAccessMode) + commonRC.defineRAMode(pAllowed, pAccessMode, test) +end + +function c.rpcAllowed(pModuleType, pAppId, pRPC) + local mobSession = c.getMobileSession(pAppId) + local cid = mobSession:SendRPC(c.getAppEventName(pRPC), c.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(c.getHMIEventName(pRPC), c.getHMIRequestParams(pRPC, pModuleType, pAppId)) + :Do(function(_, data) + test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", c.getHMIResponseParams(pRPC, pModuleType)) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +function c.rpcAllowedWithConsent(pModuleType, pAppId, pRPC) + local mobSession = c.getMobileSession(pAppId) + local cid = mobSession:SendRPC(c.getAppEventName(pRPC), c.getAppRequestParams(pRPC, pModuleType)) + local consentRPC = "GetInteriorVehicleDataConsent" + EXPECT_HMICALL(c.getHMIEventName(consentRPC), c.getHMIRequestParams(consentRPC, pModuleType, pAppId)) + :Do(function(_, data) + test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", c.getHMIResponseParams(consentRPC, true)) + EXPECT_HMICALL(c.getHMIEventName(pRPC), c.getHMIRequestParams(pRPC, pModuleType, pAppId)) + :Do(function(_, data2) + test.hmiConnection:SendResponse(data2.id, data2.method, "SUCCESS", c.getHMIResponseParams(pRPC, pModuleType)) + end) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +function c.isSubscribed(pModuleType, pAppId) + local mobSession = c.getMobileSession(pAppId) + local rpc = "OnInteriorVehicleData" + test.hmiConnection:SendNotification(c.getHMIEventName(rpc), c.getHMIResponseParams(rpc, pModuleType)) + mobSession:ExpectNotification(c.getAppEventName(rpc), c.getAppResponseParams(rpc, pModuleType)) + :ValidIf(function(_,data) + if "AUDIO" == pModuleType and + nil ~= data.payload.moduleData.audioControlData.keepContext then + return false, "Mobile notification OnInteriorVehicleData contains unexpected keepContext parameter" + end + return true + end) +end + +function c.isUnsubscribed(pModuleType, pAppId) + local mobSession = c.getMobileSession(pAppId) + local rpc = "OnInteriorVehicleData" + test.hmiConnection:SendNotification(c.getHMIEventName(rpc), c.getHMIResponseParams(rpc, pModuleType)) + mobSession:ExpectNotification(c.getAppEventName(rpc), {}):Times(0) +end + +function c.rpcDenied(pModuleType, pAppId, pRPC, pResultCode) + local mobSession = c.getMobileSession(pAppId) + local cid = mobSession:SendRPC(c.getAppEventName(pRPC), c.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(c.getHMIEventName(pRPC), {}):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = pResultCode }) +end + +function c.rpcRejectWithConsent(pModuleType, pAppId, pRPC) + local info = "The resource is in use and the driver disallows this remote control RPC" + local consentRPC = "GetInteriorVehicleDataConsent" + local mobSession = c.getMobileSession(pAppId) + local cid = mobSession:SendRPC(c.getAppEventName(pRPC), c.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(c.getHMIEventName(consentRPC), c.getHMIRequestParams(consentRPC, pModuleType, pAppId)) + :Do(function(_, data) + test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", c.getHMIResponseParams(consentRPC, false)) + EXPECT_HMICALL(c.getHMIEventName(pRPC)):Times(0) + end) + mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED", info = info }) +end + +function c.rpcRejectWithoutConsent(pModuleType, pAppId, pRPC) + local mobSession = c.getMobileSession( pAppId) + local cid = mobSession:SendRPC(c.getAppEventName(pRPC), c.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(c.getHMIEventName("GetInteriorVehicleDataConsent")):Times(0) + EXPECT_HMICALL(c.getHMIEventName(pRPC)):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) +end + +function c.postconditions() + commonRC.postconditions() +end + +function c.buildHmiRcCapabilities(pCapabilities) + local hmiParams = hmi_values.getDefaultHMITable() + hmiParams.RC.IsReady.params.available = true + local capParams = hmiParams.RC.GetCapabilities.params.remoteControlCapability + for k, v in pairs(c.capMap) do + if pCapabilities[k] then + if pCapabilities[k] ~= commonRC.DEFAULT then + capParams[v] = pCapabilities[v] + end + else + capParams[v] = nil + end + end + return hmiParams +end + +function c.updateDefaultCapabilities(pDisabledModuleTypes) + local hmiCapabilitiesFile = commonPreconditions:GetPathToSDL() + .. commonFunctions:read_parameter_from_smart_device_link_ini("HMICapabilities") + local hmiCapTbl = commonRC.jsonFileToTable(hmiCapabilitiesFile) + local rcCapTbl = hmiCapTbl.UI.systemCapabilities.remoteControlCapability + for _, pDisabledModuleType in pairs(pDisabledModuleTypes) do + local buttonId = commonRC.getButtonIdByName( + rcCapTbl.buttonCapabilities, commonRC.getButtonNameByModule(pDisabledModuleType)) + table.remove(rcCapTbl.buttonCapabilities, buttonId) + rcCapTbl[c.capMap[pDisabledModuleType]] = nil + end + commonRC.tableToJsonFile(hmiCapTbl, hmiCapabilitiesFile) +end + +function c.getModuleControlDataForResponse(pModuleType) + local moduleData = c.getModuleControlData(pModuleType) + if moduleData.audioControlData then + moduleData.audioControlData.keepContext = nil + end + return moduleData +end + +return c diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/025_IN_USE_in_case_3_requests.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/025_IN_USE_in_case_3_requests.lua new file mode 100644 index 0000000000..1a8ca84562 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/025_IN_USE_in_case_3_requests.lua @@ -0,0 +1,224 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/10 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/resource_allocation.md +-- Item: Use Case 1: Exception 2 +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/9 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/button_press_emulation.md +-- Item: Use Case 1: Exception 1.5 +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Exception 6.1 +-- +-- Requirement summary: +-- [SDL_RC] Resource allocation based on access mode +-- +-- Description: TRS: OnRemoteControlSettings, #3 +-- In case: +-- 1) SDL received OnRemoteControlSettings notification from HMI with allowed:true +-- 2) and "accessMode" = "AUTO_ALLOW" or without "accessMode" parameter at all +-- 3) and RC_module on HMI is alreay in control by RC-application_1 +-- 4) and RC_module is currently executing request by RC_application_1 +-- 5) and another RC_application_2 in HMILevel LIMITED sends control RPC (either SetInteriorVehicleData or ButtonPress) +-- 6) and another RC_application_3 in HMILevel FULL sends control RPC (either SetInteriorVehicleData or ButtonPress) +-- SDL must: +-- 1) deny access to RC_module for RC_application_2, RC_application_3 without asking a driver +-- 2) not process the request from RC_application_2, RC_application_3 and respond with result code IN_USE, success:false +-- 3) leave RC_application_1 in control of the RC_module +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local mobile_session = require("mobile_session") + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local access_modes = { nil, "AUTO_ALLOW" } +local hmiAppIds = { } + +local app1Params = config.application1.registerAppInterfaceParams +local app2Params = config.application2.registerAppInterfaceParams +local app3Params = config.application3.registerAppInterfaceParams + +app1Params.isMediaApplication = false +app1Params.appHMIType = { "NAVIGATION", "REMOTE_CONTROL" } +app2Params.isMediaApplication = true +app2Params.appHMIType = { "DEFAULT", "REMOTE_CONTROL" } +app3Params.isMediaApplication = false +app3Params.appHMIType = { "DEFAULT", "REMOTE_CONTROL" } + +--[[ Local Functions ]] +local function ptu_update_func(tbl) + tbl.policy_table.app_policies[app1Params.appID].AppHMIType = app1Params.appHMIType + tbl.policy_table.app_policies[app2Params.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[app2Params.appID].AppHMIType = app2Params.appHMIType + tbl.policy_table.app_policies[app3Params.appID] = commonRC.getRCAppConfig() + tbl.policy_table.app_policies[app3Params.appID].AppHMIType = app3Params.appHMIType +end + +local function step(pModuleType, pRPC1, pRPC2, self) + local cid1 + if pRPC1 == "SetInteriorVehicleData" then + cid1 = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, data) + local function hmiRespond() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + end + RUN_AFTER(hmiRespond, 4000) + end) + elseif pRPC1 == "ButtonPress" then + cid1 = self.mobileSession1:SendRPC("ButtonPress", { + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + EXPECT_HMICALL("Buttons.ButtonPress", { + appID = commonRC.getHMIAppId(1), + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + :Do(function(_, data) + local function hmiRespond() + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end + RUN_AFTER(hmiRespond, 4000) + end) + end + self.mobileSession1:ExpectResponse(cid1, { success = true, resultCode = "SUCCESS" }) + + local req3_func = function() + local cid3 + local pRPC3 = pRPC2 + if pRPC3 == "SetInteriorVehicleData" then + cid3 = self.mobileSession3:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + elseif pRPC3 == "ButtonPress" then + cid3 = self.mobileSession3:SendRPC("ButtonPress", { + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + end + self.mobileSession3:ExpectResponse(cid3, { success = false, resultCode = "IN_USE" }) + end + + local req2_func = function() + local cid2 + if pRPC2 == "SetInteriorVehicleData" then + cid2 = self.mobileSession2:SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + elseif pRPC2 == "ButtonPress" then + cid2 = self.mobileSession2:SendRPC("ButtonPress", { + moduleType = pModuleType, + buttonName = commonRC.getButtonNameByModule(pModuleType), + buttonPressMode = "SHORT" + }) + end + self.mobileSession2:ExpectResponse(cid2, { success = false, resultCode = "IN_USE" }) + :Do(function() + req3_func() + end) + end + + RUN_AFTER(req2_func, 1000) +end + +local function rai_n(id, self) + self, id = commonRC.getSelfAndParams(id, self) + if not id then id = 1 end + self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) + self["mobileSession" .. id]:StartService(7) + :Do(function() + local corId = self["mobileSession" .. id]:SendRPC("RegisterAppInterface", + config["application" .. id].registerAppInterfaceParams) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", + { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) + :Do(function(_, d1) + hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID + end) + self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") + end) + end) +end + +local function activate_app(pAppId, pOnHMIStatusFunc, self) + self, pAppId = commonRC.getSelfAndParams(pAppId, self) + if not pAppId then pAppId = 1 end + local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] + local mobSession = commonRC.getMobileSession(self, pAppId) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + EXPECT_HMIRESPONSE(requestId) + if not pOnHMIStatusFunc then + mobSession:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + else + pOnHMIStatusFunc(self) + end +end + +local function OnHMIStatus2Apps(self) + self.mobileSession2:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) +end + +local function OnHMIStatus3Apps(self) + self.mobileSession3:ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + self.mobileSession1:ExpectNotification("OnHMIStatus") + :Times(0) + self.mobileSession2:ExpectNotification("OnHMIStatus", + { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) +runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI2", rai_n, { 2 }) +runner.Step("Activate App2", activate_app, { 2, OnHMIStatus2Apps }) +runner.Step("RAI3", rai_n, { 3 }) +runner.Step("Activate App3", activate_app, { 3, OnHMIStatus3Apps }) + +runner.Title("Test") + +for _, mod in pairs(modules) do + runner.Title("Module: " .. mod) + -- set control for App1 + runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) + for i = 1, #access_modes do + runner.Title("Access mode: " .. tostring(access_modes[i])) + -- set RA mode + runner.Step("Set RA mode", commonRC.defineRAMode, { true, access_modes[i] }) + -- try to set control for App2 while request for App1 is executing + local rpcs = { "SetInteriorVehicleData", "ButtonPress" } + for _, rpc1 in pairs(rpcs) do + for _, rpc2 in pairs(rpcs) do + runner.Step("App1 " .. rpc1 .. " App2_App3_" .. rpc2, step, { mod, rpc1, rpc2 }) + end + end + end +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt b/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt new file mode 100644 index 0000000000..d7d8732a00 --- /dev/null +++ b/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt @@ -0,0 +1,54 @@ +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/004_HMI_no_response_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/005_HMI_invalid_response_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/001_Success_flow.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/003_UNSUPPORTED_RESOURCE_in_case_RC_interface_is_unavailable.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/004_Allowed_true_accessMode_AUTO_DENY.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/005_Allowed_true_accessMode_ASK_DRIVER.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/006_Default_accessMode.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/008_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_without_keepContext.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_false.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua diff --git a/test_sets/rc_CLIMATE_RADIO.txt b/test_sets/rc_CLIMATE_RADIO.txt index d960cea13e..d39912361e 100644 --- a/test_sets/rc_CLIMATE_RADIO.txt +++ b/test_sets/rc_CLIMATE_RADIO.txt @@ -89,6 +89,7 @@ ./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua ./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua ./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/025_IN_USE_in_case_3_requests.lua ./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/001_Success_flow.lua ./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua ./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index 163c2ad830..6793089132 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -346,7 +346,11 @@ function module.getDefaultHMITable() ventilationModeAvailable = true, ventilationMode = { "UPPER", "LOWER", "BOTH", "NONE" - } + }, + heatedSteeringWheelAvailable = true, + heatedWindshieldAvailable = true, + heatedRearWindowAvailable = true, + heatedMirrorsAvailable = true } }, radioControlCapabilities = { @@ -360,7 +364,17 @@ function module.getDefaultHMITable() availableHDsAvailable = true, stateAvailable = true, signalStrengthAvailable = true, - signalChangeThresholdAvailable = true + signalChangeThresholdAvailable = true, + sisDataAvailable = true + } + }, + audioControlCapabilities = { + { + moduleName = "Audio", + sourceAvailable = true, + volumeAvailable = true, + equalizerAvailable = true, + equalizerMaxChannelId = 100 } }, seatControlCapabilities = { @@ -383,6 +397,38 @@ function module.getDefaultHMITable() memoryAvailable = true } }, + hmiSettingsControlCapabilities = { + moduleName = "HmiSettings", + distanceUnitAvailable = true, + temperatureUnitAvailable = true, + displayModeUnitAvailable = true + }, + lightControlCapabilities = { + moduleName = "Light", + supportedLights = (function() + local lights = { "FRONT_LEFT_HIGH_BEAM", "FRONT_RIGHT_HIGH_BEAM", "FRONT_LEFT_LOW_BEAM", + "FRONT_RIGHT_LOW_BEAM", "FRONT_LEFT_PARKING_LIGHT", "FRONT_RIGHT_PARKING_LIGHT", + "FRONT_LEFT_FOG_LIGHT", "FRONT_RIGHT_FOG_LIGHT", "FRONT_LEFT_DAYTIME_RUNNING_LIGHT", + "FRONT_RIGHT_DAYTIME_RUNNING_LIGHT", "FRONT_LEFT_TURN_LIGHT", "FRONT_RIGHT_TURN_LIGHT", + "REAR_LEFT_FOG_LIGHT", "REAR_RIGHT_FOG_LIGHT", "REAR_LEFT_TAIL_LIGHT", "REAR_RIGHT_TAIL_LIGHT", + "REAR_LEFT_BREAK_LIGHT", "REAR_RIGHT_BREAK_LIGHT", "REAR_LEFT_TURN_LIGHT", "REAR_RIGHT_TURN_LIGHT", + "REAR_REGISTRATION_PLATE_LIGHT", "HIGH_BEAMS", "LOW_BEAMS", "FOG_LIGHTS", "RUNNING_LIGHTS", + "PARKING_LIGHTS", "BRAKE_LIGHTS", "REAR_REVERSING_LIGHTS", "SIDE_MARKER_LIGHTS", "LEFT_TURN_LIGHTS", + "RIGHT_TURN_LIGHTS", "HAZARD_LIGHTS", "AMBIENT_LIGHTS", "OVERHEAD_LIGHTS", "READING_LIGHTS", + "TRUNK_LIGHTS", "EXTERIOR_FRONT_LIGHTS", "EXTERIOR_REAR_LIGHTS", "EXTERIOR_LEFT_LIGHTS", + "EXTERIOR_RIGHT_LIGHTS" } + local out = { } + for _, name in pairs(lights) do + local item = { + name = name, + densityAvailable = true, + sRGBColorSpaceAvailable = true + } + table.insert(out, item) + end + return out + end)() + }, buttonCapabilities = (function() local buttons = { -- climate From ce66cca59eba37faf3fc8ba55f85b9bb6b70cd30 Mon Sep 17 00:00:00 2001 From: "Ira Lytvynenko (GitHub)" Date: Wed, 30 May 2018 16:40:06 +0300 Subject: [PATCH 582/681] Add new parameter keepContextAvailable to hmi capabilities --- user_modules/hmi_values.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index 6793089132..9443a5d9d3 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -372,6 +372,7 @@ function module.getDefaultHMITable() { moduleName = "Audio", sourceAvailable = true, + keepContextAvailable = true, volumeAvailable = true, equalizerAvailable = true, equalizerMaxChannelId = 100 From 796f73f8c12fbe36489ead11e86081d4c1673f24 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 25 Jul 2018 11:29:37 +0300 Subject: [PATCH 583/681] Remove duplicate scripts with wrong numbering --- .../010_Change_audio_source_in_BACKGROUND.lua | 75 --------------- ..._audio_source_in_FULL_rc_non_media_app.lua | 67 ------------- ...ce_from_MOBILE_APP_without_keepContext.lua | 86 ----------------- ...urce_from_MOBILE_APP_keepContext_false.lua | 86 ----------------- ..._from_MOBILE_APP_keepContext_true_FULL.lua | 86 ----------------- ...om_MOBILE_APP_keepContext_true_LIMITED.lua | 96 ------------------- ...ype_except_MOBILE_APP_keepContext_true.lua | 88 ----------------- 7 files changed, 584 deletions(-) delete mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_BACKGROUND.lua delete mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_FULL_rc_non_media_app.lua delete mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_from_MOBILE_APP_without_keepContext.lua delete mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_keepContext_false.lua delete mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua delete mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua delete mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_BACKGROUND.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_BACKGROUND.lua deleted file mode 100644 index da6953ec1c..0000000000 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_BACKGROUND.lua +++ /dev/null @@ -1,75 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- User story: TBD --- Use case: TBD --- --- Requirement summary: --- TBD --- --- Description: --- In case: --- 1) App is RC and Media --- 2) App in NONE or BACKGROUND HMI level --- 3) App tries to change audio source --- SDL must: --- 1) Not change audio source ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ General configuration parameters ]] -config.application1.registerAppInterfaceParams.isMediaApplication = true -config.application2.registerAppInterfaceParams.isMediaApplication = true - ---[[ Local Variables ]] -local audioData = common.getSettableModuleControlData("AUDIO") -local audioSources = { - "NO_SOURCE_SELECTED", - "CD", - "BLUETOOTH_STEREO_BTST", - "USB", - "USB2", - "LINE_IN", - "IPOD", - "MOBILE_APP", - "RADIO_TUNER" -} - ---[[ Local Functions ]] -local function setVehicleData(pSource) - audioData.audioControlData.source = pSource - local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = audioData }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = common.getHMIAppId(), moduleData = audioData }) - :Do(function(_, data) - common.getHMIconnection():SendError(data.id, data.method, "REJECTED", "Error") - end) - - common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "REJECTED", info = "Error" }) -end - -local function BringAppToBACKGROUND() - common.activateApp(2) - common.getMobileSession():ExpectNotification("OnHMIStatus", - { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU App1", common.raiPTUn) -runner.Step("RAI App2", common.raiN, {2}) -runner.Step("Activate App1", common.activateApp) -runner.Step("Set App1 to BACKGROUND HMI level", BringAppToBACKGROUND) - -runner.Title("Test") -for _, source in pairs(audioSources) do - runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) -end - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_FULL_rc_non_media_app.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_FULL_rc_non_media_app.lua deleted file mode 100644 index 5c9c76218d..0000000000 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_FULL_rc_non_media_app.lua +++ /dev/null @@ -1,67 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- User story: TBD --- Use case: TBD --- --- Requirement summary: --- TBD --- --- Description: --- In case: --- 1) App is RC and Non-Media --- 2) App in any HMI level --- 3) App tries to change audio source --- SDL must: --- 1) Not change audio source ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ General configuration parameters ]] -config.application1.registerAppInterfaceParams.isMediaApplication = false - ---[[ Local Variables ]] -local audioData = common.getSettableModuleControlData("AUDIO") -local audioSources = { - "NO_SOURCE_SELECTED", - "CD", - "BLUETOOTH_STEREO_BTST", - "USB", - "USB2", - "LINE_IN", - "IPOD", - "MOBILE_APP", - "RADIO_TUNER" -} - ---[[ Local Functions ]] -local function setVehicleData(pSource) - audioData.audioControlData.source = pSource - local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) - - -- Confirmation nedded, not clear what resultCode must be - common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) -runner.Step("Activate App", common.activateApp) - -runner.Title("Test") -for _, source in pairs(audioSources) do - runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) -end - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_from_MOBILE_APP_without_keepContext.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_from_MOBILE_APP_without_keepContext.lua deleted file mode 100644 index 4d1c5d8d74..0000000000 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_from_MOBILE_APP_without_keepContext.lua +++ /dev/null @@ -1,86 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- User story: TBD --- Use case: TBD --- --- Requirement summary: --- TBD --- --- Description: --- In case: --- 1) App is RC and Media --- 2) App in FULL HMI level --- 3) App tries to change audio source from MOBILE_APP with keepContext = false --- SDL must: --- 1) Change audio source successfully --- 2) Change HMI level of App to BACKGROUND ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ General configuration parameters ]] -config.application1.registerAppInterfaceParams.isMediaApplication = true - ---[[ Local Variables ]] -local audioData = common.getSettableModuleControlData("AUDIO") - ---[[ Local Functions ]] -local function setVehicleDataMobileApp() - local mobSession = common.getMobileSession() - audioData.audioControlData.source = "MOBILE_APP" - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - -local function setVehicleData() - local mobSession = common.getMobileSession() - audioData.audioControlData.source = "USB" - audioData.audioControlData.keepContext = nil - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { - eventName = "AUDIO_SOURCE", - isActive = true - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) - mobSession:ExpectNotification("OnHMIStatus", - { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) -runner.Step("Activate App", common.activateApp) -runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) - -runner.Title("Test") -runner.Step("Change audio source from MOBILE_APP without keepContext", setVehicleData) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_keepContext_false.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_keepContext_false.lua deleted file mode 100644 index b5942647c3..0000000000 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_keepContext_false.lua +++ /dev/null @@ -1,86 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- User story: TBD --- Use case: TBD --- --- Requirement summary: --- TBD --- --- Description: --- In case: --- 1) App is RC and Media --- 2) App in FULL HMI level --- 3) App tries to change audio source from MOBILE_APP without keepContext parameter defined --- SDL must: --- 1) Change audio source successfully --- 2) Change HMI level of App to BACKGROUND ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ General configuration parameters ]] -config.application1.registerAppInterfaceParams.isMediaApplication = true - ---[[ Local Variables ]] -local audioData = common.getSettableModuleControlData("AUDIO") - ---[[ Local Functions ]] -local function setVehicleDataMobileApp() - local mobSession = common.getMobileSession() - audioData.audioControlData.source = "MOBILE_APP" - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - -local function setVehicleData() - local mobSession = common.getMobileSession() - audioData.audioControlData.source = "USB" - audioData.audioControlData.keepContext = false - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { - eventName = "AUDIO_SOURCE", - isActive = true - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) - mobSession:ExpectNotification("OnHMIStatus", - { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) -runner.Step("Activate App", common.activateApp) -runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) - -runner.Title("Test") -runner.Step("Change audio source from MOBILE_APP keepContext is false", setVehicleData) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua deleted file mode 100644 index f4f5afd6d0..0000000000 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua +++ /dev/null @@ -1,86 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- User story: TBD --- Use case: TBD --- --- Requirement summary: --- TBD --- --- Description: --- In case: --- 1)App is RC and Media --- 2) App in FULL HMI level --- 3) App tries to change audio source from MOBILE_APP with keepContext = true --- SDL must: --- 1) Change audio source successfully --- 2) Not change HMI level, but change audioStreamingState to "NOT_AUDIBLE" ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ General configuration parameters ]] -config.application1.registerAppInterfaceParams.isMediaApplication = true - ---[[ Local Variables ]] -local audioData = common.getSettableModuleControlData("AUDIO") - ---[[ Local Functions ]] -local function setVehicleDataMobileApp() - local mobSession = common.getMobileSession() - audioData.audioControlData.source = "MOBILE_APP" - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - -local function setVehicleData() - local mobSession = common.getMobileSession() - audioData.audioControlData.source = "USB" - audioData.audioControlData.keepContext = true - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { - eventName = "AUDIO_SOURCE", - isActive = true - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) - mobSession:ExpectNotification("OnHMIStatus", - { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) -runner.Step("Activate App", common.activateApp) -runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) - -runner.Title("Test") -runner.Step("Change audio source from MOBILE_APP keepContext is true", setVehicleData) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua deleted file mode 100644 index e7b1e7728b..0000000000 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua +++ /dev/null @@ -1,96 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- User story: TBD --- Use case: TBD --- --- Requirement summary: --- TBD --- --- Description: --- In case: --- 1)App is RC and Media --- 2) App in LIMITED HMI level --- 3) App tries to change audio source from MOBILE_APP with keepContext = true --- SDL must: --- 1) Change audio source successfully --- 2) Change HMI level to BACKGROUND and change audioStreamingState to "NOT_AUDIBLE" ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ General configuration parameters ]] -config.application1.registerAppInterfaceParams.isMediaApplication = true - ---[[ Local Variables ]] -local audioData = common.getSettableModuleControlData("AUDIO") - ---[[ Local Functions ]] -local function setVehicleDataMobileApp() - local mobSession = common.getMobileSession() - audioData.audioControlData.source = "MOBILE_APP" - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - -local function setVehicleData() - local mobSession = common.getMobileSession() - audioData.audioControlData.source = "USB" - audioData.audioControlData.keepContext = true - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { - eventName = "AUDIO_SOURCE", - isActive = true - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) - mobSession:ExpectNotification("OnHMIStatus", - { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) -end - -local function bringAppToLIMITED() - common.getHMIconnection():SendNotification("BasicCommunication.OnAppDeactivated", { - appID = common.getHMIAppId(), - reason = "GENERAL" - }) - common.getMobileSession():ExpectNotification("OnHMIStatus", - { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) -runner.Step("Activate App", common.activateApp) -runner.Step("Set App to LIMITED HMI level", bringAppToLIMITED) -runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) - -runner.Title("Test") -runner.Step("Change audio source from MOBILE_APP keepContext is true", setVehicleData) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua deleted file mode 100644 index 68e6e2b82f..0000000000 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua +++ /dev/null @@ -1,88 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- User story: TBD --- Use case: TBD --- --- Requirement summary: --- TBD --- --- Description: --- In case: --- 1) App is RC and Media --- 2) App in FULL HMI level --- 3) App tries to change audio source from any type except of MOBILE_APP and with any value of keepContext parameter or event without it --- SDL must: --- 1) Change audio source successfully --- 2) Not change HMI level ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') - ---[[ Test Configuration ]] -runner.testSettings.isSelfIncluded = false - ---[[ General configuration parameters ]] -config.application1.registerAppInterfaceParams.isMediaApplication = true - ---[[ Local Variables ]] -local audioData = common.getSettableModuleControlData("AUDIO") -local audioSources = { - "NO_SOURCE_SELECTED", - "CD", - "BLUETOOTH_STEREO_BTST", - "USB", - "USB2", - "LINE_IN", - "IPOD", - "RADIO_TUNER" -} - -local keepContext = { - false, - true, - "empty" -} - ---[[ Local Functions ]] -local function setVehicleData(pSource,pKeepContext) - local mobSession = common.getMobileSession() - audioData.audioControlData.source = pSource - if "empty" == pKeepContext then - audioData.audioControlData.keepContext = nil - else - audioData.audioControlData.keepContext = pKeepContext - end - local cid = mobSession:SendRPC("SetInteriorVehicleData", { - moduleData = audioData - }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = audioData - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = audioData - }) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) - mobSession:ExpectNotification("OnHMIStatus") - :Times(0) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) -runner.Step("Activate App", common.activateApp) - -runner.Title("Test") -for _, source in pairs(audioSources) do - for _, keepContextValue in pairs(keepContext) do - runner.Step("Change audio source from " .. source .. " source with keepContext is " .. - tostring(keepContextValue), setVehicleData, { source, keepContextValue }) - end -end - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) From 85c503b6c9e62078fe6d52fa3f5ced839dd7b71f Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 14 Aug 2018 13:00:58 +0300 Subject: [PATCH 584/681] Changes regarding 'Revise New remote control modules' --- .../016_RADIO_GPSdata_in_HMI_response.lua | 128 ++++++++++++++++++ .../commonRCmodules.lua | 11 +- test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt | 1 + user_modules/hmi_values.lua | 2 +- 4 files changed, 136 insertions(+), 6 deletions(-) create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua new file mode 100644 index 0000000000..08131ad97b --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua @@ -0,0 +1,128 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0099-new-remote-control-modules-and-parameters.md +-- User story: TBD +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/current_module_status_data.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) RC app sends GetInteriorVehicleData request with valid parameters +-- 2) and SDL gets response (resultCode: SUCCESS) and data from GPSData struct in stationLocation from HMI +-- SDL must: +-- 1) Respond to App with success:true, "SUCCESS" and resend values received from HMI in case all values are valid and all mandatory parameters are present +-- S) Respond to App with success:false, "GENERIC_ERROR" in case mandatry parameters are missed +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local moduleName = "RADIO" + +local paramsForPositiveCase = { + mandatoryOnly = { + longitudeDegrees = 20.1, + latitudeDegrees = 20.1 + }, + mandatoryWithAltitude = { + longitudeDegrees = 20.1, + latitudeDegrees = 20.1, + altitude = 20.1 + }, + allGPSdata = { + longitudeDegrees = 20.1, + latitudeDegrees = 20.1, + altitude = 20.1, + utcYear = 2020, + utcMonth = 5, + utcDay = 15, + utcHours = 5, + utcMinutes = 30, + utcSeconds = 30, + compassDirection = "NORTH", + pdop = 5, + hdop = 5, + vdop = 5, + actual = true, + satellites = 5, + dimension = "NO_FIX", + heading = 10.1, + speed = 15 + } +} + +local paramsMissingMandatory = { + onlyLongitude = { + longitudeDegrees = 20.1 + }, + onlyLatitude = { + latitudeDegrees = 20.1 + } +} + +--[[ Local Functions ]] +local function getRadioParams(pStationLocationParams) + local radioParams = { + moduleType = moduleName, + radioControlData = { + sisData = { + stationShortName = "Name2", + stationIDNumber = { + countryCode = 200, + fccFacilityId = 200 + }, + stationLongName = "RadioStationLongName2", + stationLocation = pStationLocationParams, + stationMessage = "station message 2" + } + } + } + return radioParams +end + +local function getDataForModule(pStationLocationParams, isSuccess) + local radioParams = getRadioParams(pStationLocationParams) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = moduleName + }) + + EXPECT_HMICALL("RC.GetInteriorVehicleData", { + appID = common.getHMIAppId(), + moduleType = moduleName + }) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = radioParams }) + end) + if isSuccess == true then + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = radioParams }) + else + mobileSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Invalid message received from vehicle" }) + end + +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for key, value in pairs(paramsForPositiveCase) do + runner.Step("GetInteriorVehicleData stationLocation " .. key, getDataForModule, { value, true }) +end +for key, value in pairs(paramsMissingMandatory) do + runner.Step("GetInteriorVehicleData stationLocation " .. key, getDataForModule, { value, false }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua index a0aa23083b..2eec208345 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua @@ -3,6 +3,7 @@ --------------------------------------------------------------------------------------------------- config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 --[[ Required Shared libraries ]] local commonRC = require("test_scripts/RC/commonRC") @@ -103,7 +104,7 @@ function c.getModuleControlData(pModuleType) stationLocation = { longitudeDegrees = 0.1, latitudeDegrees = 0.1, - altitudeMeters = 0.1 + altitude = 0.1 }, stationMessage = "station message" } @@ -129,7 +130,7 @@ function c.getModuleControlData(pModuleType) id = "FRONT_LEFT_HIGH_BEAM", status = "ON", density = 0.2, - sRGBColor = { + color = { red = 50, green = 150, blue = 200 @@ -170,7 +171,7 @@ function c.getAnotherModuleControlData(pModuleType) stationLocation = { longitudeDegrees = 20.1, latitudeDegrees = 20.1, - altitudeMeters = 20.1 + altitude = 20.1 }, stationMessage = "station message 2" } @@ -196,7 +197,7 @@ function c.getAnotherModuleControlData(pModuleType) id = "READING_LIGHTS", status = "ON", density = 0.5, - sRGBColor = { + color = { red = 150, green = 200, blue = 250 @@ -243,7 +244,7 @@ function c.getReadOnlyParamsByModule(pModuleType) stationLocation = { longitudeDegrees = 20.1, latitudeDegrees = 20.1, - altitudeMeters = 20.1 + altitude = 20.1 }, stationMessage = "station message 2" } diff --git a/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt b/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt index d7d8732a00..9de99a0870 100644 --- a/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt +++ b/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt @@ -13,6 +13,7 @@ ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index 9443a5d9d3..e7b97175cf 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -423,7 +423,7 @@ function module.getDefaultHMITable() local item = { name = name, densityAvailable = true, - sRGBColorSpaceAvailable = true + RGBColorSpaceAvailable = true } table.insert(out, item) end From 943753e1b65a3f77cfcb4f82674ddfa9931351c8 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 15 Aug 2018 18:31:47 +0300 Subject: [PATCH 585/681] Rename parameter RGBColorSpaceAvailable --- user_modules/hmi_values.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index e7b97175cf..63514c2257 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -423,7 +423,7 @@ function module.getDefaultHMITable() local item = { name = name, densityAvailable = true, - RGBColorSpaceAvailable = true + rgbColorSpaceAvailable = true } table.insert(out, item) end From 2004e5ed0f18ff319031e866cc1224f0548115fc Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 16 Aug 2018 11:12:12 +0300 Subject: [PATCH 586/681] Update BREAK_LIGHT to BRAKE_LIGHT --- user_modules/hmi_values.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index 63514c2257..84ad02b7e8 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -412,7 +412,7 @@ function module.getDefaultHMITable() "FRONT_LEFT_FOG_LIGHT", "FRONT_RIGHT_FOG_LIGHT", "FRONT_LEFT_DAYTIME_RUNNING_LIGHT", "FRONT_RIGHT_DAYTIME_RUNNING_LIGHT", "FRONT_LEFT_TURN_LIGHT", "FRONT_RIGHT_TURN_LIGHT", "REAR_LEFT_FOG_LIGHT", "REAR_RIGHT_FOG_LIGHT", "REAR_LEFT_TAIL_LIGHT", "REAR_RIGHT_TAIL_LIGHT", - "REAR_LEFT_BREAK_LIGHT", "REAR_RIGHT_BREAK_LIGHT", "REAR_LEFT_TURN_LIGHT", "REAR_RIGHT_TURN_LIGHT", + "REAR_LEFT_BRAKE_LIGHT", "REAR_RIGHT_BRAKE_LIGHT", "REAR_LEFT_TURN_LIGHT", "REAR_RIGHT_TURN_LIGHT", "REAR_REGISTRATION_PLATE_LIGHT", "HIGH_BEAMS", "LOW_BEAMS", "FOG_LIGHTS", "RUNNING_LIGHTS", "PARKING_LIGHTS", "BRAKE_LIGHTS", "REAR_REVERSING_LIGHTS", "SIDE_MARKER_LIGHTS", "LEFT_TURN_LIGHTS", "RIGHT_TURN_LIGHTS", "HAZARD_LIGHTS", "AMBIENT_LIGHTS", "OVERHEAD_LIGHTS", "READING_LIGHTS", From 3fbe90104878470be35953741643f5c252066a34 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 16 Aug 2018 16:17:24 +0300 Subject: [PATCH 587/681] Added majorVersion=5 in common files --- test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua | 1 + test_scripts/RC/commonRC.lua | 2 ++ 2 files changed, 3 insertions(+) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua index 2eec208345..28cf34198e 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua @@ -4,6 +4,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 +config.application2.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 --[[ Required Shared libraries ]] local commonRC = require("test_scripts/RC/commonRC") diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 3526622f57..875bceed55 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -7,6 +7,8 @@ config.defaultProtocolVersion = 2 config.ValidateSchema = false config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 +config.application2.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") From f50f8132499a12dd44162726e349d9fb8d6d14f1 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 16 Aug 2018 18:46:40 +0300 Subject: [PATCH 588/681] Update according to review comments --- ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 4 ++-- ...se_moduleType_is_an_empty_array_in_LPT.lua | 20 +------------------ 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 4687c71312..719ae038f9 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -29,7 +29,7 @@ local function ptUpdateFunc(pTbl) pTbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } end -local function rpcDissallowed() +local function rpcDisallowed() local cid = common.getMobileSession():SendRPC("GetSystemCapability", { systemCapabilityType = "REMOTE_CONTROL" }) common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) end @@ -42,7 +42,7 @@ runner.Step("RAI, PTU", common.raiPTUn, { ptUpdateFunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") -runner.Step("GetSystemCapability DISALLOWED", rpcDissallowed) +runner.Step("GetSystemCapability DISALLOWED", rpcDisallowed) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 0e92caf8e1..149fa6aa4c 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -27,24 +27,6 @@ runner.testSettings.isSelfIncluded = false local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } --[[ Local Functions ]] -local function setVehicleData(pModuleType) - local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { - moduleData = common.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = common.getHMIAppId(), - moduleData = common.getSettableModuleControlData(pModuleType) - }) - :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = common.getSettableModuleControlData(pModuleType) - }) - end) - - common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY @@ -60,7 +42,7 @@ runner.Step("Activate App", common.activateApp) runner.Title("Test") for _, mod in pairs(modules) do - runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) + runner.Step("SetInteriorVehicleData " .. mod, common.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) end runner.Title("Postconditions") From 4fbeb12809a53ef3b7b04551a56fd30ca7e3efc0 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 16 Aug 2018 19:48:35 +0300 Subject: [PATCH 589/681] Added majorVersion=5 in common file for app3 --- test_scripts/RC/commonRC.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 875bceed55..b7069fa35b 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -9,6 +9,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 config.application2.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 +config.application3.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 --[[ Required Shared libraries ]] local commonFunctions = require("user_modules/shared_testcases/commonFunctions") From 492b7932e3a0317ef2f5f9ffe27ee74653c736fa Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 16 Aug 2018 23:08:34 +0300 Subject: [PATCH 590/681] Use rpcDenied in disallowed cases --- .../002_Disallow_flow_by_policy_CLIMATE.lua | 14 ++------------ .../003_Disallow_flow_by_policy_AUDIO.lua | 14 ++------------ .../004_Disallow_flow_by_policy_LIGHT.lua | 14 ++------------ .../005_Disallow_flow_by_policy_HMI_SETTINGS.lua | 14 ++------------ 4 files changed, 8 insertions(+), 48 deletions(-) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 2530721fbc..d2fccf2c44 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -23,19 +23,9 @@ runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local mod = "CLIMATE" +local rpc = "SetInteriorVehicleData" --[[ Local Functions ]] -local function setVehicleData(pModuleType) - local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { - moduleData = common.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) - - common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } @@ -49,7 +39,7 @@ runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") -runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +runner.Step("SetInteriorVehicleData " .. mod, common.rpcDenied, {mod, 1, rpc, "DISALLOWED"}) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua index 18c29a6e63..4b252fc5a1 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua @@ -23,19 +23,9 @@ runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local mod = "AUDIO" +local rpc = "SetInteriorVehicleData" --[[ Local Functions ]] -local function setVehicleData(pModuleType) - local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { - moduleData = common.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) - - common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } @@ -49,7 +39,7 @@ runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") -runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +runner.Step("SetInteriorVehicleData " .. mod, common.rpcDenied, {mod, 1, rpc, "DISALLOWED"}) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua index c3fa95671d..71bc5c0a7f 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua @@ -23,19 +23,9 @@ runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local mod = "LIGHT" +local rpc = "SetInteriorVehicleData" --[[ Local Functions ]] -local function setVehicleData(pModuleType) - local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { - moduleData = common.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) - - common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } @@ -49,7 +39,7 @@ runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") -runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +runner.Step("SetInteriorVehicleData " .. mod, common.rpcDenied, {mod, 1, rpc, "DISALLOWED"}) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua index 00202d0464..08b9b014fd 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua @@ -23,19 +23,9 @@ runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local mod = "HMI_SETTINGS" +local rpc = "SetInteriorVehicleData" --[[ Local Functions ]] -local function setVehicleData(pModuleType) - local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { - moduleData = common.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) - - common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } @@ -49,7 +39,7 @@ runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") -runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +runner.Step("SetInteriorVehicleData " .. mod, common.rpcDenied, {mod, 1, rpc, "DISALLOWED"}) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) From c31621f4b5343766e7c36b52c712e955c4d8aa06 Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Thu, 16 Aug 2018 17:27:03 -0400 Subject: [PATCH 591/681] Reduce redundant code --- .../002_Disallow_flow_by_policy_AUDIO.lua | 12 +----------- .../003_Disallow_flow_by_policy_LIGHT.lua | 12 +----------- .../004_Disallow_flow_by_policy_HMI_SETTINGS.lua | 12 +----------- ...ow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua | 13 +------------ ...ow_flow_in_case_moduleType_is_absent_in_LPT.lua | 14 +------------- 5 files changed, 5 insertions(+), 58 deletions(-) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua index f2e9b53c5b..30c648ab1f 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua @@ -16,16 +16,6 @@ local commonRC = require('test_scripts/RC/commonRC') --[[ Local Variables ]] local mod = "AUDIO" ---[[ Local Functions ]] -local function getDataForModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType - }) - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } end @@ -38,7 +28,7 @@ runner.Step("RAI, PTU", commonRC.rai_ptu, { PTUfunc }) runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") -runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +runner.Step("GetInteriorVehicleData " .. mod, commonRC.rpcDenied, { mod, 1, "GetInteriorVehicleData", "DISALLOWED" }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua index 61c949c8aa..95d9065102 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua @@ -16,16 +16,6 @@ local commonRC = require('test_scripts/RC/commonRC') --[[ Local Variables ]] local mod = "LIGHT" ---[[ Local Functions ]] -local function getDataForModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType - }) - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } end @@ -38,7 +28,7 @@ runner.Step("RAI, PTU", commonRC.rai_ptu, { PTUfunc }) runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") -runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +runner.Step("GetInteriorVehicleData " .. mod, commonRC.rpcDenied, { mod, 1, "GetInteriorVehicleData", "DISALLOWED" }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua index b52f650aeb..5e84b4e2f1 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua @@ -16,16 +16,6 @@ local commonRC = require('test_scripts/RC/commonRC') --[[ Local Variables ]] local mod = "HMI_SETTINGS" ---[[ Local Functions ]] -local function getDataForModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType - }) - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } end @@ -38,7 +28,7 @@ runner.Step("RAI, PTU", commonRC.rai_ptu, { PTUfunc }) runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") -runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +runner.Step("GetInteriorVehicleData " .. mod, commonRC.rpcDenied, { mod, 1, "GetInteriorVehicleData", "DISALLOWED" }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index ca593e5567..aca8d87025 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -23,17 +23,6 @@ runner.testSettings.isSelfIncluded = false --[[ General configuration parameters ]] config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } ---[[ Local Functions ]] -local function getDataForModule(pModuleType) - local mobileSession = common.getMobileSession() - local cid = mobileSession:SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType - }) - EXPECT_HMICALL("RC.GetInteriorVehicleData") - :Times(0) - mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) local appId = config.application1.registerAppInterfaceParams.appID tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } @@ -49,7 +38,7 @@ runner.Step("Activate App", common.activateApp) runner.Title("Test") for _, mod in pairs(common.modules) do - runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) + runner.Step("GetInteriorVehicleData " .. mod, common.rpcDenied, { mod, 1, "GetInteriorVehicleData", "DISALLOWED" }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 87ffb43115..2aee29a21b 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -25,18 +25,6 @@ runner.testSettings.isSelfIncluded = false --modules array does not contain "RADIO" because "RADIO" module has read only parameters local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } ---[[ Local Functions ]] -local function setVehicleData(pModuleType) - local cid = common.getMobileSession():SendRPC("SetInteriorVehicleData", { - moduleData = common.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) - - common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil end @@ -50,7 +38,7 @@ runner.Step("Activate App", common.activateApp) runner.Title("Test") for _, mod in pairs(modules) do - runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) + runner.Step("SetInteriorVehicleData " .. mod, common.rpcDenied, { mod, 1, "SetInteriorVehicleData", "DISALLOWED" }) end runner.Title("Postconditions") From e5130a3eb8165aedd49de19be9153c8e6c5c91d7 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 17 Aug 2018 15:32:26 +0300 Subject: [PATCH 592/681] Expand common file with new module values for OnRCStatus --- .../RC/OnRCStatus/commonOnRCStatus.lua | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua index 5ef39ddfa6..c11690c73e 100644 --- a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua +++ b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua @@ -24,7 +24,7 @@ local m = {} local getRCAppConfigOrigin = commonRC.getRCAppConfig function commonRC.getRCAppConfig(tbl) local rcAppConfig = getRCAppConfigOrigin(tbl) - rcAppConfig.moduleType = { "RADIO", "CLIMATE", "SEAT" } + rcAppConfig.moduleType = { "RADIO", "CLIMATE", "SEAT", "AUDIO", "LIGHT", "HMI_SETTINGS" } return rcAppConfig end @@ -106,6 +106,35 @@ function commonRC.getModuleControlData(module_type) action = "SAVE" } } + elseif module_type == "AUDIO" then + out.moduleType = "AUDIO" + out.audioControlData = { + source = "RADIO_TUNER", + volume = 50 + } + elseif module_type == "LIGHT" then + out.moduleType = "LIGHT" + out.lightControlData = { + lightState = { + { + id = "FRONT_LEFT_HIGH_BEAM", + status = "ON", + density = 0.2, + color = { + red = 50, + green = 150, + blue = 200 + } + } + } + } + elseif module_type == "HMI_SETTINGS" then + out.moduleType = "HMI_SETTINGS" + out.hmiSettingsControlData = { + displayMode = "DAY", + temperatureUnit = "CELSIUS", + distanceUnit = "KILOMETERS" + } else out = origGetModuleControlData(module_type) end @@ -122,7 +151,7 @@ function m.getModules() end function m.getAllModules() - return commonFunctions:cloneTable({ "RADIO", "CLIMATE", "SEAT" }) + return commonFunctions:cloneTable({ "RADIO", "CLIMATE", "SEAT", "AUDIO", "LIGHT", "HMI_SETTINGS" }) end function m.getRCAppConfig() From 06363ff3e55af495504b9e1113ebc66b55fc77e3 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 24 Jul 2018 18:14:29 +0300 Subject: [PATCH 593/681] Replace the RADIO_TUNER with four enumeration elements AM, FM, XM and DAB --- .../017_Success_audio_source_values.lua | 61 +++++++++++++++++++ .../009_Success_audio_source_values.lua | 56 +++++++++++++++++ .../009_Change_audio_source_in_FULL.lua | 13 +--- .../010_Change_audio_source_in_LIMITED.lua | 13 +--- .../011_Change_audio_source_in_BACKGROUND.lua | 13 +--- ..._audio_source_in_FULL_rc_non_media_app.lua | 13 +--- ...ype_except_MOBILE_APP_keepContext_true.lua | 5 +- .../commonRCmodules.lua | 17 +++++- test_sets/audio_source_am_fm_xm.txt | 9 +++ test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt | 2 + 10 files changed, 152 insertions(+), 50 deletions(-) create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua create mode 100644 test_sets/audio_source_am_fm_xm.txt diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua new file mode 100644 index 0000000000..ea7f9614bc --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0182-audio-source-am-fm-xm.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1) Mobile app sends GetInteriorVehicleData request with moduleType=AUDIO +-- 2) SDL transfers this request to HMI +-- 3) HMI responds with source from PrimaryAudioSource enum +-- SDL must: +-- 1) Process this response and transfer it to mobile +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function subscribeToModule(pAudioSources) + local rpc = "GetInteriorVehicleData" + local subscribe = nil + local moduleType = "AUDIO" + local mobSession = common.getMobileSession(1) + local hmiResponseParams = common.getHMIResponseParams(rpc, moduleType, subscribe) + hmiResponseParams.moduleData.audioControlData.source = pAudioSources + local mobileResponseParams = common.getAppResponseParams(rpc, true, "SUCCESS", moduleType, subscribe) + mobileResponseParams.moduleData.audioControlData.source = pAudioSources + local cid = mobSession:SendRPC(common.getAppEventName(rpc), common.getAppRequestParams(rpc, moduleType, subscribe)) + EXPECT_HMICALL(common.getHMIEventName(rpc), common.getHMIRequestParams(rpc, moduleType, 1, subscribe)) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", hmiResponseParams) + end) + mobSession:ExpectResponse(cid, mobileResponseParams) + :ValidIf(function(_,data) + if nil ~= data.payload.moduleData.audioControlData.keepContext then + return false, "Mobile response GetInteriorVehicleData contains unexpected keepContext parameter" + end + return true + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +for _, source in pairs(common.audioSources) do + runner.Step("GetInteriorVehicleData source " .. source, subscribeToModule, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua new file mode 100644 index 0000000000..51d44aacd3 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0182-audio-source-am-fm-xm.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Mobile app is subscribed to get interior vehicle data for module AUDIO +-- 2) HMI sends OnInteriorVehicleData with source from PrimaryAudioSource enum +-- SDL must: +-- 1) Process this notification and transfer it to mobile +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function isSubscribed(pAudioSources) + local moduleType = "AUDIO" + local mobSession = common.getMobileSession(1) + local rpc = "OnInteriorVehicleData" + local hmiParams = common.getHMIResponseParams(rpc, moduleType) + hmiParams.moduleData.audioControlData.source = pAudioSources + local mobileParams = common.getAppResponseParams(rpc, moduleType) + mobileParams.moduleData.audioControlData.source = pAudioSources + common.getHMIconnection():SendNotification(common.getHMIEventName(rpc), hmiParams) + mobSession:ExpectNotification(common.getAppEventName(rpc), mobileParams) + :ValidIf(function(_,data) + if nil ~= data.payload.moduleData.audioControlData.keepContext then + return false, "Mobile notification OnInteriorVehicleData contains unexpected keepContext parameter" + end + return true + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) +runner.Step("Subscribe app to AUDIO", common.subscribeToModule, { "AUDIO" }) + +runner.Title("Test") + +for _, source in pairs(common.audioSources) do + runner.Step("Send notification OnInteriorVehicleData " .. source .. ". App is subscribed", isSubscribed, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua index 077918a2af..744f56c4a2 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua @@ -25,17 +25,6 @@ config.application1.registerAppInterfaceParams.isMediaApplication = true --[[ Local Variables ]] local audioData = common.getSettableModuleControlData("AUDIO") -local audioSources = { - "NO_SOURCE_SELECTED", - "CD", - "BLUETOOTH_STEREO_BTST", - "USB", - "USB2", - "LINE_IN", - "IPOD", - "MOBILE_APP", - "RADIO_TUNER" -} --[[ Local Functions ]] local function setVehicleData(pSource) @@ -65,7 +54,7 @@ runner.Step("RAI, PTU", common.raiPTUn) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, source in pairs(audioSources) do +for _, source in pairs(common.audioSources) do runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua index 1d372b1222..e45271edb0 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua @@ -25,17 +25,6 @@ config.application1.registerAppInterfaceParams.isMediaApplication = true --[[ Local Variables ]] local audioData = common.getSettableModuleControlData("AUDIO") -local audioSources = { - "NO_SOURCE_SELECTED", - "CD", - "BLUETOOTH_STEREO_BTST", - "USB", - "USB2", - "LINE_IN", - "IPOD", - "MOBILE_APP", - "RADIO_TUNER" -} --[[ Local Functions ]] local function setVehicleData(pSource) @@ -75,7 +64,7 @@ runner.Step("Activate App", common.activateApp) runner.Step("Set App to LIMITED HMI level", bringAppToLIMITED) runner.Title("Test") -for _, source in pairs(audioSources) do +for _, source in pairs(common.audioSources) do runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua index da6953ec1c..e10ad08462 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua @@ -26,17 +26,6 @@ config.application2.registerAppInterfaceParams.isMediaApplication = true --[[ Local Variables ]] local audioData = common.getSettableModuleControlData("AUDIO") -local audioSources = { - "NO_SOURCE_SELECTED", - "CD", - "BLUETOOTH_STEREO_BTST", - "USB", - "USB2", - "LINE_IN", - "IPOD", - "MOBILE_APP", - "RADIO_TUNER" -} --[[ Local Functions ]] local function setVehicleData(pSource) @@ -67,7 +56,7 @@ runner.Step("Activate App1", common.activateApp) runner.Step("Set App1 to BACKGROUND HMI level", BringAppToBACKGROUND) runner.Title("Test") -for _, source in pairs(audioSources) do +for _, source in pairs(common.audioSources) do runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua index 5c9c76218d..751921cb50 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua @@ -25,17 +25,6 @@ config.application1.registerAppInterfaceParams.isMediaApplication = false --[[ Local Variables ]] local audioData = common.getSettableModuleControlData("AUDIO") -local audioSources = { - "NO_SOURCE_SELECTED", - "CD", - "BLUETOOTH_STEREO_BTST", - "USB", - "USB2", - "LINE_IN", - "IPOD", - "MOBILE_APP", - "RADIO_TUNER" -} --[[ Local Functions ]] local function setVehicleData(pSource) @@ -59,7 +48,7 @@ runner.Step("RAI, PTU", common.raiPTUn) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, source in pairs(audioSources) do +for _, source in pairs(common.audioSources) do runner.Step("SetInteriorVehicleData with source " .. source, setVehicleData, { source }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua index 68e6e2b82f..4006803660 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua @@ -34,7 +34,10 @@ local audioSources = { "USB2", "LINE_IN", "IPOD", - "RADIO_TUNER" + "AM", + "FM", + "XM", + "DAB" } local keepContext = { diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua index 28cf34198e..cb3d3e39ac 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua @@ -24,6 +24,21 @@ c.capMap = { ["HMI_SETTINGS"] = "hmiSettingsControlCapabilities" } +c.audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "AM", + "FM", + "XM", + "DAB" +} + c.backupHMICapabilities = commonRC.backupHMICapabilities c.restoreHMICapabilities = commonRC.restoreHMICapabilities c.DEFAULT = commonRC.DEFAULT @@ -112,7 +127,7 @@ function c.getModuleControlData(pModuleType) elseif "AUDIO" == pModuleType then struct.moduleType = "AUDIO" struct.audioControlData = { - source = "RADIO_TUNER", + source = "AM", keepContext = false, volume = 50, equalizerSettings = { diff --git a/test_sets/audio_source_am_fm_xm.txt b/test_sets/audio_source_am_fm_xm.txt new file mode 100644 index 0000000000..eb023c98e0 --- /dev/null +++ b/test_sets/audio_source_am_fm_xm.txt @@ -0,0 +1,9 @@ +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua +./test_scripts/API/VehicleData/GetVehicleData/003_Success_deviceStatus_primaryAudioSource.lua +./test_scripts/API/VehicleData/OnVehicleData/004_Success_flow_deviceStatus_primaryAudioSource.lua diff --git a/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt b/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt index 9de99a0870..faae0fd39d 100644 --- a/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt +++ b/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt @@ -14,6 +14,7 @@ ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua @@ -30,6 +31,7 @@ ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua From 8be8ba8f84ac2a5d4cce37b6205af98ef0cc44ca Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 24 Jul 2018 18:19:42 +0300 Subject: [PATCH 594/681] Replace the RADIO_TUNER with four enumeration elements for VehicleData --- ...uccess_deviceStatus_primaryAudioSource.lua | 78 +++++++++++++++ ...s_flow_deviceStatus_primaryAudioSource.lua | 95 +++++++++++++++++++ .../API/VehicleData/commonVehicleData.lua | 2 +- test_sets/VehicleData.txt | 2 + 4 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 test_scripts/API/VehicleData/GetVehicleData/004_Success_deviceStatus_primaryAudioSource.lua create mode 100644 test_scripts/API/VehicleData/OnVehicleData/005_Success_flow_deviceStatus_primaryAudioSource.lua diff --git a/test_scripts/API/VehicleData/GetVehicleData/004_Success_deviceStatus_primaryAudioSource.lua b/test_scripts/API/VehicleData/GetVehicleData/004_Success_deviceStatus_primaryAudioSource.lua new file mode 100644 index 0000000000..4cc3aca1ed --- /dev/null +++ b/test_scripts/API/VehicleData/GetVehicleData/004_Success_deviceStatus_primaryAudioSource.lua @@ -0,0 +1,78 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0182-audio-source-am-fm-xm.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1) Mobile app sends GetVehicleData request with deviceStatus=true +-- 2) SDL transfers this request to HMI +-- 3) HMI responds with value from PrimaryAudioSource enum in deviceStatus.primaryAudioSource +-- SDL must: +-- 1) Process GetVehicleData response and transfer it to mobile +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') +local utils = require("user_modules/utils") + +--[[ Local Variables ]] +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "AM", + "FM", + "XM", + "DAB" +} + +local rpc = { + name = "GetVehicleData", + params = { + deviceStatus = true + } +} + +--[[ Local Functions ]] +local function processRPCSuccess(pAudioSource, self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc.name, rpc.params) + local vehicleDataValues = { + deviceStatus = { + primaryAudioSource = pAudioSource + } + } + EXPECT_HMICALL("VehicleInfo." .. rpc.name, rpc.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", vehicleDataValues ) + end) + local responseParams = vehicleDataValues + responseParams.success = true + responseParams.resultCode = "SUCCESS" + mobileSession:ExpectResponse(cid, responseParams) + utils.wait(300) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, source in pairs(audioSources) do + runner.Step("RPC " .. rpc.name .. " source " .. source, processRPCSuccess, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/VehicleData/OnVehicleData/005_Success_flow_deviceStatus_primaryAudioSource.lua b/test_scripts/API/VehicleData/OnVehicleData/005_Success_flow_deviceStatus_primaryAudioSource.lua new file mode 100644 index 0000000000..76ea62041f --- /dev/null +++ b/test_scripts/API/VehicleData/OnVehicleData/005_Success_flow_deviceStatus_primaryAudioSource.lua @@ -0,0 +1,95 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0182-audio-source-am-fm-xm.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary:TBD +-- +-- Description: +-- In case: +-- 1) Mobile app is subscribed to get deviceStatus vehicle data +-- 2) HMI sends OnVehicleData with value from PrimaryAudioSource enum in deviceStatus.primaryAudioSource +-- SDL must: +-- 1) Process OnVehicleData notification and transfer it to mobile +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/API/VehicleData/commonVehicleData') + +--[[ Local Variables ]] +local audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "AM", + "FM", + "XM", + "DAB" +} + +local rpc1 = { + name = "SubscribeVehicleData", + params = { + deviceStatus = true + } +} + +local vehicleDataResults = { + deviceStatus = { + dataType = "VEHICLEDATA_DEVICESTATUS", + resultCode = "SUCCESS" + } +} + +local rpc2 = { + name = "OnVehicleData", + params = { + deviceStatus = { + primaryAudioSource = "CD" + } + } +} + +--[[ Local Functions ]] +local function processRPCSubscribeSuccess(self) + local mobileSession = common.getMobileSession(self, 1) + local cid = mobileSession:SendRPC(rpc1.name, rpc1.params) + EXPECT_HMICALL("VehicleInfo." .. rpc1.name, rpc1.params) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", vehicleDataResults) + end) + + local responseParams = vehicleDataResults + responseParams.success = true + responseParams.resultCode = "SUCCESS" + mobileSession:ExpectResponse(cid, responseParams) +end + +local function checkNotificationSuccess(pAudioSource, self) + rpc2.params.deviceStatus.primaryAudioSource = pAudioSource + local mobileSession = common.getMobileSession(self, 1) + self.hmiConnection:SendNotification("VehicleInfo." .. rpc2.name, rpc2.params) + mobileSession:ExpectNotification("OnVehicleData", rpc2.params) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI with PTU", common.registerAppWithPTU) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("RPC " .. rpc1.name, processRPCSubscribeSuccess) +for _, source in pairs(audioSources) do + runner.Step("RPC " .. rpc2.name .. " source " .. source, checkNotificationSuccess, { source }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/API/VehicleData/commonVehicleData.lua b/test_scripts/API/VehicleData/commonVehicleData.lua index d91a8a69d3..778ca63bda 100644 --- a/test_scripts/API/VehicleData/commonVehicleData.lua +++ b/test_scripts/API/VehicleData/commonVehicleData.lua @@ -35,7 +35,7 @@ function commonVehicleData.getGetVehicleDataConfig() steal_focus = false, priority = "NONE", default_hmi = "NONE", - groups = { "Base-4", "Emergency-1" } + groups = { "Base-4", "Emergency-1", "VehicleInfo-3" } } end diff --git a/test_sets/VehicleData.txt b/test_sets/VehicleData.txt index 8f55f8df92..105559f2a9 100644 --- a/test_sets/VehicleData.txt +++ b/test_sets/VehicleData.txt @@ -1,10 +1,12 @@ ./test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua ./test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua ./test_scripts/API/VehicleData/GetVehicleData/003_GetVD_gps_mandatory_parameters.lua +./test_scripts/API/VehicleData/GetVehicleData/004_Success_deviceStatus_primaryAudioSource.lua ./test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua ./test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua ;./test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua ./test_scripts/API/VehicleData/OnVehicleData/004_OnVD_gps_mandatory_parameters.lua +./test_scripts/API/VehicleData/OnVehicleData/005_Success_flow_deviceStatus_primaryAudioSource.lua ./test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua ;./test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua ;./test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua From 72d050842144cea1594025eda7a15c845efffa7a Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 17 Aug 2018 19:30:34 +0300 Subject: [PATCH 595/681] Fix links to scripts in test set --- test_sets/audio_source_am_fm_xm.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_sets/audio_source_am_fm_xm.txt b/test_sets/audio_source_am_fm_xm.txt index eb023c98e0..8e8a16b590 100644 --- a/test_sets/audio_source_am_fm_xm.txt +++ b/test_sets/audio_source_am_fm_xm.txt @@ -5,5 +5,5 @@ ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua -./test_scripts/API/VehicleData/GetVehicleData/003_Success_deviceStatus_primaryAudioSource.lua -./test_scripts/API/VehicleData/OnVehicleData/004_Success_flow_deviceStatus_primaryAudioSource.lua +./test_scripts/API/VehicleData/GetVehicleData/004_Success_deviceStatus_primaryAudioSource.lua +./test_scripts/API/VehicleData/OnVehicleData/005_Success_flow_deviceStatus_primaryAudioSource.lua From 526d80100ff24e36d8e88b7f64492a246ee3c8b4 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 6 Jun 2018 16:25:10 +0300 Subject: [PATCH 596/681] Initial scripts for feature Radio parameter update --- .../GetSystemCapability/001_Success_flow.lua | 82 +++++++++++++++++++ ..._RESOURCE_hdRadioEnableAvailable_false.lua | 39 +++++++++ ...ESOURCE_hdRadioEnableAvailable_omitted.lua | 39 +++++++++ .../018_Success_flow_band_setting.lua | 59 +++++++++++++ ..._RESOURCE_siriusxmRadioAvailable_false.lua | 53 ++++++++++++ ...ESOURCE_siriusxmRadioAvailable_omitted.lua | 53 ++++++++++++ ..._in_case_invalid_data_in_hdRadioEnable.lua | 49 +++++++++++ ...022_availableHDs_hdChannel_upper_bound.lua | 69 ++++++++++++++++ ...ilableHDs_hdChannel_out_of_upper_bound.lua | 62 ++++++++++++++ test_scripts/RC/commonRC.lua | 6 +- test_sets/rc_radio_parameter_update.txt | 12 +++ user_modules/hmi_values.lua | 10 ++- 12 files changed, 528 insertions(+), 5 deletions(-) create mode 100644 test_scripts/RC/CLIMATE_RADIO/GetSystemCapability/001_Success_flow.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/016_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_false.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/017_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_omitted.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/018_Success_flow_band_setting.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/019_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_false.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/020_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_omitted.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/021_INVALID_DATA_in_case_invalid_data_in_hdRadioEnable.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/022_availableHDs_hdChannel_upper_bound.lua create mode 100644 test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/023_availableHDs_hdChannel_out_of_upper_bound.lua create mode 100644 test_sets/rc_radio_parameter_update.txt diff --git a/test_scripts/RC/CLIMATE_RADIO/GetSystemCapability/001_Success_flow.lua b/test_scripts/RC/CLIMATE_RADIO/GetSystemCapability/001_Success_flow.lua new file mode 100644 index 0000000000..df9ad82807 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/GetSystemCapability/001_Success_flow.lua @@ -0,0 +1,82 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/1 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/RC/detailed_info_GetSystemCapability.md +-- Item: Use Case 2: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Capabilities +-- +-- Description: +-- In case: +-- 1) App is RC +-- 2) App tries to get RC capabilities +-- SDL must: +-- 1) Transfer RC capabilities to mobiles +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/commonRC') +local hmi_values = require("user_modules/hmi_values") + +--[[ Local Variables ]] +local modules = { "CLIMATE", "RADIO" } +local capMap = { + ["RADIO"] = "radioControlCapabilities", + ["CLIMATE"] = "climateControlCapabilities" +} +local capabParams = {} +for _, v in pairs(modules) do capabParams[v] = common.DEFAULT end -- HMI has all posible RC capabilities + +--[[ Local Functions ]] +local function buildHmiRcCapabilities(pCapabilities) + local hmiParams = hmi_values.getDefaultHMITable() + hmiParams.RC.IsReady.params.available = true + local capParams = hmiParams.RC.GetCapabilities.params.remoteControlCapability + for k, v in pairs(capMap) do + if pCapabilities[k] then + if pCapabilities[k] ~= common.DEFAULT then + capParams[v] = pCapabilities[v] + end + else + capParams[v] = nil + end + end + return hmiParams +end + +local hmiRcCapabilities = buildHmiRcCapabilities(capabParams) + +local function rpcSuccess(self) + local rcCapabilities = hmiRcCapabilities.RC.GetCapabilities.params.remoteControlCapability + local cid = common.getMobileSession(self):SendRPC("GetSystemCapability", { systemCapabilityType = "REMOTE_CONTROL" }) + common.getMobileSession(self):ExpectResponse(cid, { + success = true, + resultCode = "SUCCESS", + systemCapability = { + remoteControlCapability = { + climateControlCapabilities = rcCapabilities.climateControlCapabilities, + radioControlCapabilities = rcCapabilities.radioControlCapabilities, + audioControlCapabilities = rcCapabilities.audioControlCapabilities, + hmiSettingsControlCapabilities = rcCapabilities.hmiSettingsControlCapabilities, + lightControlCapabilities = rcCapabilities.lightControlCapabilities, + buttonCapabilities = rcCapabilities.buttonCapabilities + } + } + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Backup HMI capabilities file", common.backupHMICapabilities) +runner.Step("Update HMI capabilities file", common.updateDefaultCapabilities, { modules }) +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { hmiRcCapabilities }) +runner.Step("RAI, PTU", common.rai_ptu) +runner.Step("Activate App", common.activate_app) + +runner.Title("Test") +runner.Step("GetSystemCapability Positive Case", rpcSuccess) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) +runner.Step("Restore HMI capabilities file", common.restoreHMICapabilities) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/016_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_false.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/016_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_false.lua new file mode 100644 index 0000000000..ac17e3d581 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/016_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_false.lua @@ -0,0 +1,39 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0160-rc-radio-parameter-update.md +-- User story: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) RC.GetCapabilities received with hdRadioEnableAvailable = false from HMI +-- 2) Application is registered with REMOTE_CONTROL appHMIType +-- 3) and sends valid SetInteriorVehicleData RPC with hdRadioEnable +-- SDL must: +-- 1) Respond with UNSUPPORTED_RESOURCE result code, success = false to mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local hmi_values = require("user_modules/hmi_values") + +--[[ Local Variables ]] +local Module = "RADIO" +local hmiValues = hmi_values.getDefaultHMITable() +hmiValues.RC.GetCapabilities.params.remoteControlCapability.radioControlCapabilities[1].hdRadioEnableAvailable = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { hmiValues }) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") + +runner.Step("SetInteriorVehicleData UNSUPPORTED_RESOURCE in case hdRadioEnableAvailable false", commonRC.rpcDenied, + {Module, 1, "SetInteriorVehicleData", "UNSUPPORTED_RESOURCE"}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/017_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_omitted.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/017_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_omitted.lua new file mode 100644 index 0000000000..4898ffc5c8 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/017_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_omitted.lua @@ -0,0 +1,39 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0160-rc-radio-parameter-update.md +-- User story: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) RC.GetCapabilities received without hdRadioEnableAvailable from HMI +-- 2) Application is registered with REMOTE_CONTROL appHMIType +-- 3) and sends valid SetInteriorVehicleData RPC with hdRadioEnable +-- SDL must: +-- 1) Respond with UNSUPPORTED_RESOURCE result code, success = false to mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local hmi_values = require("user_modules/hmi_values") + +--[[ Local Variables ]] +local Module = "RADIO" +local hmiValues = hmi_values.getDefaultHMITable() +hmiValues.RC.GetCapabilities.params.remoteControlCapability.radioControlCapabilities[1].hdRadioEnableAvailable = nil + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { hmiValues }) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") + +runner.Step("SetInteriorVehicleData UNSUPPORTED_RESOURCE in case hdRadioEnableAvailable omitted", commonRC.rpcDenied, + {Module, 1, "SetInteriorVehicleData", "UNSUPPORTED_RESOURCE"}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/018_Success_flow_band_setting.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/018_Success_flow_band_setting.lua new file mode 100644 index 0000000000..31ddc6e2d6 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/018_Success_flow_band_setting.lua @@ -0,0 +1,59 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0160-rc-radio-parameter-update.md +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) and sends valid SetInteriorVehicleData RPC with valid parameters +-- SDL must: +-- 1) Transfer this request to HMI +-- 2) Respond with received from HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local Module = "RADIO" + +--[[ Local Functions ]] +local function setVehicleData(self) + local requestParams = commonRC.getSettableModuleControlData(Module) + requestParams.radioControlData.band = "XM" + + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + moduleData = requestParams + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = requestParams + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = requestParams + }) + end) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") + +runner.Step("SetInteriorVehicleData with band XM", setVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/019_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_false.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/019_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_false.lua new file mode 100644 index 0000000000..4b9ff3af77 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/019_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_false.lua @@ -0,0 +1,53 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0160-rc-radio-parameter-update.md +-- User story: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) RC.GetCapabilities received with siriusxmRadioAvailable = false from HMI +-- 2) Application is registered with REMOTE_CONTROL appHMIType +-- 3) and sends valid SetInteriorVehicleData RPC with band = XM +-- SDL must: +-- 1) Respond with UNSUPPORTED_RESOURCE result code, success = false to mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local hmi_values = require("user_modules/hmi_values") + +--[[ Local Variables ]] +local Module = "RADIO" +local hmiValues = hmi_values.getDefaultHMITable() +hmiValues.RC.GetCapabilities.params.remoteControlCapability.radioControlCapabilities[1].siriusxmRadioAvailable = false + +--[[ Local Functions ]] +local function rpcDenied(self) + local requestParams = commonRC.getSettableModuleControlData(Module) + requestParams.radioControlData.band = "XM" + + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + moduleData = requestParams + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { hmiValues }) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") + +runner.Step("SetInteriorVehicleData UNSUPPORTED_RESOURCE in case siriusxmRadioAvailable false", rpcDenied) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/020_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_omitted.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/020_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_omitted.lua new file mode 100644 index 0000000000..df7b251869 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/020_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_omitted.lua @@ -0,0 +1,53 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0160-rc-radio-parameter-update.md +-- User story: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) RC.GetCapabilities received without siriusxmRadioAvailable from HMI +-- 2) Application is registered with REMOTE_CONTROL appHMIType +-- 3) and sends valid SetInteriorVehicleData RPC with band = XM +-- SDL must: +-- 1) Respond with UNSUPPORTED_RESOURCE result code, success = false to mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local hmi_values = require("user_modules/hmi_values") + +--[[ Local Variables ]] +local Module = "RADIO" +local hmiValues = hmi_values.getDefaultHMITable() +hmiValues.RC.GetCapabilities.params.remoteControlCapability.radioControlCapabilities[1].siriusxmRadioAvailable = nil + +--[[ Local Functions ]] +local function rpcDenied(self) + local requestParams = commonRC.getSettableModuleControlData(Module) + requestParams.radioControlData.band = "XM" + + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + moduleData = requestParams + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { hmiValues }) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") + +runner.Step("SetInteriorVehicleData UNSUPPORTED_RESOURCE in case siriusxmRadioAvailable omitted", rpcDenied) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/021_INVALID_DATA_in_case_invalid_data_in_hdRadioEnable.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/021_INVALID_DATA_in_case_invalid_data_in_hdRadioEnable.lua new file mode 100644 index 0000000000..b79c3e24d6 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/021_INVALID_DATA_in_case_invalid_data_in_hdRadioEnable.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0160-rc-radio-parameter-update.md +-- User story: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) and sends valid SetInteriorVehicleData RPC with invalid value in hdRadioEnable +-- SDL must: +-- 1) Respond with INVALID_DATA result code, success = false +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local Module = "RADIO" + +--[[ Local Functions ]] +local function rpcInvalidData(self) + local requestParams = commonRC.getSettableModuleControlData(Module) + requestParams.radioControlData.hdRadioEnable = "ENABLE" + + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + moduleData = requestParams + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) + +runner.Title("Test") + +runner.Step("SetInteriorVehicleData INVALID_DATA", rpcInvalidData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/022_availableHDs_hdChannel_upper_bound.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/022_availableHDs_hdChannel_upper_bound.lua new file mode 100644 index 0000000000..e5d236b9d2 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/022_availableHDs_hdChannel_upper_bound.lua @@ -0,0 +1,69 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0160-rc-radio-parameter-update.md +-- User story: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) and sends valid SetInteriorVehicleData RPC with max value for hdChannel +-- 3) HMI sends OnInteriorVehicleData with max value for availableHDs +-- SDL must: +-- 1) Transfer this request to HMI +-- 2) Respond with received from HMI +-- 3) Transfer notification to mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local Module = "RADIO" + +--[[ Local Functions ]] +local function setVehicleData(self) + local requestParams = commonRC.getSettableModuleControlData(Module) + requestParams.radioControlData.hdChannel = 7 + + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + moduleData = requestParams + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = self.applications["Test Application"], + moduleData = requestParams + }) + :Do(function(_, data) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + moduleData = requestParams + }) + end) + + self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function onVehicleData(self) + local notificationParams = commonRC.getHMIResponseParams("OnInteriorVehicleData", Module) + notificationParams.moduleData.radioControlData.availableHDs = 7 + + self.hmiConnection:SendNotification(commonRC.getHMIEventName("OnInteriorVehicleData"), notificationParams) + self.mobileSession1:ExpectNotification(commonRC.getAppEventName("OnInteriorVehicleData"), notificationParams) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) +runner.Step("Subscribe app to " .. Module, commonRC.subscribeToModule, { Module }) + +runner.Title("Test") + +runner.Step("SetInteriorVehicleData with max value for hdChannel", setVehicleData) +runner.Step("OnInteriorVehicleData with max value for availableHDs", onVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/023_availableHDs_hdChannel_out_of_upper_bound.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/023_availableHDs_hdChannel_out_of_upper_bound.lua new file mode 100644 index 0000000000..0602f54a58 --- /dev/null +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/023_availableHDs_hdChannel_out_of_upper_bound.lua @@ -0,0 +1,62 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0160-rc-radio-parameter-update.md +-- User story: TBD +-- +-- Requirement summary: +-- TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) and sends valid SetInteriorVehicleData RPC with out of upper bound value for hdChannel +-- 3) HMI sends OnInteriorVehicleData with out of upper bound value for availableHDs +-- SDL must: +-- 1) Respond with INVALID_DATA result code, success = false to mobile application +-- 3) not transfer notification to mobile application +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Local Variables ]] +local Module = "RADIO" + +--[[ Local Functions ]] +local function setVehicleData(self) + local requestParams = commonRC.getSettableModuleControlData(Module) + requestParams.radioControlData.hdChannel = 8 + + local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + moduleData = requestParams + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData") + :Times(0) + + self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) +end + +local function onVehicleData(self) + local notificationParams = commonRC.getHMIResponseParams("OnInteriorVehicleData", Module) + notificationParams.moduleData.radioControlData.availableHDs = 8 + + self.hmiConnection:SendNotification(commonRC.getHMIEventName("OnInteriorVehicleData"), notificationParams) + self.mobileSession1:ExpectNotification(commonRC.getAppEventName("OnInteriorVehicleData")) + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) +runner.Step("RAI, PTU", commonRC.rai_ptu) +runner.Step("Activate App", commonRC.activate_app) +runner.Step("Subscribe app to " .. Module, commonRC.subscribeToModule, { Module }) + +runner.Title("Test") + +runner.Step("SetInteriorVehicleData with out of upper bound value for hdChannel", setVehicleData) +runner.Step("OnInteriorVehicleData with out of upper bound value for availableHDs", onVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index b7069fa35b..427e03d25c 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -325,7 +325,8 @@ function commonRC.getModuleControlData(module_type) signalStrength = 5, signalChangeThreshold = 10, radioEnable = true, - state = "ACQUIRING" + state = "ACQUIRING", + hdRadioEnable = true } end return out @@ -372,7 +373,8 @@ function commonRC.getAnotherModuleControlData(module_type) signalStrength = 5, signalChangeThreshold = 20, radioEnable = true, - state = "ACQUIRING" + state = "ACQUIRING", + hdRadioEnable = false } end return out diff --git a/test_sets/rc_radio_parameter_update.txt b/test_sets/rc_radio_parameter_update.txt new file mode 100644 index 0000000000..94cfc7314d --- /dev/null +++ b/test_sets/rc_radio_parameter_update.txt @@ -0,0 +1,12 @@ +./test_scripts/RC/CLIMATE_RADIO/GetSystemCapability/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/016_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_false.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/017_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_omitted.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/018_Success_flow_band_setting.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/019_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_false.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/020_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_omitted.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/021_INVALID_DATA_in_case_invalid_data_in_hdRadioEnable.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/022_availableHDs_hdChannel_upper_bound.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/023_availableHDs_hdChannel_out_of_upper_bound.lua diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index 84ad02b7e8..aa97eefd25 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -365,7 +365,9 @@ function module.getDefaultHMITable() stateAvailable = true, signalStrengthAvailable = true, signalChangeThresholdAvailable = true, - sisDataAvailable = true + sisDataAvailable = true, + hdRadioEnableAvailable = true, + siriusxmRadioAvailable = true } }, audioControlCapabilities = { @@ -375,7 +377,9 @@ function module.getDefaultHMITable() keepContextAvailable = true, volumeAvailable = true, equalizerAvailable = true, - equalizerMaxChannelId = 100 + equalizerMaxChannelId = 100, + hdRadioEnableAvailable = true, + siriusxmRadioAvailable = true } }, seatControlCapabilities = { @@ -397,7 +401,7 @@ function module.getDefaultHMITable() massageCushionFirmnessAvailable = true, memoryAvailable = true } - }, + }, hmiSettingsControlCapabilities = { moduleName = "HmiSettings", distanceUnitAvailable = true, From facff74c51af222e64faaa95a279b46c98220e46 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 17 Aug 2018 12:06:59 +0300 Subject: [PATCH 597/681] Remove redundant capabilities from audioControlCapabilities --- user_modules/hmi_values.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index aa97eefd25..26b454421c 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -377,9 +377,7 @@ function module.getDefaultHMITable() keepContextAvailable = true, volumeAvailable = true, equalizerAvailable = true, - equalizerMaxChannelId = 100, - hdRadioEnableAvailable = true, - siriusxmRadioAvailable = true + equalizerMaxChannelId = 100 } }, seatControlCapabilities = { From fba272e2291989bd034a7da5b65a08a21d159291 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Mon, 20 Aug 2018 13:45:58 +0300 Subject: [PATCH 598/681] Update RADIO_TUNER to AM in common for OnRCStatus --- test_scripts/RC/OnRCStatus/commonOnRCStatus.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua index c11690c73e..80826e10d5 100644 --- a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua +++ b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua @@ -109,7 +109,7 @@ function commonRC.getModuleControlData(module_type) elseif module_type == "AUDIO" then out.moduleType = "AUDIO" out.audioControlData = { - source = "RADIO_TUNER", + source = "AM", volume = 50 } elseif module_type == "LIGHT" then From 27803ebcdf4fc157d7281d4226e3d4285304fc86 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 11 Jul 2018 15:42:33 +0300 Subject: [PATCH 599/681] Initial scripts for InteriorVD cache --- .../000_cache_2_apps_sequence.lua | 96 +++++ .../001_GetInteriorVD_without_subscribe.lua | 36 ++ ...nteriorVD_without_subscribe_2_requests.lua | 39 +++ ...GetInteriorVD_without_subscribe_2_apps.lua | 41 +++ .../004_GetInteriorVD_subscribe_true.lua | 36 ++ ...etInteriorVD_subscribe_true_2_requests.lua | 39 +++ ...ribe_true_and_without_subscribe_2_apps.lua | 41 +++ ...07_GetInteriorVD_subscribe_true_2_apps.lua | 41 +++ ...ubscribe_true_2_apps_different_modules.lua | 43 +++ ...out_subscribe_2_apps_different_modules.lua | 43 +++ ...orVD_subscribe_true_2_apps_same_module.lua | 44 +++ .../011_OnInteriorVD_without_subscription.lua | 39 +++ .../012_OnInteriorVD_app_unsubscribed.lua | 42 +++ ...ithout_subscription_after_OnInteriorVD.lua | 42 +++ ...D_with_subscription_after_OnInteriorVD.lua | 43 +++ ...subscription_after_OnInteriorVD_2_apps.lua | 45 +++ ...D_2_apps_subscribed_and_not_subscribed.lua | 59 ++++ ...bscribe_true_after_OnInteriorVD_2_apps.lua | 45 +++ .../018_GetInteriorVD_subscribe_false.lua | 39 +++ ...9_GetInteriorVD_subscribe_false_2_apps.lua | 48 +++ ...bscribe_false_different_modules_2_apps.lua | 42 +++ ..._subscribe_false_by_app_unregistration.lua | 38 ++ ...y_app_unregistration_different_modules.lua | 46 +++ ...alse_by_app_unregistration_same_module.lua | 45 +++ .../024_GetInteriorVD_limitation.lua | 38 ++ .../025_GetInteriorVD_limitation_rejected.lua | 40 +++ ..._limitation_rejected_different_modules.lua | 44 +++ ...tion_rejected_different_modules_2_apps.lua | 46 +++ ...teriorVD_limitation_after_subscription.lua | 41 +++ ...imitation_rejected_after_unsubscribing.lua | 49 +++ .../030_GetInteriorVD_limitation_2_apps.lua | 49 +++ .../031_GetInteriorVD_resubscribe_2_apps.lua | 47 +++ .../032_OnInteriorVD_2_apps_subscribed.lua | 61 ++++ ..._false_by_app_unregistration_2_modules.lua | 78 +++++ ...ibe_false_by_app_unexpected_disconnect.lua | 45 +++ ...D_subscribe_false_by_app_disallowed_RC.lua | 66 ++++ ...rVD_subscribe_false_by_revoking_module.lua | 54 +++ ...D_subscribe_false_without_subscribtion.lua | 73 ++++ .../038_OnInteriorVD_one_parameter.lua | 48 +++ .../common_interiorVDcache.lua | 331 ++++++++++++++++++ .../interior_vehicle_data_management.txt | 39 +++ 41 files changed, 2221 insertions(+) create mode 100644 test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/001_GetInteriorVD_without_subscribe.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/002_GetInteriorVD_without_subscribe_2_requests.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/003_GetInteriorVD_without_subscribe_2_apps.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/004_GetInteriorVD_subscribe_true.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/005_GetInteriorVD_subscribe_true_2_requests.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/006_GetInteriorVD_subscribe_true_and_without_subscribe_2_apps.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/007_GetInteriorVD_subscribe_true_2_apps.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/008_GetInteriorVD_subscribe_true_2_apps_different_modules.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/009_GetInteriorVD_without_subscribe_2_apps_different_modules.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/010_GetInteriorVD_subscribe_true_2_apps_same_module.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/011_OnInteriorVD_without_subscription.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/012_OnInteriorVD_app_unsubscribed.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/013_GetInteriorVD_without_subscription_after_OnInteriorVD.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/014_GetInteriorVD_with_subscription_after_OnInteriorVD.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/015_GetInteriorVD_with_subscription_after_OnInteriorVD_2_apps.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/016_OnInteriorVD_2_apps_subscribed_and_not_subscribed.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/017_GetInteriorVD_subscribe_true_after_OnInteriorVD_2_apps.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/018_GetInteriorVD_subscribe_false.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/019_GetInteriorVD_subscribe_false_2_apps.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/021_GetInteriorVD_subscribe_false_by_app_unregistration.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/022_GetInteriorVD_subscribe_false_by_app_unregistration_different_modules.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/023_GetInteriorVD_subscribe_false_by_app_unregistration_same_module.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/024_GetInteriorVD_limitation.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/025_GetInteriorVD_limitation_rejected.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/026_GetInteriorVD_limitation_rejected_different_modules.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/027_GetInteriorVD_limitation_rejected_different_modules_2_apps.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/028_GetInteriorVD_limitation_after_subscription.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/029_GetInteriorVD_limitation_rejected_after_unsubscribing.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/030_GetInteriorVD_limitation_2_apps.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/031_GetInteriorVD_resubscribe_2_apps.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/032_OnInteriorVD_2_apps_subscribed.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/033_GetInteriorVD_subscribe_false_by_app_unregistration_2_modules.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/034_GetInteriorVD_subscribe_false_by_app_unexpected_disconnect.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/035_GetInteriorVD_subscribe_false_by_app_disallowed_RC.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/036_GetInteriorVD_subscribe_false_by_revoking_module.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/037_GetInteriorVD_subscribe_false_without_subscribtion.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua create mode 100644 test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache.lua create mode 100644 test_sets/interior_vehicle_data_management.txt diff --git a/test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua b/test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua new file mode 100644 index 0000000000..7dcc88043f --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua @@ -0,0 +1,96 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- 1. App1 sends GetInteriorVD(module_1) without subscribe parameter +-- 2. App2 sends GetInteriorVD(module_1) without subscribe parameter +-- 3. App1 sends GetInteriorVD(module_1) with subscribe=true +-- 4. HMI sends OnInteriorVD(data for module_1) +-- 5. App1 sends GetInteriorVD(module_1) with subscribe=true +-- 6. App1 sends GetInteriorVD(module_1) without subscribe parameter +-- 7. App2 sends GetInteriorVD(module_1) with subscribe=true +-- 8. App2 sends GetInteriorVD(module_1) without subscribe parameter +-- 9. HMI sends OnInteriorVD(data for module_1) +-- 10. App1 sends GetInteriorVD(module_1) with subscribe=false +-- 11. App2 sends GetInteriorVD(module_1) with subscribe=false +-- SDL must +-- 1. send GetInteriorVD(module_1, without subscribe parameter, without appId) request to HMI by processing request from app1 +-- 2. send GetInteriorVD(module_1, without subscribe parameter, without appId) request to HMI by processing request from app2 +-- 3. send GetInteriorVD(module_1, subscribe=true, without appId) request to HMI by processing request from app1 +-- 4. update data for module_1 in cache and send OnInteriorVD notification to mobile app1 +-- 5. not send GetInteriorVD(module_1, subscribe=true, without appId) request to HMI by processing request from app1 +-- 6. not send GetInteriorVD(module_1, without subscribe parameter, without appId) request to HMI by processing request from app1 +-- 7. not send GetInteriorVD(module_1, subscribe=true, without appId) request to HMI by processing request from app2 +-- 8. not send GetInteriorVD(module_1, without subscribe parameter, without appId) request to HMI by processing request from app2 +-- 9. update data for module_1 in cache and send OnInteriorVD notification to mobile app1 and mobile app2 +-- 10. not send GetInteriorVD(module_1, subscribe=false, without appId) request to HMI by processing request from app1 +-- 11. send GetInteriorVD(module_1, subscribe=true, without appId) request to HMI by processing request from app2 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Function ]] +local function OnInteriorVDUpdatedData2Apps(pModuleType) + local params = common.cloneTable(common.actualInteriorDataStateOnHMI[pModuleType]) + for key, value in pairs(params) do + if type(value) == "boolean" then + if value == true then + params[key] = false + else + params[key] = true + end + end + end + common.OnInteriorVD(pModuleType, true, 1, params) + common.getMobileSession(2):ExpectNotification("OnInteriorVehicleData", + common.getResponseParams("OnInteriorVehicleData", pModuleType, params)) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + -- Block 'Get' from diagram + runner.Step("App1 GetInteriorVehicleData " .. mod, common.GetInteriorVehicleData, { mod, nil, true, 1 }) + runner.Step("App2 GetInteriorVehicleData " .. mod, common.GetInteriorVehicleData, { mod, nil, true, 2 }) + -- Block 'Subscribe app1' from diagram + runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, true, 1 }) + runner.Step("App1 OnInteriorVehicleData for " .. mod, common.OnInteriorVD, + { mod, true, 1 }) + runner.Step("App1 GetInteriorVehicleData with subscribe=true without request to HMI " .. mod, common.GetInteriorVehicleData, + { mod, true, false, 1 }) + runner.Step("App1 GetInteriorVehicleData without request to HMI " .. mod, common.GetInteriorVehicleData, + { mod, nil, false, 1 }) + -- Block 'Subscribe app2' from diagram + runner.Step("App2 GetInteriorVehicleData with subscribe=true without request to HMI" .. mod, common.GetInteriorVehicleData, + { mod, true, false, 2 }) + runner.Step("App2 GetInteriorVehicleData without request to HMI " .. mod, common.GetInteriorVehicleData, + { mod, nil, false, 2 }) + runner.Step("App1 and App2 OnInteriorVehicleData for " .. mod, OnInteriorVDUpdatedData2Apps, + { mod }) + -- Block 'Un-Subscribe' from diagram + runner.Step("App1 GetInteriorVehicleData with subscribe=false without request to HMI " .. mod, common.GetInteriorVehicleData, + { mod, false, false, 1 }) + runner.Step("App2 GetInteriorVehicleData with subscribe=false " .. mod, common.GetInteriorVehicleData, + { mod, false, true, 2 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/001_GetInteriorVD_without_subscribe.lua b/test_scripts/RC/InteriorVehicleData_cache/001_GetInteriorVD_without_subscribe.lua new file mode 100644 index 0000000000..632315d885 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/001_GetInteriorVD_without_subscribe.lua @@ -0,0 +1,36 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app sends GetInteriorVD(module_1, without subscribe parameter) request +-- SDL must +-- 1. send GetInteriorVD(module_1, without subscribe parameter, without appId) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app", common.activateApp, { 1 }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData without subscribe parameter " .. mod, common.GetInteriorVehicleData, + { mod, nil, true, 1 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/002_GetInteriorVD_without_subscribe_2_requests.lua b/test_scripts/RC/InteriorVehicleData_cache/002_GetInteriorVD_without_subscribe_2_requests.lua new file mode 100644 index 0000000000..9497511818 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/002_GetInteriorVD_without_subscribe_2_requests.lua @@ -0,0 +1,39 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app requested GetInteriorVD(module_1, without subscribe parameter) and HMI sent GetInteriorVD to HMI +-- 2. Mobile app GetInteriorVD(module_1, without subscribe parameter) request +-- SDL must +-- 1. send GetInteriorVD(module_1, without subscribe parameter) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app", common.activateApp, { 1 }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData without subscribe parameter " .. mod, common.GetInteriorVehicleData, + { mod, nil, true, 1 }) + runner.Step("GetInteriorVehicleData without subscribe parameter second request " .. mod, common.GetInteriorVehicleData, + { mod, nil, true, 1 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/003_GetInteriorVD_without_subscribe_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/003_GetInteriorVD_without_subscribe_2_apps.lua new file mode 100644 index 0000000000..9353ed5922 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/003_GetInteriorVD_without_subscribe_2_apps.lua @@ -0,0 +1,41 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app1 requested GetInteriorVD(module_1, without subscribe parameter) and HMI sent GetInteriorVD to HMI +-- 2. Mobile app2 GetInteriorVD(module_1, without subscribe parameter) request +-- SDL must +-- 1. send GetInteriorVD(module_1, without subscribe parameter) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("App1 GetInteriorVehicleData without subscribe parameter " .. mod, common.GetInteriorVehicleData, + { mod, nil, true, 1 }) + runner.Step("App2 GetInteriorVehicleData without subscribe parameter " .. mod, common.GetInteriorVehicleData, + { mod, nil, true, 2 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/004_GetInteriorVD_subscribe_true.lua b/test_scripts/RC/InteriorVehicleData_cache/004_GetInteriorVD_subscribe_true.lua new file mode 100644 index 0000000000..5bf06e90a9 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/004_GetInteriorVD_subscribe_true.lua @@ -0,0 +1,36 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app sends GetInteriorVD(module_1, subscribe = true) request +-- SDL must +-- 1. send GetInteriorVD(module_1, subscribe = true) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app", common.activateApp, { 1 }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, true, 1 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/005_GetInteriorVD_subscribe_true_2_requests.lua b/test_scripts/RC/InteriorVehicleData_cache/005_GetInteriorVD_subscribe_true_2_requests.lua new file mode 100644 index 0000000000..9e744b3e3e --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/005_GetInteriorVD_subscribe_true_2_requests.lua @@ -0,0 +1,39 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app is subscribed to module_1 +-- 2. Mobile app sends GetInteriorVD(subscribe = true) request +-- SDL must +-- 1. not send GetInteriorVD(subscribe = true) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app", common.activateApp, { 1 }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, true, 1 }) + runner.Step("GetInteriorVehicleData with subscribe=true second request " .. mod, common.GetInteriorVehicleData, + { mod, true, false, 1 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/006_GetInteriorVD_subscribe_true_and_without_subscribe_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/006_GetInteriorVD_subscribe_true_and_without_subscribe_2_apps.lua new file mode 100644 index 0000000000..9b36886514 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/006_GetInteriorVD_subscribe_true_and_without_subscribe_2_apps.lua @@ -0,0 +1,41 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app1 is subscribed to module_1 +-- 2. Mobile app2 sends GetInteriorVD( without subscribe parameter ) request +-- SDL must +-- 1. not send GetInteriorVD(without subscribe parameter) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, true, 1 }) + runner.Step("App2 GetInteriorVehicleData without subscribe " .. mod, common.GetInteriorVehicleData, + { mod, nil, false, 2 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/007_GetInteriorVD_subscribe_true_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/007_GetInteriorVD_subscribe_true_2_apps.lua new file mode 100644 index 0000000000..1bb9368630 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/007_GetInteriorVD_subscribe_true_2_apps.lua @@ -0,0 +1,41 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app1 is subscribed to module_1 +-- 2. Mobile app2 sends GetInteriorVD(module_1, subscribe = true) request +-- SDL must +-- 1. not send GetInteriorVD(module_1, subscribe = true) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, true, 1 }) + runner.Step("App2 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, false, 2 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/008_GetInteriorVD_subscribe_true_2_apps_different_modules.lua b/test_scripts/RC/InteriorVehicleData_cache/008_GetInteriorVD_subscribe_true_2_apps_different_modules.lua new file mode 100644 index 0000000000..1f663b1f29 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/008_GetInteriorVD_subscribe_true_2_apps_different_modules.lua @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app1 is subscribed to module_1 +-- 2. Mobile app2 sends GetInteriorVD(module_2, subscribe = true) request +-- SDL must +-- 1. send GetInteriorVD(module_2, subscribe = true) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. common.modules[1], common.GetInteriorVehicleData, + { common.modules[1], true, true, 1 }) +runner.Step("App2 GetInteriorVehicleData with subscribe=true " .. common.modules[2], common.GetInteriorVehicleData, + { common.modules[2], true, true, 2 }) +runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. common.modules[2], common.GetInteriorVehicleData, + { common.modules[2], true, false, 1 }) +runner.Step("App2 GetInteriorVehicleData with subscribe=true " .. common.modules[1], common.GetInteriorVehicleData, + { common.modules[1], true, false, 2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/009_GetInteriorVD_without_subscribe_2_apps_different_modules.lua b/test_scripts/RC/InteriorVehicleData_cache/009_GetInteriorVD_without_subscribe_2_apps_different_modules.lua new file mode 100644 index 0000000000..06c315656c --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/009_GetInteriorVD_without_subscribe_2_apps_different_modules.lua @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app is subscribed to module_1 +-- 2. Mobile app2 sends GetInteriorVD(module_2, subscribe = true) request +-- SDL must +-- 1. send GetInteriorVD(module_2, subscribe = true) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. common.modules[1], common.GetInteriorVehicleData, + { common.modules[1], true, true, 1 }) +runner.Step("App2 GetInteriorVehicleData without subscribe " .. common.modules[2], common.GetInteriorVehicleData, + { common.modules[2], nil, true, 2 }) +runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. common.modules[2], common.GetInteriorVehicleData, + { common.modules[2], true, true, 1 }) +runner.Step("App2 GetInteriorVehicleData without subscribe " .. common.modules[1], common.GetInteriorVehicleData, + { common.modules[1], nil, false, 2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/010_GetInteriorVD_subscribe_true_2_apps_same_module.lua b/test_scripts/RC/InteriorVehicleData_cache/010_GetInteriorVD_subscribe_true_2_apps_same_module.lua new file mode 100644 index 0000000000..0d48025cac --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/010_GetInteriorVD_subscribe_true_2_apps_same_module.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app1 is subscribed to module_1 +-- 2. Mobile app2 is subscribed to module_1 +-- 3. Mobile app2 sends GetInteriorVD(module_1, subscribe = true) request +-- SDL must +-- 1. not send GetInteriorVD request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, true, 1 }) + runner.Step("App2 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, false, 2 }) + runner.Step("App2 GetInteriorVehicleData with subscribe=true second request " .. mod, common.GetInteriorVehicleData, + { mod, true, false, 2 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/011_OnInteriorVD_without_subscription.lua b/test_scripts/RC/InteriorVehicleData_cache/011_OnInteriorVD_without_subscription.lua new file mode 100644 index 0000000000..69e3dd4669 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/011_OnInteriorVD_without_subscription.lua @@ -0,0 +1,39 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app is not subscribed to module_1 +-- 2. HMI sends OnInteriorVD with params changing for module_1 +-- SDL must +-- 1. not sends OnInteriorVD to mobile app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app", common.activateApp, { 1 }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("OnInteriorVehicleData for " .. mod, common.OnInteriorVD, + { mod, false, 1 }) + runner.Step("GetInteriorVehicleData without subscribe parameter " .. mod, common.GetInteriorVehicleData, + { mod, nil, true, 1 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/012_OnInteriorVD_app_unsubscribed.lua b/test_scripts/RC/InteriorVehicleData_cache/012_OnInteriorVD_app_unsubscribed.lua new file mode 100644 index 0000000000..fc1d36a3eb --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/012_OnInteriorVD_app_unsubscribed.lua @@ -0,0 +1,42 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app is unsubscribed from module_1 +-- 2. HMI sends OnInteriorVD with params changing for module_1 +-- SDL must not sends OnInteriorVD to mobile app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app", common.activateApp, { 1 }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, true, 1 }) + runner.Step("GetInteriorVehicleData with subscribe=false " .. mod, common.GetInteriorVehicleData, + { mod, false, true, 1 }) + runner.Step("OnInteriorVehicleData for " .. mod, common.OnInteriorVD, + { mod, false, 1 }) + runner.Step("GetInteriorVehicleData without subscribe parameter " .. mod, common.GetInteriorVehicleData, + { mod, nil, true, 1 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/013_GetInteriorVD_without_subscription_after_OnInteriorVD.lua b/test_scripts/RC/InteriorVehicleData_cache/013_GetInteriorVD_without_subscription_after_OnInteriorVD.lua new file mode 100644 index 0000000000..f53223024c --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/013_GetInteriorVD_without_subscription_after_OnInteriorVD.lua @@ -0,0 +1,42 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. mobile app requested GetInteriorVD(module_1, without subscribe parameter) +-- 2. HMI sends OnInteriorVD with params changing for module_1 +-- 3. mobile app sends GetInteriorVD(module_1, without subscribe parameter) request +-- SDL must +-- 1. send GetInteriorVD(module_1,subscribe = true) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app", common.activateApp, { 1 }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData without subscribe " .. mod, common.GetInteriorVehicleData, + { mod, nil, true, 1 }) + runner.Step("OnInteriorVehicleData for " .. mod, common.OnInteriorVD, + { mod, false, 1 }) + runner.Step("GetInteriorVehicleData without subscribe second request" .. mod, common.GetInteriorVehicleData, + { mod, nil, true, 1 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/014_GetInteriorVD_with_subscription_after_OnInteriorVD.lua b/test_scripts/RC/InteriorVehicleData_cache/014_GetInteriorVD_with_subscription_after_OnInteriorVD.lua new file mode 100644 index 0000000000..e4b74c8361 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/014_GetInteriorVD_with_subscription_after_OnInteriorVD.lua @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app is subscribed to module_1 +-- 2. HMI sends OnInteriorVD with params changing for module_1 +-- 3. Mobile app sends GetInteriorVD(module_1, without subscribe parameter) request +-- SDL must +-- 1. not send GetInteriorVD request to HMI +-- 2. send GetinteriorVD response to mobile app with actual data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app", common.activateApp, { 1 }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, true, 1 }) + runner.Step("OnInteriorVehicleData for " .. mod, common.OnInteriorVD, + { mod, true, 1 }) + runner.Step("GetInteriorVehicleData without subscribe " .. mod, common.GetInteriorVehicleData, + { mod, nil, false, 1 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/015_GetInteriorVD_with_subscription_after_OnInteriorVD_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/015_GetInteriorVD_with_subscription_after_OnInteriorVD_2_apps.lua new file mode 100644 index 0000000000..94d9202558 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/015_GetInteriorVD_with_subscription_after_OnInteriorVD_2_apps.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app1 is subscribed to module_1 +-- 2. HMI sends OnInteriorVD with params changing for module_1 +-- 3. Mobile app2 sends GetInteriorVD(module_1, without subscribe parameter) request +-- SDL must +-- 1. not send GetInteriorVD request to HMI +-- 2. send GetinteriorVD response to mobile app2 with actual data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, true, 1 }) + runner.Step("App1 OnInteriorVehicleData for " .. mod, common.OnInteriorVD, + { mod, true, 1 }) + runner.Step("App2 GetInteriorVehicleData without subscribe " .. mod, common.GetInteriorVehicleData, + { mod, nil, false, 2 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/016_OnInteriorVD_2_apps_subscribed_and_not_subscribed.lua b/test_scripts/RC/InteriorVehicleData_cache/016_OnInteriorVD_2_apps_subscribed_and_not_subscribed.lua new file mode 100644 index 0000000000..2597050015 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/016_OnInteriorVD_2_apps_subscribed_and_not_subscribed.lua @@ -0,0 +1,59 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app1 is subscribed to module_1 +-- 2. Mobile app2 is not subscribed to modules +-- 3. HMI sends OnInteriorVD with params changing for module_1 +-- SDL must +-- 1. send OnInteriorVD to mobile app1 +-- 2. not send OnInteriorVD to mobile app2 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Funstions ]] +local function OnInteriorVDUpdatedData2Apps(pModuleType) + local params = common.cloneTable(common.actualInteriorDataStateOnHMI[pModuleType]) + for key, value in pairs(params) do + if type(value) == "boolean" then + if value == true then + params[key] = false + else + params[key] = true + end + end + end + common.OnInteriorVD(pModuleType, true, 1, params) + common.getMobileSession(2):ExpectNotification("OnInteriorVehicleData") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, true, 1 }) + runner.Step("App1 OnInteriorVehicleData for " .. mod, OnInteriorVDUpdatedData2Apps, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/017_GetInteriorVD_subscribe_true_after_OnInteriorVD_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/017_GetInteriorVD_subscribe_true_after_OnInteriorVD_2_apps.lua new file mode 100644 index 0000000000..a2ae2651fd --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/017_GetInteriorVD_subscribe_true_after_OnInteriorVD_2_apps.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app is subscribed to module_1 +-- 2. HMI sends OnInteriorVD with params changing for module_1 +-- 3. Mobile app2 sends GetInteriorVD(module_1, subscribe = true) request +-- SDL must +-- 1. not send GetInteriorVD request to HMI +-- 2. send GetinteriorVD response to mobile app with actual data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, true, 1 }) + runner.Step("App1 OnInteriorVehicleData for " .. mod, common.OnInteriorVD, + { mod, true, 1 }) + runner.Step("App2 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, false, 2 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/018_GetInteriorVD_subscribe_false.lua b/test_scripts/RC/InteriorVehicleData_cache/018_GetInteriorVD_subscribe_false.lua new file mode 100644 index 0000000000..9c5bebe534 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/018_GetInteriorVD_subscribe_false.lua @@ -0,0 +1,39 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app is subscribed to module_1 +-- 2. Mobile app sends GetInteriorVD(module_1, subscribe = false) request +-- SDL must +-- 1. send GetInteriorVD(module_1, subscribe = false) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app", common.activateApp, { 1 }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, true, 1 }) + runner.Step("GetInteriorVehicleData with subscribe=false " .. mod, common.GetInteriorVehicleData, + { mod, false, true, 1 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/019_GetInteriorVD_subscribe_false_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/019_GetInteriorVD_subscribe_false_2_apps.lua new file mode 100644 index 0000000000..555623b7a0 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/019_GetInteriorVD_subscribe_false_2_apps.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app1 is subscribed to module_1 +-- 2. Mobile app2 is subscribed to module_1 +-- 3. Mobile app1 sends GetInteriorVD(module_1, subscribe = false) request +-- 4. Mobile app2 sends GetInteriorVD(module_1, subscribe = false) request +-- SDL must +-- 1. not send GetInteriorVD(module_1, subscribe = false) request to HMI by processing requst from app1 +-- 2. send GetInteriorVD(module_1, subscribe = false) request to HMI by processing requst from app2 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, true, 1 }) + runner.Step("App2 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, false, 2 }) + runner.Step("App1 GetInteriorVehicleData with subscribe=false " .. mod, common.GetInteriorVehicleData, + { mod, false, false, 1 }) + runner.Step("App2 GetInteriorVehicleData with subscribe=false " .. mod, common.GetInteriorVehicleData, + { mod, false, true, 2 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua new file mode 100644 index 0000000000..702d53566f --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua @@ -0,0 +1,42 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app1 is subscribed to module_1 +-- 2. Mobile app2 is subscribed to module_2 +-- 3. Mobile app1 sends GetInteriorVD(module_1, subscribe = false) request +-- SDL must +-- 1. send GetInteriorVD(module_1, subscribe = false) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. common.modules[1], common.GetInteriorVehicleData, + { common.modules[1], true, true, 1 }) +runner.Step("App2 GetInteriorVehicleData with subscribe=true " .. common.modules[2], common.GetInteriorVehicleData, + { common.modules[2], true, true, 2 }) +runner.Step("App1 GetInteriorVehicleData with subscribe=false " .. common.modules[1], common.GetInteriorVehicleData, + { common.modules[1], false, true, 1 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/021_GetInteriorVD_subscribe_false_by_app_unregistration.lua b/test_scripts/RC/InteriorVehicleData_cache/021_GetInteriorVD_subscribe_false_by_app_unregistration.lua new file mode 100644 index 0000000000..c9994b01e1 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/021_GetInteriorVD_subscribe_false_by_app_unregistration.lua @@ -0,0 +1,38 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app is subscribed to module_1 +-- 2. Mobile app unregisters +-- SDL must +-- 1. send GetInteriorVD(module_1, subscribe = false) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app", common.activateApp, { 1 }) + +runner.Title("Test") + +runner.Step("GetInteriorVehicleData with subscribe=true " .. common.modules[1], common.GetInteriorVehicleData, + { common.modules[1], true, true, 1 }) +runner.Step("RC.GetInteriorVehicleData with subscribe=false by app unregistration " .. common.modules[1], + common.unregistrationApp, { 1, true, common.modules[1] }) + + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/022_GetInteriorVD_subscribe_false_by_app_unregistration_different_modules.lua b/test_scripts/RC/InteriorVehicleData_cache/022_GetInteriorVD_subscribe_false_by_app_unregistration_different_modules.lua new file mode 100644 index 0000000000..ce8c1ca147 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/022_GetInteriorVD_subscribe_false_by_app_unregistration_different_modules.lua @@ -0,0 +1,46 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app1 is subscribed to module_1 +-- 2. Mobile app2 is subscribed to module_2 +-- 3. Mobile app1 unregisters +-- 4. HMI sends OnInteriorVD for module_2 +-- SDL must +-- 1. send GetInteriorVD(module_1, subscribe = false) request to HMI +-- 2. SDL sends OnInteriorVD to mobile app2 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. common.modules[1], common.GetInteriorVehicleData, + { common.modules[1], true, true, 1 }) +runner.Step("App2 GetInteriorVehicleData with subscribe=true " .. common.modules[2], common.GetInteriorVehicleData, + { common.modules[2], true, true, 2 }) +runner.Step("RC.GetInteriorVehicleData with subscribe=false by app1 unregistration " .. common.modules[1], + common.unregistrationApp, { 1, true, common.modules[1] }) +runner.Step("OnInteriorVehicleData for " .. common.modules[2], common.OnInteriorVD, + { common.modules[2], true, 2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/023_GetInteriorVD_subscribe_false_by_app_unregistration_same_module.lua b/test_scripts/RC/InteriorVehicleData_cache/023_GetInteriorVD_subscribe_false_by_app_unregistration_same_module.lua new file mode 100644 index 0000000000..8ae1583928 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/023_GetInteriorVD_subscribe_false_by_app_unregistration_same_module.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app is subscribed to module_1 +-- 2. Mobile app2 is subscribed to module_1 +-- 3. Mobile app1 is unregistered and SDL does not resend request to HMI +-- 4. Mobile app2 unregisters +-- SDL must +-- 1. send GetInteriorVD(module_1, subscribe = false) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. common.modules[1], common.GetInteriorVehicleData, + { common.modules[1], true, true, 1 }) +runner.Step("App2 GetInteriorVehicleData with subscribe=true " .. common.modules[1], common.GetInteriorVehicleData, + { common.modules[1], true, false, 2 }) +runner.Step("Absence RC.GetInteriorVehicleData with subscribe=false by app1 unregistration " .. common.modules[1], + common.unregistrationApp, { 1, false, common.modules[1] }) +runner.Step("RC.GetInteriorVehicleData with subscribe=false by app2 unregistration " .. common.modules[1], + common.unregistrationApp, { 2, true, common.modules[1] }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/024_GetInteriorVD_limitation.lua b/test_scripts/RC/InteriorVehicleData_cache/024_GetInteriorVD_limitation.lua new file mode 100644 index 0000000000..4cbaec3a92 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/024_GetInteriorVD_limitation.lua @@ -0,0 +1,38 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. In .ini file GetInteriorVehicleDataRequest = 5, 10 +-- 2. Mobile app sends 5 GetInteriorVD(module_1, without subscribe parameter) requests per 10 sec +-- SDL must +-- 1. process successful all requests and sends GetInteriorVD requests to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Update GetInteriorVehicleDataRequest=5,10", common.setGetInteriorVehicleDataRequestValue, {"5,10"}) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app", common.activateApp, { 1 }) + +runner.Title("Test") + +for i=1,5 do + runner.Step("GetInteriorVehicleData without subscribe parameter " .. i, common.GetInteriorVehicleData, + {"CLIMATE", nil, true, 1 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/025_GetInteriorVD_limitation_rejected.lua b/test_scripts/RC/InteriorVehicleData_cache/025_GetInteriorVD_limitation_rejected.lua new file mode 100644 index 0000000000..cf4d69d4fe --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/025_GetInteriorVD_limitation_rejected.lua @@ -0,0 +1,40 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. In .ini file GetInteriorVehicleDataRequest = 10,20 +-- 2. Mobile app sends 11 GetInteriorVD(module_1, without subscribe parameter) requests per 20 sec +-- SDL must +-- 1. reject 11th GetInteriorVD(module_1, without subscribe parameter) request with result code REJECTED +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Update GetInteriorVehicleDataRequest=10,20", common.setGetInteriorVehicleDataRequestValue, {"10,20"}) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app", common.activateApp, { 1 }) + +runner.Title("Test") + +for i=1,10 do + runner.Step("GetInteriorVehicleData without subscribe parameter " .. i, common.GetInteriorVehicleData, + {"CLIMATE", nil, true, 1 }) +end +runner.Step("GetInteriorVehicleData REJECTED", common.GetInteriorVehicleDataRejected, + {"CLIMATE", nil, 1 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/026_GetInteriorVD_limitation_rejected_different_modules.lua b/test_scripts/RC/InteriorVehicleData_cache/026_GetInteriorVD_limitation_rejected_different_modules.lua new file mode 100644 index 0000000000..18cbf5ff27 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/026_GetInteriorVD_limitation_rejected_different_modules.lua @@ -0,0 +1,44 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description:In case +-- In case +-- 1. In .ini file GetInteriorVehicleDataRequest = 10, 20 +-- 2. Mobile app sends 11 GetInteriorVD(module_1, without subscribe parameter) requests per 20 sec +-- 3. Mobile app sends GetInteriorVD(module_2, without subscribe parameter) request +-- SDL must +-- 1. reject 11th GetInteriorVD(module_1, without subscribe parameter) request with result code REJECTED +-- 2. Process successful GetInteriorVD(module_2, without subscribe parameter) request +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Update GetInteriorVehicleDataRequest=10,20", common.setGetInteriorVehicleDataRequestValue, {"10,20"}) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app1", common.activateApp, { 1 }) + +runner.Title("Test") + +for i=1,10 do + runner.Step("App1 GetInteriorVehicleData without subscribe parameter CLIMATE" .. i, common.GetInteriorVehicleData, + {"CLIMATE", nil, true, 1 }) +end +runner.Step("App1 GetInteriorVehicleData REJECTED CLIMATE", common.GetInteriorVehicleDataRejected, + {"CLIMATE", nil, 1 }) +runner.Step("App1 GetInteriorVehicleData without subscribe parameter RADIO", common.GetInteriorVehicleData, + { "RADIO", nil, true, 1 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/027_GetInteriorVD_limitation_rejected_different_modules_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/027_GetInteriorVD_limitation_rejected_different_modules_2_apps.lua new file mode 100644 index 0000000000..60da52e28f --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/027_GetInteriorVD_limitation_rejected_different_modules_2_apps.lua @@ -0,0 +1,46 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. In .ini file GetInteriorVehicleDataRequest = 10, 20 +-- 2. Mobile app sends 11 GetInteriorVD(module_1, without subscribe parameter) requests per 20 sec +-- 3. Mobile app2 sends GetInteriorVD(module_2, without subscribe parameter) request +-- SDL must +-- 1. reject 11th GetInteriorVD(module_1, without subscribe parameter) request with result code REJECTED +-- 2. Process successful GetInteriorVD(module_2, without subscribe parameter) request +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Update GetInteriorVehicleDataRequest=10,20", common.setGetInteriorVehicleDataRequestValue, {"10,20"}) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +for i=1,10 do + runner.Step("App1 GetInteriorVehicleData without subscribe parameter CLIMATE" .. i, common.GetInteriorVehicleData, + {"CLIMATE", nil, true, 1 }) +end +runner.Step("App1 GetInteriorVehicleData REJECTED CLIMATE", common.GetInteriorVehicleDataRejected, + {"CLIMATE", nil, 1 }) +runner.Step("App2 GetInteriorVehicleData without subscribe parameter RADIO", common.GetInteriorVehicleData, + { "RADIO", nil, true, 2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/028_GetInteriorVD_limitation_after_subscription.lua b/test_scripts/RC/InteriorVehicleData_cache/028_GetInteriorVD_limitation_after_subscription.lua new file mode 100644 index 0000000000..50e483700c --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/028_GetInteriorVD_limitation_after_subscription.lua @@ -0,0 +1,41 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. In .ini file GetInteriorVehicleDataRequest = 5, 10 +-- 2. App is subscribed to module_1 +-- 3. Mobile app sends 7 GetInteriorVD(module_1, without subscribe parameter) requests per 10 sec +-- SDL must +-- 1. process successful all requests and does not sends GetInteriorVD requests to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Update GetInteriorVehicleDataRequest=5,10", common.setGetInteriorVehicleDataRequestValue, {"5,10"}) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app", common.activateApp, { 1 }) +runner.Step("GetInteriorVehicleData with subscribe=true", common.GetInteriorVehicleData, + {"CLIMATE", true, true, 1 }) + +runner.Title("Test") + +for i=1,7 do + runner.Step("GetInteriorVehicleData without subscribe parameter " .. i, common.GetInteriorVehicleData, + {"CLIMATE", nil, false, 1 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/029_GetInteriorVD_limitation_rejected_after_unsubscribing.lua b/test_scripts/RC/InteriorVehicleData_cache/029_GetInteriorVD_limitation_rejected_after_unsubscribing.lua new file mode 100644 index 0000000000..6b7b15a241 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/029_GetInteriorVD_limitation_rejected_after_unsubscribing.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. In .ini file GetInteriorVehicleDataRequest = 10, 20 +-- 2. App is subscribed to module_1 (request 1) +-- 3. Mobile app sends GetInteriorVD(module_1, without subscribe parameter) +-- 4. App is unsubscribe from module_1(request 2) +-- 5. Mobile app sends 9 GetInteriorVD(module_1, without subscribe parameter) requests per 20 sec +-- SDL must +-- 1. reject 9th(request 11) GetInteriorVD(module_1, without subscribe parameter) request with result code REJECTED +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Update GetInteriorVehicleDataRequest=10,20", common.setGetInteriorVehicleDataRequestValue, {"10,20"}) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app", common.activateApp, { 1 }) +runner.Step("GetInteriorVehicleData with subscribe=true", common.GetInteriorVehicleData, + {"CLIMATE", true, true, 1 }) +runner.Step("GetInteriorVehicleData without subscribe", common.GetInteriorVehicleData, + {"CLIMATE", nil, false, 1 }) +runner.Step("GetInteriorVehicleData with subscribe=false", common.GetInteriorVehicleData, + {"CLIMATE", false, true, 1 }) + +runner.Title("Test") + +for i=1,8 do + runner.Step("GetInteriorVehicleData without subscribe parameter " .. i, common.GetInteriorVehicleData, + {"CLIMATE", nil, true, 1 }) +end +runner.Step("GetInteriorVehicleData REJECTED", common.GetInteriorVehicleDataRejected, + {"CLIMATE", nil, 1 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/030_GetInteriorVD_limitation_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/030_GetInteriorVD_limitation_2_apps.lua new file mode 100644 index 0000000000..fb84b35260 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/030_GetInteriorVD_limitation_2_apps.lua @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. In .ini file GetInteriorVehicleDataRequest = 10, 20 +-- 2. Mobile app1 sends 5 GetInteriorVD(module_1, without subscribe parameter) requests per 20 sec +-- 3. Mobile app2 sends 5 GetInteriorVD(module_1, without subscribe parameter) requests per 20 sec +-- 4. Mobile app1 sends 6th GetInteriorVD(module_1, without subscribe parameter) requests per 20 sec +-- 5. Mobile app2 sends 6th GetInteriorVD(module_1, without subscribe parameter) requests per 20 sec +-- SDL must +-- 1. reject 6th GetInteriorVD(module_1, without subscribe parameter) request with result code REJECTED from both apps +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Update GetInteriorVehicleDataRequest=10,20", common.setGetInteriorVehicleDataRequestValue, {"10,20"}) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +for i=1,5 do + runner.Step("App1 GetInteriorVehicleData without subscribe parameter CLIMATE" .. i, common.GetInteriorVehicleData, + {"CLIMATE", nil, true, 1 }) + runner.Step("App2 GetInteriorVehicleData without subscribe parameter CLIMATE" .. i, common.GetInteriorVehicleData, + {"CLIMATE", nil, true, 2 }) +end +runner.Step("App1 GetInteriorVehicleData REJECTED CLIMATE", common.GetInteriorVehicleDataRejected, + {"CLIMATE", nil, 1 }) +runner.Step("App2 GetInteriorVehicleData REJECTED CLIMATE", common.GetInteriorVehicleDataRejected, + {"CLIMATE", nil, 2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/031_GetInteriorVD_resubscribe_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/031_GetInteriorVD_resubscribe_2_apps.lua new file mode 100644 index 0000000000..79abca5bdf --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/031_GetInteriorVD_resubscribe_2_apps.lua @@ -0,0 +1,47 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. App1 is subscribed to module_1 +-- 2. App2 is subscribed to module_1 +-- 3. App1 is unsubsribed without GetInteriorVD request to HMI +-- 4. App1 sends GetInteriorVD(module_1, subscribe = true) request +-- SDL must +-- 1. not send GetInteriorVD(module_1, subscribe = true) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, true, 1 }) + runner.Step("App2 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, false, 2 }) + runner.Step("App1 GetInteriorVehicleData with subscribe=false " .. mod, common.GetInteriorVehicleData, + { mod, false, false, 1 }) + runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, false, 1 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/032_OnInteriorVD_2_apps_subscribed.lua b/test_scripts/RC/InteriorVehicleData_cache/032_OnInteriorVD_2_apps_subscribed.lua new file mode 100644 index 0000000000..06f0099292 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/032_OnInteriorVD_2_apps_subscribed.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app1 is subscribed to module_1 +-- 2. Mobile app2 is subscribed to module_1 +-- 3. HMI sends OnInteriorVD with params changing for module_1 +-- SDL must +-- 1. send OnInteriorVD to mobile app1 +-- 2. send OnInteriorVD to mobile app2 +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Funstions ]] +local function OnInteriorVDUpdatedData2Apps(pModuleType) + local params = common.cloneTable(common.actualInteriorDataStateOnHMI[pModuleType]) + for key, value in pairs(params) do + if type(value) == "boolean" then + if value == true then + params[key] = false + else + params[key] = true + end + end + end + common.OnInteriorVD(pModuleType, true, 1, params) + common.getMobileSession(2):ExpectNotification("OnInteriorVehicleData", + common.getResponseParams("OnInteriorVehicleData", pModuleType, params)) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, true, 1 }) + runner.Step("App2 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, false, 2 }) + runner.Step("App1 OnInteriorVehicleData for " .. mod, OnInteriorVDUpdatedData2Apps, { mod }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/033_GetInteriorVD_subscribe_false_by_app_unregistration_2_modules.lua b/test_scripts/RC/InteriorVehicleData_cache/033_GetInteriorVD_subscribe_false_by_app_unregistration_2_modules.lua new file mode 100644 index 0000000000..78066f3a48 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/033_GetInteriorVD_subscribe_false_by_app_unregistration_2_modules.lua @@ -0,0 +1,78 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app1 is subscribed to module_1 +-- 2. Mobile app1 is subscribed to module_2 +-- 3. Mobile app1 unregisters +-- SDL must +-- 1. send GetInteriorVD(module_1, subscribe = false) request to HMI +-- 2. send GetInteriorVD(module_2, subscribe = false) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') +local commonRC = require('test_scripts/RC/commonRC') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +-- [[ Local Function ]] +local function unregistrationApp() + local rpc = "GetInteriorVehicleData" + EXPECT_HMICALL(commonRC.getHMIEventName(rpc)) + :Do(function(_, data) + if data.params.moduleType == "CLIMATE" then + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", + common.getHMIResponseParams(rpc, "CLIMATE", false)) + else + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", + common.getHMIResponseParams(rpc, "RADIO", false)) + end + end) + :ValidIf(function(_, data) + local ExpectedResult + if data.params.moduleType == "CLIMATE" then + ExpectedResult = common.getHMIRequestParams(rpc, "CLIMATE", 1, false) + else + ExpectedResult = common.getHMIRequestParams(rpc, "RADIO", 1, false) + end + if false == commonFunctions:is_table_equal(data.params, ExpectedResult) then + return false, "Parameters in RC.GetInteriorVehicleData are not match to expected result.\n" .. + "Actual result:" .. common.tableToString(data.params) .. "\n" .. + "Expected result:" ..common.tableToString(ExpectedResult) .."\n" + end + return true + end) + :Times(2) + local mobSession = common.getMobileSession(1) + local hmiAppId = commonRC.getHMIAppId(1) + local cid = mobSession:SendRPC("UnregisterAppInterface",{}) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = hmiAppId, unexpectedDisconnect = false }) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app", common.activateApp, { 1 }) + +runner.Title("Test") + +runner.Step("GetInteriorVehicleData with subscribe=true " .. common.modules[1], common.GetInteriorVehicleData, + { common.modules[1], true, true, 1 }) +runner.Step("GetInteriorVehicleData with subscribe=true " .. common.modules[2], common.GetInteriorVehicleData, + { common.modules[2], true, true, 1 }) +runner.Step("RC.GetInteriorVehicleData with subscribe=false by app unregistration", unregistrationApp) + + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/034_GetInteriorVD_subscribe_false_by_app_unexpected_disconnect.lua b/test_scripts/RC/InteriorVehicleData_cache/034_GetInteriorVD_subscribe_false_by_app_unexpected_disconnect.lua new file mode 100644 index 0000000000..bcb5a70269 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/034_GetInteriorVD_subscribe_false_by_app_unexpected_disconnect.lua @@ -0,0 +1,45 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app1 is subscribed to module_1 +-- 2. Mobile app2 is subscribed to module_1 +-- 3. Mobile app1 is disconnects and SDL does not resend request to HMI +-- 4. Mobile app2 disconnects +-- SDL must +-- 1. send GetInteriorVD(module_1, subscribe = false) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. common.modules[1], common.GetInteriorVehicleData, + { common.modules[1], true, true, 1 }) +runner.Step("App2 GetInteriorVehicleData with subscribe=true " .. common.modules[1], common.GetInteriorVehicleData, + { common.modules[1], true, false, 2 }) +runner.Step("Absence RC.GetInteriorVehicleData with subscribe=false by app1 disconnect " .. common.modules[1], + common.unexpectedDisconnect, { 1, false, common.modules[1] }) +runner.Step("RC.GetInteriorVehicleData with subscribe=false by app2 disconnect " .. common.modules[1], + common.unexpectedDisconnect, { 2, true, common.modules[1] }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/035_GetInteriorVD_subscribe_false_by_app_disallowed_RC.lua b/test_scripts/RC/InteriorVehicleData_cache/035_GetInteriorVD_subscribe_false_by_app_disallowed_RC.lua new file mode 100644 index 0000000000..feeaddd94b --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/035_GetInteriorVD_subscribe_false_by_app_disallowed_RC.lua @@ -0,0 +1,66 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app1 is subscribed to module_1 +-- 2. Mobile app2 is subscribed to module_1 +-- 3. RC functionality is disabled on HMI +-- SDL must +-- 1. send GetInteriorVD(module_1, subscribe = false) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') +local commonRC = require('test_scripts/RC/commonRC') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local test = require("user_modules/dummy_connecttest") + + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +-- [[ Local Functions ]] +local function dissalowRCFunctionality() + local rpc = "GetInteriorVehicleData" + EXPECT_HMICALL(commonRC.getHMIEventName(rpc)) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", + common.getHMIResponseParams(rpc, common.modules[1], false)) + end) + :ValidIf(function(_, data) + local ExpectedResult = common.getHMIRequestParams(rpc, common.modules[1], 1, false) + if false == commonFunctions:is_table_equal(data.params, ExpectedResult) then + return false, "Parameters in RC.GetInteriorVehicleData are not match to expected result.\n" .. + "Actual result:" .. common.tableToString(data.params) .. "\n" .. + "Expected result:" ..common.tableToString(ExpectedResult) .."\n" + end + return true + end) + commonRC.defineRAMode(false, nil, test) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. common.modules[1], common.GetInteriorVehicleData, + { common.modules[1], true, true, 1 }) +runner.Step("App2 GetInteriorVehicleData with subscribe=true " .. common.modules[1], common.GetInteriorVehicleData, + { common.modules[1], true, false, 2 }) +runner.Step("RC.GetInteriorVehicleData with subscribe=false by disabling RC functionality " .. common.modules[1], + dissalowRCFunctionality) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/036_GetInteriorVD_subscribe_false_by_revoking_module.lua b/test_scripts/RC/InteriorVehicleData_cache/036_GetInteriorVD_subscribe_false_by_revoking_module.lua new file mode 100644 index 0000000000..cecc86a8e7 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/036_GetInteriorVD_subscribe_false_by_revoking_module.lua @@ -0,0 +1,54 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app is subscribed to module_1 +-- 2. Mobile app2 is subscribed to module_1 +-- 3. Module_1 is revoked during PTU +-- SDL must +-- 1. send GetInteriorVD(module_1, subscribe = false) request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function ptuFuncRPC(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { common.modules[2] } +end + +local function ptu() + local rpc = "GetInteriorVehicleData" + EXPECT_HMICALL(commonRC.getHMIEventName(rpc), common.getHMIRequestParams(rpc, common.modules[1], 1, false)) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", + common.getHMIResponseParams(rpc, common.modules[1], false)) + end) + common.policyTableUpdate(ptuFuncRPC) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app", common.registerApp, { 1 }) +runner.Step("Activate app", common.activateApp, { 1 }) + +runner.Title("Test") + +runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. common.modules[1], common.GetInteriorVehicleData, + { common.modules[1], true, true, 1 }) +runner.Step("Absence RC.GetInteriorVehicleData with subscribe=false by revoking module during PTU " .. common.modules[1], + ptu) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/037_GetInteriorVD_subscribe_false_without_subscribtion.lua b/test_scripts/RC/InteriorVehicleData_cache/037_GetInteriorVD_subscribe_false_without_subscribtion.lua new file mode 100644 index 0000000000..ed6e7dcae4 --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/037_GetInteriorVD_subscribe_false_without_subscribtion.lua @@ -0,0 +1,73 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app1 is not subscribed to module_1 +-- 2. Mobile app1 sends GetInteriorVD(module_1, subscribe = false) request +-- 3. Mobile app1 is subscribed to module_1 +-- 4. Mobile app2 sends GetInteriorVD(module_1, subscribe = false) request +-- SDL must +-- 1. send GetInteriorVD(module_1) request without subscribe parameter to HMI by processing GetInteriorVD(module_1, subscribe = false) from app1 +-- 2. respond GetInteriorVD(module_1, subscribe = false) to mobile app +-- 3. not send GetInteriorVD(module_1) request to HMI by processing GetInteriorVD(module_1, subscribe = false) from app2 +-- 4. respond GetInteriorVD(module_1, subscribe = false) to mobile app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') +local commonRC = require('test_scripts/RC/commonRC') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +-- [[ Local Functions]] +local function GetInteriorVehicleData(pModuleType, isSubscribe) + local rpc = "GetInteriorVehicleData" + local subscribe = isSubscribe + local mobSession = common.getMobileSession(1) + local cid = mobSession:SendRPC(commonRC.getAppEventName(rpc), + commonRC.getAppRequestParams(rpc, pModuleType, subscribe)) + local hmiRequestParams = common.getHMIRequestParams(rpc, pModuleType, 1, subscribe) + hmiRequestParams.subscribe = nil + EXPECT_HMICALL(commonRC.getHMIEventName(rpc), hmiRequestParams) + :Do(function(_, data) + local hmiResponseParams = common.getHMIResponseParams(rpc, pModuleType, subscribe) + hmiResponseParams.subscribe = nil + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", hmiResponseParams) + end) + :ValidIf(function(_, data) + if data.params.subscribe then + return false, "RC.GetInteriorVehicleData request contains unexpected 'subscribe' parameter" + end + return true + end) + mobSession:ExpectResponse(cid, common.getResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("App1 GetInteriorVehicleData with subscribe=false without subscription" .. mod, GetInteriorVehicleData, + { mod, false }) + runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, true, 1 }) + runner.Step("App2 GetInteriorVehicleData with subscribe=false in case cache is available" .. mod, common.GetInteriorVehicleData, + { mod, false, false, 2 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua b/test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua new file mode 100644 index 0000000000..db837f2b5b --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. Mobile app1 is subscribed to module_1 +-- 2. HMI sends OnInteriorVD with one param changing for module_1 +-- 3. Mobile app1 sends GetInteriorVD(module_1, without subscribe parameter) request +-- SDL must +-- 1. not send GetInteriorVD request to HMI +-- 2. send GetinteriorVD response to mobile app2 with actual data +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +local OnInteriorVDparams = { + CLIMATE = { fanSpeed = 30 }, + RADIO = { frequencyFraction = 3 } +} + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app1", common.activateApp, { 1 }) + +runner.Title("Test") + +for _, mod in pairs(common.modules) do + runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, + { mod, true, true, 1 }) + runner.Step("App1 OnInteriorVehicleData for " .. mod, common.OnInteriorVD, + { mod, true, 1, OnInteriorVDparams[mod] }) + runner.Step("App2 GetInteriorVehicleData without subscribe " .. mod, common.GetInteriorVehicleData, + { mod, nil, false, 1 }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache.lua b/test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache.lua new file mode 100644 index 0000000000..0c17b8e19c --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache.lua @@ -0,0 +1,331 @@ +--------------------------------------------------------------------------------------------------- +-- Common module +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") +local commonRC = require('test_scripts/RC/commonRC') +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local json = require("modules/json") +local utils = require("user_modules/utils") + +--[[ Module ]] +local m = actions +m.cloneTable = utils.cloneTable +m.jsonFileToTable = utils.jsonFileToTable +m.tableToJsonFile = utils.tableToJsonFile +m.wait = utils.wait +m.tableToString = utils.tableToString + +local preloadedPT = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") +m.preconditionOrigin = m.preconditions +local postconditionOrigin = m.postconditions + +config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } +config.application1.registerAppInterfaceParams.isMediaApplication = true +config.application2.registerAppInterfaceParams.isMediaApplication = false + +m.modules = { "CLIMATE", "RADIO" } + +m.actualInteriorDataStateOnHMI = { + CLIMATE = { + fanSpeed = 50, + currentTemperature = { + unit = "FAHRENHEIT", + value = 20.1 + }, + desiredTemperature = { + unit = "CELSIUS", + value = 10.5 + }, + acEnable = true, + circulateAirEnable = true, + autoModeEnable = true, + defrostZone = "FRONT", + dualModeEnable = true, + acMaxEnable = true, + ventilationMode = "BOTH" + }, + RADIO = { + frequencyInteger = 1, + frequencyFraction = 2, + band = "AM", + rdsData = { + PS = "ps", + RT = "rt", + CT = "123456789012345678901234", + PI = "pi", + PTY = 1, + TP = false, + TA = true, + REG = "US" + }, + availableHDs = 1, + hdChannel = 1, + signalStrength = 5, + signalChangeThreshold = 10, + radioEnable = true, + state = "ACQUIRING" + } +} + +function m.setActualInteriorVD(pModuleType, pParams) + for key, value in pairs(pParams) do + if type(value) ~= "table" then + if value ~= m.actualInteriorDataStateOnHMI[pModuleType][key] then + m.actualInteriorDataStateOnHMI[pModuleType][key] = value + end + else + if false == commonFunctions:is_table_equal(value, m.actualInteriorDataStateOnHMI[pModuleType][key]) then + m.actualInteriorDataStateOnHMI[pModuleType][key] = value + end + end + end +end + +function m.updatePreloadedPT() + local preloadedFile = commonPreconditions:GetPathToSDL() + .. commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + local preloadedTable = m.jsonFileToTable(preloadedFile) + preloadedTable.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + preloadedTable.policy_table.functional_groupings["RemoteControl"].rpcs.OnRCStatus = { + hmi_levels = { "FULL", "BACKGROUND", "LIMITED", "NONE" } + } + preloadedTable.policy_table.app_policies.default.moduleType = { "RADIO", "CLIMATE" } + preloadedTable.policy_table.app_policies.default.groups = { "Base-4", "RemoteControl" } + preloadedTable.policy_table.app_policies.default.AppHMIType = { "REMOTE_CONTROL" } + m.tableToJsonFile(preloadedTable, preloadedFile) +end + +function m.GetInteriorVehicleData(pModuleType, isSubscribe, isHMIreqExpect, pAppId) + if not pAppId then pAppId = 1 end + local rpc = "GetInteriorVehicleData" + local HMIrequestsNumber + if isHMIreqExpect == true then + HMIrequestsNumber = 1 + else + HMIrequestsNumber = 0 + end + local cid = m.getMobileSession(pAppId):SendRPC(commonRC.getAppEventName(rpc), + commonRC.getAppRequestParams(rpc, pModuleType, isSubscribe)) + EXPECT_HMICALL(commonRC.getHMIEventName(rpc), m.getHMIRequestParams(rpc, pModuleType, pAppId, isSubscribe)) + :Do(function(_, data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", + m.getHMIResponseParams(rpc, pModuleType, isSubscribe)) + end) + :Times(HMIrequestsNumber) + m.getMobileSession(pAppId):ExpectResponse(cid, m.getResponseParams(rpc, true, "SUCCESS", pModuleType, isSubscribe)) +end + +function m.GetInteriorVehicleDataRejected(pModuleType, isSubscribe, pAppId) + if not pAppId then pAppId = 1 end + local rpc = "GetInteriorVehicleData" + local subscribe = isSubscribe + local mobSession = m.getMobileSession(pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(rpc), + commonRC.getAppRequestParams(rpc, pModuleType, subscribe)) + EXPECT_HMICALL(commonRC.getHMIEventName(rpc)) + :Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED"}) +end + +function m.OnInteriorVD(pModuleType, isExpectNotification, pAppId, pParams) + local rpc = "OnInteriorVehicleData" + local mobSession = m.getMobileSession(pAppId) + if not pParams then pParams = m.getAnotherModuleControlData(pModuleType) end + local notificationCount + if isExpectNotification == true then + notificationCount = 1 + else + notificationCount = 0 + end + m.setActualInteriorVD(pModuleType, pParams) + m.getHMIConnection():SendNotification(commonRC.getHMIEventName(rpc), + m.getHMIResponseParams(rpc, pModuleType, pParams)) + mobSession:ExpectNotification(commonRC.getAppEventName(rpc), + m.getResponseParams(rpc, pModuleType, pParams)) + :Times(notificationCount) +end + +function m.getModuleControlData(module_type, pParams) + local out = { moduleType = module_type } + if module_type == "CLIMATE" then + out.climateControlData = pParams + elseif module_type == "RADIO" then + out.radioControlData = pParams + end + return out +end + + -- RC RPCs structure + local rcRPCs = { + GetInteriorVehicleData = { + appEventName = "GetInteriorVehicleData", + hmiEventName = "RC.GetInteriorVehicleData", + requestParams = function(pModuleType, pSubscribe) + return { + moduleType = pModuleType, + subscribe = pSubscribe + } + end, + hmiRequestParams = function(pModuleType, pAppId, pSubscribe) + return { + appID = commonRC.getHMIAppId(pAppId), + moduleType = pModuleType, + subscribe = pSubscribe + } + end, + hmiResponseParams = function(pModuleType, pSubscribe) + return { + moduleData = m.getModuleControlData(pModuleType, m.actualInteriorDataStateOnHMI[pModuleType]), + isSubscribed = pSubscribe + } + end, + responseParams = function(success, resultCode, pModuleType, pSubscribe) + return { + success = success, + resultCode = resultCode, + moduleData = m.getModuleControlData(pModuleType, m.actualInteriorDataStateOnHMI[pModuleType]), + isSubscribed = pSubscribe + } + end + }, + OnInteriorVehicleData = { + appEventName = "OnInteriorVehicleData", + hmiEventName = "RC.OnInteriorVehicleData", + hmiResponseParams = function(pModuleType, pParams) + return { + moduleData = m.getModuleControlData(pModuleType, pParams) + } + end, + responseParams = function(pModuleType, pParams) + return { + moduleData = m.getModuleControlData(pModuleType, pParams) + } + end + } +} + +function m.getHMIRequestParams(pRPC, ...) + return rcRPCs[pRPC].hmiRequestParams(...) +end + +function m.getHMIResponseParams(pRPC, ...) + return rcRPCs[pRPC].hmiResponseParams(...) +end + +function m.getResponseParams(pRPC, ...) + return rcRPCs[pRPC].responseParams(...) +end + +function m.getAnotherModuleControlData(module_type) + local out = {} + if module_type == "CLIMATE" then + out = { + fanSpeed = 65, + currentTemperature = { + unit = "FAHRENHEIT", + value = 44.3 + }, + desiredTemperature = { + unit = "CELSIUS", + value = 22.6 + }, + acEnable = false, + circulateAirEnable = false, + autoModeEnable = true, + defrostZone = "ALL", + dualModeEnable = true, + acMaxEnable = false, + ventilationMode = "UPPER" + } + elseif module_type == "RADIO" then + out = { + frequencyInteger = 1, + frequencyFraction = 2, + band = "AM", + rdsData = { + PS = "ps", + RT = "rt", + CT = "123456789012345678901234", + PI = "pi", + PTY = 2, + TP = false, + TA = true, + REG = "US" + }, + availableHDs = 1, + hdChannel = 1, + signalStrength = 5, + signalChangeThreshold = 20, + radioEnable = true, + state = "ACQUIRING" + } + end + return out +end + +function m.unregistrationApp(pAppId, isHMIreqExpect, pModuleType) + local rpc = "GetInteriorVehicleData" + local HMIrequestsNumber + if isHMIreqExpect == true then + HMIrequestsNumber = 1 + else + HMIrequestsNumber = 0 + end + EXPECT_HMICALL(commonRC.getHMIEventName(rpc), m.getHMIRequestParams(rpc, pModuleType, pAppId, false)) + :Do(function(_, data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", + m.getHMIResponseParams(rpc, pModuleType, false)) + end) + :Times(HMIrequestsNumber) + local cid = m.getMobileSession(pAppId):SendRPC("UnregisterAppInterface",{}) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = commonRC.getHMIAppId(pAppId), unexpectedDisconnect = false }) + m.getMobileSession(pAppId):ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + +function m.setGetInteriorVehicleDataRequestValue(pValue) + m.setSDLIniParameter("GetInteriorVehicleDataRequest", pValue) + m.wait(1000) +end + +function m.unexpectedDisconnect(pAppId, isHMIreqExpect, pModuleType) + local rpc = "GetInteriorVehicleData" + local HMIrequestsNumber + if isHMIreqExpect == true then + HMIrequestsNumber = 1 + else + HMIrequestsNumber = 0 + end + EXPECT_HMICALL(commonRC.getHMIEventName(rpc), m.getHMIRequestParams(rpc, pModuleType, pAppId, false)) + :Do(function(_, data) + m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", + m.getHMIResponseParams(rpc, pModuleType, false)) + end) + :Times(HMIrequestsNumber) + m.getMobileSession(pAppId):Stop() +end + +function m.activateApp(pAppId, pAudioState) + if not pAppId then pAppId = 1 end + if not pAudioState then pAudioState = "AUDIBLE" end + local requestId = m.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = m.getHMIAppId(pAppId) }) + m.getHMIConnection():ExpectResponse(requestId) + m.getMobileSession(pAppId):ExpectNotification("OnHMIStatus", + { hmiLevel = "FULL", audioStreamingState = pAudioState, systemContext = "MAIN" }) + utils.wait() +end + +function m.preconditions() + m.preconditionOrigin() + commonPreconditions:BackupFile(preloadedPT) + m.updatePreloadedPT() +end + +function m.postconditions() + postconditionOrigin() + commonPreconditions:RestoreFile(preloadedPT) +end + +return m diff --git a/test_sets/interior_vehicle_data_management.txt b/test_sets/interior_vehicle_data_management.txt new file mode 100644 index 0000000000..f0a2bd7fe7 --- /dev/null +++ b/test_sets/interior_vehicle_data_management.txt @@ -0,0 +1,39 @@ +./test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua +./test_scripts/RC/InteriorVehicleData_cache/001_GetInteriorVD_without_subscribe.lua +./test_scripts/RC/InteriorVehicleData_cache/002_GetInteriorVD_without_subscribe_2_requests.lua +./test_scripts/RC/InteriorVehicleData_cache/003_GetInteriorVD_without_subscribe_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/004_GetInteriorVD_subscribe_true.lua +./test_scripts/RC/InteriorVehicleData_cache/005_GetInteriorVD_subscribe_true_2_requests.lua +./test_scripts/RC/InteriorVehicleData_cache/006_GetInteriorVD_subscribe_true_and_without_subscribe_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/007_GetInteriorVD_subscribe_true_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/008_GetInteriorVD_subscribe_true_2_apps_different_modules.lua +./test_scripts/RC/InteriorVehicleData_cache/009_GetInteriorVD_without_subscribe_2_apps_different_modules.lua +./test_scripts/RC/InteriorVehicleData_cache/010_GetInteriorVD_subscribe_true_2_apps_same_module.lua +./test_scripts/RC/InteriorVehicleData_cache/011_OnInteriorVD_without_subscription.lua +./test_scripts/RC/InteriorVehicleData_cache/012_OnInteriorVD_app_unsubscribed.lua +./test_scripts/RC/InteriorVehicleData_cache/013_GetInteriorVD_without_subscription_after_OnInteriorVD.lua +./test_scripts/RC/InteriorVehicleData_cache/014_GetInteriorVD_with_subscription_after_OnInteriorVD.lua +./test_scripts/RC/InteriorVehicleData_cache/015_GetInteriorVD_with_subscription_after_OnInteriorVD_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/016_OnInteriorVD_2_apps_subscribed_and_not_subscribed.lua +./test_scripts/RC/InteriorVehicleData_cache/017_GetInteriorVD_subscribe_true_after_OnInteriorVD_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/018_GetInteriorVD_subscribe_false.lua +./test_scripts/RC/InteriorVehicleData_cache/019_GetInteriorVD_subscribe_false_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/021_GetInteriorVD_subscribe_false_by_app_unregistration.lua +./test_scripts/RC/InteriorVehicleData_cache/022_GetInteriorVD_subscribe_false_by_app_unregistration_different_modules.lua +./test_scripts/RC/InteriorVehicleData_cache/023_GetInteriorVD_subscribe_false_by_app_unregistration_same_module.lua +./test_scripts/RC/InteriorVehicleData_cache/024_GetInteriorVD_limitation.lua +./test_scripts/RC/InteriorVehicleData_cache/025_GetInteriorVD_limitation_rejected.lua +./test_scripts/RC/InteriorVehicleData_cache/026_GetInteriorVD_limitation_rejected_different_modules.lua +./test_scripts/RC/InteriorVehicleData_cache/027_GetInteriorVD_limitation_rejected_different_modules_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/028_GetInteriorVD_limitation_after_subscription.lua +./test_scripts/RC/InteriorVehicleData_cache/029_GetInteriorVD_limitation_rejected_after_unsubscribing.lua +./test_scripts/RC/InteriorVehicleData_cache/030_GetInteriorVD_limitation_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/031_GetInteriorVD_resubscribe_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/032_OnInteriorVD_2_apps_subscribed.lua +./test_scripts/RC/InteriorVehicleData_cache/033_GetInteriorVD_subscribe_false_by_app_unregistration_2_modules.lua +./test_scripts/RC/InteriorVehicleData_cache/034_GetInteriorVD_subscribe_false_by_app_unexpected_disconnect.lua +./test_scripts/RC/InteriorVehicleData_cache/035_GetInteriorVD_subscribe_false_by_app_disallowed_RC.lua +./test_scripts/RC/InteriorVehicleData_cache/036_GetInteriorVD_subscribe_false_by_revoking_module.lua +./test_scripts/RC/InteriorVehicleData_cache/037_GetInteriorVD_subscribe_false_without_subscribtion.lua +./test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua From cbf35b5fa77f27fcce88288952df58588b0d797d Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 17 Jul 2018 15:17:50 +0300 Subject: [PATCH 600/681] Check subscription for App2 afer App1 is unsubscribed --- ...0_GetInteriorVD_subscribe_false_different_modules_2_apps.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua index 702d53566f..b384113813 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua @@ -37,6 +37,8 @@ runner.Step("App2 GetInteriorVehicleData with subscribe=true " .. common.modules { common.modules[2], true, true, 2 }) runner.Step("App1 GetInteriorVehicleData with subscribe=false " .. common.modules[1], common.GetInteriorVehicleData, { common.modules[1], false, true, 1 }) + runner.Step("App2 GetInteriorVehicleData without subscribe " .. common.modules[2], common.GetInteriorVehicleData, + { common.modules[2], nil, false, 2 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) From ea06d6d9e04ca96ddbbb85bacef011e64b5ea416 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 18 Jul 2018 13:30:18 +0300 Subject: [PATCH 601/681] Data caching after app unregistration --- ...D_subscribe_false_by_app_unregistration.lua | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/test_scripts/RC/InteriorVehicleData_cache/021_GetInteriorVD_subscribe_false_by_app_unregistration.lua b/test_scripts/RC/InteriorVehicleData_cache/021_GetInteriorVD_subscribe_false_by_app_unregistration.lua index c9994b01e1..e058863243 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/021_GetInteriorVD_subscribe_false_by_app_unregistration.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/021_GetInteriorVD_subscribe_false_by_app_unregistration.lua @@ -7,10 +7,12 @@ -- -- Description: -- In case --- 1. Mobile app is subscribed to module_1 --- 2. Mobile app unregisters +-- 1. Mobile app1 is subscribed to module_1 +-- 2. Mobile app1 unregisters +-- 3. Mobile app2 sends GetInteriorVD(module_1, without subscribe) -- SDL must -- 1. send GetInteriorVD(module_1, subscribe = false) request to HMI +-- 2. send GetInteriorVD(module_1, without subscribe) request to HMI --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -23,15 +25,19 @@ runner.testSettings.isSelfIncluded = false runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("Register app", common.registerAppWOPTU, { 1 }) -runner.Step("Activate app", common.activateApp, { 1 }) +runner.Step("Register app1", common.registerAppWOPTU, { 1 }) +runner.Step("Register app2", common.registerAppWOPTU, { 2 }) +runner.Step("Activate app1", common.activateApp, { 1 }) +runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) runner.Title("Test") -runner.Step("GetInteriorVehicleData with subscribe=true " .. common.modules[1], common.GetInteriorVehicleData, +runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. common.modules[1], common.GetInteriorVehicleData, { common.modules[1], true, true, 1 }) -runner.Step("RC.GetInteriorVehicleData with subscribe=false by app unregistration " .. common.modules[1], +runner.Step("RC.GetInteriorVehicleData with subscribe=false by app1 unregistration " .. common.modules[1], common.unregistrationApp, { 1, true, common.modules[1] }) +runner.Step("App2 GetInteriorVehicleData without subscribe to check cache cleaning " .. common.modules[1], + common.GetInteriorVehicleData, { common.modules[1], nil, true, 2 }) runner.Title("Postconditions") From 9f27469634631bba154e8a6aa1a77809c844d243 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 13 Jul 2018 12:31:50 +0300 Subject: [PATCH 602/681] Update regression scripts for RADIO,CLIMATE regarding cache --- ...ransfering_of_HMI_resultCode_to_mobile.lua | 2 -- .../006_RPC_parameters_values.lua | 1 - ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 1 - ..._in_case_HMI_respond_with_invalid_data.lua | 2 -- ...se_moduleType_is_an_empty_array_in_LPT.lua | 1 - ...ROR_in_case_HMI_respond_with_READ_ONLY.lua | 1 - ...response_from_HMI_without_isSubscribed.lua | 12 +++---- ...ut_response_from_HMI_with_isSubscribed.lua | 8 ++--- ...ase_of_2nd_Subscription_UnSubscription.lua | 6 ++-- ...ribing_with_isSubscribe_false_from_HMI.lua | 1 - ...bscribing_without_isSubscribe_from_HMI.lua | 1 - ...ase_of_subscribing_with_error_from_HMI.lua | 1 - ..._subscribing_with_no_response_from_HMI.lua | 1 - ...cribing_with_invalid_response_from_HMI.lua | 1 - ...cribing_with_isSubscribe_true_from_HMI.lua | 1 - ...bscribing_without_isSubscribe_from_HMI.lua | 1 - ...bscribing_without_isSubscribe_from_HMI.lua | 1 - test_scripts/RC/commonRC.lua | 33 ++++++++++++++++--- 18 files changed, 42 insertions(+), 33 deletions(-) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua index 526623cfe3..d16ea3cc52 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua @@ -30,7 +30,6 @@ local function stepSuccessfull(pModuleType, pResultCode, self) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType, subscribe = true }) @@ -54,7 +53,6 @@ local function stepUnsuccessfull(pModuleType, pResultCode, self) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType, subscribe = true }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/006_RPC_parameters_values.lua index e1d3029d74..47e01154eb 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/006_RPC_parameters_values.lua @@ -75,7 +75,6 @@ local function fakeParam(pModuleType, self) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType, subscribe = true }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index 63f7745089..b350f931fc 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -29,7 +29,6 @@ local function getDataForModule(pModuleType, self) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType, subscribe = true }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index fbc263a9be..b1c4afcc01 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -30,7 +30,6 @@ local function invalidParamType(pModuleType, self) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType, subscribe = true }) @@ -51,7 +50,6 @@ local function missingMandatoryParam(pModuleType, self) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType, subscribe = true }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 274b130e87..bbf5451d31 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -30,7 +30,6 @@ local function getDataForModule(pModuleType, self) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType, subscribe = true }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua index 8f9be4b91f..d85d6bb41b 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -28,7 +28,6 @@ local function getDataForModule(module_type, self) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = module_type, subscribe = true }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua index 278301a339..7e2bffed87 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -23,7 +23,7 @@ local commonRC = require('test_scripts/RC/commonRC') local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] -local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, self) +local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, pHMIRequest, self) local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = pSubscribe @@ -35,7 +35,6 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, s end EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType }) :Do(function(_, data) @@ -50,6 +49,7 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, s end return false, 'Parameter "subscribe" is transfered to HMI with value: ' .. tostring(data.params.subscribe) end) + :Times(pHMIRequest) self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", isSubscribed = isSubscriptionActive, -- return current value of subscription @@ -67,14 +67,14 @@ runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") for _, mod in pairs(modules) do - runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription_subscribe", getDataForModule, { mod, false, true }) - runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription_unsubscribe", getDataForModule, { mod, false, false }) + runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription_subscribe", getDataForModule, { mod, false, true, 1 }) + runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription_unsubscribe", getDataForModule, { mod, false, false, 1 }) end for _, mod in pairs(modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) - runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true, true }) - runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_unsubscribe", getDataForModule, { mod, true, false }) + runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true, true, 0 }) + runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_unsubscribe", getDataForModule, { mod, true, false, 1 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index 772546121d..6ed3dec27e 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -23,14 +23,13 @@ local commonRC = require('test_scripts/RC/commonRC') local modules = { "CLIMATE", "RADIO" } --[[ Local Functions ]] -local function getDataForModule(pModuleType, isSubscriptionActive, self) +local function getDataForModule(pModuleType, isSubscriptionActive, pHMIRequest, self) local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType -- no subscribe parameter }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType }) :Do(function(_, data) @@ -45,6 +44,7 @@ local function getDataForModule(pModuleType, isSubscriptionActive, self) end return false, 'Parameter "subscribe" is transfered with to HMI value: ' .. tostring(data.params.subscribe) end) + :Times(pHMIRequest) self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = commonRC.getModuleControlData(pModuleType) @@ -67,12 +67,12 @@ runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") for _, mod in pairs(modules) do - runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription", getDataForModule, { mod, false }) + runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription", getDataForModule, { mod, false, 1 }) end for _, mod in pairs(modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) - runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true }) + runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true, 0 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua index 5f5dcccff9..d2453081de 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua @@ -41,12 +41,11 @@ local function subscriptionToModule(pModuleType, pSubscribe, self) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType }) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = commonRC.actualInteriorDataStateOnHMI[pModuleType], isSubscribed = pSubscribe }) end) @@ -56,9 +55,10 @@ local function subscriptionToModule(pModuleType, pSubscribe, self) end return false, 'Parameter "subscribe" is transfered to HMI with value: ' .. tostring(data.params.subscribe) end) + :Times(AtMost(1)) self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = commonRC.actualInteriorDataStateOnHMI[pModuleType], isSubscribed = pSubscribe }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua index 726cd2e61f..7b7c760e7e 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -30,7 +30,6 @@ local function subscriptionToModule(pModuleType, self) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType, subscribe = true }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua index c62ef3b4d9..08d50a6744 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua @@ -30,7 +30,6 @@ local function subscriptionToModule(pModuleType, self) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType, subscribe = true }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua index c9e3e6bb24..c741bacb14 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua @@ -32,7 +32,6 @@ local function subscriptionToModule(pModuleType, pResultCode, self) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType, subscribe = true }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua index 498709502a..d2fd969a7e 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua @@ -31,7 +31,6 @@ local function subscriptionToModule(pModuleType, self) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType, subscribe = true }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua index 42828120a6..9f62426364 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua @@ -30,7 +30,6 @@ local function subscriptionToModule(pModuleType, self) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType, subscribe = true }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua index e086fe1e54..25b075b5b2 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua @@ -31,7 +31,6 @@ local function unSubscriptionToModule(pModuleType, self) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType, subscribe = false }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua index 9340337d82..8032bca5ec 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -31,7 +31,6 @@ local function unSubscriptionToModule(pModuleType, self) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType, subscribe = false }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua index 40d8fc4907..55a86ae5b8 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -33,7 +33,6 @@ local function unSubscriptionToModule(pModuleType, pResultCode, self) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = self.applications["Test Application"], moduleType = pModuleType, subscribe = false }) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 427e03d25c..dfdbccb1b7 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -448,16 +448,15 @@ local rcRPCs = { subscribe = pSubscribe } end, - hmiRequestParams = function(pModuleType, pAppId, pSubscribe) + hmiRequestParams = function(pModuleType, _, pSubscribe) return { - appID = commonRC.getHMIAppId(pAppId), moduleType = pModuleType, subscribe = pSubscribe } end, hmiResponseParams = function(pModuleType, pSubscribe) return { - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = commonRC.actualInteriorDataStateOnHMI[pModuleType], isSubscribed = pSubscribe } end, @@ -465,7 +464,7 @@ local rcRPCs = { return { success = success, resultCode = resultCode, - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = commonRC.actualInteriorDataStateOnHMI[pModuleType], isSubscribed = pSubscribe } end @@ -597,6 +596,7 @@ function commonRC.subscribeToModule(pModuleType, pAppId, self) EXPECT_HMICALL(commonRC.getHMIEventName(rpc), commonRC.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe)) :Do(function(_, data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(rpc, pModuleType, subscribe)) + commonRC.setActualInteriorVD(pModuleType, commonRC.getHMIResponseParams(rpc, pModuleType, subscribe).moduleData) end) mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) end @@ -619,6 +619,7 @@ function commonRC.isSubscribed(pModuleType, pAppId, self) local mobSession = commonRC.getMobileSession(self, pAppId) local rpc = "OnInteriorVehicleData" self.hmiConnection:SendNotification(commonRC.getHMIEventName(rpc), commonRC.getHMIResponseParams(rpc, pModuleType)) + commonRC.setActualInteriorVD(pModuleType, commonRC.getHMIResponseParams(rpc, pModuleType).moduleData) mobSession:ExpectNotification(commonRC.getAppEventName(rpc), commonRC.getAppResponseParams(rpc, pModuleType)) end @@ -780,5 +781,29 @@ function commonRC.deleteHMIAppId(pAppId) hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = nil end +commonRC.actualInteriorDataStateOnHMI = { + CLIMATE = utils.cloneTable(commonRC.getModuleControlData("CLIMATE")), + RADIO = utils.cloneTable(commonRC.getModuleControlData("RADIO")) +} + +function commonRC.setActualInteriorVD(pModuleType, pParams) + local moduleParams + if pModuleType == "CLIMATE" then + moduleParams = "climateControlData" + else + moduleParams = "radioControlData" + end + for key, value in pairs(pParams[moduleParams]) do + if type(value) ~= "table" then + if value ~= commonRC.actualInteriorDataStateOnHMI[pModuleType][moduleParams][key] then + commonRC.actualInteriorDataStateOnHMI[pModuleType][moduleParams][key] = value + end + else + if false == commonFunctions:is_table_equal(value, commonRC.actualInteriorDataStateOnHMI[pModuleType][moduleParams][key]) then + commonRC.actualInteriorDataStateOnHMI[pModuleType][moduleParams][key] = value + end + end + end +end return commonRC From d5951c8b8404f841feb9388458fe962b7fe12c48 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 18 Jul 2018 12:38:11 +0300 Subject: [PATCH 603/681] Update regression scripts for SEAT regarding cache --- ...snt_respond_to_RC_GetCapabilities_SEAT.lua | 11 +++-- ...snt_respond_to_RC_GetCapabilities_SEAT.lua | 11 +++-- ...ransfering_of_HMI_resultCode_to_mobile.lua | 7 ++- .../003_RPC_parameters_values.lua | 6 +-- ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 1 - ..._in_case_HMI_respond_with_invalid_data.lua | 7 ++- ...se_moduleType_is_an_empty_array_in_LPT.lua | 6 +-- ...bscribing_without_isSubscribe_from_HMI.lua | 6 +-- ...ROR_in_case_HMI_respond_with_READ_ONLY.lua | 1 - ...response_from_HMI_without_isSubscribed.lua | 17 +++---- ...ut_response_from_HMI_with_isSubscribed.lua | 13 ++--- ...ase_of_2nd_Subscription_UnSubscription.lua | 19 ++++---- ...ribing_with_isSubscribe_false_from_HMI.lua | 6 +-- ...bscribing_without_isSubscribe_from_HMI.lua | 6 +-- ..._in_case_HMI_respond_with_invalid_data.lua | 3 +- test_scripts/RC/SEAT/commonRC.lua | 47 ++++++++++++++----- 16 files changed, 96 insertions(+), 71 deletions(-) diff --git a/test_scripts/RC/SEAT/Capabilities/005_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua b/test_scripts/RC/SEAT/Capabilities/005_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua index 0e15e0fc00..a1706a3704 100644 --- a/test_scripts/RC/SEAT/Capabilities/005_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua +++ b/test_scripts/RC/SEAT/Capabilities/005_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua @@ -17,6 +17,7 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/SEAT/commonRC') local hmi_values = require('user_modules/hmi_values') +local initialCommon = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -36,7 +37,7 @@ end local function rpcUnsupportedResource(pModuleType, pRPC) local pAppId = 1 local mobSession = commonRC.getMobileSession(pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), initialCommon.getAppRequestParams(pRPC, pModuleType)) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) end @@ -44,12 +45,12 @@ end local function rpcSuccess(pModuleType, pRPC) local pAppId = 1 local mobSession = commonRC.getMobileSession(pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), initialCommon.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), initialCommon.getHMIRequestParams(pRPC, pModuleType, pAppId)) :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", initialCommon.getHMIResponseParams(pRPC, pModuleType)) end) - mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) + mobSession:ExpectResponse(cid, initialCommon.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) end --[[ Scenario ]] diff --git a/test_scripts/RC/SEAT/Capabilities/006_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua b/test_scripts/RC/SEAT/Capabilities/006_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua index b145a37d7f..d396977889 100644 --- a/test_scripts/RC/SEAT/Capabilities/006_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua +++ b/test_scripts/RC/SEAT/Capabilities/006_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua @@ -17,6 +17,7 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/SEAT/commonRC') local hmi_values = require('user_modules/hmi_values') +local initialCommon = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -36,7 +37,7 @@ end local function rpcUnsupportedResource(pModuleType, pRPC) local pAppId = 1 local mobSession = commonRC.getMobileSession(pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), initialCommon.getAppRequestParams(pRPC, pModuleType)) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) end @@ -44,12 +45,12 @@ end local function rpcSuccess(pModuleType, pRPC) local pAppId = 1 local mobSession = commonRC.getMobileSession(pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), initialCommon.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), initialCommon.getHMIRequestParams(pRPC, pModuleType, pAppId)) :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) + commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", initialCommon.getHMIResponseParams(pRPC, pModuleType)) end) - mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) + mobSession:ExpectResponse(cid, initialCommon.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) end --[[ Scenario ]] diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/002_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/002_Transfering_of_HMI_resultCode_to_mobile.lua index d35bcaef74..7c4984263d 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/002_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/002_Transfering_of_HMI_resultCode_to_mobile.lua @@ -17,6 +17,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/SEAT/commonRC') +local initialCommon = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -33,20 +34,19 @@ local function stepSuccessfull(pModuleType, pResultCode) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = commonRC.getHMIAppId(), moduleType = pModuleType, subscribe = true }) :Do(function(_, data) commonRC.getHMIconnection():SendResponse(data.id, data.method, pResultCode, { - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = initialCommon.getModuleControlData(pModuleType) -- isSubscribed = true }) end) commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = pResultCode, isSubscribed = false, - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = initialCommon.getModuleControlData(pModuleType) }) end @@ -57,7 +57,6 @@ local function stepUnsuccessfull(pModuleType, pResultCode) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = commonRC.getHMIAppId(), moduleType = pModuleType, subscribe = true }) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/003_RPC_parameters_values.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/003_RPC_parameters_values.lua index b8e3d4b97e..72cccfd9b6 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/003_RPC_parameters_values.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/003_RPC_parameters_values.lua @@ -20,6 +20,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/SEAT/commonRC') +local initialCommon = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -63,20 +64,19 @@ local function fakeParam(pModuleType) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = commonRC.getHMIAppId(), moduleType = pModuleType, subscribe = true }) :Do(function(_, data) commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = initialCommon.getModuleControlData(pModuleType), isSubscribed = true }) end) commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true, - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = initialCommon.getModuleControlData(pModuleType) }) end diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/004_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/004_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index ea93f90f43..bc2b6fb190 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/004_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/004_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -27,7 +27,6 @@ local function getDataForModule(pModuleType) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = commonRC.getHMIAppId(), moduleType = pModuleType, subscribe = true }) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/005_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/005_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index 41ad6fd4a9..ff995a4f26 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/005_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/005_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -16,6 +16,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/SEAT/commonRC') +local initialCommon = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -29,13 +30,12 @@ local function invalidParamType(pModuleType) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = commonRC.getHMIAppId(), moduleType = pModuleType, subscribe = true }) :Do(function(_, data) commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = initialCommon.getModuleControlData(pModuleType), isSubscribed = "yes" -- invalid type of parameter }) end) @@ -51,13 +51,12 @@ local function missingMandatoryParam(pModuleType) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = commonRC.getHMIAppId(), moduleType = pModuleType, subscribe = true }) :Do(function(_, data) - local moduleData = commonRC.getModuleControlData(pModuleType) + local moduleData = initialCommon.getModuleControlData(pModuleType) moduleData.moduleType = nil -- missing mandatory parameter commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = moduleData, diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 69e486cb04..71132c1c8f 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -14,6 +14,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/SEAT/commonRC') +local initialCommon = require('test_scripts/RC/commonRC') local json = require('modules/json') --[[ Test Configuration ]] @@ -28,20 +29,19 @@ local function getDataForModule(pModuleType) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = commonRC.getHMIAppId(), moduleType = pModuleType, subscribe = true }) :Do(function(_, data) commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = initialCommon.getModuleControlData(pModuleType), isSubscribed = true }) end) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true, - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = initialCommon.getModuleControlData(pModuleType) }) end diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua index a0e93168d2..b0f7bca902 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -17,6 +17,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/SEAT/commonRC') +local initialCommon = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -30,19 +31,18 @@ local function unSubscriptionToModule(pModuleType) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = commonRC.getHMIAppId(), moduleType = pModuleType, subscribe = false }) :Do(function(_, data) commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = initialCommon.getModuleControlData(pModuleType), -- no isSubscribed parameter }) end) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = initialCommon.getModuleControlData(pModuleType), isSubscribed = true }) end diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua index 5166f69a06..ebe943b6f4 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -27,7 +27,6 @@ local function getDataForModule(module_type) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = commonRC.getHMIAppId(), moduleType = module_type, subscribe = true }) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua index 57bcc124ba..cea34fb787 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -16,12 +16,13 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/SEAT/commonRC') +local initialCommon = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe) +local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, pHMIrequests) local mobSession = commonRC.getMobileSession() local cid = mobSession:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, @@ -34,12 +35,11 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe) end EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = commonRC.getHMIAppId(), moduleType = pModuleType }) :Do(function(_, data) commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = initialCommon.getModuleControlData(pModuleType), -- no isSubscribed parameter }) end) @@ -49,10 +49,11 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe) end return false, 'Parameter "subscribe" is transfered to HMI with value: ' .. tostring(data.params.subscribe) end) + :Times(pHMIrequests) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", isSubscribed = isSubscriptionActive, -- return current value of subscription - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = initialCommon.getModuleControlData(pModuleType) }) end @@ -64,12 +65,12 @@ runner.Step("RAI, PTU", commonRC.rai_ptu) runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") -runner.Step("GetInteriorVehicleData SEAT NoSubscription_subscribe", getDataForModule, { "SEAT", false, true }) -runner.Step("GetInteriorVehicleData SEAT NoSubscription_unsubscribe", getDataForModule, { "SEAT", false, false }) +runner.Step("GetInteriorVehicleData SEAT NoSubscription_subscribe", getDataForModule, { "SEAT", false, true, 1 }) +runner.Step("GetInteriorVehicleData SEAT NoSubscription_unsubscribe", getDataForModule, { "SEAT", false, false, 1 }) runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) -runner.Step("GetInteriorVehicleData SEAT ActiveSubscription_subscribe", getDataForModule, { "SEAT", true, true }) -runner.Step("GetInteriorVehicleData SEAT ActiveSubscription_unsubscribe", getDataForModule, { "SEAT", true, false }) +runner.Step("GetInteriorVehicleData SEAT ActiveSubscription_subscribe", getDataForModule, { "SEAT", true, true, 0 }) +runner.Step("GetInteriorVehicleData SEAT ActiveSubscription_unsubscribe", getDataForModule, { "SEAT", true, false, 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index 722ce863fd..fd4c8c9cf8 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -16,12 +16,13 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/SEAT/commonRC') +local initialCommon = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, isSubscriptionActive) +local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequest) local mobSession = commonRC.getMobileSession() local cid = mobSession:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType @@ -29,12 +30,11 @@ local function getDataForModule(pModuleType, isSubscriptionActive) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = commonRC.getHMIAppId(), moduleType = pModuleType }) :Do(function(_, data) commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = initialCommon.getModuleControlData(pModuleType), isSubscribed = isSubscriptionActive -- return current value of subscription }) end) @@ -44,9 +44,10 @@ local function getDataForModule(pModuleType, isSubscriptionActive) end return false, 'Parameter "subscribe" is transfered with to HMI value: ' .. tostring(data.params.subscribe) end) + :Times(pHMIrequest) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = commonRC.getModuleControlData(pModuleType) + moduleData = initialCommon.getModuleControlData(pModuleType) }) :ValidIf(function(_, data) -- no isSubscribed parameter if data.payload.isSubscribed == nil then @@ -64,9 +65,9 @@ runner.Step("RAI, PTU", commonRC.rai_ptu) runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") -runner.Step("GetInteriorVehicleData SEAT NoSubscription", getDataForModule, { "SEAT", false }) +runner.Step("GetInteriorVehicleData SEAT NoSubscription", getDataForModule, { "SEAT", false, 1 }) runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) -runner.Step("GetInteriorVehicleData SEAT ActiveSubscription_subscribe", getDataForModule, { "SEAT", true }) +runner.Step("GetInteriorVehicleData SEAT ActiveSubscription_subscribe", getDataForModule, { "SEAT", true, 0 }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua index 9d801cac0a..f6d8a0729e 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua @@ -27,12 +27,13 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/SEAT/commonRC') +local initialCommon = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function subscriptionToModule(pModuleType, pSubscribe) +local function subscriptionToModule(pModuleType, pSubscribe, pHMIrequest) local mobSession = commonRC.getMobileSession() local cid = mobSession:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, @@ -40,12 +41,11 @@ local function subscriptionToModule(pModuleType, pSubscribe) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = commonRC.getHMIAppId(), moduleType = pModuleType }) :Do(function(_, data) commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = initialCommon.actualInteriorDataStateOnHMI[pModuleType], isSubscribed = pSubscribe }) end) @@ -55,8 +55,9 @@ local function subscriptionToModule(pModuleType, pSubscribe) end return false, 'Parameter "subscribe" is transfered to HMI with value: ' .. tostring(data.params.subscribe) end) + :Times(pHMIrequest) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = initialCommon.actualInteriorDataStateOnHMI[pModuleType], isSubscribed = pSubscribe }) end @@ -70,19 +71,19 @@ runner.Step("Activate App", commonRC.activate_app) runner.Title("Test") -- app has not subscribed yet -runner.Step("Unsubscribe app to SEAT", subscriptionToModule, { "SEAT", false }) +runner.Step("Unsubscribe app to SEAT", subscriptionToModule, { "SEAT", false, 1 }) runner.Step("Send notification OnInteriorVehicleData SEAT. App is not subscribed", commonRC.isUnsubscribed, { "SEAT" }) -- subscribe to module 1st time -runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) +runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT", 1 }) runner.Step("Send notification OnInteriorVehicleData SEAT. App is subscribed", commonRC.isSubscribed, { "SEAT" }) -- subscribe to module 2nd time -runner.Step("Subscribe 2nd time app to SEAT", subscriptionToModule, { "SEAT", true }) +runner.Step("Subscribe 2nd time app to SEAT", subscriptionToModule, { "SEAT", true, 0 }) runner.Step("Send notification OnInteriorVehicleData SEAT. App is subscribed", commonRC.isSubscribed, { "SEAT" }) -- unsubscribe to module 1st time -runner.Step("Unsubscribe app to SEAT", commonRC.unSubscribeToModule, { "SEAT" }) +runner.Step("Unsubscribe app to SEAT", commonRC.unSubscribeToModule, { "SEAT", 1 }) runner.Step("Send notification OnInteriorVehicleData SEAT. App is not subscribed", commonRC.isUnsubscribed, { "SEAT" }) -- unsubscribe to module 2nd time -runner.Step("Unsubscribe 2nd time app to SEAT", subscriptionToModule, { "SEAT", false }) +runner.Step("Unsubscribe 2nd time app to SEAT", subscriptionToModule, { "SEAT", false, 1 }) runner.Step("Send notification OnInteriorVehicleData SEAT. App is not subscribed", commonRC.isUnsubscribed, { "SEAT" }) runner.Title("Postconditions") diff --git a/test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua index 947163d432..29cdd208d3 100644 --- a/test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -16,6 +16,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/SEAT/commonRC') +local initialCommon = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -29,19 +30,18 @@ local function subscriptionToModule(pModuleType) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = commonRC.getHMIAppId(), moduleType = pModuleType, subscribe = true }) :Do(function(_, data) commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = initialCommon.getModuleControlData(pModuleType), isSubscribed = false -- not subscribe }) end) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = initialCommon.getModuleControlData(pModuleType), isSubscribed = false }) end diff --git a/test_scripts/RC/SEAT/OnInteriorVehicleData/003_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/SEAT/OnInteriorVehicleData/003_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua index bcfecc4b26..069669535a 100644 --- a/test_scripts/RC/SEAT/OnInteriorVehicleData/003_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/SEAT/OnInteriorVehicleData/003_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -17,6 +17,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/SEAT/commonRC') +local initialCommon = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -30,19 +31,18 @@ local function unSubscriptionToModule(pModuleType) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = commonRC.getHMIAppId(), moduleType = pModuleType, subscribe = false }) :Do(function(_, data) commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = initialCommon.getModuleControlData(pModuleType), -- no isSubscribed parameter }) end) mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = initialCommon.getModuleControlData(pModuleType), isSubscribed = true }) end diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index e562c7a511..e402a0f0f1 100644 --- a/test_scripts/RC/SEAT/SetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -14,6 +14,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/SEAT/commonRC') +local initialCommon = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -52,7 +53,7 @@ local function missingMandatoryParam(pModuleType) moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :Do(function(_, data) - local moduleData = commonRC.getModuleControlData(pModuleType) + local moduleData = initialCommon.getModuleControlData(pModuleType) moduleData.moduleType = nil -- missing mandatory parameter commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = moduleData diff --git a/test_scripts/RC/SEAT/commonRC.lua b/test_scripts/RC/SEAT/commonRC.lua index 8ea05d1c18..a1421eb836 100644 --- a/test_scripts/RC/SEAT/commonRC.lua +++ b/test_scripts/RC/SEAT/commonRC.lua @@ -13,6 +13,9 @@ config.application2.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 --[[ Required Shared libraries ]] local initialCommon = require('test_scripts/RC/commonRC') local test = require("user_modules/dummy_connecttest") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local utils = require('user_modules/utils') + --[[ Local Variables ]] local commonRC = {} @@ -92,10 +95,6 @@ function initialCommon.getModuleControlData(module_type) return out end -function commonRC.getModuleControlData(module_type) - return initialCommon.getModuleControlData(module_type) -end - local origGetAnotherModuleControlData = initialCommon.getAnotherModuleControlData function commonRC.getAnotherModuleControlData(module_type) local out = { } @@ -162,6 +161,31 @@ function commonRC.getModuleParams(pModuleData) return initialCommon.getModuleParams(pModuleData) end +initialCommon.actualInteriorDataStateOnHMI = { + CLIMATE = utils.cloneTable(initialCommon.getModuleControlData("CLIMATE")), + RADIO = utils.cloneTable(initialCommon.getModuleControlData("RADIO")), + SEAT = utils.cloneTable(initialCommon.getModuleControlData("SEAT")) +} + +local setActualInteriorVDorigin = initialCommon.setActualInteriorVD +function initialCommon.setActualInteriorVD(pModuleType, pParams) + if pModuleType == "SEAT" then + for key, value in pairs(pParams["seatControlData"]) do + if type(value) ~= "table" then + if value ~= initialCommon.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] then + initialCommon.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] = value + end + else + if false == commonFunctions:is_table_equal(value, initialCommon.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key]) then + initialCommon.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] = value + end + end + end + else + setActualInteriorVDorigin(pModuleType, pParams) + end +end + function commonRC.buildHmiRcCapabilities(pClimateCapabilities, pRadioCapabilities, pSeatCapabilities, pButtonCapabilities) local hmiParams = initialCommon.buildHmiRcCapabilities(pClimateCapabilities, pRadioCapabilities, pButtonCapabilities) local capParams = hmiParams.RC.GetCapabilities.params.remoteControlCapability @@ -268,16 +292,15 @@ local rcRPCs = { subscribe = pSubscribe } end, - hmiRequestParams = function(pModuleType, pAppId, pSubscribe) + hmiRequestParams = function(pModuleType, _, pSubscribe) return { - appID = commonRC.getHMIAppId(pAppId), moduleType = pModuleType, subscribe = pSubscribe } end, hmiResponseParams = function(pModuleType, pSubscribe) return { - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = initialCommon.actualInteriorDataStateOnHMI[pModuleType], isSubscribed = pSubscribe } end, @@ -285,7 +308,7 @@ local rcRPCs = { return { success = success, resultCode = resultCode, - moduleData = commonRC.getModuleControlData(pModuleType), + moduleData = initialCommon.actualInteriorDataStateOnHMI[pModuleType], isSubscribed = pSubscribe } end @@ -364,19 +387,19 @@ function commonRC.getHMIEventName(pRPC) return rcRPCs[pRPC].hmiEventName end -function commonRC.getAppRequestParams(pRPC, ...) +function initialCommon.getAppRequestParams(pRPC, ...) return rcRPCs[pRPC].requestParams(...) end -function commonRC.getAppResponseParams(pRPC, ...) +function initialCommon.getAppResponseParams(pRPC, ...) return rcRPCs[pRPC].responseParams(...) end -function commonRC.getHMIRequestParams(pRPC, ...) +function initialCommon.getHMIRequestParams(pRPC, ...) return rcRPCs[pRPC].hmiRequestParams(...) end -function commonRC.getHMIResponseParams(pRPC, ...) +function initialCommon.getHMIResponseParams(pRPC, ...) return rcRPCs[pRPC].hmiResponseParams(...) end From 5205bc56a5a4b40d5785cd2e585b290169255f8a Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 20 Jul 2018 12:09:46 +0300 Subject: [PATCH 604/681] Script for changed frequency counting strategy --- ...GetInteriorVD_limitation_time_interval.lua | 130 ++++++++++++++++++ .../interior_vehicle_data_management.txt | 1 + 2 files changed, 131 insertions(+) create mode 100644 test_scripts/RC/InteriorVehicleData_cache/039_GetInteriorVD_limitation_time_interval.lua diff --git a/test_scripts/RC/InteriorVehicleData_cache/039_GetInteriorVD_limitation_time_interval.lua b/test_scripts/RC/InteriorVehicleData_cache/039_GetInteriorVD_limitation_time_interval.lua new file mode 100644 index 0000000000..4bb58e4bca --- /dev/null +++ b/test_scripts/RC/InteriorVehicleData_cache/039_GetInteriorVD_limitation_time_interval.lua @@ -0,0 +1,130 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0178-GetInteriorVehicleData.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case +-- 1. In .ini file GetInteriorVehicleDataRequest = 3, 11 +-- 2. Mobile app sends 3 GetInteriorVD(module_1, without subscribe parameter) requests per 8 sec +-- 3. Mobile app starts sends a lot of requests before 1st success request processing +-- SDL must +-- 1. process successful 3 requests per 8 sec and send GetInteriorVD requests to HMI +-- 2. rejects requests starting from 4th one +-- 3. when time between received request and 1st success request is more then 11 sec process request successful and send GetInteriorVD requests to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') +local commonRC = require('test_scripts/RC/commonRC') +local functionId = require('function_id') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +-- [[ Local Variables]] +local timestampArray = {} + +-- [[ Local Functions]] +local function GetInteriorVehicleData(pModuleType, pRequestNubmer) + local rpc = "GetInteriorVehicleData" + local subscribe = nil + local mobSession = common.getMobileSession(1) + local cid = mobSession:SendRPC(commonRC.getAppEventName(rpc), + commonRC.getAppRequestParams(rpc, pModuleType, subscribe)) + + local hmiRequestParams = common.getHMIRequestParams(rpc, pModuleType, 1, subscribe) + timestampArray[pRequestNubmer] = timestamp() + hmiRequestParams.subscribe = nil + EXPECT_HMICALL(commonRC.getHMIEventName(rpc), hmiRequestParams) + :Do(function(_, data) + local hmiResponseParams = common.getHMIResponseParams(rpc, pModuleType, subscribe) + hmiResponseParams.subscribe = nil + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", hmiResponseParams) + end) + :ValidIf(function(_, data) + if data.params.subscribe then + return false, "RC.GetInteriorVehicleData request contains unexpected 'subscribe' parameter" + end + return true + end) + mobSession:ExpectResponse(cid, common.getResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) +end + +local function GetInteriorVehicleDataRejectedSuccess(pModuleType, pCompareRequest) + local rpc = "GetInteriorVehicleData" + local subscribe = nil + local mobSession = common.getMobileSession(1) + local function request() + mobSession:SendRPC(commonRC.getAppEventName(rpc), + commonRC.getAppRequestParams(rpc, pModuleType, subscribe)) + end + + request() + + local hmiRequestParams = common.getHMIRequestParams(rpc, pModuleType, 1, subscribe) + hmiRequestParams.subscribe = nil + EXPECT_HMICALL(commonRC.getHMIEventName(rpc), hmiRequestParams) + :Do(function(_, data) + timestampArray[4] = timestamp() + local hmiResponseParams = common.getHMIResponseParams(rpc, pModuleType, subscribe) + hmiResponseParams.subscribe = nil + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", hmiResponseParams) + common.wait(2000) + end) + + mobSession:ExpectAny() + :ValidIf(function(_, data) + if data.rpcFunctionId == functionId[rpc] then + if data.payload.resultCode == "SUCCESS" then + local timeToRequest = { + [1] = timestampArray[4] - timestampArray[1], + [2] = timestampArray[4] - timestampArray[2], + [3] = timestampArray[4] - timestampArray[3] + } + if timeToRequest[pCompareRequest] >= 11000 and + timeToRequest[pCompareRequest] < 11700 then + return true + else + return false, "Time to first success request after " .. pCompareRequest .. " request is not 11 seconds.\n" .. + "Actual result: time to first request " .. timeToRequest[1] .. "\n" .. + "time to second request " .. timeToRequest[2] .. "\n" .. + "time to third request " .. timeToRequest[3] .. "\n" + end + else + RUN_AFTER(request, 100) + end + return true + else + return false, "Unexpected rpc " .. data.rpcFunctionId .. " came" + end + end) + :Times(AnyNumber()) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Update GetInteriorVehicleDataRequest=3,11", common.setGetInteriorVehicleDataRequestValue, {"3,11"}) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register app", common.registerAppWOPTU, { 1 }) +runner.Step("Activate app", common.activateApp, { 1 }) + +runner.Title("Test") +runner.Step("GetInteriorVehicleData without subscribe parameter " .. 1, GetInteriorVehicleData, + {"CLIMATE", 1 }) +runner.Step("Wait 5 secs", common.wait, { 5000 }) +runner.Step("GetInteriorVehicleData without subscribe parameter " .. 2, GetInteriorVehicleData, + {"CLIMATE", 2 }) +runner.Step("Wait 3 secs", common.wait, { 3000 }) +runner.Step("GetInteriorVehicleData without subscribe parameter " .. 3, GetInteriorVehicleData, + {"CLIMATE", 3 }) +runner.Step("GetInteriorVehicleData without subscribe parameter rejected before 11 seconds to 1st request", + GetInteriorVehicleDataRejectedSuccess, { "CLIMATE", 1 }) +runner.Step("GetInteriorVehicleData without subscribe parameter rejected before 11 seconds to 2st request", + GetInteriorVehicleDataRejectedSuccess, { "CLIMATE", 2 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_sets/interior_vehicle_data_management.txt b/test_sets/interior_vehicle_data_management.txt index f0a2bd7fe7..27d0ccc785 100644 --- a/test_sets/interior_vehicle_data_management.txt +++ b/test_sets/interior_vehicle_data_management.txt @@ -37,3 +37,4 @@ ./test_scripts/RC/InteriorVehicleData_cache/036_GetInteriorVD_subscribe_false_by_revoking_module.lua ./test_scripts/RC/InteriorVehicleData_cache/037_GetInteriorVD_subscribe_false_without_subscribtion.lua ./test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua +./test_scripts/RC/InteriorVehicleData_cache/039_GetInteriorVD_limitation_time_interval.lua From 83c091cd8809052f57f65fd7290fbbd51a0d4ff5 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 18 Jul 2018 12:38:11 +0300 Subject: [PATCH 605/681] Update OnRCStatus for SEAT module --- .../RC/OnRCStatus/commonOnRCStatus.lua | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua index 80826e10d5..056233f02a 100644 --- a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua +++ b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua @@ -432,4 +432,29 @@ function m.registerNonRCApp(pAppId) :Times(0) end +commonRC.actualInteriorDataStateOnHMI = { + CLIMATE = utils.cloneTable(commonRC.getModuleControlData("CLIMATE")), + RADIO = utils.cloneTable(commonRC.getModuleControlData("RADIO")), + SEAT = utils.cloneTable(commonRC.getModuleControlData("SEAT")) +} + +local setActualInteriorVDorigin = commonRC.setActualInteriorVD +function commonRC.setActualInteriorVD(pModuleType, pParams) + if pModuleType == "SEAT" then + for key, value in pairs(pParams["seatControlData"]) do + if type(value) ~= "table" then + if value ~= commonRC.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] then + commonRC.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] = value + end + else + if false == commonFunctions:is_table_equal(value, commonRC.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key]) then + commonRC.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] = value + end + end + end + else + setActualInteriorVDorigin(pModuleType, pParams) + end +end + return m From c49f772a17df6f85938df422ce6418d1f4f1f8eb Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 20 Jul 2018 19:00:08 +0300 Subject: [PATCH 606/681] Updated description according to comments --- .../002_GetInteriorVD_without_subscribe_2_requests.lua | 4 ++-- .../003_GetInteriorVD_without_subscribe_2_apps.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test_scripts/RC/InteriorVehicleData_cache/002_GetInteriorVD_without_subscribe_2_requests.lua b/test_scripts/RC/InteriorVehicleData_cache/002_GetInteriorVD_without_subscribe_2_requests.lua index 9497511818..84b98cdf83 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/002_GetInteriorVD_without_subscribe_2_requests.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/002_GetInteriorVD_without_subscribe_2_requests.lua @@ -7,8 +7,8 @@ -- -- Description: -- In case --- 1. Mobile app requested GetInteriorVD(module_1, without subscribe parameter) and HMI sent GetInteriorVD to HMI --- 2. Mobile app GetInteriorVD(module_1, without subscribe parameter) request +-- 1. Mobile app requested GetInteriorVD(module_1, without subscribe parameter) and SDL sent GetInteriorVD to HMI +-- 2. Mobile app GetInteriorVD(module_1, without subscribe parameter) request -- SDL must -- 1. send GetInteriorVD(module_1, without subscribe parameter) request to HMI --------------------------------------------------------------------------------------------------- diff --git a/test_scripts/RC/InteriorVehicleData_cache/003_GetInteriorVD_without_subscribe_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/003_GetInteriorVD_without_subscribe_2_apps.lua index 9353ed5922..31f789d6c9 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/003_GetInteriorVD_without_subscribe_2_apps.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/003_GetInteriorVD_without_subscribe_2_apps.lua @@ -7,7 +7,7 @@ -- -- Description: -- In case --- 1. Mobile app1 requested GetInteriorVD(module_1, without subscribe parameter) and HMI sent GetInteriorVD to HMI +-- 1. Mobile app1 requested GetInteriorVD(module_1, without subscribe parameter) and SDL sent GetInteriorVD to HMI -- 2. Mobile app2 GetInteriorVD(module_1, without subscribe parameter) request -- SDL must -- 1. send GetInteriorVD(module_1, without subscribe parameter) request to HMI From aec9bbf151feb4f6218068d9a30a381863897cfb Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Mon, 20 Aug 2018 12:41:33 +0300 Subject: [PATCH 607/681] Expand tests for InteriorVD management with new modules --- .../common_interiorVDcache.lua | 159 +++++++++++++++++- 1 file changed, 157 insertions(+), 2 deletions(-) diff --git a/test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache.lua b/test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache.lua index 0c17b8e19c..de8aa887e5 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache.lua @@ -25,8 +25,11 @@ config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application1.registerAppInterfaceParams.isMediaApplication = true config.application2.registerAppInterfaceParams.isMediaApplication = false +config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 +config.application2.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 -m.modules = { "CLIMATE", "RADIO" } + +m.modules = { "RADIO", "CLIMATE", "SEAT", "AUDIO", "LIGHT", "HMI_SETTINGS" } m.actualInteriorDataStateOnHMI = { CLIMATE = { @@ -67,6 +70,76 @@ m.actualInteriorDataStateOnHMI = { signalChangeThreshold = 10, radioEnable = true, state = "ACQUIRING" + }, + SEAT = { + id = "DRIVER", + heatingEnabled = true, + coolingEnabled = true, + heatingLevel = 50, + coolingLevel = 50, + horizontalPosition = 50, + verticalPosition = 50, + frontVerticalPosition = 50, + backVerticalPosition = 50, + backTiltAngle = 50, + headSupportHorizontalPosition = 50, + headSupportVerticalPosition = 50, + massageEnabled = true, + massageMode = { + { + massageZone = "LUMBAR", + massageMode = "HIGH" + }, + { + massageZone = "SEAT_CUSHION", + massageMode = "LOW" + } + }, + massageCushionFirmness = { + { + cushion = "TOP_LUMBAR", + firmness = 30 + }, + { + cushion = "BACK_BOLSTERS", + firmness = 60 + } + }, + memory = { + id = 1, + label = "Label value", + action = "SAVE" + } + }, + AUDIO = { + source = "AM", + volume = 50, + equalizerSettings = { + { + channelId = 10, + channelName = "Channel 1", + channelSetting = 50 + } + } + }, + LIGHT = { + lightState = { + { + id = "FRONT_LEFT_HIGH_BEAM", + status = "ON", + density = 0.2, + color = { + red = 50, + green = 150, + blue = 200 + } + } + } + }, + HMI_SETTINGS = { + displayMode = "DAY", + temperatureUnit = "CELSIUS", + distanceUnit = "KILOMETERS" } } @@ -92,7 +165,7 @@ function m.updatePreloadedPT() preloadedTable.policy_table.functional_groupings["RemoteControl"].rpcs.OnRCStatus = { hmi_levels = { "FULL", "BACKGROUND", "LIMITED", "NONE" } } - preloadedTable.policy_table.app_policies.default.moduleType = { "RADIO", "CLIMATE" } + preloadedTable.policy_table.app_policies.default.moduleType = m.modules preloadedTable.policy_table.app_policies.default.groups = { "Base-4", "RemoteControl" } preloadedTable.policy_table.app_policies.default.AppHMIType = { "REMOTE_CONTROL" } m.tableToJsonFile(preloadedTable, preloadedFile) @@ -154,6 +227,14 @@ function m.getModuleControlData(module_type, pParams) out.climateControlData = pParams elseif module_type == "RADIO" then out.radioControlData = pParams + elseif module_type == "SEAT" then + out.seatControlData = pParams + elseif module_type == "AUDIO" then + out.audioControlData = pParams + elseif module_type == "LIGHT" then + out.lightControlData = pParams + elseif module_type == "HMI_SETTINGS" then + out.hmiSettingsControlData = pParams end return out end @@ -262,6 +343,80 @@ function m.getAnotherModuleControlData(module_type) radioEnable = true, state = "ACQUIRING" } + elseif module_type == "SEAT" then + out = { + id = "DRIVER", + heatingEnabled = true, + coolingEnabled = false, + heatingLevel = 35, + coolingLevel = 35, + horizontalPosition = 50, + verticalPosition = 50, + frontVerticalPosition = 50, + backVerticalPosition = 50, + backTiltAngle = 50, + headSupportHorizontalPosition = 50, + headSupportVerticalPosition = 50, + massageEnabled = true, + massageMode = { + { + massageZone = "LUMBAR", + massageMode = "HIGH" + }, + { + massageZone = "SEAT_CUSHION", + massageMode = "LOW" + } + }, + massageCushionFirmness = { + { + cushion = "TOP_LUMBAR", + firmness = 30 + }, + { + cushion = "BACK_BOLSTERS", + firmness = 60 + } + }, + memory = { + id = 1, + label = "Label value", + action = "SAVE" + } + } + elseif module_type == "AUDIO" then + out = { + source = "AM", + volume = 35, + equalizerSettings = { + { + channelId = 10, + channelName = "Channel 1", + channelSetting = 50 + } + } + } + elseif module_type == "LIGHT" then + out = { + lightState = { + { + id = "FRONT_RIGHT_HIGH_BEAM", + status = "ON", + density = 0.4, + color = { + red = 45, + green = 145, + blue = 190 + } + } + } + } + elseif module_type == "HMI_SETTINGS" then + out = { + displayMode = "DAY", + temperatureUnit = "CELSIUS", + distanceUnit = "KILOMETERS" + } end return out end From b7263027fb81a789cd5bc365c88cae20cf43f9bf Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Mon, 20 Aug 2018 16:33:11 +0300 Subject: [PATCH 608/681] Expand common for OnRCStatus with new modules within IVD management feature --- .../RC/OnRCStatus/commonOnRCStatus.lua | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua index 056233f02a..398aa440f2 100644 --- a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua +++ b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua @@ -435,7 +435,10 @@ end commonRC.actualInteriorDataStateOnHMI = { CLIMATE = utils.cloneTable(commonRC.getModuleControlData("CLIMATE")), RADIO = utils.cloneTable(commonRC.getModuleControlData("RADIO")), - SEAT = utils.cloneTable(commonRC.getModuleControlData("SEAT")) + SEAT = utils.cloneTable(commonRC.getModuleControlData("SEAT")), + AUDIO = utils.cloneTable(commonRC.getModuleControlData("AUDIO")), + LIGHT = utils.cloneTable(commonRC.getModuleControlData("LIGHT")), + HMI_SETTINGS = utils.cloneTable(commonRC.getModuleControlData("HMI_SETTINGS")) } local setActualInteriorVDorigin = commonRC.setActualInteriorVD @@ -452,6 +455,42 @@ function commonRC.setActualInteriorVD(pModuleType, pParams) end end end + elseif pModuleType == "AUDIO" then + for key, value in pairs(pParams["audioControlData"]) do + if type(value) ~= "table" then + if value ~= commonRC.actualInteriorDataStateOnHMI[pModuleType]["audioControlData"][key] then + commonRC.actualInteriorDataStateOnHMI[pModuleType]["audioControlData"][key] = value + end + else + if false == commonFunctions:is_table_equal(value, commonRC.actualInteriorDataStateOnHMI[pModuleType]["audioControlData"][key]) then + commonRC.actualInteriorDataStateOnHMI[pModuleType]["audioControlData"][key] = value + end + end + end + elseif pModuleType == "LIGHT" then + for key, value in pairs(pParams["lightControlData"]) do + if type(value) ~= "table" then + if value ~= commonRC.actualInteriorDataStateOnHMI[pModuleType]["lightControlData"][key] then + commonRC.actualInteriorDataStateOnHMI[pModuleType]["lightControlData"][key] = value + end + else + if false == commonFunctions:is_table_equal(value, commonRC.actualInteriorDataStateOnHMI[pModuleType]["lightControlData"][key]) then + commonRC.actualInteriorDataStateOnHMI[pModuleType]["lightControlData"][key] = value + end + end + end + elseif pModuleType == "HMI_SETTINGS" then + for key, value in pairs(pParams["hmiSettingsControlData"]) do + if type(value) ~= "table" then + if value ~= commonRC.actualInteriorDataStateOnHMI[pModuleType]["hmiSettingsControlData"][key] then + commonRC.actualInteriorDataStateOnHMI[pModuleType]["hmiSettingsControlData"][key] = value + end + else + if false == commonFunctions:is_table_equal(value, commonRC.actualInteriorDataStateOnHMI[pModuleType]["hmiSettingsControlData"][key]) then + commonRC.actualInteriorDataStateOnHMI[pModuleType]["hmiSettingsControlData"][key] = value + end + end + end else setActualInteriorVDorigin(pModuleType, pParams) end From c728b209ab17bf3e28737d90eee8877e3abd9dcf Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Mon, 20 Aug 2018 19:08:05 +0300 Subject: [PATCH 609/681] Update for new modules within IVD management feature --- .../006_RPC_parameters_values.lua | 1 - ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 1 - ..._in_case_HMI_respond_with_invalid_data.lua | 2 - ...ROR_in_case_HMI_respond_with_READ_ONLY.lua | 1 - ...ransfering_of_HMI_resultCode_to_mobile.lua | 2 - ...ut_response_from_HMI_with_isSubscribed.lua | 1 - ...ase_of_2nd_Subscription_UnSubscription.lua | 10 +-- ...response_from_HMI_without_isSubscribed.lua | 21 ++--- .../016_RADIO_GPSdata_in_HMI_response.lua | 1 - .../017_Success_audio_source_values.lua | 2 + ...ribing_with_isSubscribe_false_from_HMI.lua | 1 - ...cribing_with_isSubscribe_true_from_HMI.lua | 1 - ...bscribing_without_isSubscribe_from_HMI.lua | 1 - ...bscribing_without_isSubscribe_from_HMI.lua | 1 - .../commonRCmodules.lua | 80 +++++++++++++++++-- 15 files changed, 94 insertions(+), 32 deletions(-) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua index d6a6351f97..75decaa4ed 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua @@ -75,7 +75,6 @@ local function fakeParam(pModuleType) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = common.getHMIAppId(), moduleType = pModuleType, subscribe = true }) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index 6701c0a2c1..7e974b8e89 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -32,7 +32,6 @@ local function getDataForModule(pModuleType) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = common.getHMIAppId(), moduleType = pModuleType, subscribe = true }) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index 23891efbfc..7923c37b93 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -34,7 +34,6 @@ local function invalidParamType(pModuleType) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = common.getHMIAppId(), moduleType = pModuleType, subscribe = true }) @@ -56,7 +55,6 @@ local function missingMandatoryParam(pModuleType) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = common.getHMIAppId(), moduleType = pModuleType, subscribe = true }) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua index bd2a47fef8..81ab15f0e8 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -32,7 +32,6 @@ local function getDataForModule(module_type) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = common.getHMIAppId(), moduleType = module_type, subscribe = true }) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua index fcef64b4dd..bcc69527ff 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua @@ -34,7 +34,6 @@ local function stepSuccessfull(pModuleType, pResultCode) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = common.getHMIAppId(), moduleType = pModuleType, subscribe = true }) @@ -59,7 +58,6 @@ local function stepUnsuccessfull(pModuleType, pResultCode) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = common.getHMIAppId(), moduleType = pModuleType, subscribe = true }) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index 105350555b..01f18fc30a 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -31,7 +31,6 @@ local function getDataForModule(pModuleType, isSubscriptionActive) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = common.getHMIAppId(), moduleType = pModuleType }) :Do(function(_, data) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua index 5cbd7c6b4c..ebbcd4367b 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua @@ -34,7 +34,7 @@ local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function subscriptionToModule(pModuleType, pSubscribe) +local function subscriptionToModule(pModuleType, pSubscribe, pHMIReqTimes) local mobileSession = common.getMobileSession() local cid = mobileSession:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, @@ -42,7 +42,6 @@ local function subscriptionToModule(pModuleType, pSubscribe) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = common.getHMIAppId(), moduleType = pModuleType }) :Do(function(_, data) @@ -57,6 +56,7 @@ local function subscriptionToModule(pModuleType, pSubscribe) end return false, 'Parameter "subscribe" is transfered to HMI with value: ' .. tostring(data.params.subscribe) end) + :Times(pHMIReqTimes) mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = common.getModuleControlDataForResponse(pModuleType), @@ -75,7 +75,7 @@ runner.Title("Test") for _, mod in pairs(common.modules) do -- app has not subscribed yet - runner.Step("Unsubscribe app to " .. mod, subscriptionToModule, { mod, false }) + runner.Step("Unsubscribe app to " .. mod, subscriptionToModule, { mod, false, 1 }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", common.isUnsubscribed, { mod }) @@ -85,7 +85,7 @@ for _, mod in pairs(common.modules) do { mod }) -- subscribe to module 2nd time - runner.Step("Subscribe 2nd time app to " .. mod, subscriptionToModule, { mod, true }) + runner.Step("Subscribe 2nd time app to " .. mod, subscriptionToModule, { mod, true, 0 }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", common.isSubscribed, { mod }) @@ -95,7 +95,7 @@ for _, mod in pairs(common.modules) do { mod }) -- unsubscribe to module 2nd time - runner.Step("Unsubscribe 2nd time app to " .. mod, subscriptionToModule, { mod, false }) + runner.Step("Unsubscribe 2nd time app to " .. mod, subscriptionToModule, { mod, false, 1 }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", common.isUnsubscribed, { mod }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua index 6df7c061c8..718c2d64ce 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -23,7 +23,7 @@ local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe) +local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, pHMIreqCount, isCheckSubscribeAbsence) local mobileSession = common.getMobileSession() local cid = mobileSession:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, @@ -36,7 +36,6 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe) end EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = common.getHMIAppId(), moduleType = pModuleType }) :Do(function(_, data) @@ -46,11 +45,15 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe) }) end) :ValidIf(function(_, data) - if data.params.subscribe == pSubscribeHMI then - return true + if isCheckSubscribeAbsence == true then + if data.params.subscribe == pSubscribeHMI then + return true + end + return false, 'Parameter "subscribe" is transfered to HMI with value: ' .. tostring(data.params.subscribe) end - return false, 'Parameter "subscribe" is transfered to HMI with value: ' .. tostring(data.params.subscribe) + return true end) + :Times(pHMIreqCount) mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", isSubscribed = isSubscriptionActive, -- return current value of subscription @@ -69,17 +72,17 @@ runner.Title("Test") for _, mod in pairs(common.modules) do runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription_subscribe", getDataForModule, - { mod, false, true }) + { mod, false, true, 1 ,true }) runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription_unsubscribe", getDataForModule, - { mod, false, false }) + { mod, false, false, 1, true }) end for _, mod in pairs(common.modules) do runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, - { mod, true, true }) + { mod, true, true, 0 }) runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_unsubscribe", getDataForModule, - { mod, true, false }) + { mod, true, false, 1, false }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua index 08131ad97b..3435adbf72 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua @@ -94,7 +94,6 @@ local function getDataForModule(pStationLocationParams, isSuccess) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = common.getHMIAppId(), moduleType = moduleName }) :Do(function(_, data) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua index ea7f9614bc..62eb80e567 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua @@ -16,6 +16,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local utils = require("user_modules/utils") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -42,6 +43,7 @@ local function subscribeToModule(pAudioSources) end return true end) + utils.wait(500) end --[[ Scenario ]] diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua index 63c1de1647..5c293fe8c4 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -34,7 +34,6 @@ local function subscriptionToModule(pModuleType) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = common.getHMIAppId(), moduleType = pModuleType, subscribe = true }) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua index 4ca483025f..704b8c979f 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua @@ -35,7 +35,6 @@ local function unSubscriptionToModule(pModuleType) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = common.getHMIAppId(), moduleType = pModuleType, subscribe = false }) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua index 0ba691b995..f78812383a 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -35,7 +35,6 @@ local function unSubscriptionToModule(pModuleType) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = common.getHMIAppId(), moduleType = pModuleType, subscribe = false }) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua index 23193d50e3..eec824c480 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -37,7 +37,6 @@ local function unSubscriptionToModule(pModuleType, pResultCode) }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - appID = common.getHMIAppId(), moduleType = pModuleType, subscribe = false }) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua index cb3d3e39ac..58952e11f1 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua @@ -12,6 +12,7 @@ local test = require("user_modules/dummy_connecttest") local hmi_values = require("user_modules/hmi_values") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local utils = require("user_modules/utils") --[[ Local Variables ]] local c = {} @@ -303,15 +304,14 @@ local rcRPCs = { subscribe = pSubscribe } end, - hmiRequestParams = function(pModuleType, pAppId, pSubscribe) + hmiRequestParams = function(pModuleType, _, pSubscribe) return { - appID = c.getHMIAppId(pAppId), moduleType = pModuleType, subscribe = pSubscribe } end, hmiResponseParams = function(pModuleType, pSubscribe) - local GetInteriorVDModuleData = c.getModuleControlData(pModuleType) + local GetInteriorVDModuleData = commonRC.actualInteriorDataStateOnHMI[pModuleType] if GetInteriorVDModuleData.audioControlData then GetInteriorVDModuleData.audioControlData.keepContext = nil end @@ -321,7 +321,7 @@ local rcRPCs = { } end, responseParams = function(success, resultCode, pModuleType, pSubscribe) - local GetInteriorVDModuleData = c.getModuleControlData(pModuleType) + local GetInteriorVDModuleData = commonRC.actualInteriorDataStateOnHMI[pModuleType] if GetInteriorVDModuleData.audioControlData then GetInteriorVDModuleData.audioControlData.keepContext = nil end @@ -478,7 +478,9 @@ function c.subscribeToModule(pModuleType, pAppId) :Do(function(_, data) test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", c.getHMIResponseParams(rpc, pModuleType, subscribe)) + commonRC.setActualInteriorVD(pModuleType, c.getHMIResponseParams(rpc, pModuleType, subscribe).moduleData) end) + :Times(AtMost(1)) mobSession:ExpectResponse(cid, c.getAppResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) :ValidIf(function(_,data) if "AUDIO" == pModuleType and @@ -498,7 +500,9 @@ function c.unSubscribeToModule(pModuleType, pAppId) :Do(function(_, data) test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", c.getHMIResponseParams(rpc, pModuleType, subscribe)) + commonRC.setActualInteriorVD(pModuleType, c.getHMIResponseParams(rpc, pModuleType, subscribe).moduleData) end) + :Times(AtMost(1)) mobSession:ExpectResponse(cid, c.getAppResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) :ValidIf(function(_,data) if "AUDIO" == pModuleType and @@ -552,6 +556,7 @@ function c.isSubscribed(pModuleType, pAppId) local mobSession = c.getMobileSession(pAppId) local rpc = "OnInteriorVehicleData" test.hmiConnection:SendNotification(c.getHMIEventName(rpc), c.getHMIResponseParams(rpc, pModuleType)) + commonRC.setActualInteriorVD(pModuleType, c.getHMIResponseParams(rpc, pModuleType).moduleData) mobSession:ExpectNotification(c.getAppEventName(rpc), c.getAppResponseParams(rpc, pModuleType)) :ValidIf(function(_,data) if "AUDIO" == pModuleType and @@ -566,6 +571,7 @@ function c.isUnsubscribed(pModuleType, pAppId) local mobSession = c.getMobileSession(pAppId) local rpc = "OnInteriorVehicleData" test.hmiConnection:SendNotification(c.getHMIEventName(rpc), c.getHMIResponseParams(rpc, pModuleType)) + commonRC.setActualInteriorVD(pModuleType, c.getHMIResponseParams(rpc, pModuleType).moduleData) mobSession:ExpectNotification(c.getAppEventName(rpc), {}):Times(0) end @@ -632,11 +638,75 @@ function c.updateDefaultCapabilities(pDisabledModuleTypes) end function c.getModuleControlDataForResponse(pModuleType) - local moduleData = c.getModuleControlData(pModuleType) + local moduleData = commonRC.actualInteriorDataStateOnHMI[pModuleType] if moduleData.audioControlData then moduleData.audioControlData.keepContext = nil end return moduleData end +commonRC.actualInteriorDataStateOnHMI = { + CLIMATE = utils.cloneTable(c.getModuleControlData("CLIMATE")), + RADIO = utils.cloneTable(c.getModuleControlData("RADIO")), + SEAT = utils.cloneTable(c.getModuleControlData("SEAT")), + AUDIO = utils.cloneTable(c.getModuleControlData("AUDIO")), + LIGHT = utils.cloneTable(c.getModuleControlData("LIGHT")), + HMI_SETTINGS = utils.cloneTable(c.getModuleControlData("HMI_SETTINGS")) +} + +local setActualInteriorVDorigin = commonRC.setActualInteriorVD +function commonRC.setActualInteriorVD(pModuleType, pParams) + if pModuleType == "SEAT" then + for key, value in pairs(pParams["seatControlData"]) do + if type(value) ~= "table" then + if value ~= commonRC.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] then + commonRC.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] = value + end + else + if false == commonFunctions:is_table_equal(value, commonRC.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key]) then + commonRC.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] = value + end + end + end + elseif pModuleType == "AUDIO" then + for key, value in pairs(pParams["audioControlData"]) do + if type(value) ~= "table" then + if value ~= commonRC.actualInteriorDataStateOnHMI[pModuleType]["audioControlData"][key] then + commonRC.actualInteriorDataStateOnHMI[pModuleType]["audioControlData"][key] = value + end + else + if false == commonFunctions:is_table_equal(value, commonRC.actualInteriorDataStateOnHMI[pModuleType]["audioControlData"][key]) then + commonRC.actualInteriorDataStateOnHMI[pModuleType]["audioControlData"][key] = value + end + end + end + elseif pModuleType == "LIGHT" then + for key, value in pairs(pParams["lightControlData"]) do + if type(value) ~= "table" then + if value ~= commonRC.actualInteriorDataStateOnHMI[pModuleType]["lightControlData"][key] then + commonRC.actualInteriorDataStateOnHMI[pModuleType]["lightControlData"][key] = value + end + else + if false == commonFunctions:is_table_equal(value, commonRC.actualInteriorDataStateOnHMI[pModuleType]["lightControlData"][key]) then + commonRC.actualInteriorDataStateOnHMI[pModuleType]["lightControlData"][key] = value + end + end + end + elseif pModuleType == "HMI_SETTINGS" then + for key, value in pairs(pParams["hmiSettingsControlData"]) do + if type(value) ~= "table" then + if value ~= commonRC.actualInteriorDataStateOnHMI[pModuleType]["hmiSettingsControlData"][key] then + commonRC.actualInteriorDataStateOnHMI[pModuleType]["hmiSettingsControlData"][key] = value + end + else + if false == commonFunctions:is_table_equal(value, commonRC.actualInteriorDataStateOnHMI[pModuleType]["hmiSettingsControlData"][key]) then + commonRC.actualInteriorDataStateOnHMI[pModuleType]["hmiSettingsControlData"][key] = value + end + end + end + else + setActualInteriorVDorigin(pModuleType, pParams) + end +end + return c From 390a9f3dcf66302ec8b6790c7accb954e099183c Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 22 Aug 2018 15:43:11 +0300 Subject: [PATCH 610/681] Update scripts for CLIMATE and RADIO with new initial RC common --- ...001_success_flow_for_climate_and_radio.lua | 62 +- ...02_disallow_flow_by_policy_for_climate.lua | 30 +- .../003_disallow_flow_by_policy_for_radio.lua | 30 +- ..._processing_button_press_for_nonRC_App.lua | 47 +- ...e_and_moduleType_for_radio_and_climate.lua | 54 +- ..._check_rpc_parameters_for_button_press.lua | 52 +- ...n_press_allowed_if_moduleType_is_empty.lua | 37 +- ...ess_disallowed_if_moduleType_is_absent.lua | 33 +- ...f_moduleType_is_disallowed_by_policies.lua | 33 +- ..._generic_error_if_no_response_from_hmi.lua | 18 +- ...or_if_read_only_response_come_from_hmi.lua | 20 +- ...ric_error_if_invalid_response_from_hmi.lua | 20 +- ...ransfering_of_HMI_resultCode_to_mobile.lua | 32 +- .../001_All_modules_all_params.lua | 21 +- .../002_Only_CLIMATE_all_params.lua | 16 +- .../003_Only_RADIO_all_params.lua | 16 +- ..._supported_parameter_and_reject_others.lua | 29 +- .../005_Resend_only_supported_parameters.lua | 24 +- ...supported_and_not_supported_parameters.lua | 27 +- ...f_HMI_respond_to_RC_IsReady_with_false.lua | 27 +- ...nt_respond_to_RC_GetCapabilities_RADIO.lua | 41 +- ..._respond_to_RC_GetCapabilities_CLIMATE.lua | 41 +- ...nt_respond_to_RC_GetCapabilities_RADIO.lua | 41 +- ..._respond_to_RC_GetCapabilities_CLIMATE.lua | 41 +- ...d_responds_to_RC_GetCapabilities_RADIO.lua | 55 +- ...responds_to_RC_GetCapabilities_CLIMATE.lua | 55 +- .../001_Success_flow.lua | 10 +- .../002_Disallow_flow_by_policy_CLIMATE.lua | 29 +- .../003_Disallow_flow_by_policy_RADIO.lua | 29 +- ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 32 +- ...ransfering_of_HMI_resultCode_to_mobile.lua | 28 +- .../006_RPC_parameters_values.lua | 36 +- ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 16 +- ..._in_case_HMI_respond_with_invalid_data.lua | 26 +- ...se_moduleType_is_an_empty_array_in_LPT.lua | 40 +- ...ow_in_case_moduleType_is_absent_in_LPT.lua | 33 +- ...ROR_in_case_HMI_respond_with_READ_ONLY.lua | 18 +- ...response_from_HMI_without_isSubscribed.lua | 20 +- ...ut_response_from_HMI_with_isSubscribed.lua | 20 +- ...ase_of_2nd_Subscription_UnSubscription.lua | 18 +- .../001_Consent_true_SIVD.lua | 19 +- .../002_Consent_true_BP.lua | 19 +- .../003_Consent_false_SIVD.lua | 19 +- .../004_Consent_false_BP.lua | 19 +- .../005_TIMED_OUT_from_HMI_SIVD.lua | 24 +- .../006_TIMED_OUT_from_HMI_BP.lua | 24 +- .../007_HMI_no_response_SIVD.lua | 22 +- .../008_HMI_no_response_BP.lua | 22 +- .../009_HMI_invalid_response_SIVD.lua | 24 +- .../010_HMI_invalid_response_BP.lua | 24 +- .../011_TIMED_OUT_after_default_timeout.lua | 23 +- .../GetSystemCapability/001_Success_flow.lua | 38 +- .../001_Success_flow.lua | 12 +- .../002_Disallow_flow_by_policy_CLIMATE.lua | 12 +- .../003_Disallow_flow_by_policy_RADIO.lua | 12 +- ...ribing_with_isSubscribe_false_from_HMI.lua | 18 +- ...bscribing_without_isSubscribe_from_HMI.lua | 18 +- ...ase_of_subscribing_with_error_from_HMI.lua | 18 +- ..._subscribing_with_no_response_from_HMI.lua | 16 +- ...cribing_with_invalid_response_from_HMI.lua | 18 +- ...cribing_with_isSubscribe_true_from_HMI.lua | 20 +- ...bscribing_without_isSubscribe_from_HMI.lua | 20 +- ...bscribing_without_isSubscribe_from_HMI.lua | 20 +- ...imate_and_without_one_for_module_Radio.lua | 7 +- ...dio_and_without_one_for_module_Climate.lua | 7 +- ...nd_after_unsubscribe_from_module_Radio.lua | 10 +- ..._after_unsubscribe_from_module_Climate.lua | 10 +- .../016_RPC_parameters_values.lua | 30 +- .../001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua | 19 +- .../002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua | 19 +- .../003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua | 19 +- .../004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua | 19 +- ...005_REJECTED_in_case_nonFULL_HMI_level.lua | 19 +- .../006_IN_USE_in_case_2_requests.lua | 39 +- .../007_IN_USE_in_case_AUTO_DENY.lua | 19 +- .../008_Allowed_false.lua | 49 +- ...009_Allowed_true_accessMode_AUTO_ALLOW.lua | 24 +- .../010_Allowed_true_accessMode_AUTO_DENY.lua | 24 +- ...011_Allowed_true_accessMode_ASK_DRIVER.lua | 27 +- .../012_Default_accessMode.lua | 21 +- .../013_sequence_switches_of_accessMode.lua | 75 +- .../014_Invalid_data_from_HMI.lua | 28 +- .../015_Empty_data_from_HMI.lua | 28 +- ...DENY_for_app_with_reject_in_ASK_DRIVER.lua | 20 +- ...017_Release_resource_on_unregister_app.lua | 24 +- ...low_for_rejected_app_on_unregister_app.lua | 24 +- .../019_Release_resource_on_RC_disable.lua | 25 +- ...20_Restore_accessMode_after_RC_disable.lua | 41 +- .../021_Release_resource_on_exit_app.lua | 23 +- ...e_resource_on_PTU_with_module_disallow.lua | 21 +- ...lease_resource_on_PTU_with_app_revoked.lua | 15 +- .../024_Allowed_false_no_PTU.lua | 48 +- .../025_IN_USE_in_case_3_requests.lua | 100 +-- .../001_Success_flow.lua | 31 +- .../002_Disallow_flow_by_policy_CLIMATE.lua | 28 +- .../003_Disallow_flow_by_policy_RADIO.lua | 28 +- ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 33 +- ...rams_does_not_correspond_to_moduleType.lua | 16 +- .../006_RPC_parameters_values.lua | 38 +- ...se_moduleType_is_an_empty_array_in_LPT.lua | 35 +- ...ow_in_case_moduleType_is_absent_in_LPT.lua | 31 +- ...09_Cut-off_of_fake_parameters_from_App.lua | 16 +- ...cle_data_if_read_only_params_requested.lua | 13 +- ...read-only_and_not_read-only_parameters.lua | 109 +-- ...y_parameters_and_HMI_returns_READ_ONLY.lua | 38 +- ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 18 +- ..._in_case_HMI_respond_with_invalid_data.lua | 30 +- ...ransfering_of_HMI_resultCode_to_mobile.lua | 32 +- ..._RESOURCE_hdRadioEnableAvailable_false.lua | 7 +- ...ESOURCE_hdRadioEnableAvailable_omitted.lua | 7 +- .../018_Success_flow_band_setting.lua | 27 +- ..._RESOURCE_siriusxmRadioAvailable_false.lua | 13 +- ...ESOURCE_siriusxmRadioAvailable_omitted.lua | 13 +- ..._in_case_invalid_data_in_hdRadioEnable.lua | 13 +- ...022_availableHDs_hdChannel_upper_bound.lua | 33 +- ...ilableHDs_hdChannel_out_of_upper_bound.lua | 19 +- test_scripts/RC/commonRC.lua | 767 +++++++++++------- user_modules/sequences/actions.lua | 17 + 118 files changed, 1864 insertions(+), 2100 deletions(-) diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/001_success_flow_for_climate_and_radio.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/001_success_flow_for_climate_and_radio.lua index 916f2d7ad1..dd1ab7fb1f 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/001_success_flow_for_climate_and_radio.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/001_success_flow_for_climate_and_radio.lua @@ -18,57 +18,31 @@ local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') ---[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession1:SendRPC("ButtonPress", { - moduleType = "CLIMATE", - buttonName = "AC", - buttonPressMode = "SHORT" - }) - - EXPECT_HMICALL("Buttons.ButtonPress", { - appID = self.applications["Test Application"], - moduleType = "CLIMATE", - buttonName = "AC", - buttonPressMode = "SHORT" - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - -local function step2(self) - local cid = self.mobileSession1:SendRPC("ButtonPress", { - moduleType = "RADIO", - buttonName = "VOLUME_UP", - buttonPressMode = "LONG" - }) - - EXPECT_HMICALL("Buttons.ButtonPress", { - appID = self.applications["Test Application"], - moduleType = "RADIO", - buttonName = "VOLUME_UP", - buttonPressMode = "LONG" - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local paramsStep1 = { + moduleType = "CLIMATE", + buttonName = "AC", + buttonPressMode = "SHORT" +} +local paramsStep2 = { + moduleType = "RADIO", + buttonName = "VOLUME_UP", + buttonPressMode = "LONG" +} --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -runner.Step("ButtonPress_CLIMATE", step1) -runner.Step("ButtonPress_RADIO", step2) +runner.Step("ButtonPress_CLIMATE", commonRC.rpcButtonPress, { paramsStep1, 1}) +runner.Step("ButtonPress_RADIO", commonRC.rpcButtonPress, { paramsStep2, 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua index c393bd0497..a7aae21a20 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua @@ -21,37 +21,25 @@ --[[ Required Shared libraries ]] local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') ---[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession1:SendRPC("ButtonPress", { - moduleType = "CLIMATE", - buttonName = "AC", - buttonPressMode = "SHORT" - }) - - EXPECT_HMICALL("Buttons.ButtonPress") - :Times(0) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function ptu_update_func(tbl) +--[[ Local Functions ]] +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -runner.Step("ButtonPress_CLIMATE", step1) +runner.Step("ButtonPress_CLIMATE", commonRC.rpcDenied, {"CLIMATE", 1, "ButtonPress", "DISALLOWED"}) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/003_disallow_flow_by_policy_for_radio.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/003_disallow_flow_by_policy_for_radio.lua index 71c37d1a46..58ed6d1ff7 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/003_disallow_flow_by_policy_for_radio.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/003_disallow_flow_by_policy_for_radio.lua @@ -21,37 +21,25 @@ --[[ Required Shared libraries ]] local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') ---[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession1:SendRPC("ButtonPress", { - moduleType = "RADIO", - buttonName = "VOLUME_UP", - buttonPressMode = "LONG" - }) - - EXPECT_HMICALL("Buttons.ButtonPress") - :Times(0) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function ptu_update_func(tbl) +--[[ Local Functions ]] +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -runner.Step("ButtonPress_RADIO", step1) +runner.Step("ButtonPress_RADIO", commonRC.rpcDenied, {"RADIO", 1, "ButtonPress", "DISALLOWED"}) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua index 974147748c..3defc6fc8e 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua @@ -16,57 +16,30 @@ --[[ Required Shared libraries ]] local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ General configuration parameters ]] config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } --[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession1:SendRPC("ButtonPress", { - moduleType = "CLIMATE", - buttonName = "AC", - buttonPressMode = "SHORT" - }) - - EXPECT_HMICALL("Buttons.ButtonPress") - :Times(0) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function step2(self) - local cid = self.mobileSession1:SendRPC("ButtonPress", { - moduleType = "RADIO", - buttonName = "VOLUME_UP", - buttonPressMode = "LONG" - }) - - EXPECT_HMICALL("Buttons.ButtonPress") - :Times(0) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function ptu_update_func(tbl) +local function PTUfunc(tbl) local appId = config.application1.registerAppInterfaceParams.appID tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -runner.Step("ButtonPress_CLIMATE", step1) -runner.Step("ButtonPress_RADIO", step2) +runner.Step("ButtonPress_CLIMATE", commonRC.rpcDenied, {"CLIMATE", 1, "ButtonPress", "DISALLOWED"}) +runner.Step("ButtonPress_RADIO", commonRC.rpcDenied, {"RADIO", 1, "ButtonPress", "DISALLOWED"}) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua index 3669dfc574..8a2d165247 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua @@ -16,50 +16,32 @@ --[[ Required Shared libraries ]] local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') - ---[[ Local Functions ]] -local function step1(self) - local cid = self.mobileSession1:SendRPC("ButtonPress", { - moduleType = "CLIMATE", - buttonName = "VOLUME_UP", - buttonPressMode = "SHORT" - }) - - EXPECT_HMICALL("Buttons.ButtonPress") - :Times(0) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function step2(self) - local cid = self.mobileSession1:SendRPC("ButtonPress", { - moduleType = "RADIO", - buttonName = "AC", - buttonPressMode = "LONG" - }) - - EXPECT_HMICALL("Buttons.ButtonPress") - :Times(0) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +-- [[ Local Variables ]] +local paramsStep1 = { + moduleType = "CLIMATE", + buttonName = "VOLUME_UP", + buttonPressMode = "SHORT" +} +local paramsStep2 = { + moduleType = "RADIO", + buttonName = "AC", + buttonPressMode = "LONG" +} --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -runner.Step("ButtonPress_CLIMATE", step1) -runner.Step("ButtonPress_RADIO", step2) +runner.Step("ButtonPress_CLIMATE", commonRC.rpcDeniedWithCustomParams, {paramsStep1, 1, "ButtonPress", "INVALID_DATA"}) +runner.Step("ButtonPress_RADIO", commonRC.rpcDeniedWithCustomParams, {paramsStep2, 1, "ButtonPress", "INVALID_DATA"}) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/006_check_rpc_parameters_for_button_press.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/006_check_rpc_parameters_for_button_press.lua index e09ae541d5..12bf09bec3 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/006_check_rpc_parameters_for_button_press.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/006_check_rpc_parameters_for_button_press.lua @@ -16,7 +16,9 @@ --[[ Required Shared libraries ]] local commonRC = require('test_scripts/RC/commonRC') local runner = require('user_modules/script_runner') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local variables for tests ]] local climate_button_names = { @@ -52,49 +54,21 @@ local function reset_radio_params() return {moduleType = "RADIO", buttonName = "VOLUME_UP", buttonPressMode = "SHORT"} end -local function SendButtonPressPositive(button_press_params, self) - local cid = self.mobileSession1:SendRPC("ButtonPress", button_press_params) - - EXPECT_HMICALL("Buttons.ButtonPress", { - appID = self.applications["Test Application"], - moduleType = button_press_params.moduleType, - buttonName = button_press_params.buttonName, - buttonPressMode = button_press_params.buttonPressMode - }) - :Times(1) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - -local function SendButtonPressNegative(button_press_params, self) - local cid = self.mobileSession1:SendRPC("ButtonPress", button_press_params) - - EXPECT_HMICALL("Buttons.ButtonPress") - :Times(0) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - --[[ Positive Scenario - check all positive climate names params]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) for _, button_name_value in pairs( climate_button_names ) do local climate_params = reset_climate_params() climate_params.buttonPressMode = "SHORT" climate_params.buttonName = button_name_value runner.Title("Test - ButtonPress with buttonName " .. button_name_value) - runner.Step("ButtonPress_CLIMATE_" .. button_name_value .. "_SHORT", SendButtonPressPositive, {climate_params}) + runner.Step("ButtonPress_CLIMATE_" .. button_name_value .. "_SHORT", commonRC.rpcButtonPress, {climate_params, 1}) climate_params.buttonPressMode = "LONG" - runner.Step("ButtonPress_CLIMATE_" .. button_name_value .. "_LONG", SendButtonPressPositive, {climate_params}) + runner.Step("ButtonPress_CLIMATE_" .. button_name_value .. "_LONG", commonRC.rpcButtonPress, {climate_params, 1}) end --[[ Positive Scenario - check all positive radio names params]] @@ -103,9 +77,9 @@ for _, button_name_value in pairs( radio_button_names ) do radio_params.buttonPressMode = "SHORT" radio_params.buttonName = button_name_value runner.Title("Test - ButtonPress with buttonName " .. button_name_value) - runner.Step("ButtonPress_RADIO_" .. button_name_value .. "_SHORT", SendButtonPressPositive, {radio_params}) + runner.Step("ButtonPress_RADIO_" .. button_name_value .. "_SHORT", commonRC.rpcButtonPress, {radio_params, 1}) radio_params.buttonPressMode = "LONG" - runner.Step("ButtonPress_RADIO_" .. button_name_value .. "_LONG", SendButtonPressPositive, {radio_params}) + runner.Step("ButtonPress_RADIO_" .. button_name_value .. "_LONG", commonRC.rpcButtonPress, {radio_params, 1}) end --[[ Negative Scenario - invalid value of buttonName in mobile request]] @@ -114,8 +88,8 @@ local radio_params = reset_radio_params() climate_params.buttonName = "invalid_name" radio_params.buttonName = "invalid_name" runner.Title("Test - negative, invalid value of buttonName in mobile request") -runner.Step("ButtonPress_CLIMATE", SendButtonPressNegative, {climate_params}) -runner.Step("ButtonPress_RADIO", SendButtonPressNegative, {radio_params}) +runner.Step("ButtonPress_CLIMATE", commonRC.rpcDeniedWithCustomParams, {climate_params, 1, "ButtonPress", "INVALID_DATA"}) +runner.Step("ButtonPress_RADIO", commonRC.rpcDeniedWithCustomParams, {radio_params, 1, "ButtonPress", "INVALID_DATA"}) climate_params = reset_climate_params() radio_params = reset_radio_params() @@ -123,7 +97,7 @@ radio_params = reset_radio_params() climate_params.buttonPressMode = "invalid_name" radio_params.buttonPressMode = "invalid_name" runner.Title("Test - negative, invalid value of buttonPressMode in mobile request") -runner.Step("ButtonPress_CLIMATE", SendButtonPressNegative, {climate_params}) -runner.Step("ButtonPress_RADIO", SendButtonPressNegative, {radio_params}) +runner.Step("ButtonPress_CLIMATE", commonRC.rpcDeniedWithCustomParams, {climate_params, 1, "ButtonPress", "INVALID_DATA"}) +runner.Step("ButtonPress_RADIO", commonRC.rpcDeniedWithCustomParams, {radio_params, 1, "ButtonPress", "INVALID_DATA"}) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua index 3727afa44e..087d53b079 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua @@ -19,45 +19,26 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local json = require('modules/json') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("ButtonPress", { - moduleType = pModuleType, - buttonName = commonRC.getButtonNameByModule(pModuleType), - buttonPressMode = "SHORT" - }) - - EXPECT_HMICALL("Buttons.ButtonPress", { - appID = self.applications["Test Application"], - moduleType = pModuleType, - buttonName = commonRC.getButtonNameByModule(pModuleType), - buttonPressMode = "SHORT" - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do - runner.Step("ButtonPress " .. mod, getDataForModule, { mod }) +for _, mod in pairs(commonRC.modules) do + runner.Step("ButtonPress " .. mod, commonRC.rpcAllowed, {mod, 1, "ButtonPress"}) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua index 0f1f877f7d..285573cca4 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua @@ -17,42 +17,27 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("ButtonPress", { - moduleType = pModuleType, - buttonName = commonRC.getButtonNameByModule(pModuleType), - buttonPressMode = "SHORT" - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do - runner.Step("ButtonPress " .. mod, getDataForModule, { mod }) +for _, mod in pairs(commonRC.modules) do + runner.Step("ButtonPress " .. mod, commonRC.rpcDenied, {mod, 1, "ButtonPress", "DISALLOWED"}) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua index f5963de3d5..b103271387 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua @@ -17,42 +17,27 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("ButtonPress", { - moduleType = pModuleType, - buttonName = commonRC.getButtonNameByModule(pModuleType), - buttonPressMode = "SHORT" - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.functional_groupings["RemoteControl"].rpcs.ButtonPress = nil end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do - runner.Step("ButtonPress " .. mod, getDataForModule, { mod }) +for _, mod in pairs(commonRC.modules) do + runner.Step("ButtonPress " .. mod, commonRC.rpcDenied, {mod, 1, "ButtonPress", "DISALLOWED"}) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/010_generic_error_if_no_response_from_hmi.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/010_generic_error_if_no_response_from_hmi.lua index 06414f3e8c..42747b0d0b 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/010_generic_error_if_no_response_from_hmi.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/010_generic_error_if_no_response_from_hmi.lua @@ -18,19 +18,19 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("ButtonPress", { +local function getDataForModule(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" }) EXPECT_HMICALL("Buttons.ButtonPress", { - appID = self.applications["Test Application"], + appID = commonRC.getHMIAppId(), moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" @@ -39,7 +39,7 @@ local function getDataForModule(pModuleType, self) -- HMI does not respond end) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR"}) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR"}) commonTestCases:DelayedExp(11000) end @@ -48,12 +48,12 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("ButtonPress " .. mod, getDataForModule, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua index 26a9f4c59c..afaf50e88b 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua @@ -17,40 +17,40 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("ButtonPress", { +local function getDataForModule(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" }) EXPECT_HMICALL("Buttons.ButtonPress", { - appID = self.applications["Test Application"], + appID = commonRC.getHMIAppId(), moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" }) :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Info message") + commonRC.getHMIConnection():SendError(data.id, data.method, "READ_ONLY", "Info message") end) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Info message" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Info message" }) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("ButtonPress " .. mod, getDataForModule, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua index b72ec8d3cc..3bc067c024 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua @@ -17,40 +17,40 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("ButtonPress", { +local function getDataForModule(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" }) EXPECT_HMICALL("Buttons.ButtonPress", { - appID = self.applications["Test Application"], + appID = commonRC.getHMIAppId(), moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" }) :Do(function(_, _) - self.hmiConnection:Send('{"jsonrpc";"2.0","result":{"cod":0,"method":"Buttons.ButtonPress"},"id":32}') + commonRC.getHMIConnection():Send('{"jsonrpc";"2.0","result":{"cod":0,"method":"Buttons.ButtonPress"},"id":32}') end) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR"}) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR"}) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("ButtonPress " .. mod, getDataForModule, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua index 03d0ed51a7..1f946c1487 100644 --- a/test_scripts/RC/CLIMATE_RADIO/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/CLIMATE_RADIO/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua @@ -18,71 +18,73 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } local success_codes = { "WARNINGS" } local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } --[[ Local Functions ]] -local function stepSuccessfull(pModuleType, pResultCode, self) - local cid = self.mobileSession1:SendRPC("ButtonPress", { +local function stepSuccessfull(pModuleType, pResultCode) + local cid = commonRC.getMobileSession():SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" }) EXPECT_HMICALL("Buttons.ButtonPress", { - appID = self.applications["Test Application"], + appID = commonRC.getHMIAppId(), moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, pResultCode, { + commonRC.getHMIConnection():SendResponse(data.id, data.method, pResultCode, { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) end) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = pResultCode }) + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = pResultCode }) end -local function stepUnsuccessfull(pModuleType, pResultCode, self) - local cid = self.mobileSession1:SendRPC("ButtonPress", { +local function stepUnsuccessfull(pModuleType, pResultCode) + local cid = commonRC.getMobileSession():SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" }) EXPECT_HMICALL("Buttons.ButtonPress", { - appID = self.applications["Test Application"], + appID = commonRC.getHMIAppId(), moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" }) :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") + commonRC.getHMIConnection():SendError(data.id, data.method, pResultCode, "Error error") end) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = pResultCode }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = pResultCode }) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) for _, code in pairs(success_codes) do runner.Step("ButtonPress with " .. code .. " resultCode", stepSuccessfull, { mod, code }) end end -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) for _, code in pairs(error_codes) do runner.Step("ButtonPress with " .. code .. " resultCode", stepUnsuccessfull, { mod, code }) diff --git a/test_scripts/RC/CLIMATE_RADIO/Capabilities/001_All_modules_all_params.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/001_All_modules_all_params.lua index c42aa2fadb..9a14794768 100644 --- a/test_scripts/RC/CLIMATE_RADIO/Capabilities/001_All_modules_all_params.lua +++ b/test_scripts/RC/CLIMATE_RADIO/Capabilities/001_All_modules_all_params.lua @@ -16,22 +16,29 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +-- [[ Local Variables ]] +local capParams = {} +capParams.CLIMATE = commonRC.DEFAULT +capParams.RADIO = commonRC.DEFAULT +capParams.BUTTONS = commonRC.DEFAULT +local hmiRcCapabilities = commonRC.buildHmiRcCapabilities(capParams) --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { "CLIMATE", "RADIO" } }) runner.Step("Clean environment", commonRC.preconditions) -runner.Step("Start SDL, HMI (HMI has all posible RC capabilities), connect Mobile, start Session", commonRC.start, - {commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, commonRC.DEFAULT, commonRC.DEFAULT)}) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App1", commonRC.activate_app) +runner.Step("Start SDL, HMI (HMI has all possible RC capabilities), connect Mobile, start Session", commonRC.start, + {hmiRcCapabilities}) +runner.Step("RAI, PTU", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("GetInteriorVehicleData " .. mod, commonRC.subscribeToModule, { mod, 1 }) runner.Step("SetInteriorVehicleData " .. mod, commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) runner.Step("ButtonPress " .. mod, commonRC.rpcAllowed, { mod, 1, "ButtonPress" }) diff --git a/test_scripts/RC/CLIMATE_RADIO/Capabilities/002_Only_CLIMATE_all_params.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/002_Only_CLIMATE_all_params.lua index 6e280c8cfb..72415da37f 100644 --- a/test_scripts/RC/CLIMATE_RADIO/Capabilities/002_Only_CLIMATE_all_params.lua +++ b/test_scripts/RC/CLIMATE_RADIO/Capabilities/002_Only_CLIMATE_all_params.lua @@ -21,15 +21,25 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +-- [[ Local Variables ]] +local capParams = {} +capParams.CLIMATE = commonRC.DEFAULT +capParams.RADIO = nil +capParams.BUTTONS = commonRC.DEFAULT +local hmiRcCapabilities = commonRC.buildHmiRcCapabilities(capParams) + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { "CLIMATE", "RADIO" } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI (HMI has all CLIMATE RC capabilities), connect Mobile, start Session", commonRC.start, - {commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, nil, commonRC.DEFAULT)}) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App1", commonRC.activate_app) + {hmiRcCapabilities}) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/CLIMATE_RADIO/Capabilities/003_Only_RADIO_all_params.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/003_Only_RADIO_all_params.lua index 429005e250..e7eaa746e9 100644 --- a/test_scripts/RC/CLIMATE_RADIO/Capabilities/003_Only_RADIO_all_params.lua +++ b/test_scripts/RC/CLIMATE_RADIO/Capabilities/003_Only_RADIO_all_params.lua @@ -21,15 +21,25 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +-- [[ Local Variables ]] +local capParams = {} +capParams.CLIMATE = nil +capParams.RADIO = commonRC.DEFAULT +capParams.BUTTONS = commonRC.DEFAULT +local hmiRcCapabilities = commonRC.buildHmiRcCapabilities(capParams) + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { "CLIMATE", "RADIO" } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI (HMI has all CLIMATE RC capabilities), connect Mobile, start Session", commonRC.start, - {commonRC.buildHmiRcCapabilities(nil, commonRC.DEFAULT, commonRC.DEFAULT)}) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App1", commonRC.activate_app) + {hmiRcCapabilities}) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/CLIMATE_RADIO/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua index 0453e038df..eacb31f08b 100644 --- a/test_scripts/RC/CLIMATE_RADIO/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua +++ b/test_scripts/RC/CLIMATE_RADIO/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua @@ -18,28 +18,35 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local common_functions = require('user_modules/shared_testcases/commonTestCases') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local climate_capabilities = {{moduleName = "Climate", fanSpeedAvailable = true}} -local rc_capabilities = commonRC.buildHmiRcCapabilities(climate_capabilities, commonRC.DEFAULT, commonRC.DEFAULT) +local capParams = {} +capParams.CLIMATE = climate_capabilities +capParams.RADIO = commonRC.DEFAULT +capParams.BUTTONS = commonRC.DEFAULT +local rc_capabilities = commonRC.buildHmiRcCapabilities(capParams) local available_params = {moduleType = "CLIMATE", climateControlData = {fanSpeed = 30}} local absent_params = {moduleType = "CLIMATE", climateControlData = {acMaxEnable = true}} --[[ Local Functions ]] -local function setVehicleData(params, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", {moduleData = params}) +local function setVehicleData(pParams) + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", {moduleData = pParams}) - if params.climateControlData.fanSpeed then + if pParams.climateControlData.fanSpeed then EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = commonRC.getHMIAppId(1), - moduleData = params}) + moduleData = pParams}) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = params}) + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = pParams}) end) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) else EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) common_functions:DelayedExp(commonRC.timeout) end end @@ -48,8 +55,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, {rc_capabilities}) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate_App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate_App", commonRC.activateApp) runner.Title("Test") for _, module_name in pairs({"CLIMATE", "RADIO"}) do diff --git a/test_scripts/RC/CLIMATE_RADIO/Capabilities/005_Resend_only_supported_parameters.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/005_Resend_only_supported_parameters.lua index 79de9fdfb1..e2d0d86a11 100644 --- a/test_scripts/RC/CLIMATE_RADIO/Capabilities/005_Resend_only_supported_parameters.lua +++ b/test_scripts/RC/CLIMATE_RADIO/Capabilities/005_Resend_only_supported_parameters.lua @@ -18,10 +18,16 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local common_functions = require('user_modules/shared_testcases/commonTestCases') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local radio_capabilities = {{moduleName = "Radio", radioFrequencyAvailable = true, radioBandAvailable = true}} - -local rc_capabilities = commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, radio_capabilities, commonRC.DEFAULT) +local capParams = {} +capParams.CLIMATE = commonRC.DEFAULT +capParams.RADIO = radio_capabilities +capParams.BUTTONS = commonRC.DEFAULT +local rc_capabilities = commonRC.buildHmiRcCapabilities(capParams) local available_params = { moduleType = "RADIO", @@ -30,21 +36,21 @@ local available_params = local absent_params = {moduleType = "RADIO", radioControlData = {frequencyInteger = 1, frequencyFraction = 2}} --[[ Local Functions ]] -local function setVehicleData(params, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", {moduleData = params}) +local function setVehicleData(params) + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", {moduleData = params}) if params.radioControlData.frequencyInteger then EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = commonRC.getHMIAppId(1), moduleData = params}) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = params}) end) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) else EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) common_functions.DelayedExp(commonRC.timeout) end end @@ -53,8 +59,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, {rc_capabilities}) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate_App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate_App", commonRC.activateApp) runner.Title("Test") for _, module_name in pairs({"CLIMATE", "RADIO"}) do diff --git a/test_scripts/RC/CLIMATE_RADIO/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua index facede9853..4bc964f7ba 100644 --- a/test_scripts/RC/CLIMATE_RADIO/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua +++ b/test_scripts/RC/CLIMATE_RADIO/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua @@ -17,6 +17,9 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local climate_capabilities = {{ moduleName = "Climate", @@ -24,7 +27,11 @@ local climate_capabilities = {{ acEnableAvailable = true, acMaxEnableAvailable = true }} -local rc_capabilities = commonRC.buildHmiRcCapabilities(climate_capabilities, commonRC.DEFAULT, commonRC.DEFAULT) +local capParams = {} +capParams.CLIMATE = climate_capabilities +capParams.RADIO = commonRC.DEFAULT +capParams.BUTTONS = commonRC.DEFAULT +local rc_capabilities = commonRC.buildHmiRcCapabilities(capParams) local climate_params = { moduleType = "CLIMATE", @@ -37,24 +44,20 @@ local climate_params = } } ---[[ Local Functions ]] -local function setVehicleData(params, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", {moduleData = params}) - - EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, {rc_capabilities}) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate_App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate_App", commonRC.activateApp) runner.Title("Test") for _, module_name in pairs({"CLIMATE", "RADIO"}) do runner.Step("GetInteriorVehicleData for " .. module_name, commonRC.subscribeToModule, {module_name, 1}) runner.Step("ButtonPress for " .. module_name, commonRC.rpcAllowed, {module_name, 1, "ButtonPress"}) end -runner.Step("SetInteriorVehicleData rejected if at least one prameter unsuported", setVehicleData, { climate_params }) +runner.Step("SetInteriorVehicleData rejected if at least one prameter unsuported", commonRC.rpcDeniedWithCustomParams, + { climate_params, 1, "SetInteriorVehicleData", resultCode = "UNSUPPORTED_RESOURCE"}) + +runner.Title("Postconditions") +runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua index d36ae24bb8..9aa2be83d8 100644 --- a/test_scripts/RC/CLIMATE_RADIO/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua +++ b/test_scripts/RC/CLIMATE_RADIO/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua @@ -19,8 +19,8 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local hmi_values = require('user_modules/hmi_values') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] local function getHMIParams() @@ -31,29 +31,24 @@ local function getHMIParams() return params end -local function rpcUnsupportedResource(pModuleType, pRPC, self) - local pAppId = 1 - local mobSession = commonRC.getMobileSession(self, pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) - mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) - runner.Step("GetInteriorVehicleData", rpcUnsupportedResource, { mod, "GetInteriorVehicleData" }) - runner.Step("SetInteriorVehicleData", rpcUnsupportedResource, { mod, "SetInteriorVehicleData" }) - runner.Step("ButtonPress", rpcUnsupportedResource, { mod, "ButtonPress" }) + runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { mod, 1, "GetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) +runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { mod, 1, "SetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) +runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { mod, 1, "ButtonPress", "UNSUPPORTED_RESOURCE" }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua index 3aa3e6bf39..f899485bd7 100644 --- a/test_scripts/RC/CLIMATE_RADIO/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua +++ b/test_scripts/RC/CLIMATE_RADIO/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua @@ -20,6 +20,9 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local hmi_values = require('user_modules/hmi_values') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local disabledModule = "CLIMATE" local enabledModule = "RADIO" @@ -32,43 +35,27 @@ local function getHMIParams() return params end -local function rpcUnsupportedResource(pModuleType, pRPC, self) - local pAppId = 1 - local mobSession = commonRC.getMobileSession(self, pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) - mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) -end - -local function rpcSuccess(pModuleType, pRPC, self) - local pAppId = 1 - local mobSession = commonRC.getMobileSession(self, pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) - end) - mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { disabledModule } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test - Module enabled: " .. enabledModule .. ", disabled: " .. disabledModule) -runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "GetInteriorVehicleData" }) -runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "SetInteriorVehicleData" }) -runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "ButtonPress" }) +runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "GetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) +runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "SetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) +runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "ButtonPress", "UNSUPPORTED_RESOURCE" }) -runner.Step("GetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "GetInteriorVehicleData" }) -runner.Step("SetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "SetInteriorVehicleData" }) -runner.Step("ButtonPress_SUCCESS", rpcSuccess, { enabledModule, "ButtonPress" }) +runner.Step("GetInteriorVehicleData_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "ButtonPress" }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua index c9d6c61615..8cea3b4dc6 100644 --- a/test_scripts/RC/CLIMATE_RADIO/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua +++ b/test_scripts/RC/CLIMATE_RADIO/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua @@ -20,6 +20,9 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local hmi_values = require('user_modules/hmi_values') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local disabledModule = "RADIO" local enabledModule = "CLIMATE" @@ -32,43 +35,27 @@ local function getHMIParams() return params end -local function rpcUnsupportedResource(pModuleType, pRPC, self) - local pAppId = 1 - local mobSession = commonRC.getMobileSession(self, pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) - mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) -end - -local function rpcSuccess(pModuleType, pRPC, self) - local pAppId = 1 - local mobSession = commonRC.getMobileSession(self, pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) - end) - mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { disabledModule } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test - Module enabled: " .. enabledModule .. ", disabled: " .. disabledModule) -runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "GetInteriorVehicleData" }) -runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "SetInteriorVehicleData" }) -runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "ButtonPress" }) +runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "GetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) +runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "SetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) +runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "ButtonPress", "UNSUPPORTED_RESOURCE" }) -runner.Step("GetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "GetInteriorVehicleData" }) -runner.Step("SetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "SetInteriorVehicleData" }) -runner.Step("ButtonPress_SUCCESS", rpcSuccess, { enabledModule, "ButtonPress" }) +runner.Step("GetInteriorVehicleData_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "ButtonPress" }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua index ba0782b4e9..67c763343a 100644 --- a/test_scripts/RC/CLIMATE_RADIO/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua +++ b/test_scripts/RC/CLIMATE_RADIO/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua @@ -20,6 +20,9 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local hmi_values = require('user_modules/hmi_values') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local disabledModule = "CLIMATE" local enabledModule = "RADIO" @@ -32,43 +35,27 @@ local function getHMIParams() return params end -local function rpcUnsupportedResource(pModuleType, pRPC, self) - local pAppId = 1 - local mobSession = commonRC.getMobileSession(self, pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) - mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) -end - -local function rpcSuccess(pModuleType, pRPC, self) - local pAppId = 1 - local mobSession = commonRC.getMobileSession(self, pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) - end) - mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { disabledModule } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test - Module enabled: " .. enabledModule .. ", disabled: " .. disabledModule) -runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "GetInteriorVehicleData" }) -runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "SetInteriorVehicleData" }) -runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "ButtonPress" }) +runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "GetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) +runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "SetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) +runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "ButtonPress", "UNSUPPORTED_RESOURCE" }) -runner.Step("GetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "GetInteriorVehicleData" }) -runner.Step("SetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "SetInteriorVehicleData" }) -runner.Step("ButtonPress_SUCCESS", rpcSuccess, { enabledModule, "ButtonPress" }) +runner.Step("GetInteriorVehicleData_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "ButtonPress" }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua index 76d6a707e9..c237454554 100644 --- a/test_scripts/RC/CLIMATE_RADIO/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua +++ b/test_scripts/RC/CLIMATE_RADIO/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua @@ -20,6 +20,9 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local hmi_values = require('user_modules/hmi_values') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local disabledModule = "RADIO" local enabledModule = "CLIMATE" @@ -32,43 +35,27 @@ local function getHMIParams() return params end -local function rpcUnsupportedResource(pModuleType, pRPC, self) - local pAppId = 1 - local mobSession = commonRC.getMobileSession(self, pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) - mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) -end - -local function rpcSuccess(pModuleType, pRPC, self) - local pAppId = 1 - local mobSession = commonRC.getMobileSession(self, pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) - end) - mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { disabledModule } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test - Module enabled: " .. enabledModule .. ", disabled: " .. disabledModule) -runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "GetInteriorVehicleData" }) -runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "SetInteriorVehicleData" }) -runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "ButtonPress" }) +runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "GetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) +runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "SetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) +runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "ButtonPress", "UNSUPPORTED_RESOURCE" }) -runner.Step("GetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "GetInteriorVehicleData" }) -runner.Step("SetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "SetInteriorVehicleData" }) -runner.Step("ButtonPress_SUCCESS", rpcSuccess, { enabledModule, "ButtonPress" }) +runner.Step("GetInteriorVehicleData_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "ButtonPress" }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua index 94c66a0294..d9ee6d5ad0 100644 --- a/test_scripts/RC/CLIMATE_RADIO/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua +++ b/test_scripts/RC/CLIMATE_RADIO/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua @@ -20,6 +20,9 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local disabledModule = "CLIMATE" local enabledModule = "RADIO" @@ -28,12 +31,20 @@ local enabledModule = "RADIO" local function getHMIParams() local function getHMICapsParams() if enabledModule == "CLIMATE" then - return { commonRC.DEFAULT, nil, commonRC.DEFAULT } + local capParams = {} + capParams.CLIMATE = commonRC.DEFAULT + capParams.RADIO = nil + capParams.BUTTONS = commonRC.DEFAULT + return capParams elseif enabledModule == "RADIO" then - return { nil, commonRC.DEFAULT, commonRC.DEFAULT } + local capParams = {} + capParams.CLIMATE = nil + capParams.RADIO = commonRC.DEFAULT + capParams.BUTTONS = commonRC.DEFAULT + return capParams end end - local hmiCaps = commonRC.buildHmiRcCapabilities(unpack(getHMICapsParams())) + local hmiCaps = commonRC.buildHmiRcCapabilities(getHMICapsParams()) hmiCaps.RC.IsReady = nil local buttonCaps = hmiCaps.RC.GetCapabilities.params.remoteControlCapability.buttonCapabilities local buttonId = commonRC.getButtonIdByName(buttonCaps, commonRC.getButtonNameByModule(disabledModule)) @@ -41,43 +52,27 @@ local function getHMIParams() return hmiCaps end -local function rpcUnsupportedResource(pModuleType, pRPC, self) - local pAppId = 1 - local mobSession = commonRC.getMobileSession(self, pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) - mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) -end - -local function rpcSuccess(pModuleType, pRPC, self) - local pAppId = 1 - local mobSession = commonRC.getMobileSession(self, pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) - end) - mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { enabledModule } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test - Module enabled: " .. enabledModule .. ", disabled: " .. disabledModule) -runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "GetInteriorVehicleData" }) -runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "SetInteriorVehicleData" }) -runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "ButtonPress" }) +runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "GetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) +runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "SetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) +runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "ButtonPress", "UNSUPPORTED_RESOURCE" }) -runner.Step("GetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "GetInteriorVehicleData" }) -runner.Step("SetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "SetInteriorVehicleData" }) -runner.Step("ButtonPress_SUCCESS", rpcSuccess, { enabledModule, "ButtonPress" }) +runner.Step("GetInteriorVehicleData_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "ButtonPress" }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua b/test_scripts/RC/CLIMATE_RADIO/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua index 1b0b24e20a..707e645a30 100644 --- a/test_scripts/RC/CLIMATE_RADIO/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua +++ b/test_scripts/RC/CLIMATE_RADIO/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua @@ -20,6 +20,9 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local disabledModule = "RADIO" local enabledModule = "CLIMATE" @@ -28,12 +31,20 @@ local enabledModule = "CLIMATE" local function getHMIParams() local function getHMICapsParams() if enabledModule == "CLIMATE" then - return { commonRC.DEFAULT, nil, commonRC.DEFAULT } + local capParams = {} + capParams.CLIMATE = commonRC.DEFAULT + capParams.RADIO = nil + capParams.BUTTONS = commonRC.DEFAULT + return capParams elseif enabledModule == "RADIO" then - return { nil, commonRC.DEFAULT, commonRC.DEFAULT } + local capParams = {} + capParams.CLIMATE = nil + capParams.RADIO = commonRC.DEFAULT + capParams.BUTTONS = commonRC.DEFAULT + return capParams end end - local hmiCaps = commonRC.buildHmiRcCapabilities(unpack(getHMICapsParams())) + local hmiCaps = commonRC.buildHmiRcCapabilities(getHMICapsParams()) hmiCaps.RC.IsReady = nil local buttonCaps = hmiCaps.RC.GetCapabilities.params.remoteControlCapability.buttonCapabilities local buttonId = commonRC.getButtonIdByName(buttonCaps, commonRC.getButtonNameByModule(disabledModule)) @@ -41,43 +52,27 @@ local function getHMIParams() return hmiCaps end -local function rpcUnsupportedResource(pModuleType, pRPC, self) - local pAppId = 1 - local mobSession = commonRC.getMobileSession(self, pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) - mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) -end - -local function rpcSuccess(pModuleType, pRPC, self) - local pAppId = 1 - local mobSession = commonRC.getMobileSession(self, pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) - end) - mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { enabledModule } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test - Module enabled: " .. enabledModule .. ", disabled: " .. disabledModule) -runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "GetInteriorVehicleData" }) -runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "SetInteriorVehicleData" }) -runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, { disabledModule, "ButtonPress" }) +runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "GetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) +runner.Step("SetInteriorVehicleData_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "SetInteriorVehicleData", "UNSUPPORTED_RESOURCE" }) +runner.Step("ButtonPress_UNSUPPORTED_RESOURCE", commonRC.rpcDenied, + { disabledModule, 1, "ButtonPress", "UNSUPPORTED_RESOURCE" }) -runner.Step("GetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "GetInteriorVehicleData" }) -runner.Step("SetInteriorVehicleData_SUCCESS", rpcSuccess, { enabledModule, "SetInteriorVehicleData" }) -runner.Step("ButtonPress_SUCCESS", rpcSuccess, { enabledModule, "ButtonPress" }) +runner.Step("GetInteriorVehicleData_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "GetInteriorVehicleData" }) +runner.Step("SetInteriorVehicleData_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "SetInteriorVehicleData" }) +runner.Step("ButtonPress_SUCCESS", commonRC.rpcAllowed, { enabledModule, 1, "ButtonPress" }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/001_Success_flow.lua index 10e5caf581..8b998e8032 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/001_Success_flow.lua @@ -17,19 +17,19 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("GetInteriorVehicleData " .. mod, commonRC.subscribeToModule, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 7746ffaefd..31f3443336 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -17,38 +17,29 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local mod = "CLIMATE" +local rpc = "GetInteriorVehicleData" --[[ Local Functions ]] -local function getDataForModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +runner.Step("GetInteriorVehicleData " .. mod, commonRC.rpcDenied, {mod, 1, rpc, "DISALLOWED"}) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index e163bbe968..649f7cb251 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -17,38 +17,29 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local mod = "RADIO" +local rpc = "GetInteriorVehicleData" --[[ Local Functions ]] -local function getDataForModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +runner.Step("GetInteriorVehicleData " .. mod, commonRC.rpcDenied, {mod, 1, rpc, "DISALLOWED"}) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 672b90282d..4af3da0b47 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -16,44 +16,34 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ General configuration parameters ]] config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +local rpc = "GetInteriorVehicleData" --[[ Local Functions ]] -local function getDataForModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData") - :Times(0) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function ptu_update_func(tbl) +local function PTUfunc(tbl) local appId = config.application1.registerAppInterfaceParams.appID tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do - runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +for _, mod in pairs(commonRC.modules) do + runner.Step("GetInteriorVehicleData " .. mod, commonRC.rpcDenied, {mod, 1, rpc, "DISALLOWED"}) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua index d16ea3cc52..644e1b0f93 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua @@ -17,14 +17,16 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } local success_codes = { "WARNINGS" } local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } --[[ Local Functions ]] -local function stepSuccessfull(pModuleType, pResultCode, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function stepSuccessfull(pModuleType, pResultCode) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -34,20 +36,20 @@ local function stepSuccessfull(pModuleType, pResultCode, self) subscribe = true }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, pResultCode, { + commonRC.getHMIConnection():SendResponse(data.id, data.method, pResultCode, { moduleData = commonRC.getModuleControlData(pModuleType) -- isSubscribed = true }) end) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = pResultCode, + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = pResultCode, isSubscribed = false, moduleData = commonRC.getModuleControlData(pModuleType) }) end -local function stepUnsuccessfull(pModuleType, pResultCode, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function stepUnsuccessfull(pModuleType, pResultCode) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -57,28 +59,28 @@ local function stepUnsuccessfull(pModuleType, pResultCode, self) subscribe = true }) :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") + commonRC.getHMIConnection():SendError(data.id, data.method, pResultCode, "Error error") end) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = pResultCode}) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = pResultCode}) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do for _, code in pairs(success_codes) do runner.Step("GetInteriorVehicleData " .. mod .. " with " .. code .. " resultCode", stepSuccessfull, { mod, code }) end end -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do for _, code in pairs(error_codes) do runner.Step("GetInteriorVehicleData " .. mod .. " with " .. code .. " resultCode", stepUnsuccessfull, { mod, code }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/006_RPC_parameters_values.lua index 47e01154eb..999ea56a04 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/006_RPC_parameters_values.lua @@ -21,12 +21,12 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function invalidParamName(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function invalidParamName(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { modduleType = pModuleType, -- invalid name of parameter subscribe = true }) @@ -34,13 +34,13 @@ local function invalidParamName(pModuleType, self) EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) :Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) commonTestCases:DelayedExp(commonRC.timeout) end -local function invalidParamType(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function invalidParamType(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = 17 -- invalid type of parameter }) @@ -48,13 +48,13 @@ local function invalidParamType(pModuleType, self) EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) :Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) commonTestCases:DelayedExp(commonRC.timeout) end -local function missingMandatoryParam(self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function missingMandatoryParam() + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { -- moduleType = "CLIMATE", -- mandatory parameter absent subscribe = true }) @@ -62,13 +62,13 @@ local function missingMandatoryParam(self) EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) :Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) commonTestCases:DelayedExp(commonRC.timeout) end -local function fakeParam(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function fakeParam(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, fakeParam = 7, subscribe = true @@ -79,13 +79,13 @@ local function fakeParam(pModuleType, self) subscribe = true }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = true }) end) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true, moduleData = commonRC.getModuleControlData(pModuleType) }) @@ -95,12 +95,12 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("GetInteriorVehicleData " .. mod .. " invalid name of parameter", invalidParamName, { mod }) runner.Step("GetInteriorVehicleData " .. mod .. " invalid type of parameter", invalidParamType, { mod }) runner.Step("GetInteriorVehicleData " .. mod .. " fake parameter", fakeParam, { mod }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index b350f931fc..85c4f25f40 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -18,12 +18,12 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function getDataForModule(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -36,7 +36,7 @@ local function getDataForModule(pModuleType, self) -- HMI does not respond end) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR"}) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR"}) commonTestCases:DelayedExp(11000) end @@ -45,12 +45,12 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("GetInteriorVehicleData " .. mod .. " HMI does not respond", getDataForModule, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index b1c4afcc01..881524fc61 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -19,12 +19,12 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function invalidParamType(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function invalidParamType(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -34,17 +34,17 @@ local function invalidParamType(pModuleType, self) subscribe = true }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = "yes" -- invalid type of parameter }) end) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) end -local function missingMandatoryParam(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function missingMandatoryParam(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -56,25 +56,25 @@ local function missingMandatoryParam(pModuleType, self) :Do(function(_, data) local moduleData = commonRC.getModuleControlData(pModuleType) moduleData.moduleType = nil -- missing mandatory parameter - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = moduleData, isSubscribed = true }) end) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("GetInteriorVehicleData " .. mod .. " Invalid response from HMI-Invalid type of parameter", invalidParamType, { mod }) runner.Step("GetInteriorVehicleData " .. mod .. " Invalid response from HMI-Missing mandatory parameter", missingMandatoryParam, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index bbf5451d31..a707434c63 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -19,48 +19,26 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local json = require('modules/json') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", { - moduleType = pModuleType, - subscribe = true - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlData(pModuleType), - isSubscribed = true - }) - end) - - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - isSubscribed = true, - moduleData = commonRC.getModuleControlData(pModuleType) - }) -end - -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do - runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +for _, mod in pairs(commonRC.modules) do + runner.Step("GetInteriorVehicleData " .. mod, commonRC.subscribeToModule, { mod, 1 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 2d3e1389e5..1b424e8cc9 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -17,41 +17,30 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +local rpc = "GetInteriorVehicleData" --[[ Local Functions ]] -local function getDataForModule(module_type, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { - moduleType = module_type, - subscribe = true - }) - - EXPECT_HMICALL("RC.GetInteriorVehicleData", {}) - :Times(0) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do - runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) +for _, mod in pairs(commonRC.modules) do + runner.Step("GetInteriorVehicleData " .. mod, commonRC.rpcDenied, {mod, 1, rpc, "DISALLOWED"}) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua index d85d6bb41b..79e9530074 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -17,12 +17,12 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(module_type, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function getDataForModule(module_type) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = module_type, subscribe = true }) @@ -32,22 +32,22 @@ local function getDataForModule(module_type, self) subscribe = true }) :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Info message") + commonRC.getHMIConnection():SendError(data.id, data.method, "READ_ONLY", "Info message") end) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Info message" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Info message" }) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua index 7e2bffed87..c3cfe4e63b 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -19,12 +19,12 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, pHMIRequest, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, pHMIRequest) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = pSubscribe }) @@ -38,7 +38,7 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, p moduleType = pModuleType }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = commonRC.getModuleControlData(pModuleType), -- no isSubscribed parameter }) @@ -51,7 +51,7 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, p end) :Times(pHMIRequest) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", isSubscribed = isSubscriptionActive, -- return current value of subscription moduleData = commonRC.getModuleControlData(pModuleType) }) @@ -61,17 +61,17 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription_subscribe", getDataForModule, { mod, false, true, 1 }) runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription_unsubscribe", getDataForModule, { mod, false, false, 1 }) end -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true, true, 0 }) runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_unsubscribe", getDataForModule, { mod, true, false, 1 }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index 6ed3dec27e..a3331683c7 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -19,12 +19,12 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, isSubscriptionActive, pHMIRequest, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function getDataForModule(pModuleType, isSubscriptionActive, pHMIRequest) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType -- no subscribe parameter }) @@ -33,7 +33,7 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pHMIRequest, moduleType = pModuleType }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = isSubscriptionActive -- return current value of subscription }) @@ -46,7 +46,7 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pHMIRequest, end) :Times(pHMIRequest) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = commonRC.getModuleControlData(pModuleType) }) :ValidIf(function(_, data) -- no isSubscribed parameter @@ -61,16 +61,16 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription", getDataForModule, { mod, false, 1 }) end -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true, 0 }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua index d2453081de..19d9da6e2d 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua @@ -30,12 +30,12 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function subscriptionToModule(pModuleType, pSubscribe, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function subscriptionToModule(pModuleType, pSubscribe) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = pSubscribe }) @@ -44,7 +44,7 @@ local function subscriptionToModule(pModuleType, pSubscribe, self) moduleType = pModuleType }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = commonRC.actualInteriorDataStateOnHMI[pModuleType], isSubscribed = pSubscribe }) @@ -57,7 +57,7 @@ local function subscriptionToModule(pModuleType, pSubscribe, self) end) :Times(AtMost(1)) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = commonRC.actualInteriorDataStateOnHMI[pModuleType], isSubscribed = pSubscribe }) @@ -67,12 +67,12 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do -- app has not subscribed yet runner.Step("Unsubscribe app to " .. mod, subscriptionToModule, { mod, false }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", commonRC.isUnsubscribed, { mod }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua index 753d815958..7f4bd4fd11 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua @@ -21,27 +21,22 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } - ---[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Title("Test") runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) -- set control for App1 runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua index c1ff27508f..8c0bc1ed0b 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua @@ -21,27 +21,22 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } - ---[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Title("Test") runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) -- set control for App1 runner.Step("App1 ButtonPress", commonRC.rpcAllowed, { mod, 1, "ButtonPress" }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua index e73364055e..d399bc2957 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua @@ -25,27 +25,22 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } - ---[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Title("Test") runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) -- set control for App1 runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua index e73a05f598..231fc25fec 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua @@ -25,27 +25,22 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } - ---[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Title("Test") runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) -- set control for App1 runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua index ca4278b1d6..fe82b4fc91 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua @@ -26,22 +26,18 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require("user_modules/shared_testcases/commonTestCases") ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - -local function rpcTimedOutHMIResponse(pModuleType, pAppId, pRPC, self) +local function rpcTimedOutHMIResponse(pModuleType, pAppId, pRPC) local info = "The resource is in use and the driver did not respond in time" local consentRPC = "GetInteriorVehicleDataConsent" - local mobSession = commonRC.getMobileSession(self, pAppId) + local mobSession = commonRC.getMobileSession(pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", info) + commonRC.getHMIConnection():SendError(data.id, data.method, "TIMED_OUT", info) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) end) mobSession:ExpectResponse(cid, { success = false, resultCode = "TIMED_OUT", info = info }) @@ -52,15 +48,15 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Title("Test") runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) -- set control for App1 runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua index 75c7edeb75..15d824bae3 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua @@ -26,22 +26,18 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require("user_modules/shared_testcases/commonTestCases") ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - -local function rpcTimedOutHMIResponse(pModuleType, pAppId, pRPC, self) +local function rpcTimedOutHMIResponse(pModuleType, pAppId, pRPC) local info = "The resource is in use and the driver did not respond in time" local consentRPC = "GetInteriorVehicleDataConsent" - local mobSession = commonRC.getMobileSession(self, pAppId) + local mobSession = commonRC.getMobileSession(pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", info) + commonRC.getHMIConnection():SendError(data.id, data.method, "TIMED_OUT", info) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) end) mobSession:ExpectResponse(cid, { success = false, resultCode = "TIMED_OUT", info = info }) @@ -52,15 +48,15 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Title("Test") runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) -- set control for App1 runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua index ee43ec6d2d..8103413821 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua @@ -24,17 +24,13 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require("user_modules/shared_testcases/commonTestCases") ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - -local function rpcNoHMIResponse(pModuleType, pAppId, pRPC, self) +local function rpcNoHMIResponse(pModuleType, pAppId, pRPC) local consentRPC = "GetInteriorVehicleDataConsent" - local mobSession = commonRC.getMobileSession(self, pAppId) + local mobSession = commonRC.getMobileSession(pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, _) @@ -49,15 +45,15 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Title("Test") runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) -- set control for App1 runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua index 8edd8f8a51..7d996cefb2 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua @@ -24,17 +24,13 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require("user_modules/shared_testcases/commonTestCases") ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - -local function rpcNoHMIResponse(pModuleType, pAppId, pRPC, self) +local function rpcNoHMIResponse(pModuleType, pAppId, pRPC) local consentRPC = "GetInteriorVehicleDataConsent" - local mobSession = commonRC.getMobileSession(self, pAppId) + local mobSession = commonRC.getMobileSession(pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, _) @@ -49,15 +45,15 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Title("Test") runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) -- set control for App1 runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua index d02876ba6f..bb62073931 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua @@ -24,21 +24,17 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require("user_modules/shared_testcases/commonTestCases") ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - -local function rpcInvalidHMIResponse(pModuleType, pAppId, pRPC, self) +local function rpcInvalidHMIResponse(pModuleType, pAppId, pRPC) local consentRPC = "GetInteriorVehicleDataConsent" - local mobSession = commonRC.getMobileSession(self, pAppId) + local mobSession = commonRC.getMobileSession(pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { allowed = "aaa" -- invalid type of parameter }) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) @@ -51,15 +47,15 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Title("Test") runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) -- set control for App1 runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua index 913017bd6f..6e251d517a 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua @@ -24,21 +24,17 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require("user_modules/shared_testcases/commonTestCases") ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - -local function rpcInvalidHMIResponse(pModuleType, pAppId, pRPC, self) +local function rpcInvalidHMIResponse(pModuleType, pAppId, pRPC) local consentRPC = "GetInteriorVehicleDataConsent" - local mobSession = commonRC.getMobileSession(self, pAppId) + local mobSession = commonRC.getMobileSession(pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { allowed = "aaa" -- invalid type of parameter }) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) @@ -51,15 +47,15 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Title("Test") runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) -- set control for App1 runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua index 5309196f86..78b76438ab 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua @@ -23,28 +23,27 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local pModuleType = "CLIMATE" local pRPC1 = "SetInteriorVehicleData" --[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - -local function rpcHMIRespondAfterDefaultTimeout(self) - local cid1 = self.mobileSession2:SendRPC(commonRC.getAppEventName(pRPC1), commonRC.getAppRequestParams(pRPC1, pModuleType)) +local function rpcHMIRespondAfterDefaultTimeout() + local cid1 = commonRC.getMobileSession(2):SendRPC(commonRC.getAppEventName(pRPC1), commonRC.getAppRequestParams(pRPC1, pModuleType)) local consentRPC = "GetInteriorVehicleDataConsent" EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, 2)) :Do(function(_, data) local function hmiRespond() - self.hmiConnection:SendError(data.id, data.method, "TIMED_OUT", "info") + commonRC.getHMIConnection():SendError(data.id, data.method, "TIMED_OUT", "info") EXPECT_HMICALL(commonRC.getHMIEventName(pRPC1)):Times(0) end RUN_AFTER(hmiRespond, 11000) end) - self.mobileSession2:ExpectResponse(cid1, { success = false, resultCode = "GENERIC_ERROR" }) + commonRC.getMobileSession(2):ExpectResponse(cid1, { success = false, resultCode = "GENERIC_ERROR" }) commonTestCases:DelayedExp(12000) end @@ -52,16 +51,16 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App1", commonRC.activate_app) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("Activate App1", commonRC.activateApp) runner.Title("Test") runner.Step("Set RA mode: ASK_DRIVER", commonRC.defineRAMode, { true, "ASK_DRIVER" }) runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { pModuleType, 1, "SetInteriorVehicleData" }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("App2 SetInteriorVehicleData, HMI respond after default timeout", rpcHMIRespondAfterDefaultTimeout) runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/GetSystemCapability/001_Success_flow.lua b/test_scripts/RC/CLIMATE_RADIO/GetSystemCapability/001_Success_flow.lua index df9ad82807..b2f0119703 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetSystemCapability/001_Success_flow.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetSystemCapability/001_Success_flow.lua @@ -15,26 +15,24 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/commonRC') +local commonRC = require('test_scripts/RC/commonRC') local hmi_values = require("user_modules/hmi_values") +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } -local capMap = { - ["RADIO"] = "radioControlCapabilities", - ["CLIMATE"] = "climateControlCapabilities" -} local capabParams = {} -for _, v in pairs(modules) do capabParams[v] = common.DEFAULT end -- HMI has all posible RC capabilities +for _, v in pairs(commonRC.modules) do capabParams[v] = commonRC.DEFAULT end -- HMI has all posible RC capabilities --[[ Local Functions ]] local function buildHmiRcCapabilities(pCapabilities) local hmiParams = hmi_values.getDefaultHMITable() hmiParams.RC.IsReady.params.available = true local capParams = hmiParams.RC.GetCapabilities.params.remoteControlCapability - for k, v in pairs(capMap) do + for k, v in pairs(commonRC.capMap) do if pCapabilities[k] then - if pCapabilities[k] ~= common.DEFAULT then + if pCapabilities[k] ~= commonRC.DEFAULT then capParams[v] = pCapabilities[v] end else @@ -46,10 +44,10 @@ end local hmiRcCapabilities = buildHmiRcCapabilities(capabParams) -local function rpcSuccess(self) +local function rpcSuccess() local rcCapabilities = hmiRcCapabilities.RC.GetCapabilities.params.remoteControlCapability - local cid = common.getMobileSession(self):SendRPC("GetSystemCapability", { systemCapabilityType = "REMOTE_CONTROL" }) - common.getMobileSession(self):ExpectResponse(cid, { + local cid = commonRC.getMobileSession():SendRPC("GetSystemCapability", { systemCapabilityType = "REMOTE_CONTROL" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", systemCapability = { @@ -67,16 +65,16 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Backup HMI capabilities file", common.backupHMICapabilities) -runner.Step("Update HMI capabilities file", common.updateDefaultCapabilities, { modules }) -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { hmiRcCapabilities }) -runner.Step("RAI, PTU", common.rai_ptu) -runner.Step("Activate App", common.activate_app) +runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) +runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { commonRC.modules }) +runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { hmiRcCapabilities }) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("GetSystemCapability Positive Case", rpcSuccess) runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) -runner.Step("Restore HMI capabilities file", common.restoreHMICapabilities) +runner.Step("Stop SDL", commonRC.postconditions) +runner.Step("Restore HMI capabilities file", commonRC.restoreHMICapabilities) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/001_Success_flow.lua index e2c2c5de34..537d999c87 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/001_Success_flow.lua @@ -37,24 +37,24 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", commonRC.isSubscribed, { mod }) end -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("Unsubscribe app to " .. mod, commonRC.unSubscribeToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is unsubscribed", commonRC.isUnsubscribed, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 9a4a6be45c..7e52425a95 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -19,19 +19,23 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local mod = "CLIMATE" -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { mod } end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("GetInteriorVehicleData " .. mod, commonRC.subscribeToModule, { mod }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index f1cb4cbeac..394b7e17b9 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -19,19 +19,23 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local mod = "RADIO" -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { mod } end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("GetInteriorVehicleData " .. mod, commonRC.subscribeToModule, { mod }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua index 7b7c760e7e..fbd026891e 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -19,12 +19,12 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function subscriptionToModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function subscriptionToModule(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -34,13 +34,13 @@ local function subscriptionToModule(pModuleType, self) subscribe = true }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = false -- not subscribe }) end) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = false }) @@ -50,12 +50,12 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("Subscribe app to " .. mod, subscriptionToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", commonRC.isUnsubscribed, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua index 08d50a6744..f6667fc403 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua @@ -19,12 +19,12 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function subscriptionToModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function subscriptionToModule(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -34,13 +34,13 @@ local function subscriptionToModule(pModuleType, self) subscribe = true }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = commonRC.getModuleControlData(pModuleType), -- no isSubscribed parameter }) end) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = false }) @@ -50,12 +50,12 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("Subscribe app to " .. mod, subscriptionToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", commonRC.isUnsubscribed, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua index c741bacb14..54e372dab4 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua @@ -20,13 +20,15 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Valiables ]] -local modules = { "CLIMATE", "RADIO" } local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } --[[ Local Functions ]] -local function subscriptionToModule(pModuleType, pResultCode, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function subscriptionToModule(pModuleType, pResultCode) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -36,10 +38,10 @@ local function subscriptionToModule(pModuleType, pResultCode, self) subscribe = true }) :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") + commonRC.getHMIConnection():SendError(data.id, data.method, pResultCode, "Error error") end) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = pResultCode }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = pResultCode }) :ValidIf(function(_, data) -- no isSubscribed parameter if data.payload.isSubscribed == nil then return true @@ -52,12 +54,12 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do for _, err in pairs(error_codes) do runner.Step("Subscribe app to " .. mod .. " (" .. err .. " from HMI)", subscriptionToModule, { mod, err }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", commonRC.isUnsubscribed, { mod }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua index d2fd969a7e..0e39b69808 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua @@ -20,12 +20,12 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') ---[[ Local Valiables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function subscriptionToModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function subscriptionToModule(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -38,7 +38,7 @@ local function subscriptionToModule(pModuleType, self) -- no response from HMI end) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) commonTestCases:DelayedExp(11000) end @@ -47,12 +47,12 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("Subscribe app to " .. mod, subscriptionToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", commonRC.isUnsubscribed, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua index 9f62426364..328a3b8025 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua @@ -19,12 +19,12 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Valiables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function subscriptionToModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function subscriptionToModule(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = true }) @@ -34,25 +34,25 @@ local function subscriptionToModule(pModuleType, self) subscribe = true }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = 123, -- invalid data isSubscribed = true }) end) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("Subscribe app to " .. mod, subscriptionToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", commonRC.isUnsubscribed, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua index 25b075b5b2..7e6eab5081 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua @@ -20,12 +20,12 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function unSubscriptionToModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function unSubscriptionToModule(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = false }) @@ -35,13 +35,13 @@ local function unSubscriptionToModule(pModuleType, self) subscribe = false }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = true -- HMI responds with true }) end) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = true }) @@ -51,17 +51,17 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", commonRC.isSubscribed, { mod }) end runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("Subscribe app to " .. mod, unSubscriptionToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App still subscribed", commonRC.isSubscribed, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua index 8032bca5ec..0e957aa95a 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -20,12 +20,12 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function unSubscriptionToModule(pModuleType, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function unSubscriptionToModule(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = false }) @@ -35,13 +35,13 @@ local function unSubscriptionToModule(pModuleType, self) subscribe = false }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = commonRC.getModuleControlData(pModuleType), -- no isSubscribed parameter }) end) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = true }) @@ -51,17 +51,17 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", commonRC.isSubscribed, { mod }) end runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("Subscribe app to " .. mod, unSubscriptionToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App still subscribed", commonRC.isSubscribed, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua index 55a86ae5b8..464fe9130e 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -21,13 +21,15 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } --[[ Local Functions ]] -local function unSubscriptionToModule(pModuleType, pResultCode, self) - local cid = self.mobileSession1:SendRPC("GetInteriorVehicleData", { +local function unSubscriptionToModule(pModuleType, pResultCode) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { moduleType = pModuleType, subscribe = false }) @@ -37,11 +39,11 @@ local function unSubscriptionToModule(pModuleType, pResultCode, self) subscribe = false }) :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") + commonRC.getHMIConnection():SendError(data.id, data.method, pResultCode, "Error error") -- no isSubscribed parameter end) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = pResultCode }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = pResultCode }) :ValidIf(function(_, data) -- no isSubscribed parameter if data.payload.isSubscribed == nil then return true @@ -54,17 +56,17 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App subscribed", commonRC.isSubscribed, { mod }) end runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do for _, err in pairs(error_codes) do runner.Step("Unsubscribe app to " .. mod .. " (" .. err .. " from HMI)", unSubscriptionToModule, { mod, err }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App still subscribed", commonRC.isSubscribed, { mod }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua index 2f0340392f..3e39772d15 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua @@ -18,6 +18,9 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local mod1 = "CLIMATE" local mod2 = "RADIO" @@ -26,8 +29,8 @@ local mod2 = "RADIO" runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua index decaab1b0d..e5aebbfc98 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua @@ -18,6 +18,9 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local mod1 = "RADIO" local mod2 = "CLIMATE" @@ -26,8 +29,8 @@ local mod2 = "CLIMATE" runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua index 1b381d86a3..28d63f84c1 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua @@ -19,8 +19,10 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } local mod1 = "RADIO" local mod2 = "CLIMATE" @@ -28,10 +30,10 @@ local mod2 = "CLIMATE" runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", commonRC.isSubscribed, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua index ca815b23c0..df097bcf0e 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua @@ -19,8 +19,10 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } local mod1 = "CLIMATE" local mod2 = "RADIO" @@ -28,10 +30,10 @@ local mod2 = "RADIO" runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", commonRC.isSubscribed, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/016_RPC_parameters_values.lua b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/016_RPC_parameters_values.lua index e51beb981b..7d5f48386c 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/016_RPC_parameters_values.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/016_RPC_parameters_values.lua @@ -22,44 +22,44 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function invalidParamName(pModuleType, self) - self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { +local function invalidParamName(pModuleType) + commonRC.getHMIConnection():SendNotification("RC.OnInteriorVehicleData", { modduleData = commonRC.getAnotherModuleControlData(pModuleType) -- invalid name of parameter }) - self.mobileSession1:ExpectNotification("OnInteriorVehicleData") + commonRC.getMobileSession():ExpectNotification("OnInteriorVehicleData") :Times(0) commonTestCases:DelayedExp(commonRC.timeout) end -local function invalidParamType(pModuleType, self) +local function invalidParamType(pModuleType) local moduleData = commonRC.getAnotherModuleControlData(pModuleType) moduleData.moduleType = {} -- invalid type of parameter - self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + commonRC.getHMIConnection():SendNotification("RC.OnInteriorVehicleData", { moduleData = moduleData }) - self.mobileSession1:ExpectNotification("OnInteriorVehicleData") + commonRC.getMobileSession():ExpectNotification("OnInteriorVehicleData") :Times(0) commonTestCases:DelayedExp(commonRC.timeout) end -local function missingMandatoryParam(pModuleType, self) +local function missingMandatoryParam(pModuleType) local moduleData = commonRC.getAnotherModuleControlData(pModuleType) moduleData.moduleType = nil -- mandatory parameter missing - self.hmiConnection:SendNotification("RC.OnInteriorVehicleData", { + commonRC.getHMIConnection():SendNotification("RC.OnInteriorVehicleData", { moduleData = moduleData }) - self.mobileSession1:ExpectNotification("OnInteriorVehicleData") + commonRC.getMobileSession():ExpectNotification("OnInteriorVehicleData") :Times(0) commonTestCases:DelayedExp(commonRC.timeout) @@ -69,17 +69,17 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", commonRC.isSubscribed, { mod }) end runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("OnInteriorVehicleData " .. mod .. " invalid name of parameter", invalidParamName, { mod }) runner.Step("OnInteriorVehicleData " .. mod .. " invalid type of parameter", invalidParamType, { mod }) runner.Step("OnInteriorVehicleData " .. mod .. " mandatory parameter missing", missingMandatoryParam, { mod }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua index 1e7307d267..c5125ae9f7 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua @@ -20,35 +20,32 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } local access_modes = { nil, "AUTO_ALLOW" } ---[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) for i = 1, #access_modes do runner.Title("Access mode: " .. tostring(access_modes[i])) -- set control for App1 - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) -- set RA mode runner.Step("Set RA mode", commonRC.defineRAMode, { true, access_modes[i] }) -- set control for App2 --> Allowed - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) runner.Step("App2 ButtonPress", commonRC.rpcAllowed, { mod, 2, "ButtonPress" }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua index 681bf2178a..616415841a 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua @@ -20,35 +20,32 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } local access_modes = { nil, "AUTO_ALLOW" } ---[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) for i = 1, #access_modes do runner.Title("Access mode: " .. tostring(access_modes[i])) -- set control for App1 - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) -- set RA mode runner.Step("Set RA mode", commonRC.defineRAMode, { true, access_modes[i] }) -- set control for App2 --> Allowed - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("App2 ButtonPress", commonRC.rpcAllowed, { mod, 2, "ButtonPress" }) runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua index 449e83335d..6d2a6673da 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua @@ -20,35 +20,32 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } local access_modes = { nil, "AUTO_ALLOW" } ---[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) for i = 1, #access_modes do runner.Title("Access mode: " .. tostring(access_modes[i])) -- set control for App1 - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("App1 ButtonPress", commonRC.rpcAllowed, { mod, 1, "ButtonPress" }) -- set RA mode runner.Step("Set RA mode", commonRC.defineRAMode, { true, access_modes[i] }) -- set control for App2 --> Allowed - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("App2 ButtonPress", commonRC.rpcAllowed, { mod, 2, "ButtonPress" }) runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua index 30ea672fd2..babb9ba38e 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua @@ -20,35 +20,32 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } local access_modes = { nil, "AUTO_ALLOW" } ---[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) for i = 1, #access_modes do runner.Title("Access mode: " .. tostring(access_modes[i])) -- set control for App1 - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("App1 ButtonPress", commonRC.rpcAllowed, { mod, 1, "ButtonPress" }) -- set RA mode runner.Step("Set RA mode", commonRC.defineRAMode, { true, access_modes[i] }) -- set control for App2 --> Allowed - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) runner.Step("App2 ButtonPress", commonRC.rpcAllowed, { mod, 2, "ButtonPress" }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua index 46fdc199bd..5d22e49982 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua @@ -22,29 +22,26 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } local access_modes = { nil, "AUTO_ALLOW", "AUTO_DENY", "ASK_DRIVER" } ---[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) -- App's HMI levels: 1 - BACKGROUND, 2 - FULL runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) -- set control for App2 runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua index a2c026b1cc..023a2dcd1f 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua @@ -30,35 +30,32 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } local access_modes = { nil, "AUTO_ALLOW" } ---[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - -local function step(pModuleType, pRPC1, pRPC2, self) +local function step(pModuleType, pRPC1, pRPC2) local cid1 if pRPC1 == "SetInteriorVehicleData" then - cid1 = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + cid1 = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = self.applications["Test Application"], + appID = commonRC.getHMIAppId(), moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :Do(function(_, data) local function hmiRespond() - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) end RUN_AFTER(hmiRespond, 2000) end) elseif pRPC1 == "ButtonPress" then - cid1 = self.mobileSession1:SendRPC("ButtonPress", { + cid1 = commonRC.getMobileSession():SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" @@ -71,27 +68,27 @@ local function step(pModuleType, pRPC1, pRPC2, self) }) :Do(function(_, data) local function hmiRespond() - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) end RUN_AFTER(hmiRespond, 2000) end) end - self.mobileSession1:ExpectResponse(cid1, { success = true, resultCode = "SUCCESS" }) + commonRC.getMobileSession():ExpectResponse(cid1, { success = true, resultCode = "SUCCESS" }) local req2_func = function() local cid2 if pRPC2 == "SetInteriorVehicleData" then - cid2 = self.mobileSession2:SendRPC("SetInteriorVehicleData", { + cid2 = commonRC.getMobileSession(2):SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) elseif pRPC2 == "ButtonPress" then - cid2 = self.mobileSession2:SendRPC("ButtonPress", { + cid2 = commonRC.getMobileSession(2):SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" }) end - self.mobileSession2:ExpectResponse(cid2, { success = false, resultCode = "IN_USE" }) + commonRC.getMobileSession(2):ExpectResponse(cid2, { success = false, resultCode = "IN_USE" }) end RUN_AFTER(req2_func, 1000) @@ -101,14 +98,14 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) -- set control for App1 runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua index 6c79b8d044..90eea5a89a 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua @@ -20,27 +20,22 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } - ---[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Title("Test") runner.Step("Set RA mode: AUTO_DENY", commonRC.defineRAMode, { true, "AUTO_DENY" }) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) -- set control for App1 runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua index f272226a97..61d150e569 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua @@ -21,37 +21,37 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +--[[ Local Variables ]] local rcRpcs = {"GetInteriorVehicleData", "SetInteriorVehicleData", "ButtonPress"} --[[ Local Functions ]] - -local function ptu_update_func(tbl) - local notRcAppConfig = { - keep_context = false, - steal_focus = false, +local function PTUfunc(tbl) + local notRcAppConfig = { + keep_context = false, + steal_focus = false, priority = "NONE", default_hmi = "NONE", groups = { "Base-4" }, groups_primaryRC = { "Base-4"}, AppHMIType = { "NAVIGATION" } - } - + } + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() tbl.policy_table.app_policies[config.application3.registerAppInterfaceParams.appID] = notRcAppConfig end -local function disableRcFromHmi(self) - local mobileSession1 = commonRC.getMobileSession(self, 1) - local mobileSession2 = commonRC.getMobileSession(self, 2) - local mobileSession3 = commonRC.getMobileSession(self, 3) +local function disableRcFromHmi() + local mobileSession1 = commonRC.getMobileSession(1) + local mobileSession2 = commonRC.getMobileSession(2) + local mobileSession3 = commonRC.getMobileSession(3) - commonRC.defineRAMode(false, nil, self) + commonRC.defineRAMode(false, nil) - mobileSession1:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE"}):Times(AtLeast(1)) -- issue with SDL --> notification is sent twice - mobileSession2:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE"}):Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + mobileSession1:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE"}):Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + mobileSession2:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE"}):Times(AtLeast(1)) -- issue with SDL --> notification is sent twice mobileSession3:ExpectNotification("OnHMIStatus"):Times(0) -- NAVIGATION app commonTestCases:DelayedExp(commonRC.timeout) @@ -59,21 +59,22 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("RAI1", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App1", commonRC.activateApp) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Subscribe App2 on CLIMATE module", commonRC.subscribeToModule, { "CLIMATE", 2 }) runner.Step("Subscribe App1 on RADIO module", commonRC.subscribeToModule, { "RADIO", 1 }) -runner.Step("RAI3", commonRC.rai_n, { 3 }) -runner.Step("Activate App3", commonRC.activate_app, { 3 }) +runner.Step("RAI3", commonRC.registerAppWOPTU, { 3 }) +runner.Step("Activate App3", commonRC.activateApp, { 3 }) runner.Title("Test") runner.Step("Disable RC from HMI", disableRcFromHmi) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do -- Apps are not subscribed from RC modules runner.Step("Check App1 is not subscribed on " .. mod, commonRC.isUnsubscribed, { mod, 1 }) runner.Step("Check App2 is not subscribed on " .. mod, commonRC.isUnsubscribed, { mod, 2 }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua index b34c1c7165..b8fccb0da2 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua @@ -20,36 +20,32 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +--[[ Local Variables ]] local rcRpcs = { "SetInteriorVehicleData", "ButtonPress" } --[[ Local Functions ]] - -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - -local function disableRcFromHmi(self) - commonRC.defineRAMode(false, nil, self) +local function disableRcFromHmi() + commonRC.defineRAMode(false, nil) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) runner.Step("Disable RC from HMI", disableRcFromHmi) runner.Title("Test") runner.Step("Enable RC from HMI with AUTO_ALLOW access mode", commonRC.defineRAMode, { true, "AUTO_ALLOW"}) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do for _, rpc in pairs(rcRpcs) do - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check module " .. mod .." App1 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 1, rpc }) - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Check module " .. mod .." App2 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 2, rpc }) end end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua index 00f5e7cc21..e26da25fe2 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua @@ -20,36 +20,32 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +--[[ Local Variables ]] local rcRpcs = {"SetInteriorVehicleData", "ButtonPress"} --[[ Local Functions ]] - -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - -local function disableRcFromHmi(self) - commonRC.defineRAMode(false, nil, self) +local function disableRcFromHmi() + commonRC.defineRAMode(false, nil) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) runner.Step("Disable RC from HMI", disableRcFromHmi) runner.Title("Test") runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do for _, rpc in pairs(rcRpcs) do - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check module " .. mod .." App1 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 1, rpc }) - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Check module " .. mod .." App2 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 2, rpc, "IN_USE" }) end end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua index 6651c7569f..4c478486a1 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua @@ -20,37 +20,32 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] - -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - -local function disableRcFromHmi(self) - commonRC.defineRAMode(false, nil, self) +local function disableRcFromHmi() + commonRC.defineRAMode(false, nil) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) runner.Step("Disable RC from HMI", disableRcFromHmi) runner.Title("Test") runner.Step("Enable RC from HMI with ASK_DRIVER access mode", commonRC.defineRAMode, { true, "ASK_DRIVER"}) -for _, mod in pairs(modules) do - runner.Step("Activate App2", commonRC.activate_app, { 2 }) +for _, mod in pairs(commonRC.modules) do + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check module " .. mod .." App1 SetInteriorVehicleData allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 1, "SetInteriorVehicleData" }) - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Check module " .. mod .." App1 ButtonPress allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 2, "ButtonPress" }) - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check module " .. mod .." App1 ButtonPress allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 1, "ButtonPress" }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/012_Default_accessMode.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/012_Default_accessMode.lua index f10abc7c3a..acb6b73e13 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/012_Default_accessMode.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/012_Default_accessMode.lua @@ -18,30 +18,25 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +--[[ Local Variables ]] local rcRpcs = { "SetInteriorVehicleData", "ButtonPress" } ---[[ Local Functions ]] - -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do for _, rpc in pairs(rcRpcs) do - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Check module " .. mod .." App2 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 2, rpc }) - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check module " .. mod .." App1 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 1, rpc }) end end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua index c81bf9ed81..58030dbe91 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua @@ -35,99 +35,94 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +--[[ Local Variables ]] local rcRpcs = { "SetInteriorVehicleData", "ButtonPress" } ---[[ Local Functions ]] - -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) runner.Title("Test") runner.Title("Default -> ASK_DRIVER") runner.Step("Enable RC from HMI with ASK_DRIVER access mode", commonRC.defineRAMode, { true, "ASK_DRIVER"}) -for _, mod in pairs(modules) do - runner.Step("Activate App2", commonRC.activate_app, { 2 }) - runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) - runner.Step("Activate App1", commonRC.activate_app) +for _, mod in pairs(commonRC.modules) do + runner.Step("Activate App2", commonRC.activateApp, { 2 }) + runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check module " .. mod .." App1 SetInteriorVehicleData allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 1, "SetInteriorVehicleData" }) - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Check module " .. mod .." App1 ButtonPress allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 2, "ButtonPress" }) - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check module " .. mod .." App1 ButtonPress allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 1, "ButtonPress" }) end runner.Title("ASK_DRIVER -> AUTO_ALLOW") runner.Step("Enable RC from HMI with AUTO_ALLOW access mode", commonRC.defineRAMode, { true, "AUTO_ALLOW"}) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do for _, rpc in pairs(rcRpcs) do - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Check module " .. mod .." App2 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 2, rpc }) - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check module " .. mod .." App1 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 1, rpc }) end end runner.Title("AUTO_ALLOW -> AUTO_DENY") runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do for _, rpc in pairs(rcRpcs) do - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Check module " .. mod .." App2 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 2, rpc, "IN_USE" }) - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check module " .. mod .." App1 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 1, rpc }) end end runner.Title("AUTO_DENY -> ASK_DRIVER") runner.Step("Enable RC from HMI with ASK_DRIVER access mode", commonRC.defineRAMode, { true, "ASK_DRIVER"}) -for _, mod in pairs(modules) do - runner.Step("Activate App2", commonRC.activate_app, { 2 }) - runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 2, "SetInteriorVehicleData" }) - runner.Step("Activate App1", commonRC.activate_app) +for _, mod in pairs(commonRC.modules) do + runner.Step("Activate App2", commonRC.activateApp, { 2 }) + runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check module " .. mod .." App1 SetInteriorVehicleData allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 1, "SetInteriorVehicleData" }) - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Check module " .. mod .." App1 ButtonPress allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 2, "ButtonPress" }) - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check module " .. mod .." App1 ButtonPress allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 1, "ButtonPress" }) end runner.Title("ASK_DRIVER -> AUTO_DENY") runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do for _, rpc in pairs(rcRpcs) do - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Check module " .. mod .." App2 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 2, rpc, "IN_USE" }) - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check module " .. mod .." App1 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 1, rpc }) end end runner.Title("AUTO_DENY -> AUTO_ALLOW") runner.Step("Enable RC from HMI with AUTO_ALLOW access mode", commonRC.defineRAMode, { true, "AUTO_ALLOW"}) -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do for _, rpc in pairs(rcRpcs) do - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Check module " .. mod .." App2 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 2, rpc }) - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check module " .. mod .." App1 " .. rpc .. " allowed", commonRC.rpcAllowed, { mod, 1, rpc }) end end runner.Title("AUTO_ALLOW -> ASK_DRIVER") runner.Step("Enable RC from HMI with ASK_DRIVER access mode", commonRC.defineRAMode, { true, "ASK_DRIVER"}) -for _, mod in pairs(modules) do - runner.Step("Activate App2", commonRC.activate_app, { 2 }) - runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 2, "SetInteriorVehicleData" }) - runner.Step("Activate App1", commonRC.activate_app) +for _, mod in pairs(commonRC.modules) do + runner.Step("Activate App2", commonRC.activateApp, { 2 }) + runner.Step("Check module " .. mod .." App2 SetInteriorVehicleData allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 2, "SetInteriorVehicleData" }) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check module " .. mod .." App1 SetInteriorVehicleData allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 1, "SetInteriorVehicleData" }) - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Check module " .. mod .." App1 ButtonPress allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 2, "ButtonPress" }) - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check module " .. mod .." App1 ButtonPress allowed with driver consent", commonRC.rpcAllowedWithConsent, { mod, 1, "ButtonPress" }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua index 614c759273..2f1130d762 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua @@ -17,44 +17,40 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - -local function setRAMode(self) +local function setRAMode() local rpc = "OnRemoteControlSettings" local params = { allowed = "aaa" -- invalid type of parameter } - self.hmiConnection:SendNotification(commonRC.getHMIEventName(rpc), params) + commonRC.getHMIConnection():SendNotification(commonRC.getHMIEventName(rpc), params) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) -runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) runner.Title("RA mode Default AUTO_ALLOW") - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Send OnRemoteControlSettings with invalid data", setRAMode) runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) runner.Title("RA mode AUTO_DENY") runner.Step("Set RA mode", commonRC.defineRAMode, { true, "AUTO_DENY" }) - runner.Step("Activate App1", commonRC.activate_app, { 1 }) + runner.Step("Activate App1", commonRC.activateApp, { 1 }) runner.Step("Send OnRemoteControlSettings with invalid data", setRAMode) runner.Step("App2 SetInteriorVehicleData", commonRC.rpcDenied, { mod, 1, "SetInteriorVehicleData", "IN_USE" }) @@ -66,10 +62,10 @@ for _, mod in pairs(modules) do runner.Title("RA mode AUTO_ALLOW") runner.Step("Set RA mode", commonRC.defineRAMode, { true, "AUTO_ALLOW" }) - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Send OnRemoteControlSettings with invalid data", setRAMode) runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) - runner.Step("Activate App1", commonRC.activate_app, { 1 }) + runner.Step("Activate App1", commonRC.activateApp, { 1 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/015_Empty_data_from_HMI.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/015_Empty_data_from_HMI.lua index 7df469d81c..ad33ddaaa4 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/015_Empty_data_from_HMI.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/015_Empty_data_from_HMI.lua @@ -17,42 +17,38 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - -local function setRAMode(self) +local function setRAMode() local rpc = "OnRemoteControlSettings" local params = { } -- no parameters - self.hmiConnection:SendNotification(commonRC.getHMIEventName(rpc), params) + commonRC.getHMIConnection():SendNotification(commonRC.getHMIEventName(rpc), params) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) -runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) runner.Title("RA mode Default AUTO_ALLOW") - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Send OnRemoteControlSettings with invalid data", setRAMode) runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) runner.Title("RA mode AUTO_DENY") runner.Step("Set RA mode", commonRC.defineRAMode, { true, "AUTO_DENY" }) - runner.Step("Activate App1", commonRC.activate_app, { 1 }) + runner.Step("Activate App1", commonRC.activateApp, { 1 }) runner.Step("Send OnRemoteControlSettings with invalid data", setRAMode) runner.Step("App1 SetInteriorVehicleData", commonRC.rpcDenied, { mod, 1, "SetInteriorVehicleData", "IN_USE" }) @@ -64,10 +60,10 @@ for _, mod in pairs(modules) do runner.Title("RA mode AUTO_ALLOW") runner.Step("Set RA mode", commonRC.defineRAMode, { true, "AUTO_ALLOW" }) - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Send OnRemoteControlSettings with invalid data", setRAMode) runner.Step("App2 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 2, "SetInteriorVehicleData" }) - runner.Step("Activate App1", commonRC.activate_app, { 1 }) + runner.Step("Activate App1", commonRC.activateApp, { 1 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua index fba44244cb..4858172d72 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua @@ -22,38 +22,36 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) runner.Title("Default -> ASK_DRIVER") runner.Step("Enable RC from HMI with ASK_DRIVER access mode", commonRC.defineRAMode, { true, "ASK_DRIVER"}) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Module CLIMATE App2 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "CLIMATE", 2, "SetInteriorVehicleData" }) -runner.Step("Activate App1", commonRC.activate_app) +runner.Step("Activate App1", commonRC.activateApp) runner.Step("Module RADIO App1 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "RADIO", 1, "SetInteriorVehicleData" }) runner.Step("Check module CLIMATE App1 SetInteriorVehicleData rejected with driver consent", commonRC.rpcRejectWithConsent, { "CLIMATE", 1, "SetInteriorVehicleData" }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Check module RADIO App2 SetInteriorVehicleData rejected with driver consent", commonRC.rpcRejectWithConsent, { "RADIO", 2, "SetInteriorVehicleData" }) runner.Title("Test") runner.Title("ASK_DRIVER -> AUTO_DENY") runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) runner.Step("Check module RADIO App2 SetInteriorVehicleData denied", commonRC.rpcDenied, { "RADIO", 2, "SetInteriorVehicleData", "IN_USE" }) -runner.Step("Activate App1", commonRC.activate_app) +runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check module CLIMATE App1 SetInteriorVehicleData denied", commonRC.rpcDenied, { "CLIMATE", 1, "SetInteriorVehicleData", "IN_USE" }) runner.Title("AUTO_DENY -> AUTO_ALLOW") runner.Step("Enable RC from HMI with AUTO_ALLOW access mode", commonRC.defineRAMode, { true, "AUTO_ALLOW"}) runner.Step("Check module CLIMATE App1 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "CLIMATE", 1, "SetInteriorVehicleData" }) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Check module RADIO App2 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "RADIO", 2, "SetInteriorVehicleData" }) runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua index dfc5e03342..eb8e34890a 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua @@ -26,33 +26,29 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false config.application3.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } ---[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() - tbl.policy_table.app_policies[config.application3.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { true, 3 }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("RAI3", commonRC.rai_n, { 3 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("RAI3", commonRC.registerAppWOPTU, { 3 }) runner.Title("Test") runner.Title("Default -> ASK_DRIVER") runner.Step("Enable RC from HMI with ASK_DRIVER access mode", commonRC.defineRAMode, { true, "ASK_DRIVER"}) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Module CLIMATE App2 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "CLIMATE", 2, "SetInteriorVehicleData" }) -runner.Step("Activate App1", commonRC.activate_app) +runner.Step("Activate App1", commonRC.activateApp) runner.Step("Module RADIO App1 ButtonPress allowed", commonRC.rpcAllowed, { "RADIO", 1, "ButtonPress" }) runner.Step("Unregister App2", commonRC.unregisterApp, { 2 }) runner.Step("Module CLIMATE App1 ButtonPress allowed", commonRC.rpcAllowed, { "CLIMATE", 1, "ButtonPress" }) -runner.Step("Activate App3", commonRC.activate_app, { 3 }) -runner.Step("Activate App1", commonRC.activate_app, { 1 }) +runner.Step("Activate App3", commonRC.activateApp, { 3 }) +runner.Step("Activate App1", commonRC.activateApp, { 1 }) runner.Title("ASK_DRIVER -> AUTO_DENY") runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) runner.Step("Unregister App1", commonRC.unregisterApp, { 1 }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua index 96b301a381..e6c498a641 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua @@ -26,36 +26,32 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false config.application3.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } ---[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() - tbl.policy_table.app_policies[config.application3.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { true, 3 }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("RAI2", commonRC.rai_n, { 2 }) -runner.Step("RAI3", commonRC.rai_n, { 3 }) +runner.Step("RAI1", commonRC.registerAppWOPTU, { 1 }) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("RAI3", commonRC.registerAppWOPTU, { 3 }) runner.Title("Test") runner.Title("Default -> ASK_DRIVER") runner.Step("Enable RC from HMI with ASK_DRIVER access mode", commonRC.defineRAMode, { true, "ASK_DRIVER"}) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Module CLIMATE App2 ButtonPress allowed", commonRC.rpcAllowed, { "CLIMATE", 2, "ButtonPress" }) -runner.Step("Activate App1", commonRC.activate_app) +runner.Step("Activate App1", commonRC.activateApp) runner.Step("Module CLIMATE App1 SetInteriorVehicleData rejected with driver consent", commonRC.rpcRejectWithConsent, { "CLIMATE", 1, "SetInteriorVehicleData" }) -runner.Step("Activate App3", commonRC.activate_app, { 3 }) +runner.Step("Activate App3", commonRC.activateApp, { 3 }) runner.Step("Module CLIMATE App3 ButtonPress rejected with driver consent", commonRC.rpcRejectWithConsent, { "CLIMATE", 3, "ButtonPress" }) runner.Step("Unregister App2", commonRC.unregisterApp, { 2 }) runner.Step("Module CLIMATE App3 ButtonPress allowed", commonRC.rpcAllowed, { "CLIMATE", 3, "ButtonPress" }) runner.Title("ASK_DRIVER -> AUTO_DENY") runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) -runner.Step("Activate App1", commonRC.activate_app) +runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check module CLIMATE App1 SetInteriorVehicleData denied", commonRC.rpcDenied, { "CLIMATE", 1, "SetInteriorVehicleData", "IN_USE" }) runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua index 89c6da5d71..f84922bdfa 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua @@ -21,23 +21,20 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } local rcRpcs = { "SetInteriorVehicleData", "ButtonPress" } local accessModes = { "AUTO_ALLOW", "AUTO_DENY", "ASK_DRIVER" } local HMILevels = { "FULL", "NOT_FULL" } ---[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) runner.Title("Test") @@ -45,21 +42,21 @@ for _, initialAccessMode in pairs(accessModes) do for _, targetAccessMode in pairs(accessModes) do for _, appLevel in pairs(HMILevels) do runner.Title(initialAccessMode .. " -> Disable RC -> " .. targetAccessMode .. " (" .. appLevel .. ")") - for _, mod in pairs(modules) do + for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) runner.Step("Enable RC from HMI with " .. initialAccessMode .." access mode", commonRC.defineRAMode, { true, initialAccessMode }) - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App1", commonRC.activateApp) runner.Step("Check App1 " .. rcRpcs[1] .. " allowed", commonRC.rpcAllowed, { mod, 1, rcRpcs[1] }) runner.Step("Disable RC from HMI", commonRC.defineRAMode, { false, initialAccessMode }) runner.Step("Enable RC from HMI with " .. targetAccessMode .. " access mode", commonRC.defineRAMode, { true, targetAccessMode }) if appLevel == "FULL" then - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) runner.Step("Check App2 " .. rcRpcs[2] .. " allowed", commonRC.rpcAllowed, { mod, 2, rcRpcs[2] }) else - runner.Step("Activate App2", commonRC.activate_app, { 2 }) - runner.Step("Activate App1", commonRC.activate_app, { 1 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) + runner.Step("Activate App1", commonRC.activateApp, { 1 }) runner.Step("Check App2 " .. rcRpcs[2] .. " allowed", commonRC.rpcAllowed, { mod, 2, rcRpcs[2] }) - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) end end end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua index dbd0b813d9..1fc0288c61 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua @@ -17,31 +17,28 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } local rcRpcs = { "SetInteriorVehicleData", "ButtonPress" } local accessModes = { "AUTO_ALLOW", "AUTO_DENY", "ASK_DRIVER" } - --[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() -end - -local function disableRcFromHmi(self) - commonRC.defineRAMode(false, nil, self) +local function disableRcFromHmi() + commonRC.defineRAMode(false, nil) end -local function enableRcFromHmi(self) - commonRC.defineRAMode(true, nil, self) +local function enableRcFromHmi() + commonRC.defineRAMode(true, nil) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("RAI1", commonRC.registerAppWOPTU) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) runner.Title("Test") @@ -50,19 +47,19 @@ for _, accessMode in pairs(accessModes) do runner.Step("Enable RC from HMI with " .. accessMode .." access mode", commonRC.defineRAMode, { true, accessMode }) runner.Step("Disable RC from HMI", disableRcFromHmi) runner.Step("Enable RC from HMI without access mode", enableRcFromHmi) - runner.Step("Activate App1", commonRC.activate_app) - runner.Step("Check module " .. modules[1] .." App1 " .. rcRpcs[2] .. " allowed", commonRC.rpcAllowed, { modules[1], 1, rcRpcs[2] }) - runner.Step("Check module " .. modules[2] .." App1 " .. rcRpcs[1] .. " allowed", commonRC.rpcAllowed, { modules[2], 1, rcRpcs[1] }) - runner.Step("Activate App2", commonRC.activate_app, { 2 }) + runner.Step("Activate App1", commonRC.activateApp) + runner.Step("Check module " .. commonRC.modules[1] .." App1 " .. rcRpcs[2] .. " allowed", commonRC.rpcAllowed, { commonRC.modules[1], 1, rcRpcs[2] }) + runner.Step("Check module " .. commonRC.modules[2] .." App1 " .. rcRpcs[1] .. " allowed", commonRC.rpcAllowed, { commonRC.modules[2], 1, rcRpcs[1] }) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) if accessMode == "AUTO_ALLOW" then - runner.Step("Check module " .. modules[1] .." App2 " .. rcRpcs[2] .. " allowed", commonRC.rpcAllowed, { modules[1], 2, rcRpcs[2] }) - runner.Step("Check module " .. modules[2] .." App1 " .. rcRpcs[1] .. " allowed", commonRC.rpcAllowed, { modules[2], 2, rcRpcs[1] }) + runner.Step("Check module " .. commonRC.modules[1] .." App2 " .. rcRpcs[2] .. " allowed", commonRC.rpcAllowed, { commonRC.modules[1], 2, rcRpcs[2] }) + runner.Step("Check module " .. commonRC.modules[2] .." App1 " .. rcRpcs[1] .. " allowed", commonRC.rpcAllowed, { commonRC.modules[2], 2, rcRpcs[1] }) elseif accessMode == "AUTO_DENY" then - runner.Step("Check module " .. modules[1] .." App2 " .. rcRpcs[2] .. " denied", commonRC.rpcDenied, { modules[1], 2, rcRpcs[2], "IN_USE" }) - runner.Step("Check module " .. modules[2] .." App2 " .. rcRpcs[1] .. " denied", commonRC.rpcDenied, { modules[2], 2, rcRpcs[1], "IN_USE" }) + runner.Step("Check module " .. commonRC.modules[1] .." App2 " .. rcRpcs[2] .. " denied", commonRC.rpcDenied, { commonRC.modules[1], 2, rcRpcs[2], "IN_USE" }) + runner.Step("Check module " .. commonRC.modules[2] .." App2 " .. rcRpcs[1] .. " denied", commonRC.rpcDenied, { commonRC.modules[2], 2, rcRpcs[1], "IN_USE" }) elseif accessMode == "ASK_DRIVER" then - runner.Step("Check module " .. modules[1] .." App2 " .. rcRpcs[1] .. " allowed with driver consent", commonRC.rpcAllowedWithConsent, { modules[1], 2, rcRpcs[1] }) - runner.Step("Check module " .. modules[2] .." App2 " .. rcRpcs[2] .. " allowed with driver consent", commonRC.rpcAllowedWithConsent, { modules[2], 2, rcRpcs[2] }) + runner.Step("Check module " .. commonRC.modules[1] .." App2 " .. rcRpcs[1] .. " allowed with driver consent", commonRC.rpcAllowedWithConsent, { commonRC.modules[1], 2, rcRpcs[1] }) + runner.Step("Check module " .. commonRC.modules[2] .." App2 " .. rcRpcs[2] .. " allowed with driver consent", commonRC.rpcAllowedWithConsent, { commonRC.modules[2], 2, rcRpcs[2] }) end end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua index a2749a5ce0..483a578a57 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua @@ -17,19 +17,23 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local exitAppReasons = {"USER_EXIT", "DRIVER_DISTRACTION_VIOLATION"} --[[ Local Functions ]] -local function ptu_update_func(tbl) +local function PTUfunc(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() table.insert(tbl.policy_table.functional_groupings.RemoteControl.rpcs.OnInteriorVehicleData.hmi_levels, "NONE") end -local function exitApp(pReason, pAppId, self) +local function exitApp(pReason, pAppId) local hmiAppId = commonRC.getHMIAppId(pAppId) - local mobSession = commonRC.getMobileSession(self, pAppId) - self.hmiConnection:SendNotification("BasicCommunication.OnExitApplication", + local mobSession = commonRC.getMobileSession(pAppId) + commonRC.getHMIConnection():SendNotification("BasicCommunication.OnExitApplication", { appID = hmiAppId, reason = pReason }) mobSession:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) @@ -37,17 +41,18 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("RAI2", commonRC.rai_n, { 2 }) +runner.Step("RAI1", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) runner.Title("Test") runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) for _, reason in pairs(exitAppReasons) do runner.Title("Exit reason " .. reason) - runner.Step("Activate App2", commonRC.activate_app, { 2 }) - runner.Step("Activate App1", commonRC.activate_app) + runner.Step("Activate App2", commonRC.activateApp, { 2 }) + runner.Step("Activate App1", commonRC.activateApp) -- App1: FULL, App2: BACKGROUND runner.Step("Module CLIMATE App1 ButtonPress allowed", commonRC.rpcAllowed, { "CLIMATE", 1, "ButtonPress" }) runner.Step("Subscribe App1 to CLIMATE", commonRC.subscribeToModule, { "CLIMATE", 1 }) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua index 63b96dea08..e3ceaad51b 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua @@ -17,8 +17,15 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Functions ]] -local function ptu_update_func(tbl) +local function PTUfunc1(tbl) + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } +end + +local function PTUfunc2(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = { keep_context = false, steal_focus = false, @@ -34,21 +41,23 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU with RADIO for App1", commonRC.rai_ptu) +runner.Step("RAI1", commonRC.registerApp) +runner.Step("PTU with RADIO for App1", commonRC.policyTableUpdate, { PTUfunc1 }) runner.Title("Test") runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) -runner.Step("Activate App1", commonRC.activate_app) +runner.Step("Activate App1", commonRC.activateApp) -- App1: FULL runner.Step("Module RADIO App1 ButtonPress allowed", commonRC.rpcAllowed, { "RADIO", 1, "ButtonPress" }) runner.Step("Subscribe App1 to RADIO", commonRC.subscribeToModule, { "RADIO", 1 }) runner.Step("Send notification OnInteriorVehicleData RADIO. App1 is subscribed", commonRC.isSubscribed, { "RADIO", 1 }) -runner.Step("RAI2, PTU without RADIO for App1", commonRC.rai_ptu_n, { 2, ptu_update_func }) +runner.Step("RAI2", commonRC.registerApp, { 2 }) +runner.Step("PTU with CLIMATE for App1", commonRC.policyTableUpdate, { PTUfunc2 }) runner.Step("Module RADIO App1 SetInteriorVehicleData disallowed", commonRC.rpcDenied, { "RADIO", 1, "SetInteriorVehicleData", "DISALLOWED"}) runner.Step("Module CLIMATE App1 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "CLIMATE", 1, "SetInteriorVehicleData"}) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) -- App1: BACKGROUND, App2: FULL runner.Step("Send notification OnInteriorVehicleData RADIO. App1 is unsubscribed", commonRC.isUnsubscribed, { "RADIO", 1 }) runner.Step("Module RADIO App2 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "RADIO", 2, "SetInteriorVehicleData"}) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua index 29a473cf86..d5d9549452 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua @@ -18,30 +18,33 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local json = require("modules/json") +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = json.null tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig() end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { true, 1 }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU with RADIO for App1", commonRC.rai_ptu) +runner.Step("RAI1", commonRC.registerAppWOPTU) runner.Title("Test") runner.Step("Enable RC from HMI with AUTO_DENY access mode", commonRC.defineRAMode, { true, "AUTO_DENY"}) -runner.Step("Activate App1", commonRC.activate_app) +runner.Step("Activate App1", commonRC.activateApp) -- App1: FULL runner.Step("Module RADIO App1 ButtonPress allowed", commonRC.rpcAllowed, { "RADIO", 1, "ButtonPress" }) runner.Step("Subscribe App1 to RADIO", commonRC.subscribeToModule, { "RADIO", 1 }) runner.Step("Send notification OnInteriorVehicleData RADIO. App1 is subscribed", commonRC.isSubscribed, { "RADIO", 1 }) -runner.Step("RAI2, PTU App1 permissions revoked", commonRC.rai_ptu_n, { 2, ptu_update_func }) +runner.Step("RAI2", commonRC.registerApp, { 2 }) +runner.Step("PTU App1 permissions revoked", commonRC.policyTableUpdate, { PTUfunc }) runner.Step("Module RADIO App1 SetInteriorVehicleData disallowed", commonRC.rpcDenied, { "RADIO", 1, "SetInteriorVehicleData", "DISALLOWED"}) runner.Step("Module CLIMATE App1 SetInteriorVehicleData disallowed", commonRC.rpcDenied, { "CLIMATE", 1, "SetInteriorVehicleData", "DISALLOWED"}) -runner.Step("Activate App2", commonRC.activate_app, { 2 }) +runner.Step("Activate App2", commonRC.activateApp, { 2 }) -- App1: BACKGROUND, App2: FULL runner.Step("Send notification OnInteriorVehicleData RADIO. App1 is unsubscribed", commonRC.isUnsubscribed, { "RADIO", 1 }) runner.Step("Module RADIO App2 SetInteriorVehicleData allowed", commonRC.rpcAllowed, { "RADIO", 2, "SetInteriorVehicleData"}) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua index f3e8812b5c..10ee97a21e 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua @@ -20,56 +20,24 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') -local mobile_session = require("mobile_session") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ General configuration parameters ]] config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application3.registerAppInterfaceParams.appHMIType = { "DEFAULT" } ---[[ Local Variables ]] -local hmiAppIds = { } - --[[ Local Functions ]] -local function register_app(pAppId, self) - self["mobileSession" .. pAppId] = mobile_session.MobileSession(self, self.mobileConnection) - self["mobileSession" .. pAppId]:StartService(7) - :Do(function() - local corId = self["mobileSession" .. pAppId]:SendRPC("RegisterAppInterface", - config["application" .. pAppId].registerAppInterfaceParams) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", - { application = { appName = config["application" .. pAppId].registerAppInterfaceParams.appName } }) - :Do(function(_, d1) - hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = d1.params.application.appID - end) - self["mobileSession" .. pAppId]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) - :Do(function() - self["mobileSession" .. pAppId]:ExpectNotification("OnHMIStatus", - { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice - self["mobileSession" .. pAppId]:ExpectNotification("OnPermissionsChange") - end) - end) -end - -local function activate_app(pAppId, self) - local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", - { appID = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] }) - EXPECT_HMIRESPONSE(requestId) - - self["mobileSession" .. pAppId]:ExpectNotification("OnHMIStatus", - { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) - commonTestCases:DelayedExp(commonRC.minTimeout) -end - local function disableRCFromHMI(self) commonRC.defineRAMode(false, nil, self) - self.mobileSession1:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE" }) + commonRC.getMobileSession():ExpectNotification("OnHMIStatus", { hmiLevel = "NONE" }) :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice - self.mobileSession2:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE" }) + commonRC.getMobileSession(2):ExpectNotification("OnHMIStatus", { hmiLevel = "NONE" }) :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice - self.mobileSession3:ExpectNotification("OnHMIStatus") + commonRC.getMobileSession(3):ExpectNotification("OnHMIStatus") :Times(0) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered") @@ -83,8 +51,8 @@ runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) for i = 1, 3 do - runner.Step("RAI " .. i, register_app, { i }) - runner.Step("Activate App " .. i, activate_app, { i }) + runner.Step("RAI " .. i, commonRC.registerAppWOPTU, { i }) + runner.Step("Activate App " .. i, commonRC.activateApp, { i }) end runner.Title("Test") diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/025_IN_USE_in_case_3_requests.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/025_IN_USE_in_case_3_requests.lua index 1a8ca84562..78e1128e4a 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/025_IN_USE_in_case_3_requests.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/025_IN_USE_in_case_3_requests.lua @@ -30,12 +30,12 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') -local mobile_session = require("mobile_session") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } local access_modes = { nil, "AUTO_ALLOW" } -local hmiAppIds = { } local app1Params = config.application1.registerAppInterfaceParams local app2Params = config.application2.registerAppInterfaceParams @@ -49,7 +49,8 @@ app3Params.isMediaApplication = false app3Params.appHMIType = { "DEFAULT", "REMOTE_CONTROL" } --[[ Local Functions ]] -local function ptu_update_func(tbl) +local function PTUfunc(tbl) + tbl.policy_table.app_policies[app1Params.appID] = commonRC.getRCAppConfig() tbl.policy_table.app_policies[app1Params.appID].AppHMIType = app1Params.appHMIType tbl.policy_table.app_policies[app2Params.appID] = commonRC.getRCAppConfig() tbl.policy_table.app_policies[app2Params.appID].AppHMIType = app2Params.appHMIType @@ -57,26 +58,26 @@ local function ptu_update_func(tbl) tbl.policy_table.app_policies[app3Params.appID].AppHMIType = app3Params.appHMIType end -local function step(pModuleType, pRPC1, pRPC2, self) +local function step(pModuleType, pRPC1, pRPC2) local cid1 if pRPC1 == "SetInteriorVehicleData" then - cid1 = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + cid1 = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = self.applications["Test Application"], + appID = commonRC.getHMIAppId(), moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :Do(function(_, data) local function hmiRespond() - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) end RUN_AFTER(hmiRespond, 4000) end) elseif pRPC1 == "ButtonPress" then - cid1 = self.mobileSession1:SendRPC("ButtonPress", { + cid1 = commonRC.getMobileSession():SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" @@ -89,44 +90,44 @@ local function step(pModuleType, pRPC1, pRPC2, self) }) :Do(function(_, data) local function hmiRespond() - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) end RUN_AFTER(hmiRespond, 4000) end) end - self.mobileSession1:ExpectResponse(cid1, { success = true, resultCode = "SUCCESS" }) + commonRC.getMobileSession():ExpectResponse(cid1, { success = true, resultCode = "SUCCESS" }) local req3_func = function() local cid3 local pRPC3 = pRPC2 if pRPC3 == "SetInteriorVehicleData" then - cid3 = self.mobileSession3:SendRPC("SetInteriorVehicleData", { + cid3 = commonRC.getMobileSession(3):SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) elseif pRPC3 == "ButtonPress" then - cid3 = self.mobileSession3:SendRPC("ButtonPress", { + cid3 = commonRC.getMobileSession(3):SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" }) end - self.mobileSession3:ExpectResponse(cid3, { success = false, resultCode = "IN_USE" }) + commonRC.getMobileSession(3):ExpectResponse(cid3, { success = false, resultCode = "IN_USE" }) end local req2_func = function() local cid2 if pRPC2 == "SetInteriorVehicleData" then - cid2 = self.mobileSession2:SendRPC("SetInteriorVehicleData", { + cid2 = commonRC.getMobileSession(2):SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) elseif pRPC2 == "ButtonPress" then - cid2 = self.mobileSession2:SendRPC("ButtonPress", { + cid2 = commonRC.getMobileSession(2):SendRPC("ButtonPress", { moduleType = pModuleType, buttonName = commonRC.getButtonNameByModule(pModuleType), buttonPressMode = "SHORT" }) end - self.mobileSession2:ExpectResponse(cid2, { success = false, resultCode = "IN_USE" }) + commonRC.getMobileSession(2):ExpectResponse(cid2, { success = false, resultCode = "IN_USE" }) :Do(function() req3_func() end) @@ -135,74 +136,49 @@ local function step(pModuleType, pRPC1, pRPC2, self) RUN_AFTER(req2_func, 1000) end -local function rai_n(id, self) - self, id = commonRC.getSelfAndParams(id, self) - if not id then id = 1 end - self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) - self["mobileSession" .. id]:StartService(7) - :Do(function() - local corId = self["mobileSession" .. id]:SendRPC("RegisterAppInterface", - config["application" .. id].registerAppInterfaceParams) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", - { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) - :Do(function(_, d1) - hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID - end) - self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) - :Do(function() - self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", - { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice - self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") - end) - end) -end - -local function activate_app(pAppId, pOnHMIStatusFunc, self) - self, pAppId = commonRC.getSelfAndParams(pAppId, self) - if not pAppId then pAppId = 1 end - local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] - local mobSession = commonRC.getMobileSession(self, pAppId) - local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) +local function activateApp(pAppId, pOnHMIStatusFunc) + local mobSession = commonRC.getMobileSession(pAppId) + local requestId = commonRC.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = commonRC.getHMIAppId(pAppId) }) EXPECT_HMIRESPONSE(requestId) if not pOnHMIStatusFunc then mobSession:ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) else - pOnHMIStatusFunc(self) + pOnHMIStatusFunc() end end -local function OnHMIStatus2Apps(self) - self.mobileSession2:ExpectNotification("OnHMIStatus", +local function OnHMIStatus2Apps() + commonRC.getMobileSession(2):ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) - self.mobileSession1:ExpectNotification("OnHMIStatus", + commonRC.getMobileSession():ExpectNotification("OnHMIStatus", { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) end -local function OnHMIStatus3Apps(self) - self.mobileSession3:ExpectNotification("OnHMIStatus", +local function OnHMIStatus3Apps() + commonRC.getMobileSession(3):ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - self.mobileSession1:ExpectNotification("OnHMIStatus") + commonRC.getMobileSession():ExpectNotification("OnHMIStatus") :Times(0) - self.mobileSession2:ExpectNotification("OnHMIStatus", + commonRC.getMobileSession(2):ExpectNotification("OnHMIStatus", { hmiLevel = "LIMITED", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI1, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App1", commonRC.activate_app) -runner.Step("RAI2", rai_n, { 2 }) -runner.Step("Activate App2", activate_app, { 2, OnHMIStatus2Apps }) -runner.Step("RAI3", rai_n, { 3 }) -runner.Step("Activate App3", activate_app, { 3, OnHMIStatus3Apps }) +runner.Step("RAI1", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App1", activateApp, { 1 }) +runner.Step("RAI2", commonRC.registerAppWOPTU, { 2 }) +runner.Step("Activate App2", activateApp, { 2, OnHMIStatus2Apps }) +runner.Step("RAI3", commonRC.registerAppWOPTU, { 3 }) +runner.Step("Activate App3", activateApp, { 3, OnHMIStatus3Apps }) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) -- set control for App1 runner.Step("App1 SetInteriorVehicleData", commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/001_Success_flow.lua index e5dea60edc..4420fc406b 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/001_Success_flow.lua @@ -18,39 +18,20 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } - ---[[ Local Functions ]] -local function setVehicleData(pModuleType, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - end) - - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do - runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +for _, mod in pairs(commonRC.modules) do + runner.Step("SetInteriorVehicleData " .. mod, commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index 044a6748cb..ae0b942d4a 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -17,38 +17,28 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local mod = "CLIMATE" --[[ Local Functions ]] -local function setVehicleData(pModuleType, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "RADIO" } end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +runner.Step("SetInteriorVehicleData " .. mod, commonRC.rpcDenied, { mod, 1, "SetInteriorVehicleData", "DISALLOWED" }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua index 06b5067914..dde7a8291b 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua @@ -17,38 +17,28 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local mod = "RADIO" --[[ Local Functions ]] -local function setVehicleData(pModuleType, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +runner.Step("SetInteriorVehicleData " .. mod, commonRC.rpcDenied, { mod, 1, "SetInteriorVehicleData", "DISALLOWED" }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 7a774630bc..e23b7126fd 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -16,44 +16,31 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ General configuration parameters ]] config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } - --[[ Local Functions ]] -local function setVehicleData(pModuleType, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function ptu_update_func(tbl) +local function PTUfunc(tbl) local appId = config.application1.registerAppInterfaceParams.appID tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do - runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +for _, mod in pairs(commonRC.modules) do + runner.Step("SetInteriorVehicleData " .. mod, commonRC.rpcDenied, { mod, 1, "SetInteriorVehicleData", "DISALLOWED" }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua index 7c011d9a98..62c97b71d1 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua @@ -21,11 +21,11 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function setVehicleData(pModuleType, self) +local function setVehicleData(pModuleType) local moduleType2 = nil if pModuleType == "CLIMATE" then moduleType2 = "RADIO" @@ -36,14 +36,14 @@ local function setVehicleData(pModuleType, self) local moduleData = commonRC.getSettableModuleControlData(moduleType2) moduleData.moduleType = pModuleType - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = moduleData }) EXPECT_HMICALL("RC.SetInteriorVehicleData") :Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) commonTestCases:DelayedExp(commonRC.timeout) end @@ -52,12 +52,12 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("SetInteriorVehicleData " .. mod .. "_gets_INVALID_DATA", setVehicleData, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/006_RPC_parameters_values.lua index a69e0d3ff8..15c5c64698 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/006_RPC_parameters_values.lua @@ -21,84 +21,84 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function invalidParamName(pModuleType, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { +local function invalidParamName(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleDData = commonRC.getSettableModuleControlData(pModuleType) -- invalid name of parameter }) EXPECT_HMICALL("RC.SetInteriorVehicleData", {}) :Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) commonTestCases:DelayedExp(commonRC.timeout) end -local function invalidParamType(pModuleType, self) +local function invalidParamType(pModuleType) local moduleData = commonRC.getSettableModuleControlData(pModuleType) moduleData.moduleType = {} -- invalid type of parameter - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { modduleData = moduleData }) EXPECT_HMICALL("RC.SetInteriorVehicleData", {}) :Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) commonTestCases:DelayedExp(commonRC.timeout) end -local function missingMandatoryParam(pModuleType, self) +local function missingMandatoryParam(pModuleType) local moduleData = commonRC.getSettableModuleControlData(pModuleType) moduleData.moduleType = nil -- mandatory parameter missing - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { modduleData = moduleData }) EXPECT_HMICALL("RC.SetInteriorVehicleData", {}) :Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA"}) commonTestCases:DelayedExp(commonRC.timeout) end -local function fakeParam(pModuleType, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { +local function fakeParam(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType), fakeParam = 6 }) EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = self.applications["Test Application"], + appID = commonRC.getHMIAppId(), moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) end) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("SetInteriorVehicleData " .. mod .. " invalid name of parameter", invalidParamName, { mod }) runner.Step("SetInteriorVehicleData " .. mod .. " invalid type of parameter", invalidParamType, { mod }) runner.Step("SetInteriorVehicleData " .. mod .. " fake parameter", fakeParam, { mod }) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 40d3aecc34..3890fcc283 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -19,43 +19,26 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local json = require('modules/json') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function setVehicleData(pModuleType, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - end) - - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do - runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +for _, mod in pairs(commonRC.modules) do + runner.Step("SetInteriorVehicleData " .. mod, commonRC.rpcAllowed, { mod, 1, "SetInteriorVehicleData" }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 591d1b8195..9742dedbe0 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -17,40 +17,27 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') -local commonTestCases = require('user_modules/shared_testcases/commonTestCases') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function setVehicleData(pModuleType, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData") - :Times(0) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) - - commonTestCases:DelayedExp(commonRC.timeout) -end - -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do - runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) +for _, mod in pairs(commonRC.modules) do + runner.Step("SetInteriorVehicleData " .. mod, commonRC.rpcDenied, { mod, 1, "SetInteriorVehicleData", "DISALLOWED" }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua index 59c2c2691a..296ff9a4a4 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua @@ -17,19 +17,19 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function setVehicleData(pModuleType, self) +local function setVehicleData(pModuleType) local moduleData = commonRC.getSettableModuleControlData(pModuleType) moduleData.fakeParam = 123 - self.mobileSession1:SendRPC("SetInteriorVehicleData", { + commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = moduleData }) EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = self.applications["Test Application"], + appID = commonRC.getHMIAppId(), moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :ValidIf(function(_, data) @@ -44,12 +44,12 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua index e900c86a20..9ce54bf2a7 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua @@ -19,17 +19,20 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local module_data_climate = commonRC.getReadOnlyParamsByModule("CLIMATE") local module_data_radio = commonRC.getReadOnlyParamsByModule("RADIO") --[[ Local Functions ]] -local function setVehicleData(module_data, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", {moduleData = module_data}) +local function setVehicleData(module_data) + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", {moduleData = module_data}) EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "READ_ONLY" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "READ_ONLY" }) commonTestCases:DelayedExp(commonRC.timeout) end @@ -37,8 +40,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test: SDL respond with READ_ONLY if SetInteriorVehicleData is sent with read_only params") diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua index bf14213497..68867ba9ec 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua @@ -19,80 +19,81 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +--[[ Local Functions ]] local function isModuleDataCorrect(pModuleType, actualModuleData) - local isFalse = false - for param_readonly, _ in pairs(commonRC.getModuleParams(commonRC.getReadOnlyParamsByModule(pModuleType))) do - for param_actual, _ in pairs(commonRC.getModuleParams(actualModuleData)) do - if param_readonly == param_actual then - isFalse = true - commonFunctions:userPrint(36, "Unexpected read-only parameter: " .. param_readonly) - end - end - end - if isFalse then - return false - end - return true + local isFalse = false + for param_readonly, _ in pairs(commonRC.getModuleParams(commonRC.getReadOnlyParamsByModule(pModuleType))) do + for param_actual, _ in pairs(commonRC.getModuleParams(actualModuleData)) do + if param_readonly == param_actual then + isFalse = true + commonFunctions:userPrint(36, "Unexpected read-only parameter: " .. param_readonly) + end + end + end + if isFalse then + return false + end + return true end -local function setVehicleData(pModuleType, pParams, self) - local moduleDataCombined = commonRC.getReadOnlyParamsByModule(pModuleType) - local moduleDataSettable = { moduleType = pModuleType } - for k, v in pairs(pParams) do - commonRC.getModuleParams(moduleDataCombined)[k] = v - commonRC.getModuleParams(moduleDataSettable)[k] = v - end +local function setVehicleData(pModuleType, pParams) + local moduleDataCombined = commonRC.getReadOnlyParamsByModule(pModuleType) + local moduleDataSettable = { moduleType = pModuleType } + for k, v in pairs(pParams) do + commonRC.getModuleParams(moduleDataCombined)[k] = v + commonRC.getModuleParams(moduleDataSettable)[k] = v + end - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { - moduleData = moduleDataCombined - }) + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = moduleDataCombined + }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = self.applications["Test Application"] }) - :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = moduleDataSettable - }) - end) - :ValidIf(function(_, data) - if not isModuleDataCorrect(pModuleType, data.params.moduleData) then - return false, "Test step failed, see prints" - end - return true - end) + EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = commonRC.getHMIAppId() }) + :Do(function(_, data) + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = moduleDataSettable + }) + end) + :ValidIf(function(_, data) + if not isModuleDataCorrect(pModuleType, data.params.moduleData) then + return false, "Test step failed, see prints" + end + return true + end) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) - :ValidIf(function(_, data) - if not isModuleDataCorrect(pModuleType, data.payload.moduleData) then - return false, "Test step failed, see prints" - end - return true - end) + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + :ValidIf(function(_, data) + if not isModuleDataCorrect(pModuleType, data.payload.moduleData) then + return false, "Test step failed, see prints" + end + return true + end) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -- one settable parameter -for _, mod in pairs(modules) do - local settableParams = commonRC.getModuleParams(commonRC.getSettableModuleControlData(mod)) - for param, value in pairs(settableParams) do - runner.Step("SetInteriorVehicleData " .. mod .. "_one_settable_param_" .. param, setVehicleData, { mod, { [param] = value } }) - end +for _, mod in pairs(commonRC.modules) do + local settableParams = commonRC.getModuleParams(commonRC.getSettableModuleControlData(mod)) + for param, value in pairs(settableParams) do + runner.Step("SetInteriorVehicleData " .. mod .. "_one_settable_param_" .. param, setVehicleData, { mod, { [param] = value } }) + end end -- all settable parameters -for _, mod in pairs(modules) do - local settableParams = commonRC.getModuleParams(commonRC.getSettableModuleControlData(mod)) - runner.Step("SetInteriorVehicleData " .. mod .. "_all_settable_params", setVehicleData, { mod, settableParams }) +for _, mod in pairs(commonRC.modules) do + local settableParams = commonRC.getModuleParams(commonRC.getSettableModuleControlData(mod)) + runner.Step("SetInteriorVehicleData " .. mod .. "_all_settable_params", setVehicleData, { mod, settableParams }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua index 95cce203fc..0db2676f1c 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua @@ -17,36 +17,36 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function setVehicleData(pModuleType, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, "READ_ONLY", "Info message") - end) - - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "READ_ONLY", info = "Info message" }) +local function setVehicleData(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleData = commonRC.getSettableModuleControlData(pModuleType) + }) + :Do(function(_, data) + commonRC.getHMIConnection():SendError(data.id, data.method, "READ_ONLY", "Info message") + end) + + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "READ_ONLY", info = "Info message" }) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("SetInteriorVehicleData " .. mod, setVehicleData, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index 004e995989..1214163e59 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -18,24 +18,24 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function setVehicleData(pModuleType, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { +local function setVehicleData(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = self.applications["Test Application"], + appID = commonRC.getHMIAppId(), moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :Do(function(_, _) -- HMI does not respond end) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR"}) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR"}) commonTestCases:DelayedExp(11000) end @@ -44,12 +44,12 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("SetInteriorVehicleData " .. mod .. " HMI does not respond", setVehicleData, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index 16657e564e..902c00a992 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -17,61 +17,61 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') ---[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function invalidParamType(pModuleType, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { +local function invalidParamType(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = self.applications["Test Application"], + appID = commonRC.getHMIAppId(), moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :Do(function(_, data) local modData = commonRC.getSettableModuleControlData(pModuleType) modData.moduleType = "MODULE" -- invalid value of parameter - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = modData, isSubscribed = "yes" -- fake parameter }) end) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) end -local function missingMandatoryParam(pModuleType, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { +local function missingMandatoryParam(pModuleType) + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = self.applications["Test Application"], + appID = commonRC.getHMIAppId(), moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :Do(function(_, data) local moduleData = commonRC.getModuleControlData(pModuleType) moduleData.moduleType = nil -- missing mandatory parameter - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = moduleData }) end) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR" }) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Step("SetInteriorVehicleData " .. mod .. " Invalid response from HMI-Invalid type of parameter", invalidParamType, { mod }) runner.Step("SetInteriorVehicleData " .. mod .. " Invalid response from HMI-Missing mandatory parameter", missingMandatoryParam, { mod }) end diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua index 46d7b72042..f54e6a3394 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua @@ -18,64 +18,66 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] -local modules = { "CLIMATE", "RADIO" } local success_codes = { "WARNINGS" } local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } --[[ Local Functions ]] -local function stepSuccessfull(pModuleType, pResultCode, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { +local function stepSuccessfull(pModuleType, pResultCode) + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = self.applications["Test Application"], + appID = commonRC.getHMIAppId(), moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, pResultCode, { + commonRC.getHMIConnection():SendResponse(data.id, data.method, pResultCode, { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) end) - self.mobileSession1:ExpectResponse(cid, + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = pResultCode, moduleData = commonRC.getSettableModuleControlData(pModuleType) }) end -local function stepUnsuccessfull(pModuleType, pResultCode, self) - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { +local function stepUnsuccessfull(pModuleType, pResultCode) + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = self.applications["Test Application"], + appID = commonRC.getHMIAppId(), moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :Do(function(_, data) - self.hmiConnection:SendError(data.id, data.method, pResultCode, "Error error") + commonRC.getHMIConnection():SendError(data.id, data.method, pResultCode, "Error error") end) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = pResultCode }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = pResultCode }) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) for _, code in pairs(success_codes) do runner.Step("SetInteriorVehicleData with " .. code .. " resultCode", stepSuccessfull, { mod, code }) end end -for _, mod in pairs(modules) do +for _, mod in pairs(commonRC.modules) do runner.Title("Module: " .. mod) for _, code in pairs(error_codes) do runner.Step("SetInteriorVehicleData with " .. code .. " resultCode", stepUnsuccessfull, { mod, code }) diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/016_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_false.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/016_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_false.lua index ac17e3d581..6f706b8049 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/016_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_false.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/016_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_false.lua @@ -18,6 +18,9 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local hmi_values = require("user_modules/hmi_values") +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local Module = "RADIO" local hmiValues = hmi_values.getDefaultHMITable() @@ -27,8 +30,8 @@ hmiValues.RC.GetCapabilities.params.remoteControlCapability.radioControlCapabili runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { hmiValues }) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/017_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_omitted.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/017_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_omitted.lua index 4898ffc5c8..f4481ddd10 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/017_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_omitted.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/017_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_omitted.lua @@ -18,6 +18,9 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local hmi_values = require("user_modules/hmi_values") +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local Module = "RADIO" local hmiValues = hmi_values.getDefaultHMITable() @@ -27,8 +30,8 @@ hmiValues.RC.GetCapabilities.params.remoteControlCapability.radioControlCapabili runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { hmiValues }) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/018_Success_flow_band_setting.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/018_Success_flow_band_setting.lua index 31ddc6e2d6..f94a1dcb3a 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/018_Success_flow_band_setting.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/018_Success_flow_band_setting.lua @@ -19,37 +19,40 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local Module = "RADIO" --[[ Local Functions ]] -local function setVehicleData(self) +local function setVehicleData() local requestParams = commonRC.getSettableModuleControlData(Module) requestParams.radioControlData.band = "XM" - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { - moduleData = requestParams + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = requestParams }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleData = requestParams + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleData = requestParams }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = requestParams - }) + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = requestParams + }) end) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/019_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_false.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/019_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_false.lua index 4b9ff3af77..fa9a847276 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/019_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_false.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/019_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_false.lua @@ -18,32 +18,35 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local hmi_values = require("user_modules/hmi_values") +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local Module = "RADIO" local hmiValues = hmi_values.getDefaultHMITable() hmiValues.RC.GetCapabilities.params.remoteControlCapability.radioControlCapabilities[1].siriusxmRadioAvailable = false --[[ Local Functions ]] -local function rpcDenied(self) +local function rpcDenied() local requestParams = commonRC.getSettableModuleControlData(Module) requestParams.radioControlData.band = "XM" - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = requestParams }) EXPECT_HMICALL("RC.SetInteriorVehicleData") :Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { hmiValues }) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/020_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_omitted.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/020_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_omitted.lua index df7b251869..f738d6a4d5 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/020_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_omitted.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/020_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_omitted.lua @@ -18,32 +18,35 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') local hmi_values = require("user_modules/hmi_values") +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local Module = "RADIO" local hmiValues = hmi_values.getDefaultHMITable() hmiValues.RC.GetCapabilities.params.remoteControlCapability.radioControlCapabilities[1].siriusxmRadioAvailable = nil --[[ Local Functions ]] -local function rpcDenied(self) +local function rpcDenied() local requestParams = commonRC.getSettableModuleControlData(Module) requestParams.radioControlData.band = "XM" - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = requestParams }) EXPECT_HMICALL("RC.SetInteriorVehicleData") :Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { hmiValues }) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/021_INVALID_DATA_in_case_invalid_data_in_hdRadioEnable.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/021_INVALID_DATA_in_case_invalid_data_in_hdRadioEnable.lua index b79c3e24d6..bd96715db7 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/021_INVALID_DATA_in_case_invalid_data_in_hdRadioEnable.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/021_INVALID_DATA_in_case_invalid_data_in_hdRadioEnable.lua @@ -16,30 +16,33 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local Module = "RADIO" --[[ Local Functions ]] -local function rpcInvalidData(self) +local function rpcInvalidData() local requestParams = commonRC.getSettableModuleControlData(Module) requestParams.radioControlData.hdRadioEnable = "ENABLE" - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = requestParams }) EXPECT_HMICALL("RC.SetInteriorVehicleData") :Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/022_availableHDs_hdChannel_upper_bound.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/022_availableHDs_hdChannel_upper_bound.lua index e5d236b9d2..6420833b64 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/022_availableHDs_hdChannel_upper_bound.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/022_availableHDs_hdChannel_upper_bound.lua @@ -19,45 +19,48 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local Module = "RADIO" --[[ Local Functions ]] -local function setVehicleData(self) +local function setVehicleData() local requestParams = commonRC.getSettableModuleControlData(Module) requestParams.radioControlData.hdChannel = 7 - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { - moduleData = requestParams + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { + moduleData = requestParams }) - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = self.applications["Test Application"], - moduleData = requestParams + EXPECT_HMICALL("RC.SetInteriorVehicleData", { + appID = commonRC.getHMIAppId(), + moduleData = requestParams }) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", { - moduleData = requestParams - }) + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = requestParams + }) end) - self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end -local function onVehicleData(self) +local function onVehicleData() local notificationParams = commonRC.getHMIResponseParams("OnInteriorVehicleData", Module) notificationParams.moduleData.radioControlData.availableHDs = 7 - self.hmiConnection:SendNotification(commonRC.getHMIEventName("OnInteriorVehicleData"), notificationParams) - self.mobileSession1:ExpectNotification(commonRC.getAppEventName("OnInteriorVehicleData"), notificationParams) + commonRC.getHMIConnection():SendNotification(commonRC.getHMIEventName("OnInteriorVehicleData"), notificationParams) + commonRC.getMobileSession():ExpectNotification(commonRC.getAppEventName("OnInteriorVehicleData"), notificationParams) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Step("Subscribe app to " .. Module, commonRC.subscribeToModule, { Module }) runner.Title("Test") diff --git a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/023_availableHDs_hdChannel_out_of_upper_bound.lua b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/023_availableHDs_hdChannel_out_of_upper_bound.lua index 0602f54a58..7b11c9fbcd 100644 --- a/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/023_availableHDs_hdChannel_out_of_upper_bound.lua +++ b/test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/023_availableHDs_hdChannel_out_of_upper_bound.lua @@ -18,30 +18,33 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local Module = "RADIO" --[[ Local Functions ]] -local function setVehicleData(self) +local function setVehicleData() local requestParams = commonRC.getSettableModuleControlData(Module) requestParams.radioControlData.hdChannel = 8 - local cid = self.mobileSession1:SendRPC("SetInteriorVehicleData", { + local cid = commonRC.getMobileSession():SendRPC("SetInteriorVehicleData", { moduleData = requestParams }) EXPECT_HMICALL("RC.SetInteriorVehicleData") :Times(0) - self.mobileSession1:ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) + commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "INVALID_DATA" }) end -local function onVehicleData(self) +local function onVehicleData() local notificationParams = commonRC.getHMIResponseParams("OnInteriorVehicleData", Module) notificationParams.moduleData.radioControlData.availableHDs = 8 - self.hmiConnection:SendNotification(commonRC.getHMIEventName("OnInteriorVehicleData"), notificationParams) - self.mobileSession1:ExpectNotification(commonRC.getAppEventName("OnInteriorVehicleData")) + commonRC.getHMIConnection():SendNotification(commonRC.getHMIEventName("OnInteriorVehicleData"), notificationParams) + commonRC.getMobileSession():ExpectNotification(commonRC.getAppEventName("OnInteriorVehicleData")) :Times(0) end @@ -49,8 +52,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Step("Subscribe app to " .. Module, commonRC.subscribeToModule, { Module }) runner.Title("Test") diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index dfdbccb1b7..b791b98383 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -5,6 +5,7 @@ config.mobileHost = "127.0.0.1" config.defaultProtocolVersion = 2 config.ValidateSchema = false +config.checkAllValidations = true config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 @@ -12,19 +13,17 @@ config.application2.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 config.application3.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 --[[ Required Shared libraries ]] +local test = require("user_modules/dummy_connecttest") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonTestCases = require("user_modules/shared_testcases/commonTestCases") local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') -local mobile_session = require("mobile_session") local json = require("modules/json") local hmi_values = require("user_modules/hmi_values") local events = require("events") local utils = require('user_modules/utils') +local actions = require("user_modules/sequences/actions") ---[[ Local Variables ]] -local ptu_table = {} -local hmiAppIds = {} +--[[ Common Variables ]] local commonRC = {} @@ -32,21 +31,51 @@ commonRC.timeout = 2000 commonRC.minTimeout = 500 commonRC.DEFAULT = "Default" commonRC.buttons = { climate = "FAN_UP", radio = "VOLUME_UP" } +commonRC.getHMIConnection = actions.getHMIConnection +commonRC.getMobileSession = actions.getMobileSession +commonRC.policyTableUpdate = actions.policyTableUpdate +commonRC.registerApp = actions.registerApp +commonRC.registerAppWOPTU = actions.registerAppWOPTU +commonRC.getHMIAppId = actions.getHMIAppId +commonRC.jsonFileToTable = utils.jsonFileToTable +commonRC.tableToJsonFile = utils.tableToJsonFile +commonRC.cloneTable = utils.cloneTable + +commonRC.modules = { "RADIO", "CLIMATE" } +commonRC.allModules = { "RADIO", "CLIMATE", "SEAT", "AUDIO", "LIGHT", "HMI_SETTINGS" } +commonRC.newModules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } +commonRC.modulesWithoutSeat = { "RADIO", "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } + +commonRC.capMap = { + ["RADIO"] = "radioControlCapabilities", + ["CLIMATE"] = "climateControlCapabilities", + ["SEAT"] = "seatControlCapabilities", + ["AUDIO"] = "audioControlCapabilities", + ["LIGHT"] = "lightControlCapabilities", + ["HMI_SETTINGS"] = "hmiSettingsControlCapabilities", + ["BUTTONS"] = "buttonCapabilities" +} -local function getPTUFromPTS(tbl) - tbl.policy_table.consumer_friendly_messages.messages = nil - tbl.policy_table.device_data = nil - tbl.policy_table.module_meta = nil - tbl.policy_table.usage_and_error_counts = nil - tbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null - tbl.policy_table.module_config.preloaded_pt = nil - tbl.policy_table.module_config.preloaded_date = nil -end +commonRC.audioSources = { + "NO_SOURCE_SELECTED", + "CD", + "BLUETOOTH_STEREO_BTST", + "USB", + "USB2", + "LINE_IN", + "IPOD", + "MOBILE_APP", + "AM", + "FM", + "XM", + "DAB" +} +--[[ Common Functions ]] function commonRC.getRCAppConfig(tbl) if tbl then - local out = utils.cloneTable(tbl.policy_table.app_policies.default) - out.moduleType = { "RADIO", "CLIMATE" } + local out = commonRC.cloneTable(tbl.policy_table.app_policies.default) + out.moduleType = commonRC.allModules out.groups = { "Base-4", "RemoteControl" } out.AppHMIType = { "REMOTE_CONTROL" } return out @@ -56,234 +85,107 @@ function commonRC.getRCAppConfig(tbl) steal_focus = false, priority = "NONE", default_hmi = "NONE", - moduleType = { "RADIO", "CLIMATE" }, + moduleType = commonRC.allModules, groups = { "Base-4", "RemoteControl" }, AppHMIType = { "REMOTE_CONTROL" } } end end -local function updatePTU(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = commonRC.getRCAppConfig(tbl) -end - -function commonRC.jsonFileToTable(file_name) - local f = io.open(file_name, "r") - local content = f:read("*all") - f:close() - return json.decode(content) -end - -function commonRC.tableToJsonFile(tbl, file_name) - local f = io.open(file_name, "w") - f:write(json.encode(tbl)) - f:close() -end - -local function checkIfPTSIsSentAsBinary(bin_data) - if not (bin_data ~= nil and string.len(bin_data) > 0) then - commonFunctions:userPrint(31, "PTS was not sent to Mobile in payload of OnSystemRequest") - end -end - -local function ptu(self, ptu_update_func) - local function getAppsCount() - local count = 0 - for _, _ in pairs(hmiAppIds) do - count = count + 1 - end - return count - end - - local policy_file_name = "PolicyTableUpdate" - local policy_file_path = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") - local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") - local ptu_file_name = os.tmpname() - local requestId = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(requestId) - :Do(function() - self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = pts_file_name }) - getPTUFromPTS(ptu_table) - updatePTU(ptu_table) - if ptu_update_func then - ptu_update_func(ptu_table) - end - commonRC.tableToJsonFile(ptu_table, ptu_file_name) - - local event = events.Event() - event.matches = function(self, e) return self == e end - EXPECT_EVENT(event, "PTU event") - :Timeout(11000) - - for id = 1, getAppsCount() do - local mobileSession = commonRC.getMobileSession(self, id) - mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }) - :DoOnce(function(_, d2) - print("App ".. id .. " was used for PTU") - RAISE_EVENT(event, event, "PTU event") - checkIfPTSIsSentAsBinary(d2.binaryData) - local corIdSystemRequest = mobileSession:SendRPC("SystemRequest", { requestType = "PROPRIETARY", fileName = policy_file_name }, ptu_file_name) - EXPECT_HMICALL("BasicCommunication.SystemRequest") - :Do(function(_, d3) - self.hmiConnection:SendResponse(d3.id, "BasicCommunication.SystemRequest", "SUCCESS", { }) - self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = policy_file_path .. "/" .. policy_file_name }) - end) - mobileSession:ExpectResponse(corIdSystemRequest, { success = true, resultCode = "SUCCESS" }) - :Do(function() os.remove(ptu_file_name) end) - end) - :Times(AtMost(1)) - end - end) +function actions.getAppDataForPTU(pAppId) + return { + keep_context = false, + steal_focus = false, + priority = "NONE", + default_hmi = "NONE", + groups = { "Base-4", "RemoteControl" }, + AppHMIType = actions.getConfigAppParams(pAppId).appHMIType + } end -local function allow_sdl(self) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", { +local function allowSDL() + commonRC.getHMIConnection():SendNotification("SDL.OnAllowSDLFunctionality", { allowed = true, source = "GUI", device = { - id = commonRC.getDeviceMAC(), - name = commonRC.getDeviceName() + id = utils.getDeviceMAC(), + name = utils.getDeviceName() } }) end -function commonRC.getDeviceName() - return config.mobileHost .. ":" .. config.mobilePort -end - -function commonRC.getDeviceMAC() - local cmd = "echo -n " .. commonRC.getDeviceName() .. " | sha256sum | awk '{printf $1}'" - local handle = io.popen(cmd) - local result = handle:read("*a") - handle:close() - return result -end - -function commonRC.preconditions() - commonFunctions:SDLForceStop() - commonSteps:DeletePolicyTable() - commonSteps:DeleteLogsFiles() -end - -function commonRC.start(pHMIParams, self) - self, pHMIParams = commonRC.getSelfAndParams(pHMIParams, self) - self:runSDL() - commonFunctions:waitForSDLStart(self) +function commonRC.start(pHMIParams) + test:runSDL() + commonFunctions:waitForSDLStart(test) :Do(function() - self:initHMI(self) + test:initHMI(test) :Do(function() commonFunctions:userPrint(35, "HMI initialized") - self:initHMI_onReady(pHMIParams) + test:initHMI_onReady(pHMIParams) :Do(function() commonFunctions:userPrint(35, "HMI is ready") - self:connectMobile() + test:connectMobile() :Do(function() commonFunctions:userPrint(35, "Mobile connected") - allow_sdl(self) + allowSDL() end) end) end) end) end -function commonRC.rai_ptu(ptu_update_func, self) - self, ptu_update_func = commonRC.getSelfAndParams(ptu_update_func, self) - commonRC.rai_ptu_n(1, ptu_update_func, self) +local function backupPreloadedPT() + local preloadedFile = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + commonPreconditions:BackupFile(preloadedFile) end -function commonRC.rai_ptu_n(id, ptu_update_func, self) - self, id, ptu_update_func = commonRC.getSelfAndParams(id, ptu_update_func, self) - if not id then id = 1 end - self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) - self["mobileSession" .. id]:StartService(7) - :Do(function() - local corId = self["mobileSession" .. id]:SendRPC("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) - :Do(function(_, d1) - hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UP_TO_DATE" }) - :Times(3) - EXPECT_HMICALL("BasicCommunication.PolicyUpdate") - :Do(function(_, d2) - self.hmiConnection:SendResponse(d2.id, d2.method, "SUCCESS", { }) - ptu_table = commonRC.jsonFileToTable(d2.params.file) - ptu(self, ptu_update_func) - end) - end) - self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) - :Do(function() - self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice - self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") - :Times(2) - end) - end) -end - -function commonRC.rai_n(id, self) - self, id = commonRC.getSelfAndParams(id, self) - if not id then id = 1 end - self["mobileSession" .. id] = mobile_session.MobileSession(self, self.mobileConnection) - self["mobileSession" .. id]:StartService(7) - :Do(function() - local corId = self["mobileSession" .. id]:SendRPC("RegisterAppInterface", config["application" .. id].registerAppInterfaceParams) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = config["application" .. id].registerAppInterfaceParams.appName } }) - :Do(function(_, d1) - hmiAppIds[config["application" .. id].registerAppInterfaceParams.appID] = d1.params.application.appID - end) - self["mobileSession" .. id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) - :Do(function() - self["mobileSession" .. id]:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice - self["mobileSession" .. id]:ExpectNotification("OnPermissionsChange") - self["mobileSession" .. id]:ExpectNotification("OnDriverDistraction", { state = "DD_OFF" }) - end) - end) +local function updatePreloadedPT(pCountOfRCApps) + if not pCountOfRCApps then pCountOfRCApps = 2 end + local preloadedFile = commonPreconditions:GetPathToSDL() + .. commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + local preloadedTable = commonRC.jsonFileToTable(preloadedFile) + preloadedTable.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + preloadedTable.policy_table.functional_groupings["RemoteControl"].rpcs.OnRCStatus = { + hmi_levels = { "FULL", "BACKGROUND", "LIMITED", "NONE" } + } + for i = 1, pCountOfRCApps do + local appId = config["application" .. i].registerAppInterfaceParams.appID + preloadedTable.policy_table.app_policies[appId] = commonRC.getRCAppConfig(preloadedTable) + preloadedTable.policy_table.app_policies[appId].AppHMIType = nil + end + commonRC.tableToJsonFile(preloadedTable, preloadedFile) end -function commonRC.unregisterApp(pAppId, self) - local mobSession = commonRC.getMobileSession(self, pAppId) - local hmiAppId = commonRC.getHMIAppId(pAppId) - local cid = mobSession:SendRPC("UnregisterAppInterface",{}) - EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = hmiAppId, unexpectedDisconnect = false }) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +function commonRC.preconditions(isPreloadedUpdate, pCountOfRCApps) + if isPreloadedUpdate == nil then isPreloadedUpdate = true end + actions.preconditions() + if isPreloadedUpdate == true then + backupPreloadedPT() + updatePreloadedPT(pCountOfRCApps) + end end -function commonRC.activate_app(pAppId, self) - self, pAppId = commonRC.getSelfAndParams(pAppId, self) - if not pAppId then pAppId = 1 end - local pHMIAppId = hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] - local mobSession = commonRC.getMobileSession(self, pAppId) - local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) - EXPECT_HMIRESPONSE(requestId) - mobSession:ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) - commonTestCases:DelayedExp(commonRC.minTimeout) +local function restorePreloadedPT() + local preloadedFile = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + commonPreconditions:RestoreFile(preloadedFile) end function commonRC.postconditions() - StopSDL() + actions.postconditions() + restorePreloadedPT() end -function commonRC.getSelfAndParams(...) - local out = { } - local selfIdx = nil - for i,v in pairs({...}) do - if type(v) == "table" and v.isTest then - table.insert(out, v) - selfIdx = i - break - end - end - local idx = 2 - for i = 1, table.maxn({...}) do - if i ~= selfIdx then - out[idx] = ({...})[i] - idx = idx + 1 - end - end - return table.unpack(out, 1, table.maxn(out)) +function commonRC.unregisterApp(pAppId) + if not pAppId then pAppId = 1 end + local mobSession = commonRC.getMobileSession(pAppId) + local hmiAppId = commonRC.getHMIAppId(pAppId) + commonRC.deleteHMIAppId(pAppId) + local cid = mobSession:SendRPC("UnregisterAppInterface",{}) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = hmiAppId, unexpectedDisconnect = false }) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) end + function commonRC.getModuleControlData(module_type) local out = { moduleType = module_type } if module_type == "CLIMATE" then @@ -303,7 +205,11 @@ function commonRC.getModuleControlData(module_type) defrostZone = "FRONT", dualModeEnable = true, acMaxEnable = true, - ventilationMode = "BOTH" + ventilationMode = "BOTH", + heatedSteeringWheelEnable = true, + heatedWindshieldEnable = true, + heatedRearWindowEnable = true, + heatedMirrorsEnable = true } elseif module_type == "RADIO" then out.radioControlData = { @@ -326,7 +232,96 @@ function commonRC.getModuleControlData(module_type) signalChangeThreshold = 10, radioEnable = true, state = "ACQUIRING", - hdRadioEnable = true + hdRadioEnable = true, + sisData = { + stationShortName = "Name1", + stationIDNumber = { + countryCode = 100, + fccFacilityId = 100 + }, + stationLongName = "RadioStationLongName", + stationLocation = { + longitudeDegrees = 0.1, + latitudeDegrees = 0.1, + altitude = 0.1 + }, + stationMessage = "station message" + } + } + elseif module_type == "SEAT" then + out.seatControlData = { + id = "DRIVER", + heatingEnabled = true, + coolingEnabled = true, + heatingLevel = 50, + coolingLevel = 50, + horizontalPosition = 50, + verticalPosition = 50, + frontVerticalPosition = 50, + backVerticalPosition = 50, + backTiltAngle = 50, + headSupportHorizontalPosition = 50, + headSupportVerticalPosition = 50, + massageEnabled = true, + massageMode = { + { + massageZone = "LUMBAR", + massageMode = "HIGH" + }, + { + massageZone = "SEAT_CUSHION", + massageMode = "LOW" + } + }, + massageCushionFirmness = { + { + cushion = "TOP_LUMBAR", + firmness = 30 + }, + { + cushion = "BACK_BOLSTERS", + firmness = 60 + } + }, + memory = { + id = 1, + label = "Label value", + action = "SAVE" + } + } + elseif module_type == "AUDIO" then + out.audioControlData = { + source = "AM", + keepContext = false, + volume = 50, + equalizerSettings = { + { + channelId = 10, + channelName = "Channel 1", + channelSetting = 50 + } + } + } + elseif module_type == "LIGHT" then + out.lightControlData = { + lightState = { + { + id = "FRONT_LEFT_HIGH_BEAM", + status = "ON", + density = 0.2, + color = { + red = 50, + green = 150, + blue = 200 + } + } + } + } + elseif module_type == "HMI_SETTINGS" then + out.hmiSettingsControlData = { + displayMode = "DAY", + temperatureUnit = "CELSIUS", + distanceUnit = "KILOMETERS" } end return out @@ -374,7 +369,96 @@ function commonRC.getAnotherModuleControlData(module_type) signalChangeThreshold = 20, radioEnable = true, state = "ACQUIRING", - hdRadioEnable = false + hdRadioEnable = false, + sisData = { + stationShortName = "Name2", + stationIDNumber = { + countryCode = 200, + fccFacilityId = 200 + }, + stationLongName = "RadioStationLongName2", + stationLocation = { + longitudeDegrees = 20.1, + latitudeDegrees = 20.1, + altitude = 20.1 + }, + stationMessage = "station message 2" + } + } + elseif module_type == "SEAT" then + out.seatControlData ={ + id = "FRONT_PASSENGER", + heatingEnabled = true, + coolingEnabled = false, + heatingLevel = 75, + coolingLevel = 0, + horizontalPosition = 75, + verticalPosition = 75, + frontVerticalPosition = 75, + backVerticalPosition = 75, + backTiltAngle = 75, + headSupportHorizontalPosition = 75, + headSupportVerticalPosition = 75, + massageEnabled = true, + massageMode = { + { + massageZone = "LUMBAR", + massageMode = "OFF" + }, + { + massageZone = "SEAT_CUSHION", + massageMode = "HIGH" + } + }, + massageCushionFirmness = { + { + cushion = "MIDDLE_LUMBAR", + firmness = 65 + }, + { + cushion = "SEAT_BOLSTERS", + firmness = 30 + } + }, + memory = { + id = 2, + label = "Another label value", + action = "RESTORE" + } + } + elseif module_type == "AUDIO" then + out.audioControlData = { + source = "USB", + keepContext = true, + volume = 20, + equalizerSettings = { + { + channelId = 20, + channelName = "Channel 2", + channelSetting = 20 + } + } + } + elseif module_type == "LIGHT" then + out.lightControlData = { + lightState = { + { + id = "READING_LIGHTS", + status = "ON", + density = 0.5, + color = { + red = 150, + green = 200, + blue = 250 + } + } + } + } + elseif module_type == "HMI_SETTINGS" then + out.hmiSettingsControlData = { + displayMode = "NIGHT", + temperatureUnit = "FAHRENHEIT", + distanceUnit = "MILES" } end return out @@ -408,7 +492,25 @@ function commonRC.getReadOnlyParamsByModule(pModuleType) availableHDs = 2, signalStrength = 4, signalChangeThreshold = 22, - state = "MULTICAST" + state = "MULTICAST", + sisData = { + stationShortName = "Name2", + stationIDNumber = { + countryCode = 200, + fccFacilityId = 200 + }, + stationLongName = "RadioStationLongName2", + stationLocation = { + longitudeDegrees = 20.1, + latitudeDegrees = 20.1, + altitude = 20.1 + }, + stationMessage = "station message 2" + } + } + elseif pModuleType == "AUDIO" then + out.audioControlData = { + equalizerSettings = { { channelName = "Channel 1" } } } end return out @@ -425,14 +527,34 @@ function commonRC.getModuleParams(pModuleData) pModuleData.radioControlData = { } end return pModuleData.radioControlData + elseif pModuleData.moduleType == "AUDIO" then + if not pModuleData.audioControlData then + pModuleData.audioControlData = { } + end + return pModuleData.audioControlData + elseif pModuleData.moduleType == "SEAT" then + if not pModuleData.seatControlData then + pModuleData.seatControlData = { } + end + return pModuleData.seatControlData end end function commonRC.getSettableModuleControlData(pModuleType) local out = commonRC.getModuleControlData(pModuleType) local params_read_only = commonRC.getModuleParams(commonRC.getReadOnlyParamsByModule(pModuleType)) - for p_read_only in pairs(params_read_only) do - commonRC.getModuleParams(out)[p_read_only] = nil + if params_read_only then + for p_read_only, p_read_only_value in pairs(params_read_only) do + if pModuleType == "AUDIO" then + for sub_read_only_key, sub_read_only_value in pairs(p_read_only_value) do + for sub_read_only_name in pairs(sub_read_only_value) do + commonRC.getModuleParams(out)[p_read_only][sub_read_only_key][sub_read_only_name] = nil + end + end + else + commonRC.getModuleParams(out)[p_read_only] = nil + end + end end return out end @@ -455,16 +577,24 @@ local rcRPCs = { } end, hmiResponseParams = function(pModuleType, pSubscribe) + local GetInteriorVDModuleData = commonRC.actualInteriorDataStateOnHMI[pModuleType] + if GetInteriorVDModuleData.audioControlData then + GetInteriorVDModuleData.audioControlData.keepContext = nil + end return { - moduleData = commonRC.actualInteriorDataStateOnHMI[pModuleType], + moduleData = GetInteriorVDModuleData, isSubscribed = pSubscribe } end, responseParams = function(success, resultCode, pModuleType, pSubscribe) + local GetInteriorVDModuleData = commonRC.actualInteriorDataStateOnHMI[pModuleType] + if GetInteriorVDModuleData.audioControlData then + GetInteriorVDModuleData.audioControlData.keepContext = nil + end return { success = success, resultCode = resultCode, - moduleData = commonRC.actualInteriorDataStateOnHMI[pModuleType], + moduleData = GetInteriorVDModuleData, isSubscribed = pSubscribe } end @@ -542,13 +672,21 @@ local rcRPCs = { appEventName = "OnInteriorVehicleData", hmiEventName = "RC.OnInteriorVehicleData", hmiResponseParams = function(pModuleType) + local OnInteriorVDModuleData = commonRC.getAnotherModuleControlData(pModuleType) + if OnInteriorVDModuleData.audioControlData then + OnInteriorVDModuleData.audioControlData.keepContext = nil + end return { - moduleData = commonRC.getAnotherModuleControlData(pModuleType) + moduleData = OnInteriorVDModuleData } end, responseParams = function(pModuleType) + local OnInteriorVDModuleData = commonRC.getAnotherModuleControlData(pModuleType) + if OnInteriorVDModuleData.audioControlData then + OnInteriorVDModuleData.audioControlData.keepContext = nil + end return { - moduleData = commonRC.getAnotherModuleControlData(pModuleType) + moduleData = OnInteriorVDModuleData } end }, @@ -587,117 +725,132 @@ function commonRC.getHMIResponseParams(pRPC, ...) return rcRPCs[pRPC].hmiResponseParams(...) end -function commonRC.subscribeToModule(pModuleType, pAppId, self) - self, pAppId = commonRC.getSelfAndParams(pAppId, self) +function commonRC.subscribeToModule(pModuleType, pAppId) local rpc = "GetInteriorVehicleData" local subscribe = true - local mobSession = commonRC.getMobileSession(self, pAppId) + local mobSession = commonRC.getMobileSession(pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(rpc), commonRC.getAppRequestParams(rpc, pModuleType, subscribe)) EXPECT_HMICALL(commonRC.getHMIEventName(rpc), commonRC.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe)) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(rpc, pModuleType, subscribe)) + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(rpc, pModuleType, subscribe)) commonRC.setActualInteriorVD(pModuleType, commonRC.getHMIResponseParams(rpc, pModuleType, subscribe).moduleData) end) mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) + :ValidIf(function(_,data) + if "AUDIO" == pModuleType and + nil ~= data.payload.moduleData.audioControlData.keepContext then + return false, "Mobile response GetInteriorVehicleData contains unexpected keepContext parameter" + end + return true + end) end -function commonRC.unSubscribeToModule(pModuleType, pAppId, self) - self, pAppId = commonRC.getSelfAndParams(pAppId, self) +function commonRC.unSubscribeToModule(pModuleType, pAppId) local rpc = "GetInteriorVehicleData" local subscribe = false - local mobSession = commonRC.getMobileSession(self, pAppId) + local mobSession = commonRC.getMobileSession(pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(rpc), commonRC.getAppRequestParams(rpc, pModuleType, subscribe)) EXPECT_HMICALL(commonRC.getHMIEventName(rpc), commonRC.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe)) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(rpc, pModuleType, subscribe)) + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(rpc, pModuleType, subscribe)) end) mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) + :ValidIf(function(_,data) + if "AUDIO" == pModuleType and + nil ~= data.payload.moduleData.audioControlData.keepContext then + return false, "Mobile response GetInteriorVehicleData contains unexpected keepContext parameter" + end + return true + end) end -function commonRC.isSubscribed(pModuleType, pAppId, self) - self, pAppId = commonRC.getSelfAndParams(pAppId, self) - local mobSession = commonRC.getMobileSession(self, pAppId) +function commonRC.isSubscribed(pModuleType, pAppId) + local mobSession = commonRC.getMobileSession(pAppId) local rpc = "OnInteriorVehicleData" - self.hmiConnection:SendNotification(commonRC.getHMIEventName(rpc), commonRC.getHMIResponseParams(rpc, pModuleType)) + commonRC.getHMIConnection():SendNotification(commonRC.getHMIEventName(rpc), commonRC.getHMIResponseParams(rpc, pModuleType)) commonRC.setActualInteriorVD(pModuleType, commonRC.getHMIResponseParams(rpc, pModuleType).moduleData) mobSession:ExpectNotification(commonRC.getAppEventName(rpc), commonRC.getAppResponseParams(rpc, pModuleType)) + :ValidIf(function(_,data) + if "AUDIO" == pModuleType and + nil ~= data.payload.moduleData.audioControlData.keepContext then + return false, "Mobile notification OnInteriorVehicleData contains unexpected keepContext parameter" + end + return true + end) end -function commonRC.isUnsubscribed(pModuleType, pAppId, self) - self, pAppId = commonRC.getSelfAndParams(pAppId, self) - local mobSession = commonRC.getMobileSession(self, pAppId) +function commonRC.isUnsubscribed(pModuleType, pAppId) + local mobSession = commonRC.getMobileSession(pAppId) local rpc = "OnInteriorVehicleData" - self.hmiConnection:SendNotification(commonRC.getHMIEventName(rpc), commonRC.getHMIResponseParams(rpc, pModuleType)) + commonRC.getHMIConnection():SendNotification(commonRC.getHMIEventName(rpc), commonRC.getHMIResponseParams(rpc, pModuleType)) + commonRC.setActualInteriorVD(pModuleType, commonRC.getHMIResponseParams(rpc, pModuleType).moduleData) mobSession:ExpectNotification(commonRC.getAppEventName(rpc), {}):Times(0) commonTestCases:DelayedExp(commonRC.timeout) end -function commonRC.getHMIAppId(pAppId) - if not pAppId then pAppId = 1 end - return hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] -end - -function commonRC.getMobileSession(self, pAppId) - if not pAppId then pAppId = 1 end - return self["mobileSession" .. pAppId] -end - -function commonRC.defineRAMode(pAllowed, pAccessMode, self) - self, pAccessMode = commonRC.getSelfAndParams(pAccessMode, self) +function commonRC.defineRAMode(pAllowed, pAccessMode) local rpc = "OnRemoteControlSettings" - self.hmiConnection:SendNotification(commonRC.getHMIEventName(rpc), commonRC.getHMIResponseParams(rpc, pAllowed, pAccessMode)) + commonRC.getHMIConnection():SendNotification(commonRC.getHMIEventName(rpc), commonRC.getHMIResponseParams(rpc, pAllowed, pAccessMode)) commonTestCases:DelayedExp(commonRC.minTimeout) -- workaround due to issue with SDL -> redundant OnHMIStatus notification is sent end -function commonRC.rpcDenied(pModuleType, pAppId, pRPC, pResultCode, self) - local mobSession = commonRC.getMobileSession(self, pAppId) +function commonRC.rpcDenied(pModuleType, pAppId, pRPC, pResultCode) + local mobSession = commonRC.getMobileSession(pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) mobSession:ExpectResponse(cid, { success = false, resultCode = pResultCode }) commonTestCases:DelayedExp(commonRC.timeout) end -function commonRC.rpcAllowed(pModuleType, pAppId, pRPC, self) - local mobSession = commonRC.getMobileSession(self, pAppId) +function commonRC.rpcDeniedWithCustomParams(pParams, pAppId, pRPC, pResultCode) + local mobSession = commonRC.getMobileSession(pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), pParams) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) + mobSession:ExpectResponse(cid, { success = false, resultCode = pResultCode }) + commonTestCases:DelayedExp(commonRC.timeout) +end + +function commonRC.rpcAllowed(pModuleType, pAppId, pRPC) + local mobSession = commonRC.getMobileSession(pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) end) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end -function commonRC.rpcAllowedWithConsent(pModuleType, pAppId, pRPC, self) - local mobSession = commonRC.getMobileSession(self, pAppId) +function commonRC.rpcAllowedWithConsent(pModuleType, pAppId, pRPC) + local mobSession = commonRC.getMobileSession(pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) local consentRPC = "GetInteriorVehicleDataConsent" EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(consentRPC, true)) + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(consentRPC, true)) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) :Do(function(_, data2) - self.hmiConnection:SendResponse(data2.id, data2.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) + commonRC.getHMIConnection():SendResponse(data2.id, data2.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) end) end) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) end -function commonRC.rpcRejectWithConsent(pModuleType, pAppId, pRPC, self) +function commonRC.rpcRejectWithConsent(pModuleType, pAppId, pRPC) local info = "The resource is in use and the driver disallows this remote control RPC" local consentRPC = "GetInteriorVehicleDataConsent" - local mobSession = commonRC.getMobileSession(self, pAppId) + local mobSession = commonRC.getMobileSession(pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) EXPECT_HMICALL(commonRC.getHMIEventName(consentRPC), commonRC.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(consentRPC, false)) + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(consentRPC, false)) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) end) mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED", info = info }) commonTestCases:DelayedExp(commonRC.timeout) end -function commonRC.rpcRejectWithoutConsent(pModuleType, pAppId, pRPC, self) - local mobSession = commonRC.getMobileSession(self, pAppId) +function commonRC.rpcRejectWithoutConsent(pModuleType, pAppId, pRPC) + local mobSession = commonRC.getMobileSession(pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) EXPECT_HMICALL(commonRC.getHMIEventName("GetInteriorVehicleDataConsent")):Times(0) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)):Times(0) @@ -705,40 +858,33 @@ function commonRC.rpcRejectWithoutConsent(pModuleType, pAppId, pRPC, self) commonTestCases:DelayedExp(commonRC.timeout) end +function commonRC.rpcButtonPress(pParams, pAppId) + local cid = commonRC.getMobileSession(pAppId):SendRPC("ButtonPress", pParams) + pParams.appID = commonRC.getHMIAppId(pAppId) + EXPECT_HMICALL("Buttons.ButtonPress", pParams) + :Do(function(_, data) + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + commonRC.getMobileSession(pAppId):ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + function commonRC.buildButtonCapability(name, shortPressAvailable, longPressAvailable, upDownAvailable) return hmi_values.createButtonCapability(name, shortPressAvailable, longPressAvailable, upDownAvailable) end -function commonRC.buildHmiRcCapabilities(pClimateCapabilities, pRadioCapabilities, pButtonCapabilities) +function commonRC.buildHmiRcCapabilities(pCapabilities) local hmiParams = hmi_values.getDefaultHMITable() - local capParams = hmiParams.RC.GetCapabilities.params.remoteControlCapability - hmiParams.RC.IsReady.params.available = true - - if pClimateCapabilities then - if pClimateCapabilities ~= commonRC.DEFAULT then - capParams.climateControlCapabilities = pClimateCapabilities - end - else - capParams.climateControlCapabilities = nil - end - - if pRadioCapabilities then - if pRadioCapabilities ~= commonRC.DEFAULT then - capParams.radioControlCapabilities = pRadioCapabilities - end - else - capParams.radioControlCapabilities = nil - end - - if pButtonCapabilities then - if pButtonCapabilities ~= commonRC.DEFAULT then - capParams.buttonCapabilities = pButtonCapabilities + local capParams = hmiParams.RC.GetCapabilities.params.remoteControlCapability + for k, v in pairs(commonRC.capMap) do + if pCapabilities[k] then + if pCapabilities[k] ~= commonRC.DEFAULT then + capParams[v] = pCapabilities[k] + end + else + capParams[v] = nil end - else - capParams.buttonCapabilities = nil end - return hmiParams end @@ -760,6 +906,28 @@ function commonRC.getButtonIdByName(pArray, pButtonName) end end +local function audibleState(pAppId) + if not pAppId then pAppId = 1 end + local appParams = config["application" .. pAppId].registerAppInterfaceParams + local audibleStateValue + if appParams.isMediaApplication == true then + audibleStateValue = "AUDIBLE" + else + audibleStateValue = "NOT_AUDIBLE" + end + return audibleStateValue +end + +function commonRC.activateApp(pAppId) + if not pAppId then pAppId = 1 end + local pHMIAppId = commonRC.getHMIAppId(pAppId) + local mobSession = commonRC.getMobileSession(pAppId) + local requestId = test.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) + EXPECT_HMIRESPONSE(requestId) + mobSession:ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = audibleState(pAppId), + systemContext = "MAIN" }) +end + function commonRC.updateDefaultCapabilities(pDisabledModuleTypes) local hmiCapabilitiesFile = commonPreconditions:GetPathToSDL() .. commonFunctions:read_parameter_from_smart_device_link_ini("HMICapabilities") @@ -773,25 +941,32 @@ function commonRC.updateDefaultCapabilities(pDisabledModuleTypes) commonRC.tableToJsonFile(hmiCapTbl, hmiCapabilitiesFile) end -function commonRC.getHMIAppIds() - return hmiAppIds -end - -function commonRC.deleteHMIAppId(pAppId) - hmiAppIds[config["application" .. pAppId].registerAppInterfaceParams.appID] = nil -end +commonRC.getHMIAppIds = actions.getHMIAppIds +commonRC.deleteHMIAppId = actions.deleteHMIAppId commonRC.actualInteriorDataStateOnHMI = { - CLIMATE = utils.cloneTable(commonRC.getModuleControlData("CLIMATE")), - RADIO = utils.cloneTable(commonRC.getModuleControlData("RADIO")) + CLIMATE = commonRC.cloneTable(commonRC.getModuleControlData("CLIMATE")), + RADIO = commonRC.cloneTable(commonRC.getModuleControlData("RADIO")), + SEAT = commonRC.cloneTable(commonRC.getModuleControlData("SEAT")), + AUDIO = commonRC.cloneTable(commonRC.getModuleControlData("AUDIO")), + LIGHT = commonRC.cloneTable(commonRC.getModuleControlData("LIGHT")), + HMI_SETTINGS = commonRC.cloneTable(commonRC.getModuleControlData("HMI_SETTINGS")) } function commonRC.setActualInteriorVD(pModuleType, pParams) local moduleParams if pModuleType == "CLIMATE" then moduleParams = "climateControlData" - else + elseif pModuleType == "RADIO" then moduleParams = "radioControlData" + elseif pModuleType == "SEAT" then + moduleParams = "seatControlData" + elseif pModuleType == "AUDIO" then + moduleParams = "audioControlData" + elseif pModuleType == "LIGHT" then + moduleParams = "lightControlData" + elseif pModuleType == "HMI_SETTINGS" then + moduleParams = "hmiSettingsControlData" end for key, value in pairs(pParams[moduleParams]) do if type(value) ~= "table" then @@ -806,4 +981,12 @@ function commonRC.setActualInteriorVD(pModuleType, pParams) end end +function commonRC.getModuleControlDataForResponse(pModuleType) + local moduleData = commonRC.actualInteriorDataStateOnHMI[pModuleType] + if moduleData.audioControlData then + moduleData.audioControlData.keepContext = nil + end + return moduleData +end + return commonRC diff --git a/user_modules/sequences/actions.lua b/user_modules/sequences/actions.lua index df68d17476..b443876ee8 100644 --- a/user_modules/sequences/actions.lua +++ b/user_modules/sequences/actions.lua @@ -489,4 +489,21 @@ function m.setHMIAppId(pHMIAppId, pAppId) hmiAppIds[m.getConfigAppParams(pAppId).appID] = pHMIAppId end +--[[ @getHMIAppIds: return array of all HMI application identifiers +--! @parameters: none +--! @return: array of all HMI application identifiers +--]] +function m.getHMIAppIds() + return hmiAppIds +end + +--[[ @deleteHMIAppId: remove HMI application identifier +--! @parameters: +--! pAppId - application number (1, 2, etc.) +--! @return: none +--]] +function m.deleteHMIAppId(pAppId) + hmiAppIds[m.getConfigAppParams(pAppId).appID] = nil +end + return m From da593799f15b07442b70909d34c7757a6f4b0dc0 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 22 Aug 2018 15:44:48 +0300 Subject: [PATCH 611/681] Update scripts for SEAT with new initial RC common --- .../001_SEAT_all_params_SUCCESS.lua | 16 +- ...2_SEAT_all_params_UNSUPPORTED_RESOURCE.lua | 16 +- .../003_Resend_only_supported_parameters.lua | 15 +- ...supported_and_not_supported_parameters.lua | 13 +- ...snt_respond_to_RC_GetCapabilities_SEAT.lua | 17 +- ...snt_respond_to_RC_GetCapabilities_SEAT.lua | 17 +- .../001_Success_flow.lua | 6 +- ...ransfering_of_HMI_resultCode_to_mobile.lua | 15 +- .../003_RPC_parameters_values.lua | 13 +- ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 6 +- ..._in_case_HMI_respond_with_invalid_data.lua | 15 +- ...se_moduleType_is_an_empty_array_in_LPT.lua | 18 +- ...ow_in_case_moduleType_is_absent_in_LPT.lua | 11 +- ...bscribing_without_isSubscribe_from_HMI.lua | 13 +- ...ROR_in_case_HMI_respond_with_READ_ONLY.lua | 8 +- ...response_from_HMI_without_isSubscribed.lua | 13 +- ...ut_response_from_HMI_with_isSubscribed.lua | 13 +- ...ase_of_2nd_Subscription_UnSubscription.lua | 13 +- .../001_Success_flow.lua | 6 +- ...ribing_with_isSubscribe_false_from_HMI.lua | 13 +- ...bscribing_without_isSubscribe_from_HMI.lua | 13 +- ..._Radio_and_without_one_for_module_Seat.lua | 6 +- ..._after_unsubscribe_from_module_Climate.lua | 6 +- .../006_RPC_parameters_values.lua | 12 +- .../001_Success_flow.lua | 28 +- .../002_Disallow_flow_by_policy_SEAT.lua | 23 +- ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 23 +- .../004_RPC_parameters_values.lua | 8 +- ...ow_in_case_moduleType_is_absent_in_LPT.lua | 23 +- ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 6 +- ..._in_case_HMI_respond_with_invalid_data.lua | 13 +- ...ransfering_of_HMI_resultCode_to_mobile.lua | 10 +- test_scripts/RC/SEAT/commonRC.lua | 406 ------------------ 33 files changed, 198 insertions(+), 636 deletions(-) delete mode 100644 test_scripts/RC/SEAT/commonRC.lua diff --git a/test_scripts/RC/SEAT/Capabilities/001_SEAT_all_params_SUCCESS.lua b/test_scripts/RC/SEAT/Capabilities/001_SEAT_all_params_SUCCESS.lua index db05cd3e4c..2003909e0d 100644 --- a/test_scripts/RC/SEAT/Capabilities/001_SEAT_all_params_SUCCESS.lua +++ b/test_scripts/RC/SEAT/Capabilities/001_SEAT_all_params_SUCCESS.lua @@ -12,20 +12,28 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false +-- [[ Local Variables ]] +local capParams = {} +capParams.CLIMATE = commonRC.DEFAULT +capParams.RADIO = commonRC.DEFAULT +capParams.BUTTONS = commonRC.DEFAULT +capParams.SEAT = commonRC.DEFAULT +local hmiRcCapabilities = commonRC.buildHmiRcCapabilities(capParams) + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { "SEAT" } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI (HMI has all posible RC capabilities), connect Mobile, start Session", commonRC.start, - {commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, commonRC.DEFAULT, commonRC.DEFAULT, commonRC.DEFAULT)}) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App1", commonRC.activate_app) + { hmiRcCapabilities }) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/SEAT/Capabilities/002_SEAT_all_params_UNSUPPORTED_RESOURCE.lua b/test_scripts/RC/SEAT/Capabilities/002_SEAT_all_params_UNSUPPORTED_RESOURCE.lua index 157ab5d0ab..f67a516b6d 100644 --- a/test_scripts/RC/SEAT/Capabilities/002_SEAT_all_params_UNSUPPORTED_RESOURCE.lua +++ b/test_scripts/RC/SEAT/Capabilities/002_SEAT_all_params_UNSUPPORTED_RESOURCE.lua @@ -13,18 +13,26 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false +-- [[ Local Variables ]] +local capParams = {} +capParams.CLIMATE = commonRC.DEFAULT +capParams.RADIO = commonRC.DEFAULT +capParams.BUTTONS = commonRC.DEFAULT +capParams.SEAT = nil +local hmiRcCapabilities = commonRC.buildHmiRcCapabilities(capParams) + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI (HMI has not SEAT RC capabilities), connect Mobile, start Session", commonRC.start, - {commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, commonRC.DEFAULT, nil, commonRC.DEFAULT)}) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App1", commonRC.activate_app) + {hmiRcCapabilities}) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App1", commonRC.activateApp) runner.Title("Test") runner.Step("GetInteriorVehicleData SEAT(UNSUPPORTED_RESOURCE)", commonRC.rpcDenied, diff --git a/test_scripts/RC/SEAT/Capabilities/003_Resend_only_supported_parameters.lua b/test_scripts/RC/SEAT/Capabilities/003_Resend_only_supported_parameters.lua index 7bed41e538..f29a1a2b70 100644 --- a/test_scripts/RC/SEAT/Capabilities/003_Resend_only_supported_parameters.lua +++ b/test_scripts/RC/SEAT/Capabilities/003_Resend_only_supported_parameters.lua @@ -13,14 +13,19 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local seat_capabilities = {{moduleName = "Seat", horizontalPositionAvailable = true, verticalPositionAvailable = false}} -local rc_capabilities = commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, commonRC.DEFAULT, seat_capabilities, commonRC.DEFAULT) +local capParams = {} +capParams.CLIMATE = commonRC.DEFAULT +capParams.RADIO = commonRC.DEFAULT +capParams.BUTTONS = commonRC.DEFAULT +capParams.SEAT = seat_capabilities +local rc_capabilities = commonRC.buildHmiRcCapabilities(capParams) local available_params = {moduleType = "SEAT", seatControlData = {id = "DRIVER", horizontalPosition = 75}} local absent_params = {moduleType = "SEAT", seatControlData = {id = "DRIVER", frontVerticalPosition = 55}} local unavailable_params = {moduleType = "SEAT", seatControlData = {id = "DRIVER", verticalPosition = 65}} @@ -35,7 +40,7 @@ local function setVehicleData(params) appID = commonRC.getHMIAppId(1), moduleData = params}) :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = params}) end) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) @@ -49,8 +54,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, {rc_capabilities}) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate_App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate_App", commonRC.activateApp) runner.Title("Test") runner.Step("SetInteriorVehicleData rejected with unavailable parameter", setVehicleData, { unavailable_params }) diff --git a/test_scripts/RC/SEAT/Capabilities/004_Reject_request_with_both_supported_and_not_supported_parameters.lua b/test_scripts/RC/SEAT/Capabilities/004_Reject_request_with_both_supported_and_not_supported_parameters.lua index c1e250247f..31145fe6e5 100644 --- a/test_scripts/RC/SEAT/Capabilities/004_Reject_request_with_both_supported_and_not_supported_parameters.lua +++ b/test_scripts/RC/SEAT/Capabilities/004_Reject_request_with_both_supported_and_not_supported_parameters.lua @@ -16,14 +16,19 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local seat_capabilities = {{moduleName = "Seat", horizontalPositionAvailable = true, verticalPositionAvailable = false}} -local rc_capabilities = commonRC.buildHmiRcCapabilities(commonRC.DEFAULT, commonRC.DEFAULT, seat_capabilities, commonRC.DEFAULT) +local capParams = {} +capParams.CLIMATE = commonRC.DEFAULT +capParams.RADIO = commonRC.DEFAULT +capParams.BUTTONS = commonRC.DEFAULT +capParams.SEAT = seat_capabilities +local rc_capabilities = commonRC.buildHmiRcCapabilities(capParams) local seat_params = { moduleType = "SEAT", seatControlData = { @@ -44,8 +49,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, {rc_capabilities}) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate_App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate_App", commonRC.activateApp) runner.Title("Test") runner.Step("SetInteriorVehicleData rejected if at least one prameter unsuported", setVehicleData, { seat_params }) diff --git a/test_scripts/RC/SEAT/Capabilities/005_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua b/test_scripts/RC/SEAT/Capabilities/005_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua index a1706a3704..eaa1e28a13 100644 --- a/test_scripts/RC/SEAT/Capabilities/005_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua +++ b/test_scripts/RC/SEAT/Capabilities/005_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua @@ -15,9 +15,8 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') local hmi_values = require('user_modules/hmi_values') -local initialCommon = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -37,7 +36,7 @@ end local function rpcUnsupportedResource(pModuleType, pRPC) local pAppId = 1 local mobSession = commonRC.getMobileSession(pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), initialCommon.getAppRequestParams(pRPC, pModuleType)) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) end @@ -45,12 +44,12 @@ end local function rpcSuccess(pModuleType, pRPC) local pAppId = 1 local mobSession = commonRC.getMobileSession(pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), initialCommon.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), initialCommon.getHMIRequestParams(pRPC, pModuleType, pAppId)) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", initialCommon.getHMIResponseParams(pRPC, pModuleType)) + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) end) - mobSession:ExpectResponse(cid, initialCommon.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) + mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) end --[[ Scenario ]] @@ -59,8 +58,8 @@ runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { disabledModule } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test - Module enabled: " .. enabledModule .. ", disabled: " .. disabledModule) runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, diff --git a/test_scripts/RC/SEAT/Capabilities/006_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua b/test_scripts/RC/SEAT/Capabilities/006_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua index d396977889..7fdd448673 100644 --- a/test_scripts/RC/SEAT/Capabilities/006_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua +++ b/test_scripts/RC/SEAT/Capabilities/006_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua @@ -15,9 +15,8 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') local hmi_values = require('user_modules/hmi_values') -local initialCommon = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -37,7 +36,7 @@ end local function rpcUnsupportedResource(pModuleType, pRPC) local pAppId = 1 local mobSession = commonRC.getMobileSession(pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), initialCommon.getAppRequestParams(pRPC, pModuleType)) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), {}):Times(0) mobSession:ExpectResponse(cid, { success = false, resultCode = "UNSUPPORTED_RESOURCE" }) end @@ -45,12 +44,12 @@ end local function rpcSuccess(pModuleType, pRPC) local pAppId = 1 local mobSession = commonRC.getMobileSession(pAppId) - local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), initialCommon.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), initialCommon.getHMIRequestParams(pRPC, pModuleType, pAppId)) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), commonRC.getAppRequestParams(pRPC, pModuleType)) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC), commonRC.getHMIRequestParams(pRPC, pModuleType, pAppId)) :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", initialCommon.getHMIResponseParams(pRPC, pModuleType)) + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", commonRC.getHMIResponseParams(pRPC, pModuleType)) end) - mobSession:ExpectResponse(cid, initialCommon.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) + mobSession:ExpectResponse(cid, commonRC.getAppResponseParams(pRPC, true, "SUCCESS", pModuleType)) end --[[ Scenario ]] @@ -59,8 +58,8 @@ runner.Step("Backup HMI capabilities file", commonRC.backupHMICapabilities) runner.Step("Update HMI capabilities file", commonRC.updateDefaultCapabilities, { { disabledModule } }) runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start, { getHMIParams() }) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test - Module enabled: " .. enabledModule .. ", disabled: " .. disabledModule) runner.Step("GetInteriorVehicleData_UNSUPPORTED_RESOURCE", rpcUnsupportedResource, diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/001_Success_flow.lua index 183e0e3935..99019ed222 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/001_Success_flow.lua @@ -13,7 +13,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -22,8 +22,8 @@ runner.testSettings.isSelfIncluded = false runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("GetInteriorVehicleData SEAT", commonRC.subscribeToModule, { "SEAT" }) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/002_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/002_Transfering_of_HMI_resultCode_to_mobile.lua index 7c4984263d..ebd47693ca 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/002_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/002_Transfering_of_HMI_resultCode_to_mobile.lua @@ -16,8 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') -local initialCommon = require('test_scripts/RC/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -38,15 +37,15 @@ local function stepSuccessfull(pModuleType, pResultCode) subscribe = true }) :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, pResultCode, { - moduleData = initialCommon.getModuleControlData(pModuleType) + commonRC.getHMIConnection():SendResponse(data.id, data.method, pResultCode, { + moduleData = commonRC.getModuleControlData(pModuleType) -- isSubscribed = true }) end) commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = pResultCode, isSubscribed = false, - moduleData = initialCommon.getModuleControlData(pModuleType) + moduleData = commonRC.getModuleControlData(pModuleType) }) end @@ -61,7 +60,7 @@ local function stepUnsuccessfull(pModuleType, pResultCode) subscribe = true }) :Do(function(_, data) - commonRC.getHMIconnection():SendError(data.id, data.method, pResultCode, "Error error") + commonRC.getHMIConnection():SendError(data.id, data.method, pResultCode, "Error error") end) commonRC.getMobileSession():ExpectResponse(cid, { success = false, resultCode = pResultCode}) @@ -71,8 +70,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/003_RPC_parameters_values.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/003_RPC_parameters_values.lua index 72cccfd9b6..77ab797930 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/003_RPC_parameters_values.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/003_RPC_parameters_values.lua @@ -19,8 +19,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') -local initialCommon = require('test_scripts/RC/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -68,15 +67,15 @@ local function fakeParam(pModuleType) subscribe = true }) :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = initialCommon.getModuleControlData(pModuleType), + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = true }) end) commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true, - moduleData = initialCommon.getModuleControlData(pModuleType) + moduleData = commonRC.getModuleControlData(pModuleType) }) end @@ -84,8 +83,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/004_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/004_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index bc2b6fb190..5f2a418c69 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/004_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/004_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -13,7 +13,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -41,8 +41,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("GetInteriorVehicleData SEAT HMI does not respond", getDataForModule, { "SEAT" }) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/005_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/005_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index ff995a4f26..af5427f012 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/005_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/005_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -15,8 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') -local initialCommon = require('test_scripts/RC/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -34,8 +33,8 @@ local function invalidParamType(pModuleType) subscribe = true }) :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = initialCommon.getModuleControlData(pModuleType), + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = "yes" -- invalid type of parameter }) end) @@ -56,9 +55,9 @@ local function missingMandatoryParam(pModuleType) }) :Do(function(_, data) - local moduleData = initialCommon.getModuleControlData(pModuleType) + local moduleData = commonRC.getModuleControlData(pModuleType) moduleData.moduleType = nil -- missing mandatory parameter - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = moduleData, isSubscribed = true }) @@ -71,8 +70,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("GetInteriorVehicleData SEAT Invalid response from HMI-Invalid type of parameter", invalidParamType, diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 71132c1c8f..08efa550bc 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -13,8 +13,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') -local initialCommon = require('test_scripts/RC/commonRC') +local commonRC = require('test_scripts/RC/commonRC') local json = require('modules/json') --[[ Test Configuration ]] @@ -33,28 +32,29 @@ local function getDataForModule(pModuleType) subscribe = true }) :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = initialCommon.getModuleControlData(pModuleType), + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = true }) end) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", isSubscribed = true, - moduleData = initialCommon.getModuleControlData(pModuleType) + moduleData = commonRC.getModuleControlData(pModuleType) }) end -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = json.EMPTY_ARRAY end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("GetInteriorVehicleData SEAT", getDataForModule, { "SEAT" }) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 75d229e2ca..336729f23b 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -13,7 +13,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -32,16 +32,17 @@ local function getDataForModule(module_type) mobSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) end -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("GetInteriorVehicleData SEAT", getDataForModule, { "SEAT" }) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua index b0f7bca902..901a4a16cd 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -16,8 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') -local initialCommon = require('test_scripts/RC/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -35,14 +34,14 @@ local function unSubscriptionToModule(pModuleType) subscribe = false }) :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = initialCommon.getModuleControlData(pModuleType), + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), -- no isSubscribed parameter }) end) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = initialCommon.getModuleControlData(pModuleType), + moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = true }) end @@ -51,8 +50,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) runner.Step("Send notification OnInteriorVehicleData SEAT. App is subscribed", commonRC.isSubscribed, { "SEAT" }) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua index ebe943b6f4..a9a770f78f 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -13,7 +13,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -31,7 +31,7 @@ local function getDataForModule(module_type) subscribe = true }) :Do(function(_, data) - commonRC.getHMIconnection():SendError(data.id, data.method, "READ_ONLY", "Info message") + commonRC.getHMIConnection():SendError(data.id, data.method, "READ_ONLY", "Info message") end) mobSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Info message" }) end @@ -40,8 +40,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("GetInteriorVehicleData SEAT", getDataForModule, { "SEAT" }) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua index cea34fb787..3d04acf4a3 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -15,8 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') -local initialCommon = require('test_scripts/RC/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -38,8 +37,8 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, p moduleType = pModuleType }) :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = initialCommon.getModuleControlData(pModuleType), + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), -- no isSubscribed parameter }) end) @@ -53,7 +52,7 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, p mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", isSubscribed = isSubscriptionActive, -- return current value of subscription - moduleData = initialCommon.getModuleControlData(pModuleType) + moduleData = commonRC.getModuleControlData(pModuleType) }) end @@ -61,8 +60,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("GetInteriorVehicleData SEAT NoSubscription_subscribe", getDataForModule, { "SEAT", false, true, 1 }) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index fd4c8c9cf8..24350508fb 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -15,8 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') -local initialCommon = require('test_scripts/RC/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -33,8 +32,8 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequest) moduleType = pModuleType }) :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = initialCommon.getModuleControlData(pModuleType), + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = isSubscriptionActive -- return current value of subscription }) end) @@ -47,7 +46,7 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequest) :Times(pHMIrequest) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = initialCommon.getModuleControlData(pModuleType) + moduleData = commonRC.getModuleControlData(pModuleType) }) :ValidIf(function(_, data) -- no isSubscribed parameter if data.payload.isSubscribed == nil then @@ -61,8 +60,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("GetInteriorVehicleData SEAT NoSubscription", getDataForModule, { "SEAT", false, 1 }) diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua index f6d8a0729e..4052c28106 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua @@ -26,8 +26,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') -local initialCommon = require('test_scripts/RC/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -44,8 +43,8 @@ local function subscriptionToModule(pModuleType, pSubscribe, pHMIrequest) moduleType = pModuleType }) :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = initialCommon.actualInteriorDataStateOnHMI[pModuleType], + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.actualInteriorDataStateOnHMI[pModuleType], isSubscribed = pSubscribe }) end) @@ -57,7 +56,7 @@ local function subscriptionToModule(pModuleType, pSubscribe, pHMIrequest) end) :Times(pHMIrequest) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = initialCommon.actualInteriorDataStateOnHMI[pModuleType], + moduleData = commonRC.actualInteriorDataStateOnHMI[pModuleType], isSubscribed = pSubscribe }) end @@ -66,8 +65,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -- app has not subscribed yet diff --git a/test_scripts/RC/SEAT/OnInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/SEAT/OnInteriorVehicleData/001_Success_flow.lua index ffb23dbeb5..0d547c6a5b 100644 --- a/test_scripts/RC/SEAT/OnInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/SEAT/OnInteriorVehicleData/001_Success_flow.lua @@ -27,7 +27,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -36,8 +36,8 @@ runner.testSettings.isSelfIncluded = false runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) diff --git a/test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua index 29cdd208d3..89ffb96ee8 100644 --- a/test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -15,8 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') -local initialCommon = require('test_scripts/RC/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -34,14 +33,14 @@ local function subscriptionToModule(pModuleType) subscribe = true }) :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = initialCommon.getModuleControlData(pModuleType), + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = false -- not subscribe }) end) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = initialCommon.getModuleControlData(pModuleType), + moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = false }) end @@ -50,8 +49,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("Subscribe app to SEAT", subscriptionToModule, { "SEAT" }) diff --git a/test_scripts/RC/SEAT/OnInteriorVehicleData/003_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/SEAT/OnInteriorVehicleData/003_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua index 069669535a..d5efb70332 100644 --- a/test_scripts/RC/SEAT/OnInteriorVehicleData/003_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/SEAT/OnInteriorVehicleData/003_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -16,8 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') -local initialCommon = require('test_scripts/RC/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -35,14 +34,14 @@ local function unSubscriptionToModule(pModuleType) subscribe = false }) :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = initialCommon.getModuleControlData(pModuleType), + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlData(pModuleType), -- no isSubscribed parameter }) end) mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = initialCommon.getModuleControlData(pModuleType), + moduleData = commonRC.getModuleControlData(pModuleType), isSubscribed = true }) end @@ -51,8 +50,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) runner.Step("Send notification OnInteriorVehicleData SEAT. App is subscribed", commonRC.isSubscribed, { "SEAT" }) diff --git a/test_scripts/RC/SEAT/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Seat.lua b/test_scripts/RC/SEAT/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Seat.lua index 96faab8837..37d09c84de 100644 --- a/test_scripts/RC/SEAT/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Seat.lua +++ b/test_scripts/RC/SEAT/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Seat.lua @@ -13,7 +13,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -22,8 +22,8 @@ runner.testSettings.isSelfIncluded = false runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/SEAT/OnInteriorVehicleData/005_Existence_of_OnIVD_for_module_Seat_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Climate.lua b/test_scripts/RC/SEAT/OnInteriorVehicleData/005_Existence_of_OnIVD_for_module_Seat_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Climate.lua index dc51ff6f36..e678d8d07f 100644 --- a/test_scripts/RC/SEAT/OnInteriorVehicleData/005_Existence_of_OnIVD_for_module_Seat_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Climate.lua +++ b/test_scripts/RC/SEAT/OnInteriorVehicleData/005_Existence_of_OnIVD_for_module_Seat_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Climate.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -24,8 +24,8 @@ runner.testSettings.isSelfIncluded = false runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) runner.Step("Send notification OnInteriorVehicleData SEAT. App is subscribed", commonRC.isSubscribed, { "SEAT" }) runner.Step("Subscribe app to CLIMATE", commonRC.subscribeToModule, { "CLIMATE" }) diff --git a/test_scripts/RC/SEAT/OnInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/SEAT/OnInteriorVehicleData/006_RPC_parameters_values.lua index 08ee3fb339..05e7690de3 100644 --- a/test_scripts/RC/SEAT/OnInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/SEAT/OnInteriorVehicleData/006_RPC_parameters_values.lua @@ -16,14 +16,14 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] local function invalidParamName(pModuleType) - commonRC.getHMIconnection():SendNotification("RC.OnInteriorVehicleData", { + commonRC.getHMIConnection():SendNotification("RC.OnInteriorVehicleData", { modduleData = commonRC.getAnotherModuleControlData(pModuleType) -- invalid name of parameter }) @@ -34,7 +34,7 @@ local function invalidParamType(pModuleType) local moduleData = commonRC.getAnotherModuleControlData(pModuleType) moduleData.moduleType = {} -- invalid type of parameter - commonRC.getHMIconnection():SendNotification("RC.OnInteriorVehicleData", { + commonRC.getHMIConnection():SendNotification("RC.OnInteriorVehicleData", { moduleData = moduleData }) @@ -45,7 +45,7 @@ local function missingMandatoryParam(pModuleType) local moduleData = commonRC.getAnotherModuleControlData(pModuleType) moduleData.moduleType = nil -- mandatory parameter missing - commonRC.getHMIconnection():SendNotification("RC.OnInteriorVehicleData", { + commonRC.getHMIConnection():SendNotification("RC.OnInteriorVehicleData", { moduleData = moduleData }) @@ -56,8 +56,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) runner.Step("Send notification OnInteriorVehicleData SEAT. App is subscribed", commonRC.isSubscribed, { "SEAT" }) diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/001_Success_flow.lua index e1465f2d09..b90a1fd98c 100644 --- a/test_scripts/RC/SEAT/SetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/001_Success_flow.lua @@ -14,40 +14,20 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false ---[[ Local Functions ]] -local function setVehicleData(pModuleType) - local mobileSession = commonRC.getMobileSession() - local cid = mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData", { - appID = commonRC.getHMIAppId(), - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - end) - - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -runner.Step("SetInteriorVehicleData SEAT", setVehicleData, { "SEAT" }) +runner.Step("SetInteriorVehicleData SEAT", commonRC.rpcAllowed, {"SEAT" , 1, "SetInteriorVehicleData"}) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_SEAT.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_SEAT.lua index 1d51794776..a881897cb6 100644 --- a/test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_SEAT.lua +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_SEAT.lua @@ -13,35 +13,26 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function setVehicleData(pModuleType) - local mobileSession = commonRC.getMobileSession() - local cid = mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) - mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -runner.Step("SetInteriorVehicleData SEAT", setVehicleData, { "SEAT" }) +runner.Step("SetInteriorVehicleData SEAT", commonRC.rpcDenied, {"SEAT" , 1, "SetInteriorVehicleData", "DISALLOWED"}) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/003_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/003_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 9ee3e1ca6f..a1ebb39c14 100644 --- a/test_scripts/RC/SEAT/SetInteriorVehicleData/003_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/003_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -13,7 +13,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ General configuration parameters ]] config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } @@ -22,30 +22,21 @@ config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function setVehicleData(pModuleType) - local mobileSession = commonRC.getMobileSession() - local cid = mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) - mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - -local function ptu_update_func(tbl) +local function PTUfunc(tbl) local appId = config.application1.registerAppInterfaceParams.appID tbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -runner.Step("SetInteriorVehicleData SEAT", setVehicleData, { "SEAT" }) +runner.Step("SetInteriorVehicleData SEAT", commonRC.rpcDenied, {"SEAT" , 1, "SetInteriorVehicleData", "DISALLOWED"}) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/004_RPC_parameters_values.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/004_RPC_parameters_values.lua index 9167d0e4b1..fcbb424498 100644 --- a/test_scripts/RC/SEAT/SetInteriorVehicleData/004_RPC_parameters_values.lua +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/004_RPC_parameters_values.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -68,7 +68,7 @@ local function fakeParam(pModuleType) moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) end) @@ -79,8 +79,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("SetInteriorVehicleData SEAT invalid name of parameter", invalidParamName, { "SEAT" }) diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/005_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/005_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 17076cb644..95e7302e68 100644 --- a/test_scripts/RC/SEAT/SetInteriorVehicleData/005_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/005_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -13,35 +13,26 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function setVehicleData(pModuleType) - local mobileSession = commonRC.getMobileSession() - local cid = mobileSession:SendRPC("SetInteriorVehicleData", { - moduleData = commonRC.getSettableModuleControlData(pModuleType) - }) - - EXPECT_HMICALL("RC.SetInteriorVehicleData"):Times(0) - mobileSession:ExpectResponse(cid, { success = false, resultCode = "DISALLOWED" }) -end - -local function ptu_update_func(tbl) +local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { ptu_update_func }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") -runner.Step("SetInteriorVehicleData SEAT", setVehicleData, { "SEAT" }) +runner.Step("SetInteriorVehicleData SEAT", commonRC.rpcDenied, {"SEAT" , 1, "SetInteriorVehicleData", "DISALLOWED"}) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/006_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/006_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index 5c0a498356..bb7d661c39 100644 --- a/test_scripts/RC/SEAT/SetInteriorVehicleData/006_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/006_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -13,7 +13,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') local commonTestCases = require('user_modules/shared_testcases/commonTestCases') --[[ Test Configuration ]] @@ -42,8 +42,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index e402a0f0f1..3e6bd8d282 100644 --- a/test_scripts/RC/SEAT/SetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -13,8 +13,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') -local initialCommon = require('test_scripts/RC/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -33,7 +32,7 @@ local function invalidParamType(pModuleType) :Do(function(_, data) local modData = commonRC.getSettableModuleControlData(pModuleType) modData.moduleType = "MODULE" -- invalid value of parameter - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = modData, isSubscribed = "yes" -- fake parameter }) @@ -53,9 +52,9 @@ local function missingMandatoryParam(pModuleType) moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :Do(function(_, data) - local moduleData = initialCommon.getModuleControlData(pModuleType) + local moduleData = commonRC.getModuleControlData(pModuleType) moduleData.moduleType = nil -- missing mandatory parameter - commonRC.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = moduleData }) end) @@ -67,8 +66,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("SetInteriorVehicleData SEAT Invalid response from HMI-Invalid type of parameter", invalidParamType, diff --git a/test_scripts/RC/SEAT/SetInteriorVehicleData/008_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/SEAT/SetInteriorVehicleData/008_Transfering_of_HMI_resultCode_to_mobile.lua index a12f61daa7..0c03b5dd36 100644 --- a/test_scripts/RC/SEAT/SetInteriorVehicleData/008_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/SEAT/SetInteriorVehicleData/008_Transfering_of_HMI_resultCode_to_mobile.lua @@ -14,7 +14,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonRC = require('test_scripts/RC/SEAT/commonRC') +local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -35,7 +35,7 @@ local function stepSuccessfull(pModuleType, pResultCode) moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :Do(function(_, data) - commonRC.getHMIconnection():SendResponse(data.id, data.method, pResultCode, { + commonRC.getHMIConnection():SendResponse(data.id, data.method, pResultCode, { moduleData = commonRC.getSettableModuleControlData(pModuleType) }) end) @@ -55,7 +55,7 @@ local function stepUnsuccessfull(pModuleType, pResultCode) moduleData = commonRC.getSettableModuleControlData(pModuleType) }) :Do(function(_, data) - commonRC.getHMIconnection():SendError(data.id, data.method, pResultCode, "Error error") + commonRC.getHMIConnection():SendError(data.id, data.method, pResultCode, "Error error") end) mobileSession:ExpectResponse(cid, { success = false, resultCode = pResultCode }) @@ -65,8 +65,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerAppWOPTU) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") for _, code in pairs(success_codes) do diff --git a/test_scripts/RC/SEAT/commonRC.lua b/test_scripts/RC/SEAT/commonRC.lua deleted file mode 100644 index a1421eb836..0000000000 --- a/test_scripts/RC/SEAT/commonRC.lua +++ /dev/null @@ -1,406 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RC common module ---------------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.mobileHost = "127.0.0.1" -config.defaultProtocolVersion = 2 -config.ValidateSchema = false -config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } -config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } -config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 -config.application2.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 - ---[[ Required Shared libraries ]] -local initialCommon = require('test_scripts/RC/commonRC') -local test = require("user_modules/dummy_connecttest") -local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local utils = require('user_modules/utils') - ---[[ Local Variables ]] -local commonRC = {} - -commonRC.timeout = 2000 -commonRC.minTimeout = 500 -commonRC.DEFAULT = initialCommon.DEFAULT - -function initialCommon.getRCAppConfig() - return { - keep_context = false, - steal_focus = false, - priority = "NONE", - default_hmi = "NONE", - moduleType = { "RADIO", "CLIMATE", "SEAT" }, - groups = { "Base-4", "RemoteControl" }, - AppHMIType = { "REMOTE_CONTROL" } - } -end - -function commonRC.getMobileSession(pAppId) - if not pAppId then pAppId = 1 end - return test["mobileSession" .. pAppId] -end - -function commonRC.getHMIconnection() - return test.hmiConnection -end - -local origGetModuleControlData = initialCommon.getModuleControlData -function initialCommon.getModuleControlData(module_type) - local out = { } - if module_type == "SEAT" then - out.moduleType = module_type - out.seatControlData = { - id = "DRIVER", - heatingEnabled = true, - coolingEnabled = true, - heatingLevel = 50, - coolingLevel = 50, - horizontalPosition = 50, - verticalPosition = 50, - frontVerticalPosition = 50, - backVerticalPosition = 50, - backTiltAngle = 50, - headSupportHorizontalPosition = 50, - headSupportVerticalPosition = 50, - massageEnabled = true, - massageMode = { - { - massageZone = "LUMBAR", - massageMode = "HIGH" - }, - { - massageZone = "SEAT_CUSHION", - massageMode = "LOW" - } - }, - massageCushionFirmness = { - { - cushion = "TOP_LUMBAR", - firmness = 30 - }, - { - cushion = "BACK_BOLSTERS", - firmness = 60 - } - }, - memory = { - id = 1, - label = "Label value", - action = "SAVE" - } - } - else - out = origGetModuleControlData(module_type) - end - return out -end - -local origGetAnotherModuleControlData = initialCommon.getAnotherModuleControlData -function commonRC.getAnotherModuleControlData(module_type) - local out = { } - if module_type == "SEAT" then - out.moduleType = module_type - out.seatControlData ={ - id = "FRONT_PASSENGER", - heatingEnabled = true, - coolingEnabled = false, - heatingLevel = 75, - coolingLevel = 0, - horizontalPosition = 75, - verticalPosition = 75, - frontVerticalPosition = 75, - backVerticalPosition = 75, - backTiltAngle = 75, - headSupportHorizontalPosition = 75, - headSupportVerticalPosition = 75, - massageEnabled = true, - massageMode = { - { - massageZone = "LUMBAR", - massageMode = "OFF" - }, - { - massageZone = "SEAT_CUSHION", - massageMode = "HIGH" - } - }, - massageCushionFirmness = { - { - cushion = "MIDDLE_LUMBAR", - firmness = 65 - }, - { - cushion = "SEAT_BOLSTERS", - firmness = 30 - } - }, - memory = { - id = 2, - label = "Another label value", - action = "RESTORE" - } - } - else - out = origGetAnotherModuleControlData(module_type) - end - return out -end - -local origGetModuleParams = initialCommon.getModuleParams -function initialCommon.getModuleParams(pModuleData) - if pModuleData.moduleType == "SEAT" then - if not pModuleData.seatControlData then - pModuleData.seatControlData = { } - end - return pModuleData.seatControlData - end - return origGetModuleParams(pModuleData) -end - -function commonRC.getModuleParams(pModuleData) - return initialCommon.getModuleParams(pModuleData) -end - -initialCommon.actualInteriorDataStateOnHMI = { - CLIMATE = utils.cloneTable(initialCommon.getModuleControlData("CLIMATE")), - RADIO = utils.cloneTable(initialCommon.getModuleControlData("RADIO")), - SEAT = utils.cloneTable(initialCommon.getModuleControlData("SEAT")) -} - -local setActualInteriorVDorigin = initialCommon.setActualInteriorVD -function initialCommon.setActualInteriorVD(pModuleType, pParams) - if pModuleType == "SEAT" then - for key, value in pairs(pParams["seatControlData"]) do - if type(value) ~= "table" then - if value ~= initialCommon.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] then - initialCommon.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] = value - end - else - if false == commonFunctions:is_table_equal(value, initialCommon.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key]) then - initialCommon.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] = value - end - end - end - else - setActualInteriorVDorigin(pModuleType, pParams) - end -end - -function commonRC.buildHmiRcCapabilities(pClimateCapabilities, pRadioCapabilities, pSeatCapabilities, pButtonCapabilities) - local hmiParams = initialCommon.buildHmiRcCapabilities(pClimateCapabilities, pRadioCapabilities, pButtonCapabilities) - local capParams = hmiParams.RC.GetCapabilities.params.remoteControlCapability - - if pSeatCapabilities then - if pSeatCapabilities ~= commonRC.DEFAULT then - capParams.seatControlCapabilities = pSeatCapabilities - end - else - capParams.seatControlCapabilities = nil - end - - return hmiParams -end - -function commonRC.getReadOnlyParamsByModule(pModuleType) - return initialCommon.getReadOnlyParamsByModule(pModuleType) -end - -function commonRC.getSettableModuleControlData(pModuleType) - return initialCommon.getSettableModuleControlData(pModuleType) -end - -function commonRC.preconditions() - initialCommon.preconditions() -end - -function commonRC.start(pHMIParams) - initialCommon.start(pHMIParams, test) -end - -function commonRC.rai_ptu(ptu_update_func) - initialCommon.rai_ptu(ptu_update_func, test) -end - -function commonRC.rai_ptu_n(id, ptu_update_func) - initialCommon.rai_ptu_n(id, ptu_update_func, test) -end - -function commonRC.rai_n(id) - initialCommon.rai_n(id, test) -end - -function commonRC.unregisterApp(pAppId) - initialCommon.unregisterApp(pAppId, test) -end - -function commonRC.activate_app(pAppId) - initialCommon.activate_app(pAppId, test) -end - -function commonRC.postconditions() - initialCommon.postconditions() -end - -function commonRC.subscribeToModule(pModuleType, pAppId) - return initialCommon.subscribeToModule(pModuleType, pAppId, test) -end - -function commonRC.unSubscribeToModule(pModuleType, pAppId) - return initialCommon.unSubscribeToModule(pModuleType, pAppId, test) -end - -function commonRC.isSubscribed(pModuleType, pAppId) - return initialCommon.isSubscribed(pModuleType, pAppId, test) -end - -function commonRC.isUnsubscribed(pModuleType, pAppId) - return initialCommon.isUnsubscribed(pModuleType, pAppId, test) -end - -function commonRC.getHMIAppId(pAppId) - return initialCommon.getHMIAppId(pAppId) -end - -function commonRC.rpcDenied(pModuleType, pAppId, pRPC, pResultCode) - return initialCommon.rpcDenied(pModuleType, pAppId, pRPC, pResultCode, test) -end - -function commonRC.rpcAllowed(pModuleType, pAppId, pRPC) - return initialCommon.rpcAllowed(pModuleType, pAppId, pRPC, test) -end - -function commonRC.backupHMICapabilities() - return initialCommon.backupHMICapabilities() -end - -function commonRC.restoreHMICapabilities() - return initialCommon.restoreHMICapabilities() -end - -function commonRC.updateDefaultCapabilities(pDisabledModuleTypes) - return initialCommon.updateDefaultCapabilities(pDisabledModuleTypes) -end - --- RC RPCs structure -local rcRPCs = { - GetInteriorVehicleData = { - appEventName = "GetInteriorVehicleData", - hmiEventName = "RC.GetInteriorVehicleData", - requestParams = function(pModuleType, pSubscribe) - return { - moduleType = pModuleType, - subscribe = pSubscribe - } - end, - hmiRequestParams = function(pModuleType, _, pSubscribe) - return { - moduleType = pModuleType, - subscribe = pSubscribe - } - end, - hmiResponseParams = function(pModuleType, pSubscribe) - return { - moduleData = initialCommon.actualInteriorDataStateOnHMI[pModuleType], - isSubscribed = pSubscribe - } - end, - responseParams = function(success, resultCode, pModuleType, pSubscribe) - return { - success = success, - resultCode = resultCode, - moduleData = initialCommon.actualInteriorDataStateOnHMI[pModuleType], - isSubscribed = pSubscribe - } - end - }, - SetInteriorVehicleData = { - appEventName = "SetInteriorVehicleData", - hmiEventName = "RC.SetInteriorVehicleData", - requestParams = function(pModuleType) - return { - moduleData = commonRC.getSettableModuleControlData(pModuleType) - } - end, - hmiRequestParams = function(pModuleType, pAppId) - return { - appID = commonRC.getHMIAppId(pAppId), - moduleData = commonRC.getSettableModuleControlData(pModuleType) - } - end, - hmiResponseParams = function(pModuleType) - return { - moduleData = commonRC.getSettableModuleControlData(pModuleType) - } - end, - responseParams = function(success, resultCode, pModuleType) - return { - success = success, - resultCode = resultCode, - moduleData = commonRC.getSettableModuleControlData(pModuleType) - } - end - }, - GetInteriorVehicleDataConsent = { - hmiEventName = "RC.GetInteriorVehicleDataConsent", - hmiRequestParams = function(pModuleType, pAppId) - return { - appID = commonRC.getHMIAppId(pAppId), - moduleType = pModuleType - } - end, - hmiResponseParams = function(pAllowed) - return { - allowed = pAllowed - } - end, - }, - OnInteriorVehicleData = { - appEventName = "OnInteriorVehicleData", - hmiEventName = "RC.OnInteriorVehicleData", - hmiResponseParams = function(pModuleType) - return { - moduleData = commonRC.getAnotherModuleControlData(pModuleType) - } - end, - responseParams = function(pModuleType) - return { - moduleData = commonRC.getAnotherModuleControlData(pModuleType) - } - end - }, - OnRemoteControlSettings = { - hmiEventName = "RC.OnRemoteControlSettings", - hmiResponseParams = function(pAllowed, pAccessMode) - return { - allowed = pAllowed, - accessMode = pAccessMode - } - end - } -} - -function commonRC.getAppEventName(pRPC) - return rcRPCs[pRPC].appEventName -end - -function commonRC.getHMIEventName(pRPC) - return rcRPCs[pRPC].hmiEventName -end - -function initialCommon.getAppRequestParams(pRPC, ...) - return rcRPCs[pRPC].requestParams(...) -end - -function initialCommon.getAppResponseParams(pRPC, ...) - return rcRPCs[pRPC].responseParams(...) -end - -function initialCommon.getHMIRequestParams(pRPC, ...) - return rcRPCs[pRPC].hmiRequestParams(...) -end - -function initialCommon.getHMIResponseParams(pRPC, ...) - return rcRPCs[pRPC].hmiResponseParams(...) -end - -return commonRC From 3b2edeb011405f418bbcc7e59ec3fb2bf2b47f59 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 22 Aug 2018 15:46:34 +0300 Subject: [PATCH 612/681] Update scripts for AUDIO, LIGHT, HMI_SETTINGS with new initial RC common --- .../001_Success_flow.lua | 6 +- .../002_Disallow_flow_by_policy_AUDIO.lua | 11 +- .../003_Disallow_flow_by_policy_LIGHT.lua | 10 +- ...4_Disallow_flow_by_policy_HMI_SETTINGS.lua | 10 +- ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 9 +- .../006_RPC_parameters_values.lua | 11 +- ...ERIC_ERROR_in_case_HMI_did_not_respond.lua | 9 +- ..._in_case_HMI_respond_with_invalid_data.lua | 13 +- ...se_moduleType_is_an_empty_array_in_LPT.lua | 10 +- ...ow_in_case_moduleType_is_absent_in_LPT.lua | 13 +- ...ROR_in_case_HMI_respond_with_READ_ONLY.lua | 11 +- ...ransfering_of_HMI_resultCode_to_mobile.lua | 13 +- ...ut_response_from_HMI_with_isSubscribed.lua | 17 +- ...ase_of_2nd_Subscription_UnSubscription.lua | 8 +- ...response_from_HMI_without_isSubscribed.lua | 10 +- .../016_RADIO_GPSdata_in_HMI_response.lua | 6 +- .../017_Success_audio_source_values.lua | 7 +- .../001_Consent_true_SIVD.lua | 13 +- .../002_Consent_false_SIVD.lua | 11 +- .../003_TIMED_OUT_from_HMI_SIVD.lua | 14 +- .../004_HMI_no_response_SIVD.lua | 12 +- .../005_HMI_invalid_response_SIVD.lua | 14 +- .../GetSystemCapability/001_Success_flow.lua | 8 +- ..._case_appHMIType_is_not_REMOTE_CONTROL.lua | 9 +- ...CE_in_case_RC_interface_is_unavailable.lua | 4 +- .../001_Success_flow.lua | 8 +- .../002_Disallow_flow_by_policy_AUDIO.lua | 7 +- .../003_Disallow_flow_by_policy_LIGHT.lua | 7 +- ...4_Disallow_flow_by_policy_HMI_SETTINGS.lua | 7 +- ...ribing_with_isSubscribe_false_from_HMI.lua | 11 +- ...cribing_with_isSubscribe_true_from_HMI.lua | 13 +- ...bscribing_without_isSubscribe_from_HMI.lua | 13 +- ...bscribing_without_isSubscribe_from_HMI.lua | 11 +- .../009_Success_audio_source_values.lua | 7 +- .../001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua | 13 +- ...002_REJECTED_in_case_nonFULL_HMI_level.lua | 12 +- ...003_Allowed_true_accessMode_AUTO_ALLOW.lua | 11 +- .../004_Allowed_true_accessMode_AUTO_DENY.lua | 12 +- ...005_Allowed_true_accessMode_ASK_DRIVER.lua | 12 +- .../006_Default_accessMode.lua | 13 +- .../001_Success_flow.lua | 4 +- .../002_Disallow_flow_by_policy_CLIMATE.lua | 7 +- .../003_Disallow_flow_by_policy_AUDIO.lua | 7 +- .../004_Disallow_flow_by_policy_LIGHT.lua | 7 +- ...5_Disallow_flow_by_policy_HMI_SETTINGS.lua | 7 +- ...se_moduleType_is_an_empty_array_in_LPT.lua | 7 +- ...ow_in_case_moduleType_is_absent_in_LPT.lua | 7 +- ...cle_data_if_read_only_params_requested.lua | 4 +- .../009_Change_audio_source_in_FULL.lua | 6 +- .../010_Change_audio_source_in_LIMITED.lua | 8 +- .../011_Change_audio_source_in_BACKGROUND.lua | 8 +- ..._audio_source_in_FULL_rc_non_media_app.lua | 4 +- ...ce_from_MOBILE_APP_without_keepContext.lua | 10 +- ...urce_from_MOBILE_APP_keepContext_false.lua | 10 +- ..._from_MOBILE_APP_keepContext_true_FULL.lua | 10 +- ...om_MOBILE_APP_keepContext_true_LIMITED.lua | 12 +- ...ype_except_MOBILE_APP_keepContext_true.lua | 6 +- .../commonRCmodules.lua | 712 ------------------ 58 files changed, 237 insertions(+), 1015 deletions(-) delete mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/001_Success_flow.lua index 324d99b869..0140b7848a 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/001_Success_flow.lua @@ -14,7 +14,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -23,11 +23,11 @@ runner.testSettings.isSelfIncluded = false runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, mod in pairs(common.modules) do +for _, mod in pairs(common.modulesWithoutSeat) do runner.Step("GetInteriorVehicleData " .. mod, common.subscribeToModule, { mod }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua index 30c648ab1f..f125631c87 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua @@ -13,19 +13,24 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local mod = "AUDIO" +--[[ Local Functions ]] local function PTUfunc(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { "CLIMATE" } end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { PTUfunc }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("GetInteriorVehicleData " .. mod, commonRC.rpcDenied, { mod, 1, "GetInteriorVehicleData", "DISALLOWED" }) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua index 95d9065102..d7e993be11 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua @@ -13,6 +13,9 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local mod = "LIGHT" @@ -22,10 +25,11 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { PTUfunc }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("GetInteriorVehicleData " .. mod, commonRC.rpcDenied, { mod, 1, "GetInteriorVehicleData", "DISALLOWED" }) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua index 5e84b4e2f1..637b49af85 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua @@ -13,6 +13,9 @@ local runner = require('user_modules/script_runner') local commonRC = require('test_scripts/RC/commonRC') +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + --[[ Local Variables ]] local mod = "HMI_SETTINGS" @@ -22,10 +25,11 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", commonRC.preconditions) +runner.Step("Clean environment", commonRC.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", commonRC.start) -runner.Step("RAI, PTU", commonRC.rai_ptu, { PTUfunc }) -runner.Step("Activate App", commonRC.activate_app) +runner.Step("RAI", commonRC.registerApp) +runner.Step("PTU", commonRC.policyTableUpdate, { PTUfunc }) +runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("GetInteriorVehicleData " .. mod, commonRC.rpcDenied, { mod, 1, "GetInteriorVehicleData", "DISALLOWED" }) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index aca8d87025..239cc0d5e1 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -30,14 +30,15 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) +runner.Step("Clean environment", common.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("RAI", common.registerApp) +runner.Step("PTU", common.policyTableUpdate, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, mod in pairs(common.modules) do +for _, mod in pairs(common.modulesWithoutSeat) do runner.Step("GetInteriorVehicleData " .. mod, common.rpcDenied, { mod, 1, "GetInteriorVehicleData", "DISALLOWED" }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua index 75decaa4ed..55c6ce2e1a 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua @@ -18,14 +18,11 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false ---[[ Local Variables ]] -local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } - --[[ Local Functions ]] local function invalidParamName(pModuleType) local mobileSession = common.getMobileSession() @@ -79,7 +76,7 @@ local function fakeParam(pModuleType) subscribe = true }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = common.getModuleControlDataForResponse(pModuleType), isSubscribed = true }) @@ -95,12 +92,12 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(common.newModules) do runner.Step("GetInteriorVehicleData " .. mod .. " invalid name of parameter", invalidParamName, { mod }) runner.Step("GetInteriorVehicleData " .. mod .. " invalid type of parameter", invalidParamType, { mod }) runner.Step("GetInteriorVehicleData " .. mod .. " fake parameter", fakeParam, { mod }) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua index 7e974b8e89..ff9a2f734d 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua @@ -15,14 +15,11 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false ---[[ Local Variables ]] -local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } - --[[ Local Functions ]] local function getDataForModule(pModuleType) local mobileSession = common.getMobileSession() @@ -46,12 +43,12 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(common.newModules) do runner.Step("GetInteriorVehicleData " .. mod .. " HMI does not respond", getDataForModule, { mod }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua index 7923c37b93..3e8537e141 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua @@ -17,14 +17,11 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false ---[[ Local Variables ]] -local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } - --[[ Local Functions ]] local function invalidParamType(pModuleType) local mobileSession = common.getMobileSession() @@ -38,7 +35,7 @@ local function invalidParamType(pModuleType) subscribe = true }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = common.getModuleControlData(pModuleType), isSubscribed = "yes" -- invalid type of parameter }) @@ -61,7 +58,7 @@ local function missingMandatoryParam(pModuleType) :Do(function(_, data) local moduleData = common.getModuleControlData(pModuleType) moduleData.moduleType = nil -- missing mandatory parameter - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = moduleData, isSubscribed = true }) @@ -74,12 +71,12 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(common.newModules) do runner.Step("GetInteriorVehicleData " .. mod .. " Invalid response from HMI-Invalid type of parameter", invalidParamType, { mod }) runner.Step("GetInteriorVehicleData " .. mod .. " Invalid response from HMI-Missing mandatory parameter", missingMandatoryParam, { mod }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index f0b8482268..b0f47897e9 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -17,13 +17,12 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local json = require('modules/json') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false local function PTUfunc(tbl) - common.AddOnRCStatusToPT(tbl) local appId = config.application1.registerAppInterfaceParams.appID tbl.policy_table.app_policies[appId] = common.getRCAppConfig() tbl.policy_table.app_policies[appId].moduleType = json.EMPTY_ARRAY @@ -31,13 +30,14 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) +runner.Step("Clean environment", common.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("RAI", common.registerApp) +runner.Step("PTU", common.policyTableUpdate, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, mod in pairs(common.modules) do +for _, mod in pairs(common.modulesWithoutSeat) do runner.Step("GetInteriorVehicleData " .. mod, common.rpcAllowed, { mod, 1, "GetInteriorVehicleData" }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 533450f5cf..e42e08c930 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -16,16 +16,12 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false ---[[ Local Variables ]] -local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } - local function PTUfunc(tbl) - common.AddOnRCStatusToPT(tbl) local appId = config.application1.registerAppInterfaceParams.appID tbl.policy_table.app_policies[appId] = common.getRCAppConfig() tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = nil @@ -33,14 +29,15 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) +runner.Step("Clean environment", common.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("RAI", common.registerApp) +runner.Step("PTU", common.policyTableUpdate, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(common.newModules) do runner.Step("GetInteriorVehicleData " .. mod, common.rpcDenied, { mod, 1, "GetInteriorVehicleData", "DISALLOWED" }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua index 81ab15f0e8..3eb41f00e7 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua @@ -15,14 +15,11 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false ---[[ Local Variables ]] -local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } - --[[ Local Functions ]] local function getDataForModule(module_type) local mobileSession = common.getMobileSession() @@ -36,7 +33,7 @@ local function getDataForModule(module_type) subscribe = true }) :Do(function(_, data) - common.getHMIconnection():SendError(data.id, data.method, "READ_ONLY", "Info message") + common.getHMIConnection():SendError(data.id, data.method, "READ_ONLY", "Info message") end) mobileSession:ExpectResponse(cid, { success = false, resultCode = "GENERIC_ERROR", info = "Info message" }) @@ -46,12 +43,12 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(common.newModules) do runner.Step("GetInteriorVehicleData " .. mod, getDataForModule, { mod }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua index bcc69527ff..0bf3774e18 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua @@ -15,13 +15,12 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } local success_codes = { "WARNINGS" } local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } @@ -38,7 +37,7 @@ local function stepSuccessfull(pModuleType, pResultCode) subscribe = true }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, pResultCode, { + common.getHMIConnection():SendResponse(data.id, data.method, pResultCode, { moduleData = common.getModuleControlDataForResponse(pModuleType), isSubscribed = false }) @@ -62,7 +61,7 @@ local function stepUnsuccessfull(pModuleType, pResultCode) subscribe = true }) :Do(function(_, data) - common.getHMIconnection():SendError(data.id, data.method, pResultCode, "Error error") + common.getHMIConnection():SendError(data.id, data.method, pResultCode, "Error error") end) mobileSession:ExpectResponse(cid, { success = false, resultCode = pResultCode}) @@ -72,18 +71,18 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, mod in pairs(common.modules) do +for _, mod in pairs(common.newModules) do for _, code in pairs(success_codes) do runner.Step("GetInteriorVehicleData " .. mod .. " with " .. code .. " resultCode", stepSuccessfull, { mod, code }) end end -for _, mod in pairs(modules) do +for _, mod in pairs(common.newModules) do for _, code in pairs(error_codes) do runner.Step("GetInteriorVehicleData " .. mod .. " with " .. code .. " resultCode", stepUnsuccessfull, { mod, code }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index 01f18fc30a..3be5a76c40 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -17,13 +17,13 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, isSubscriptionActive) +local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequestCount) local mobileSession = common.getMobileSession() local cid = mobileSession:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType @@ -34,7 +34,7 @@ local function getDataForModule(pModuleType, isSubscriptionActive) moduleType = pModuleType }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = common.getModuleControlDataForResponse(pModuleType), isSubscribed = isSubscriptionActive -- return current value of subscription }) @@ -45,6 +45,7 @@ local function getDataForModule(pModuleType, isSubscriptionActive) end return false, 'Parameter "subscribe" is transfered with to HMI value: ' .. tostring(data.params.subscribe) end) + :Times(pHMIrequestCount) mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = common.getModuleControlDataForResponse(pModuleType) @@ -61,18 +62,18 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, mod in pairs(common.modules) do - runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription", getDataForModule, { mod, false }) +for _, mod in pairs(common.modulesWithoutSeat) do + runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription", getDataForModule, { mod, false, 1 }) end -for _, mod in pairs(common.modules) do +for _, mod in pairs(common.modulesWithoutSeat) do runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) - runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true }) + runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true, 0 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua index ebbcd4367b..fa149f136a 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua @@ -28,7 +28,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -45,7 +45,7 @@ local function subscriptionToModule(pModuleType, pSubscribe, pHMIReqTimes) moduleType = pModuleType }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = common.getModuleControlDataForResponse(pModuleType), isSubscribed = pSubscribe }) @@ -68,12 +68,12 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, mod in pairs(common.modules) do +for _, mod in pairs(common.modulesWithoutSeat) do -- app has not subscribed yet runner.Step("Unsubscribe app to " .. mod, subscriptionToModule, { mod, false, 1 }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", common.isUnsubscribed, diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua index 718c2d64ce..60a11d4617 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua @@ -17,7 +17,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -39,7 +39,7 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pSubscribe, p moduleType = pModuleType }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = common.getModuleControlDataForResponse(pModuleType), -- no isSubscribed parameter }) @@ -65,19 +65,19 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, mod in pairs(common.modules) do +for _, mod in pairs(common.modulesWithoutSeat) do runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription_subscribe", getDataForModule, { mod, false, true, 1 ,true }) runner.Step("GetInteriorVehicleData " .. mod .. " NoSubscription_unsubscribe", getDataForModule, { mod, false, false, 1, true }) end -for _, mod in pairs(common.modules) do +for _, mod in pairs(common.modulesWithoutSeat) do runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true, true, 0 }) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua index 3435adbf72..dabeea2438 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua @@ -17,7 +17,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -97,7 +97,7 @@ local function getDataForModule(pStationLocationParams, isSuccess) moduleType = moduleName }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = radioParams }) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = radioParams }) end) if isSuccess == true then mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = radioParams }) @@ -111,7 +111,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua index 62eb80e567..1dcd91b912 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") local utils = require("user_modules/utils") --[[ Test Configuration ]] @@ -29,12 +29,13 @@ local function subscribeToModule(pAudioSources) local mobSession = common.getMobileSession(1) local hmiResponseParams = common.getHMIResponseParams(rpc, moduleType, subscribe) hmiResponseParams.moduleData.audioControlData.source = pAudioSources + hmiResponseParams.moduleData.audioControlData.keepContext = nil local mobileResponseParams = common.getAppResponseParams(rpc, true, "SUCCESS", moduleType, subscribe) mobileResponseParams.moduleData.audioControlData.source = pAudioSources local cid = mobSession:SendRPC(common.getAppEventName(rpc), common.getAppRequestParams(rpc, moduleType, subscribe)) EXPECT_HMICALL(common.getHMIEventName(rpc), common.getHMIRequestParams(rpc, moduleType, 1, subscribe)) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", hmiResponseParams) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", hmiResponseParams) end) mobSession:ExpectResponse(cid, mobileResponseParams) :ValidIf(function(_,data) @@ -50,7 +51,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua index 0751bc5bf9..bd5f707122 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua @@ -19,7 +19,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -28,20 +28,13 @@ runner.testSettings.isSelfIncluded = false --modules array does not contain "RADIO" because "RADIO" module has read only parameters local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } ---[[ Local Functions ]] -local function PTUfunc(tbl) - common.AddOnRCStatusToPT(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI1, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("RAI1", common.registerAppWOPTU) runner.Step("Activate App1", common.activateApp) -runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("RAI2", common.registerAppWOPTU, { 2 }) runner.Step("Activate App2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua index 9f7f5ad3d6..93a787182f 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua @@ -23,7 +23,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -33,19 +33,14 @@ runner.testSettings.isSelfIncluded = false local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } --[[ Local Functions ]] -local function PTUfunc(tbl) - common.AddOnRCStatusToPT(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() -end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI1, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("RAI1", common.registerAppWOPTU) runner.Step("Activate App1", common.activateApp) -runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("RAI2", common.registerAppWOPTU, { 2 }) runner.Step("Activate App2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua index fd5a6cbd86..c241a4f12c 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua @@ -23,7 +23,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -33,12 +33,6 @@ runner.testSettings.isSelfIncluded = false local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } --[[ Local Functions ]] -local function PTUfunc(tbl) - common.AddOnRCStatusToPT(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() -end - local function rpcTimedOutHMIResponse(pModuleType, pAppId, pRPC) local info = "The resource is in use and the driver did not respond in time" local consentRPC = "GetInteriorVehicleDataConsent" @@ -46,7 +40,7 @@ local function rpcTimedOutHMIResponse(pModuleType, pAppId, pRPC) local cid = mobSession:SendRPC(common.getAppEventName(pRPC), common.getAppRequestParams(pRPC, pModuleType)) EXPECT_HMICALL(common.getHMIEventName(consentRPC), common.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) - common.getHMIconnection():SendError(data.id, data.method, "TIMED_OUT", info) + common.getHMIConnection():SendError(data.id, data.method, "TIMED_OUT", info) EXPECT_HMICALL(common.getHMIEventName(pRPC)):Times(0) end) mobSession:ExpectResponse(cid, { success = false, resultCode = "TIMED_OUT", info = info }) @@ -56,9 +50,9 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI1, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("RAI1", common.registerAppWOPTU) runner.Step("Activate App1", common.activateApp) -runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("RAI2", common.registerAppWOPTU, { 2 }) runner.Step("Activate App2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/004_HMI_no_response_SIVD.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/004_HMI_no_response_SIVD.lua index 163c0b43db..0512f13571 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/004_HMI_no_response_SIVD.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/004_HMI_no_response_SIVD.lua @@ -21,7 +21,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -31,12 +31,6 @@ runner.testSettings.isSelfIncluded = false local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } --[[ Local Functions ]] -local function PTUfunc(tbl) - common.AddOnRCStatusToPT(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() -end - local function rpcNoHMIResponse(pModuleType, pAppId, pRPC) local consentRPC = "GetInteriorVehicleDataConsent" local mobSession = common.getMobileSession(pAppId) @@ -53,9 +47,9 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI1, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("RAI1", common.registerAppWOPTU) runner.Step("Activate App1", common.activateApp) -runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("RAI2", common.registerAppWOPTU, { 2 }) runner.Step("Activate App2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/005_HMI_invalid_response_SIVD.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/005_HMI_invalid_response_SIVD.lua index 9172322770..1dd71c7182 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/005_HMI_invalid_response_SIVD.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/005_HMI_invalid_response_SIVD.lua @@ -21,7 +21,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -31,19 +31,13 @@ runner.testSettings.isSelfIncluded = false local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } --[[ Local Functions ]] -local function PTUfunc(tbl) - common.AddOnRCStatusToPT(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() -end - local function rpcInvalidHMIResponse(pModuleType, pAppId, pRPC) local consentRPC = "GetInteriorVehicleDataConsent" local mobSession = common.getMobileSession(pAppId) local cid = mobSession:SendRPC(common.getAppEventName(pRPC), common.getAppRequestParams(pRPC, pModuleType)) EXPECT_HMICALL(common.getHMIEventName(consentRPC), common.getHMIRequestParams(consentRPC, pModuleType, pAppId)) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { allowed = "aaa" -- invalid type of parameter }) EXPECT_HMICALL(common.getHMIEventName(pRPC)):Times(0) @@ -55,9 +49,9 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI1, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("RAI1", common.registerAppWOPTU) runner.Step("Activate App1", common.activateApp) -runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("RAI2", common.registerAppWOPTU, { 2 }) runner.Step("Activate App2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/001_Success_flow.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/001_Success_flow.lua index 15570f87d5..0d33f2388b 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/001_Success_flow.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/001_Success_flow.lua @@ -15,14 +15,14 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] local capParams = {} -for _, v in pairs(common.modules) do capParams[v] = common.DEFAULT end -- HMI has all posible RC capabilities +for _, v in pairs(common.modulesWithoutSeat) do capParams[v] = common.DEFAULT end -- HMI has all posible RC capabilities local hmiRcCapabilities = common.buildHmiRcCapabilities(capParams) --[[ Local Functions ]] @@ -48,10 +48,10 @@ end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Backup HMI capabilities file", common.backupHMICapabilities) -runner.Step("Update HMI capabilities file", common.updateDefaultCapabilities, { common.modules }) +runner.Step("Update HMI capabilities file", common.updateDefaultCapabilities, { common.modulesWithoutSeat }) runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { hmiRcCapabilities }) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua index 719ae038f9..a63eb70838 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -24,7 +24,7 @@ runner.testSettings.isSelfIncluded = false config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } --[[ Local Functions ]] -local function ptUpdateFunc(pTbl) +local function PTUfunc(pTbl) local appId = config.application1.registerAppInterfaceParams.appID pTbl.policy_table.app_policies[appId].AppHMIType = { "DEFAULT" } end @@ -36,9 +36,10 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) +runner.Step("Clean environment", common.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn, { ptUpdateFunc }) +runner.Step("RAI", common.registerApp) +runner.Step("PTU", common.policyTableUpdate, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/003_UNSUPPORTED_RESOURCE_in_case_RC_interface_is_unavailable.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/003_UNSUPPORTED_RESOURCE_in_case_RC_interface_is_unavailable.lua index 48fac27d27..21c9239096 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/003_UNSUPPORTED_RESOURCE_in_case_RC_interface_is_unavailable.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/003_UNSUPPORTED_RESOURCE_in_case_RC_interface_is_unavailable.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") local hmi_values = require('user_modules/hmi_values') --[[ Test Configuration ]] @@ -49,7 +49,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { getHMIParams() }) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/001_Success_flow.lua index d7caa7dbb1..a966c6f780 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/001_Success_flow.lua @@ -35,7 +35,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -44,17 +44,17 @@ runner.testSettings.isSelfIncluded = false runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, mod in pairs(common.modules) do +for _, mod in pairs(common.modulesWithoutSeat) do runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", common.isSubscribed, { mod }) end -for _, mod in pairs(common.modules) do +for _, mod in pairs(common.modulesWithoutSeat) do runner.Step("Unsubscribe app to " .. mod, common.unSubscribeToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is unsubscribed", common.isUnsubscribed, { mod }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua index 2eb4921573..af75efecb2 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua @@ -17,7 +17,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -32,9 +32,10 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) +runner.Step("Clean environment", common.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("RAI", common.registerApp) +runner.Step("PTU", common.policyTableUpdate, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua index e88dd60fb1..70f47cce02 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua @@ -17,7 +17,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -32,9 +32,10 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) +runner.Step("Clean environment", common.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("RAI", common.registerApp) +runner.Step("PTU", common.policyTableUpdate, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua index 6ef489705b..ece93b14b0 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua @@ -17,7 +17,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -32,9 +32,10 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) +runner.Step("Clean environment", common.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("RAI", common.registerApp) +runner.Step("PTU", common.policyTableUpdate, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua index 5c293fe8c4..e83b96b55e 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -17,14 +17,11 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false ---[[ Local Variables ]] -local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } - --[[ Local Functions ]] local function subscriptionToModule(pModuleType) local mobileSession = common.getMobileSession() @@ -38,7 +35,7 @@ local function subscriptionToModule(pModuleType) subscribe = true }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = common.getModuleControlDataForResponse(pModuleType), isSubscribed = false -- not subscribe }) @@ -54,12 +51,12 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(common.newModules) do runner.Step("Subscribe app to " .. mod, subscriptionToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is not subscribed", common.isUnsubscribed, { mod }) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua index 704b8c979f..aafda9374c 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua @@ -18,14 +18,11 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false ---[[ Local Variables ]] -local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } - --[[ Local Functions ]] local function unSubscriptionToModule(pModuleType) local mobileSession = common.getMobileSession() @@ -39,7 +36,7 @@ local function unSubscriptionToModule(pModuleType) subscribe = false }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = common.getModuleControlDataForResponse(pModuleType), isSubscribed = true -- HMI responds with true }) @@ -55,17 +52,17 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) -for _, mod in pairs(modules) do +for _, mod in pairs(common.newModules) do runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", common.isSubscribed, { mod }) end runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(common.newModules) do runner.Step("Subscribe app to " .. mod, unSubscriptionToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App still subscribed", common.isSubscribed, { mod }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua index f78812383a..c9f7706de3 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -18,14 +18,11 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false ---[[ Local Variables ]] -local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } - --[[ Local Functions ]] local function unSubscriptionToModule(pModuleType) local mobileSession = common.getMobileSession() @@ -39,7 +36,7 @@ local function unSubscriptionToModule(pModuleType) subscribe = false }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = common.getModuleControlDataForResponse(pModuleType), -- no isSubscribed parameter }) @@ -55,17 +52,17 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) -for _, mod in pairs(modules) do +for _, mod in pairs(common.newModules) do runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App is subscribed", common.isSubscribed, { mod }) end runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(common.newModules) do runner.Step("Subscribe app to " .. mod, unSubscriptionToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App still subscribed", common.isSubscribed, { mod }) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua index eec824c480..824ab2ba24 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua @@ -19,13 +19,12 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local modules = { "AUDIO", "LIGHT", "HMI_SETTINGS" } local error_codes = { "GENERIC_ERROR", "INVALID_DATA", "OUT_OF_MEMORY", "REJECTED" } --[[ Local Functions ]] @@ -41,7 +40,7 @@ local function unSubscriptionToModule(pModuleType, pResultCode) subscribe = false }) :Do(function(_, data) - common.getHMIconnection():SendError(data.id, data.method, pResultCode, "Error error") + common.getHMIConnection():SendError(data.id, data.method, pResultCode, "Error error") -- no isSubscribed parameter end) @@ -58,17 +57,17 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) -for _, mod in pairs(modules) do +for _, mod in pairs(common.newModules) do runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App subscribed", common.isSubscribed, { mod }) end runner.Title("Test") -for _, mod in pairs(modules) do +for _, mod in pairs(common.newModules) do for _, err in pairs(error_codes) do runner.Step("Unsubscribe app to " .. mod .. " (" .. err .. " from HMI)", unSubscriptionToModule, { mod, err }) runner.Step("Send notification OnInteriorVehicleData " .. mod .. ". App still subscribed", common.isSubscribed, diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua index 51d44aacd3..16267241f9 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua @@ -14,7 +14,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -28,7 +28,8 @@ local function isSubscribed(pAudioSources) hmiParams.moduleData.audioControlData.source = pAudioSources local mobileParams = common.getAppResponseParams(rpc, moduleType) mobileParams.moduleData.audioControlData.source = pAudioSources - common.getHMIconnection():SendNotification(common.getHMIEventName(rpc), hmiParams) + mobileParams.moduleData.audioControlData.keepContext = nil + common.getHMIConnection():SendNotification(common.getHMIEventName(rpc), hmiParams) mobSession:ExpectNotification(common.getAppEventName(rpc), mobileParams) :ValidIf(function(_,data) if nil ~= data.payload.moduleData.audioControlData.keepContext then @@ -42,7 +43,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Step("Subscribe app to AUDIO", common.subscribeToModule, { "AUDIO" }) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua index 57bedf68d7..436496739f 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua @@ -18,7 +18,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -28,19 +28,12 @@ runner.testSettings.isSelfIncluded = false local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } local access_modes = { nil, "AUTO_ALLOW" } ---[[ Local Functions ]] -local function ptu_update_func(tbl) - common.AddOnRCStatusToPT(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) -runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("RAI1", common.registerAppWOPTU) +runner.Step("RAI2", common.registerAppWOPTU, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua index 43a66a26dd..1ae9d86958 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua @@ -20,7 +20,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -29,19 +29,13 @@ runner.testSettings.isSelfIncluded = false local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } local access_modes = { nil, "AUTO_ALLOW", "AUTO_DENY", "ASK_DRIVER" } ---[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) +runner.Step("RAI1", common.registerAppWOPTU) runner.Step("Activate App1", common.activateApp) -runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("RAI2", common.registerAppWOPTU, { 2 }) runner.Step("Activate App2", common.activateApp, { 2 }) -- App's HMI levels: 1 - BACKGROUND, 2 - FULL diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua index 9c65480feb..c94a630728 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua @@ -18,7 +18,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -27,11 +27,6 @@ runner.testSettings.isSelfIncluded = false local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } --[[ Local Functions ]] -local function ptu_update_func(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() -end - local function disableRcFromHmi() common.defineRAMode(false, nil) end @@ -40,8 +35,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) -runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("RAI1", common.registerAppWOPTU) +runner.Step("RAI2", common.registerAppWOPTU, { 2 }) runner.Step("Disable RC from HMI", disableRcFromHmi) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/004_Allowed_true_accessMode_AUTO_DENY.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/004_Allowed_true_accessMode_AUTO_DENY.lua index 95f253c0a8..6fc4cfb518 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/004_Allowed_true_accessMode_AUTO_DENY.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/004_Allowed_true_accessMode_AUTO_DENY.lua @@ -18,7 +18,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -28,12 +28,6 @@ runner.testSettings.isSelfIncluded = false local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } --[[ Local Functions ]] -local function ptu_update_func(tbl) - common.AddOnRCStatusToPT(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() -end - local function disableRcFromHmi(self) common.defineRAMode(false, nil, self) end @@ -42,8 +36,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) -runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("RAI1", common.registerAppWOPTU) +runner.Step("RAI2", common.registerAppWOPTU, { 2 }) runner.Step("Disable RC from HMI", disableRcFromHmi) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/005_Allowed_true_accessMode_ASK_DRIVER.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/005_Allowed_true_accessMode_ASK_DRIVER.lua index 6dc084f042..6c7909d655 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/005_Allowed_true_accessMode_ASK_DRIVER.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/005_Allowed_true_accessMode_ASK_DRIVER.lua @@ -18,7 +18,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -28,12 +28,6 @@ runner.testSettings.isSelfIncluded = false local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } --[[ Local Functions ]] -local function ptu_update_func(tbl) - common.AddOnRCStatusToPT(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() -end - local function disableRcFromHmi(self) common.defineRAMode(false, nil, self) end @@ -42,8 +36,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) -runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("RAI1", common.registerAppWOPTU) +runner.Step("RAI2", common.registerAppWOPTU, { 2 }) runner.Step("Disable RC from HMI", disableRcFromHmi) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/006_Default_accessMode.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/006_Default_accessMode.lua index 6387d63b7e..9ec2705974 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/006_Default_accessMode.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/006_Default_accessMode.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -25,19 +25,12 @@ runner.testSettings.isSelfIncluded = false --modules array does not contain "RADIO" because "RADIO" module has read only parameters local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } ---[[ Local Functions ]] -local function ptu_update_func(tbl) - common.AddOnRCStatusToPT(tbl) - tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID] = common.getRCAppConfig() - tbl.policy_table.app_policies[config.application2.registerAppInterfaceParams.appID] = common.getRCAppConfig() -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI1, PTU", common.raiPTUn, { ptu_update_func }) -runner.Step("RAI2", common.raiN, { 2 }) +runner.Step("RAI1", common.registerAppWOPTU) +runner.Step("RAI2", common.registerAppWOPTU, { 2 }) runner.Title("Test") for _, mod in pairs(modules) do diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/001_Success_flow.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/001_Success_flow.lua index ff43ad2714..77b09ca3b7 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/001_Success_flow.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/001_Success_flow.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -29,7 +29,7 @@ local modules = { "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua index d2fccf2c44..f2a430f277 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -33,9 +33,10 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) +runner.Step("Clean environment", common.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("RAI", common.registerApp) +runner.Step("PTU", common.policyTableUpdate, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua index 4b252fc5a1..f135feb914 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -33,9 +33,10 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) +runner.Step("Clean environment", common.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("RAI", common.registerApp) +runner.Step("PTU", common.policyTableUpdate, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua index 71bc5c0a7f..06eb6cf4c8 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -33,9 +33,10 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) +runner.Step("Clean environment", common.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("RAI", common.registerApp) +runner.Step("PTU", common.policyTableUpdate, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua index 08b9b014fd..e5f6a7f8ac 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -33,9 +33,10 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) +runner.Step("Clean environment", common.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("RAI", common.registerApp) +runner.Step("PTU", common.policyTableUpdate, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua index 149fa6aa4c..54a40c27ea 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua @@ -17,7 +17,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local json = require('modules/json') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -34,9 +34,10 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) +runner.Step("Clean environment", common.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("RAI", common.registerApp) +runner.Step("PTU", common.policyTableUpdate, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua index 2aee29a21b..7e6e341235 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -31,9 +31,10 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) +runner.Step("Clean environment", common.preconditions, { false }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn, { PTUfunc }) +runner.Step("RAI", common.registerApp) +runner.Step("PTU", common.policyTableUpdate, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/008_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/008_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua index 21831a0a1a..7f5cf20e0c 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/008_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/008_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua @@ -14,7 +14,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -35,7 +35,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test: SDL respond with READ_ONLY if SetInteriorVehicleData is sent with read_only params") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua index 744f56c4a2..2745215717 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -38,7 +38,7 @@ local function setVehicleData(pSource) moduleData = audioData }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = audioData }) end) @@ -50,7 +50,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua index e45271edb0..f79524108f 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -38,7 +38,7 @@ local function setVehicleData(pSource) moduleData = audioData }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = audioData }) end) @@ -47,7 +47,7 @@ local function setVehicleData(pSource) end local function bringAppToLIMITED() - common.getHMIconnection():SendNotification("BasicCommunication.OnAppDeactivated", { + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { appID = common.getHMIAppId(), reason = "GENERAL" }) @@ -59,7 +59,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Step("Set App to LIMITED HMI level", bringAppToLIMITED) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua index e10ad08462..ff02f3e6ca 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -34,7 +34,7 @@ local function setVehicleData(pSource) EXPECT_HMICALL("RC.SetInteriorVehicleData", { appID = common.getHMIAppId(), moduleData = audioData }) :Do(function(_, data) - common.getHMIconnection():SendError(data.id, data.method, "REJECTED", "Error") + common.getHMIConnection():SendError(data.id, data.method, "REJECTED", "Error") end) common.getMobileSession():ExpectResponse(cid, { success = false, resultCode = "REJECTED", info = "Error" }) @@ -50,8 +50,8 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU App1", common.raiPTUn) -runner.Step("RAI App2", common.raiN, {2}) +runner.Step("RAI App1", common.registerAppWOPTU) +runner.Step("RAI App2", common.registerAppWOPTU, {2}) runner.Step("Activate App1", common.activateApp) runner.Step("Set App1 to BACKGROUND HMI level", BringAppToBACKGROUND) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua index 751921cb50..6d57b3cb32 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -44,7 +44,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_without_keepContext.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_without_keepContext.lua index 4d1c5d8d74..ab45502a24 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_without_keepContext.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_without_keepContext.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -39,7 +39,7 @@ local function setVehicleDataMobileApp() moduleData = audioData }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = audioData }) end) @@ -58,10 +58,10 @@ local function setVehicleData() moduleData = audioData }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = audioData }) - common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { eventName = "AUDIO_SOURCE", isActive = true }) @@ -75,7 +75,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_false.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_false.lua index b5942647c3..80ca6e6d28 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_false.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_false.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -39,7 +39,7 @@ local function setVehicleDataMobileApp() moduleData = audioData }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = audioData }) end) @@ -58,10 +58,10 @@ local function setVehicleData() moduleData = audioData }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = audioData }) - common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { eventName = "AUDIO_SOURCE", isActive = true }) @@ -75,7 +75,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua index f4f5afd6d0..b2eb65aef0 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -39,7 +39,7 @@ local function setVehicleDataMobileApp() moduleData = audioData }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = audioData }) end) @@ -58,10 +58,10 @@ local function setVehicleData() moduleData = audioData }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = audioData }) - common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { eventName = "AUDIO_SOURCE", isActive = true }) @@ -75,7 +75,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua index e7b1e7728b..1e3abb62d8 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -39,7 +39,7 @@ local function setVehicleDataMobileApp() moduleData = audioData }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = audioData }) end) @@ -58,10 +58,10 @@ local function setVehicleData() moduleData = audioData }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = audioData }) - common.getHMIconnection():SendNotification("BasicCommunication.OnEventChanged", { + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { eventName = "AUDIO_SOURCE", isActive = true }) @@ -72,7 +72,7 @@ local function setVehicleData() end local function bringAppToLIMITED() - common.getHMIconnection():SendNotification("BasicCommunication.OnAppDeactivated", { + common.getHMIConnection():SendNotification("BasicCommunication.OnAppDeactivated", { appID = common.getHMIAppId(), reason = "GENERAL" }) @@ -84,7 +84,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Step("Set App to LIMITED HMI level", bringAppToLIMITED) runner.Step("SetInteriorVehicleData source MOBILE_APP", setVehicleDataMobileApp) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua index 4006803660..af415edf44 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules') +local common = require("test_scripts/RC/commonRC") --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -63,7 +63,7 @@ local function setVehicleData(pSource,pKeepContext) moduleData = audioData }) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", { + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { moduleData = audioData }) end) @@ -76,7 +76,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua deleted file mode 100644 index 58952e11f1..0000000000 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/commonRCmodules.lua +++ /dev/null @@ -1,712 +0,0 @@ ---------------------------------------------------------------------------------------------------- --- RC common module for AUDIO, LIGHT, HMI_SETTINGS modules ---------------------------------------------------------------------------------------------------- -config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } -config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } -config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 -config.application2.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 - ---[[ Required Shared libraries ]] -local commonRC = require("test_scripts/RC/commonRC") -local test = require("user_modules/dummy_connecttest") -local hmi_values = require("user_modules/hmi_values") -local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') -local utils = require("user_modules/utils") - ---[[ Local Variables ]] -local c = {} -c.modules = { "RADIO", "CLIMATE", "AUDIO", "LIGHT", "HMI_SETTINGS" } -c.capMap = { - ["RADIO"] = "radioControlCapabilities", - ["CLIMATE"] = "climateControlCapabilities", - ["AUDIO"] = "audioControlCapabilities", - ["LIGHT"] = "lightControlCapabilities", - ["HMI_SETTINGS"] = "hmiSettingsControlCapabilities" -} - -c.audioSources = { - "NO_SOURCE_SELECTED", - "CD", - "BLUETOOTH_STEREO_BTST", - "USB", - "USB2", - "LINE_IN", - "IPOD", - "MOBILE_APP", - "AM", - "FM", - "XM", - "DAB" -} - -c.backupHMICapabilities = commonRC.backupHMICapabilities -c.restoreHMICapabilities = commonRC.restoreHMICapabilities -c.DEFAULT = commonRC.DEFAULT - -function c.preconditions() - commonRC.preconditions() -end - -function c.start(pHMIParams) - commonRC.start(pHMIParams, test) -end - -local function audibleState(pAppId) - if not pAppId then pAppId = 1 end - local appParams = config["application" .. pAppId].registerAppInterfaceParams - local audibleState - if appParams.isMediaApplication == true then - audibleState = "AUDIBLE" - else - audibleState = "NOT_AUDIBLE" - end - return audibleState -end - -function c.AddOnRCStatusToPT(tbl) - tbl.policy_table.functional_groupings.RemoteControl.rpcs.OnRCStatus = { - hmi_levels = { "NONE", "BACKGROUND", "FULL", "LIMITED" } - } -end - -function c.getRCAppConfig() - local struct = commonRC.getRCAppConfig() - struct.moduleType = c.modules - return struct -end - -local function PTUfunc(tbl) - c.AddOnRCStatusToPT(tbl) - local appId = config.application1.registerAppInterfaceParams.appID - tbl.policy_table.app_policies[appId] = c.getRCAppConfig() -end - -function c.raiPTUn(pPTUfunc, pAppId) - if not pAppId then pAppId = 1 end - if not pPTUfunc then - pPTUfunc = PTUfunc - end - commonRC.rai_ptu_n(pAppId, pPTUfunc, test) -end - -function c.raiN(pAppId) - commonRC.rai_n(pAppId, test) -end - -function c.getHMIAppId(pAppId) - local appId = commonRC.getHMIAppId(pAppId) - return appId -end - -function c.getModuleControlData(pModuleType) - local struct = {} - if "CLIMATE" == pModuleType then - struct.moduleType = "CLIMATE" - struct.climateControlData = {} - struct.climateControlData.heatedSteeringWheelEnable = true - struct.climateControlData.heatedWindshieldEnable = true - struct.climateControlData.heatedRearWindowEnable = true - struct.climateControlData.heatedMirrorsEnable = true - elseif "RADIO" == pModuleType then - struct.moduleType = "RADIO" - struct.radioControlData = {} - struct.radioControlData.sisData = { - stationShortName = "Name1", - stationIDNumber = { - countryCode = 100, - fccFacilityId = 100 - }, - stationLongName = "RadioStationLongName", - stationLocation = { - longitudeDegrees = 0.1, - latitudeDegrees = 0.1, - altitude = 0.1 - }, - stationMessage = "station message" - } - elseif "AUDIO" == pModuleType then - struct.moduleType = "AUDIO" - struct.audioControlData = { - source = "AM", - keepContext = false, - volume = 50, - equalizerSettings = { - { - channelId = 10, - channelName = "Channel 1", - channelSetting = 50 - } - } - } - elseif "LIGHT" == pModuleType then - struct.moduleType = "LIGHT" - struct.lightControlData = { - lightState = { - { - id = "FRONT_LEFT_HIGH_BEAM", - status = "ON", - density = 0.2, - color = { - red = 50, - green = 150, - blue = 200 - } - } - } - } - elseif "HMI_SETTINGS" == pModuleType then - struct.moduleType = "HMI_SETTINGS" - struct.hmiSettingsControlData = { - displayMode = "DAY", - temperatureUnit = "CELSIUS", - distanceUnit = "KILOMETERS" - } - end - return struct -end - -function c.getAnotherModuleControlData(pModuleType) - local struct = {} - if "CLIMATE" == pModuleType then - struct.moduleType = "CLIMATE" - struct.climateControlData = {} - struct.climateControlData.heatedSteeringWheelEnable = false - struct.climateControlData.heatedWindshieldEnable = false - struct.climateControlData.heatedRearWindowEnable = false - struct.climateControlData.heatedMirrorsEnable = false - elseif "RADIO" == pModuleType then - struct.moduleType = "RADIO" - struct.radioControlData = {} - struct.radioControlData.sisData = { - stationShortName = "Name2", - stationIDNumber = { - countryCode = 200, - fccFacilityId = 200 - }, - stationLongName = "RadioStationLongName2", - stationLocation = { - longitudeDegrees = 20.1, - latitudeDegrees = 20.1, - altitude = 20.1 - }, - stationMessage = "station message 2" - } - elseif "AUDIO" == pModuleType then - struct.moduleType = "AUDIO" - struct.audioControlData = { - source = "USB", - keepContext = true, - volume = 20, - equalizerSettings = { - { - channelId = 20, - channelName = "Channel 2", - channelSetting = 20 - } - } - } - elseif "LIGHT" == pModuleType then - struct.moduleType = "LIGHT" - struct.lightControlData = { - lightState = { - { - id = "READING_LIGHTS", - status = "ON", - density = 0.5, - color = { - red = 150, - green = 200, - blue = 250 - } - } - } - } - elseif "HMI_SETTINGS" == pModuleType then - struct.moduleType = "HMI_SETTINGS" - struct.hmiSettingsControlData = { - displayMode = "NIGHT", - temperatureUnit = "FAHRENHEIT", - distanceUnit = "MILES" - } - end - return struct -end - -function c.getModuleParams(pModuleData) - if pModuleData.moduleType == "RADIO" then - if not pModuleData.radioControlData then - pModuleData.radioControlData = { } - end - return pModuleData.radioControlData - elseif pModuleData.moduleType == "AUDIO" then - if not pModuleData.audioControlData then - pModuleData.audioControlData = { } - end - return pModuleData.audioControlData - end -end - -function c.getReadOnlyParamsByModule(pModuleType) - local out = { moduleType = pModuleType } - if pModuleType == "RADIO" then - out.radioControlData = { - sisData = { - stationShortName = "Name2", - stationIDNumber = { - countryCode = 200, - fccFacilityId = 200 - }, - stationLongName = "RadioStationLongName2", - stationLocation = { - longitudeDegrees = 20.1, - latitudeDegrees = 20.1, - altitude = 20.1 - }, - stationMessage = "station message 2" - } - } - elseif pModuleType == "AUDIO" then - out.audioControlData = { - equalizerSettings = { { channelName = "Channel 1" } } - } - end - return out -end - -function c.getSettableModuleControlData(pModuleType) - local out = c.getModuleControlData(pModuleType) - local params_read_only = c.getModuleParams(c.getReadOnlyParamsByModule(pModuleType)) - if params_read_only then - for p_read_only, p_read_only_value in pairs(params_read_only) do - if pModuleType == "AUDIO" then - for sub_read_only_key, sub_read_only_value in pairs(p_read_only_value) do - for sub_read_only_name in pairs(sub_read_only_value) do - c.getModuleParams(out)[p_read_only][sub_read_only_key][sub_read_only_name] = nil - end - end - else - c.getModuleParams(out)[p_read_only] = nil - end - end - end - return out -end - --- RC RPCs structure -local rcRPCs = { - GetInteriorVehicleData = { - appEventName = "GetInteriorVehicleData", - hmiEventName = "RC.GetInteriorVehicleData", - requestParams = function(pModuleType, pSubscribe) - return { - moduleType = pModuleType, - subscribe = pSubscribe - } - end, - hmiRequestParams = function(pModuleType, _, pSubscribe) - return { - moduleType = pModuleType, - subscribe = pSubscribe - } - end, - hmiResponseParams = function(pModuleType, pSubscribe) - local GetInteriorVDModuleData = commonRC.actualInteriorDataStateOnHMI[pModuleType] - if GetInteriorVDModuleData.audioControlData then - GetInteriorVDModuleData.audioControlData.keepContext = nil - end - return { - moduleData = GetInteriorVDModuleData, - isSubscribed = pSubscribe - } - end, - responseParams = function(success, resultCode, pModuleType, pSubscribe) - local GetInteriorVDModuleData = commonRC.actualInteriorDataStateOnHMI[pModuleType] - if GetInteriorVDModuleData.audioControlData then - GetInteriorVDModuleData.audioControlData.keepContext = nil - end - return { - success = success, - resultCode = resultCode, - moduleData = GetInteriorVDModuleData, - isSubscribed = pSubscribe - } - end - }, - SetInteriorVehicleData = { - appEventName = "SetInteriorVehicleData", - hmiEventName = "RC.SetInteriorVehicleData", - requestParams = function(pModuleType) - return { - moduleData = c.getSettableModuleControlData(pModuleType) - } - end, - hmiRequestParams = function(pModuleType, pAppId) - return { - appID = c.getHMIAppId(pAppId), - moduleData = c.getSettableModuleControlData(pModuleType) - } - end, - hmiResponseParams = function(pModuleType) - return { - moduleData = c.getSettableModuleControlData(pModuleType) - } - end, - responseParams = function(success, resultCode, pModuleType) - return { - success = success, - resultCode = resultCode, - moduleData = c.getSettableModuleControlData(pModuleType) - } - end - }, - ButtonPress = { - appEventName = "ButtonPress", - hmiEventName = "Buttons.ButtonPress", - requestParams = function(pModuleType) - return { - moduleType = pModuleType, - buttonName = c.getButtonNameByModule(pModuleType), - buttonPressMode = "SHORT" - } - end, - hmiRequestParams = function(pModuleType, pAppId) - return { - appID = c.getHMIAppId(pAppId), - moduleType = pModuleType, - buttonName = c.getButtonNameByModule(pModuleType), - buttonPressMode = "SHORT" - } - end, - hmiResponseParams = function() - return {} - end, - responseParams = function(success, resultCode) - return { - success = success, - resultCode = resultCode - } - end - }, - GetInteriorVehicleDataConsent = { - hmiEventName = "RC.GetInteriorVehicleDataConsent", - hmiRequestParams = function(pModuleType, pAppId) - return { - appID = c.getHMIAppId(pAppId), - moduleType = pModuleType - } - end, - hmiResponseParams = function(pAllowed) - return { - allowed = pAllowed - } - end, - }, - OnInteriorVehicleData = { - appEventName = "OnInteriorVehicleData", - hmiEventName = "RC.OnInteriorVehicleData", - hmiResponseParams = function(pModuleType) - local OnInteriorVDModuleData = c.getAnotherModuleControlData(pModuleType) - if OnInteriorVDModuleData.audioControlData then - OnInteriorVDModuleData.audioControlData.keepContext = nil - end - return { - moduleData = OnInteriorVDModuleData - } - end, - responseParams = function(pModuleType) - local OnInteriorVDModuleData = c.getAnotherModuleControlData(pModuleType) - if OnInteriorVDModuleData.audioControlData then - OnInteriorVDModuleData.audioControlData.keepContext = nil - end - return { - moduleData = OnInteriorVDModuleData - } - end - }, - OnRemoteControlSettings = { - hmiEventName = "RC.OnRemoteControlSettings", - hmiResponseParams = function(pAllowed, pAccessMode) - return { - allowed = pAllowed, - accessMode = pAccessMode - } - end - } -} - -function c.getAppEventName(pRPC) - return rcRPCs[pRPC].appEventName -end - -function c.getHMIEventName(pRPC) - return rcRPCs[pRPC].hmiEventName -end - -function c.getAppRequestParams(pRPC, ...) - return rcRPCs[pRPC].requestParams(...) -end - -function c.getAppResponseParams(pRPC, ...) - return rcRPCs[pRPC].responseParams(...) -end - -function c.getHMIRequestParams(pRPC, ...) - return rcRPCs[pRPC].hmiRequestParams(...) -end - -function c.getHMIResponseParams(pRPC, ...) - return rcRPCs[pRPC].hmiResponseParams(...) -end - -function c.getMobileSession(pAppId) - if not pAppId then pAppId = 1 end - return test["mobileSession" .. pAppId] -end - -function c.getHMIconnection() - return test.hmiConnection -end - -function c.subscribeToModule(pModuleType, pAppId) - if not pAppId then pAppId = 1 end - local rpc = "GetInteriorVehicleData" - local subscribe = true - local mobSession = c.getMobileSession(pAppId) - local cid = mobSession:SendRPC(c.getAppEventName(rpc), c.getAppRequestParams(rpc, pModuleType, subscribe)) - EXPECT_HMICALL(c.getHMIEventName(rpc), c.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe)) - :Do(function(_, data) - test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", - c.getHMIResponseParams(rpc, pModuleType, subscribe)) - commonRC.setActualInteriorVD(pModuleType, c.getHMIResponseParams(rpc, pModuleType, subscribe).moduleData) - end) - :Times(AtMost(1)) - mobSession:ExpectResponse(cid, c.getAppResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) - :ValidIf(function(_,data) - if "AUDIO" == pModuleType and - nil ~= data.payload.moduleData.audioControlData.keepContext then - return false, "Mobile response GetInteriorVehicleData contains unexpected keepContext parameter" - end - return true - end) -end - -function c.unSubscribeToModule(pModuleType, pAppId) - local rpc = "GetInteriorVehicleData" - local subscribe = false - local mobSession = c.getMobileSession(pAppId) - local cid = mobSession:SendRPC(c.getAppEventName(rpc), c.getAppRequestParams(rpc, pModuleType, subscribe)) - EXPECT_HMICALL(c.getHMIEventName(rpc), c.getHMIRequestParams(rpc, pModuleType, pAppId, subscribe)) - :Do(function(_, data) - test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", - c.getHMIResponseParams(rpc, pModuleType, subscribe)) - commonRC.setActualInteriorVD(pModuleType, c.getHMIResponseParams(rpc, pModuleType, subscribe).moduleData) - end) - :Times(AtMost(1)) - mobSession:ExpectResponse(cid, c.getAppResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) - :ValidIf(function(_,data) - if "AUDIO" == pModuleType and - nil ~= data.payload.moduleData.audioControlData.keepContext then - return false, "Mobile response GetInteriorVehicleData contains unexpected keepContext parameter" - end - return true - end) -end - -function c.activateApp(pAppId) - if not pAppId then pAppId = 1 end - local pHMIAppId = c.getHMIAppId(pAppId) - local mobSession = c.getMobileSession(pAppId) - local requestId = test.hmiConnection:SendRequest("SDL.ActivateApp", { appID = pHMIAppId }) - EXPECT_HMIRESPONSE(requestId) - mobSession:ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = audibleState(), - systemContext = "MAIN" }) -end - -function c.defineRAMode(pAllowed, pAccessMode) - commonRC.defineRAMode(pAllowed, pAccessMode, test) -end - -function c.rpcAllowed(pModuleType, pAppId, pRPC) - local mobSession = c.getMobileSession(pAppId) - local cid = mobSession:SendRPC(c.getAppEventName(pRPC), c.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(c.getHMIEventName(pRPC), c.getHMIRequestParams(pRPC, pModuleType, pAppId)) - :Do(function(_, data) - test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", c.getHMIResponseParams(pRPC, pModuleType)) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - -function c.rpcAllowedWithConsent(pModuleType, pAppId, pRPC) - local mobSession = c.getMobileSession(pAppId) - local cid = mobSession:SendRPC(c.getAppEventName(pRPC), c.getAppRequestParams(pRPC, pModuleType)) - local consentRPC = "GetInteriorVehicleDataConsent" - EXPECT_HMICALL(c.getHMIEventName(consentRPC), c.getHMIRequestParams(consentRPC, pModuleType, pAppId)) - :Do(function(_, data) - test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", c.getHMIResponseParams(consentRPC, true)) - EXPECT_HMICALL(c.getHMIEventName(pRPC), c.getHMIRequestParams(pRPC, pModuleType, pAppId)) - :Do(function(_, data2) - test.hmiConnection:SendResponse(data2.id, data2.method, "SUCCESS", c.getHMIResponseParams(pRPC, pModuleType)) - end) - end) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) -end - -function c.isSubscribed(pModuleType, pAppId) - local mobSession = c.getMobileSession(pAppId) - local rpc = "OnInteriorVehicleData" - test.hmiConnection:SendNotification(c.getHMIEventName(rpc), c.getHMIResponseParams(rpc, pModuleType)) - commonRC.setActualInteriorVD(pModuleType, c.getHMIResponseParams(rpc, pModuleType).moduleData) - mobSession:ExpectNotification(c.getAppEventName(rpc), c.getAppResponseParams(rpc, pModuleType)) - :ValidIf(function(_,data) - if "AUDIO" == pModuleType and - nil ~= data.payload.moduleData.audioControlData.keepContext then - return false, "Mobile notification OnInteriorVehicleData contains unexpected keepContext parameter" - end - return true - end) -end - -function c.isUnsubscribed(pModuleType, pAppId) - local mobSession = c.getMobileSession(pAppId) - local rpc = "OnInteriorVehicleData" - test.hmiConnection:SendNotification(c.getHMIEventName(rpc), c.getHMIResponseParams(rpc, pModuleType)) - commonRC.setActualInteriorVD(pModuleType, c.getHMIResponseParams(rpc, pModuleType).moduleData) - mobSession:ExpectNotification(c.getAppEventName(rpc), {}):Times(0) -end - -function c.rpcDenied(pModuleType, pAppId, pRPC, pResultCode) - local mobSession = c.getMobileSession(pAppId) - local cid = mobSession:SendRPC(c.getAppEventName(pRPC), c.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(c.getHMIEventName(pRPC), {}):Times(0) - mobSession:ExpectResponse(cid, { success = false, resultCode = pResultCode }) -end - -function c.rpcRejectWithConsent(pModuleType, pAppId, pRPC) - local info = "The resource is in use and the driver disallows this remote control RPC" - local consentRPC = "GetInteriorVehicleDataConsent" - local mobSession = c.getMobileSession(pAppId) - local cid = mobSession:SendRPC(c.getAppEventName(pRPC), c.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(c.getHMIEventName(consentRPC), c.getHMIRequestParams(consentRPC, pModuleType, pAppId)) - :Do(function(_, data) - test.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", c.getHMIResponseParams(consentRPC, false)) - EXPECT_HMICALL(c.getHMIEventName(pRPC)):Times(0) - end) - mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED", info = info }) -end - -function c.rpcRejectWithoutConsent(pModuleType, pAppId, pRPC) - local mobSession = c.getMobileSession( pAppId) - local cid = mobSession:SendRPC(c.getAppEventName(pRPC), c.getAppRequestParams(pRPC, pModuleType)) - EXPECT_HMICALL(c.getHMIEventName("GetInteriorVehicleDataConsent")):Times(0) - EXPECT_HMICALL(c.getHMIEventName(pRPC)):Times(0) - mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED" }) -end - -function c.postconditions() - commonRC.postconditions() -end - -function c.buildHmiRcCapabilities(pCapabilities) - local hmiParams = hmi_values.getDefaultHMITable() - hmiParams.RC.IsReady.params.available = true - local capParams = hmiParams.RC.GetCapabilities.params.remoteControlCapability - for k, v in pairs(c.capMap) do - if pCapabilities[k] then - if pCapabilities[k] ~= commonRC.DEFAULT then - capParams[v] = pCapabilities[v] - end - else - capParams[v] = nil - end - end - return hmiParams -end - -function c.updateDefaultCapabilities(pDisabledModuleTypes) - local hmiCapabilitiesFile = commonPreconditions:GetPathToSDL() - .. commonFunctions:read_parameter_from_smart_device_link_ini("HMICapabilities") - local hmiCapTbl = commonRC.jsonFileToTable(hmiCapabilitiesFile) - local rcCapTbl = hmiCapTbl.UI.systemCapabilities.remoteControlCapability - for _, pDisabledModuleType in pairs(pDisabledModuleTypes) do - local buttonId = commonRC.getButtonIdByName( - rcCapTbl.buttonCapabilities, commonRC.getButtonNameByModule(pDisabledModuleType)) - table.remove(rcCapTbl.buttonCapabilities, buttonId) - rcCapTbl[c.capMap[pDisabledModuleType]] = nil - end - commonRC.tableToJsonFile(hmiCapTbl, hmiCapabilitiesFile) -end - -function c.getModuleControlDataForResponse(pModuleType) - local moduleData = commonRC.actualInteriorDataStateOnHMI[pModuleType] - if moduleData.audioControlData then - moduleData.audioControlData.keepContext = nil - end - return moduleData -end - -commonRC.actualInteriorDataStateOnHMI = { - CLIMATE = utils.cloneTable(c.getModuleControlData("CLIMATE")), - RADIO = utils.cloneTable(c.getModuleControlData("RADIO")), - SEAT = utils.cloneTable(c.getModuleControlData("SEAT")), - AUDIO = utils.cloneTable(c.getModuleControlData("AUDIO")), - LIGHT = utils.cloneTable(c.getModuleControlData("LIGHT")), - HMI_SETTINGS = utils.cloneTable(c.getModuleControlData("HMI_SETTINGS")) -} - -local setActualInteriorVDorigin = commonRC.setActualInteriorVD -function commonRC.setActualInteriorVD(pModuleType, pParams) - if pModuleType == "SEAT" then - for key, value in pairs(pParams["seatControlData"]) do - if type(value) ~= "table" then - if value ~= commonRC.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] then - commonRC.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] = value - end - else - if false == commonFunctions:is_table_equal(value, commonRC.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key]) then - commonRC.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] = value - end - end - end - elseif pModuleType == "AUDIO" then - for key, value in pairs(pParams["audioControlData"]) do - if type(value) ~= "table" then - if value ~= commonRC.actualInteriorDataStateOnHMI[pModuleType]["audioControlData"][key] then - commonRC.actualInteriorDataStateOnHMI[pModuleType]["audioControlData"][key] = value - end - else - if false == commonFunctions:is_table_equal(value, commonRC.actualInteriorDataStateOnHMI[pModuleType]["audioControlData"][key]) then - commonRC.actualInteriorDataStateOnHMI[pModuleType]["audioControlData"][key] = value - end - end - end - elseif pModuleType == "LIGHT" then - for key, value in pairs(pParams["lightControlData"]) do - if type(value) ~= "table" then - if value ~= commonRC.actualInteriorDataStateOnHMI[pModuleType]["lightControlData"][key] then - commonRC.actualInteriorDataStateOnHMI[pModuleType]["lightControlData"][key] = value - end - else - if false == commonFunctions:is_table_equal(value, commonRC.actualInteriorDataStateOnHMI[pModuleType]["lightControlData"][key]) then - commonRC.actualInteriorDataStateOnHMI[pModuleType]["lightControlData"][key] = value - end - end - end - elseif pModuleType == "HMI_SETTINGS" then - for key, value in pairs(pParams["hmiSettingsControlData"]) do - if type(value) ~= "table" then - if value ~= commonRC.actualInteriorDataStateOnHMI[pModuleType]["hmiSettingsControlData"][key] then - commonRC.actualInteriorDataStateOnHMI[pModuleType]["hmiSettingsControlData"][key] = value - end - else - if false == commonFunctions:is_table_equal(value, commonRC.actualInteriorDataStateOnHMI[pModuleType]["hmiSettingsControlData"][key]) then - commonRC.actualInteriorDataStateOnHMI[pModuleType]["hmiSettingsControlData"][key] = value - end - end - end - else - setActualInteriorVDorigin(pModuleType, pParams) - end -end - -return c From f94bb2518f6ed5f217b20779e86cece17d5bbdab Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 22 Aug 2018 15:48:00 +0300 Subject: [PATCH 613/681] Update scripts for OnRCStatus with new initial RC common --- ..._by_rc_functionality_disallowed_on_hmi.lua | 4 +- .../003_registration_non_rc_app.lua | 2 +- ...ule_allocation_two_apps_one_app_not_rc.lua | 2 +- ...ification_by_revoking_module_by_policy.lua | 9 +- .../015_notification_by_user_exit.lua | 2 +- ...cation_by_DRIVER_DISTRACTION_VIOLATION.lua | 2 +- ..._in_case_of_policy_permissions_absence.lua | 7 +- ..._disallowed_on_hmi_with_registered_app.lua | 2 +- ...ity_allowed_on_hmi_with_registered_app.lua | 6 +- ...onality_disallowed_on_hmi_several_apps.lua | 4 +- ..._non_rc_app_several_apps_rc_disallowed.lua | 4 +- ...allowed_on_hmi_with_allocated_resource.lua | 2 +- ..._by_revoking_several_modules_by_policy.lua | 9 +- .../RC/OnRCStatus/commonOnRCStatus.lua | 367 ++---------------- 14 files changed, 69 insertions(+), 353 deletions(-) diff --git a/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua b/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua index ec8de2ea3d..7a629339a2 100644 --- a/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua +++ b/test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua @@ -21,12 +21,12 @@ runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] local function disableRCFromHMI() - common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) + common.getHMIConnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) common.wait(2000) end local function registerAppOnRCStatusAllowFalse() - common.rai_n() + common.registerAppWOPTU() common.getMobileSession():ExpectNotification("OnRCStatus", { allowed = false, freeModules = {}, allocatedModules = {} }) EXPECT_HMINOTIFICATION("RC.OnRCStatus") diff --git a/test_scripts/RC/OnRCStatus/003_registration_non_rc_app.lua b/test_scripts/RC/OnRCStatus/003_registration_non_rc_app.lua index 4c69ebd2b9..807caae4a7 100644 --- a/test_scripts/RC/OnRCStatus/003_registration_non_rc_app.lua +++ b/test_scripts/RC/OnRCStatus/003_registration_non_rc_app.lua @@ -23,7 +23,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } --[[ Local Functions ]] local function registerNonRCApp() - common.rai_n() + common.registerAppWOPTU() common.getMobileSession():ExpectNotification("OnRCStatus") :Times(0) EXPECT_HMINOTIFICATION("RC.OnRCStatus") diff --git a/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua b/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua index c746732259..a23ad06749 100644 --- a/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua +++ b/test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua @@ -46,7 +46,7 @@ runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register RC application 1", common.registerRCApplication) runner.Step("Activate App 1", common.activateApp) -runner.Step("Register non-RC application 2", common.rai_n, { 2 }) +runner.Step("Register non-RC application 2", common.registerAppWOPTU, { 2 }) runner.Title("Test") for _, mod in pairs(common.getAllModules()) do diff --git a/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua b/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua index ff3a0aabdc..8ec7094735 100644 --- a/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua +++ b/test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua @@ -39,8 +39,8 @@ local function alocateModule(pModuleType) common.validateOnRCStatusForHMI(1, { pModuleStatus }) end -local function registrationAppWithRevokingModule() - common.raiPTU_n(pTUfunc, 2) +local function ptuWithRevokingModule() + common.policyTableUpdate(pTUfunc) local pModuleStatus = { freeModules = common.getModulesArray(common.getAllModules()), allocatedModules = { } @@ -51,14 +51,15 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions, { 1 }) +runner.Step("Clean environment", common.preconditions, { true, 1 }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register RC application 1", common.registerRCApplication) runner.Step("Activate App 1", common.activateApp) runner.Step("Allocating module CLIMATE", alocateModule, { "CLIMATE" }) runner.Title("Test") -runner.Step("OnRCStatus by PTU with revoking of allocated module", registrationAppWithRevokingModule) +runner.Step("Register RC application 1", common.registerApp, { 2 }) +runner.Step("OnRCStatus by PTU with revoking of allocated module", ptuWithRevokingModule) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/015_notification_by_user_exit.lua b/test_scripts/RC/OnRCStatus/015_notification_by_user_exit.lua index 17824ad788..72a210ea7c 100644 --- a/test_scripts/RC/OnRCStatus/015_notification_by_user_exit.lua +++ b/test_scripts/RC/OnRCStatus/015_notification_by_user_exit.lua @@ -30,7 +30,7 @@ end local function userExit() local hmiAppId = common.getHMIAppId() - common.getHMIconnection():SendNotification("BasicCommunication.OnExitApplication", + common.getHMIConnection():SendNotification("BasicCommunication.OnExitApplication", { appID = hmiAppId, reason = "USER_EXIT" }) common.getMobileSession(1):ExpectNotification("OnHMIStatus", { systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE" }) diff --git a/test_scripts/RC/OnRCStatus/016_notification_by_DRIVER_DISTRACTION_VIOLATION.lua b/test_scripts/RC/OnRCStatus/016_notification_by_DRIVER_DISTRACTION_VIOLATION.lua index 94bbc25d14..2f25363b9b 100644 --- a/test_scripts/RC/OnRCStatus/016_notification_by_DRIVER_DISTRACTION_VIOLATION.lua +++ b/test_scripts/RC/OnRCStatus/016_notification_by_DRIVER_DISTRACTION_VIOLATION.lua @@ -30,7 +30,7 @@ end local function driverDistractionViolation() local hmiAppId = common.getHMIAppId() - common.getHMIconnection():SendNotification("BasicCommunication.OnExitApplication", + common.getHMIConnection():SendNotification("BasicCommunication.OnExitApplication", { appID = hmiAppId, reason = "DRIVER_DISTRACTION_VIOLATION" }) common.getMobileSession(1):ExpectNotification("OnHMIStatus", { systemContext = "MAIN", hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE" }) diff --git a/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua b/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua index bb18f7c5ed..a13a984d7e 100644 --- a/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua +++ b/test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua @@ -25,7 +25,7 @@ local freeModules = common.getAllModules() local allocatedModules = {{}} --[[ Local Functions ]] -local function pTUfunc(tbl) +local function PTUfunc(tbl) local appId = config.application1.registerAppInterfaceParams.appID tbl.policy_table.app_policies[appId] = common.getRCAppConfig() local HMILevels = { "NONE", "BACKGROUND", "FULL", "LIMITED" } @@ -51,7 +51,7 @@ local function alocateModule(pModuleType) end local function registerApp() - common.raiPTU_n(pTUfunc, 1) + common.registerApp() common.getMobileSession(1):ExpectNotification("OnRCStatus") :Times(0) EXPECT_HMICALL("RC.OnRCStatus") @@ -60,11 +60,12 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions, { 0 }) +runner.Step("Clean environment", common.preconditions, { true, 0 }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Title("Test") runner.Step("Register RC application", registerApp) +runner.Step("PTU", common.policyTableUpdate, { PTUfunc }) runner.Step("Activate App", common.activateApp) runner.Step("Allocation of module CLIMATE", alocateModule, { "CLIMATE" }) diff --git a/test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua b/test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua index deb8652963..744b516063 100644 --- a/test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua +++ b/test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua @@ -27,7 +27,7 @@ config.application2.registerAppInterfaceParams.appHMIType = { "DEFAULT" } --[[ Local Functions ]] local function disableRCFromHMI() - common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) + common.getHMIConnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) common.getMobileSession(1):ExpectNotification("OnRCStatus", { allowed = false, freeModules = {}, allocatedModules = {} }) local pModuleStatusHMI = { diff --git a/test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua b/test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua index c1fb1f2e2d..47f4c3b75f 100644 --- a/test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua +++ b/test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua @@ -29,7 +29,7 @@ config.application2.registerAppInterfaceParams.appHMIType = { "DEFAULT" } --[[ Local Functions ]] local function disableRCFromHMI() - common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) + common.getHMIConnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) common.wait(2000) end @@ -40,7 +40,7 @@ local function registerRCAppRCDisallowed() allowed = false } - commonRC.rai_n(1, test) + commonRC.registerAppWOPTU(1, test) common.validateOnRCStatusForApp(1, pModuleStatusForApp, true) EXPECT_HMINOTIFICATION("RC.OnRCStatus") :Times(0) @@ -56,7 +56,7 @@ local function enableRCFromHMI() freeModules = common.getModulesArray(common.getAllModules()), allocatedModules = { } } - common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = true }) + common.getHMIConnection():SendNotification("RC.OnRemoteControlSettings", { allowed = true }) common.validateOnRCStatusForApp(1, pModuleStatus, true) common.validateOnRCStatusForHMI(1, { pModuleStatusHMI }) common.getMobileSession(2):ExpectNotification("OnRCStatus") diff --git a/test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_several_apps.lua b/test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_several_apps.lua index 3adea5bff6..c891625a3c 100644 --- a/test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_several_apps.lua +++ b/test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_several_apps.lua @@ -29,7 +29,7 @@ config.application3.registerAppInterfaceParams.appHMIType = { "DEFAULT" } -- [[ Local Functions]] local function registerAppOnRCStatusAllowFalse(pAppId) - common.rai_n(pAppId) + common.registerAppWOPTU(pAppId) common.getMobileSession(pAppId):ExpectNotification("OnRCStatus", { allowed = false, freeModules = {}, allocatedModules = {} }) EXPECT_HMINOTIFICATION("RC.OnRCStatus") @@ -45,7 +45,7 @@ local function registerRCapp() end local function disableRCFromHMI() - common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) + common.getHMIConnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) common.wait(2000) end diff --git a/test_scripts/RC/OnRCStatus/027_registration_non_rc_app_several_apps_rc_disallowed.lua b/test_scripts/RC/OnRCStatus/027_registration_non_rc_app_several_apps_rc_disallowed.lua index 9806f3787d..5b7052fef6 100644 --- a/test_scripts/RC/OnRCStatus/027_registration_non_rc_app_several_apps_rc_disallowed.lua +++ b/test_scripts/RC/OnRCStatus/027_registration_non_rc_app_several_apps_rc_disallowed.lua @@ -31,12 +31,12 @@ config.application3.registerAppInterfaceParams.appHMIType = { "DEFAULT" } --[[ Local Functions ]] local function disableRCFromHMI() - common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) + common.getHMIConnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) common.wait(2000) end local function registerAppOnRCStatusAllowFalse(pAppId) - common.rai_n(pAppId) + common.registerAppWOPTU(pAppId) common.getMobileSession(pAppId):ExpectNotification("OnRCStatus", { allowed = false, freeModules = {}, allocatedModules = {} }) EXPECT_HMINOTIFICATION("RC.OnRCStatus") diff --git a/test_scripts/RC/OnRCStatus/028_notification_by_rc_functionality_disallowed_on_hmi_with_allocated_resource.lua b/test_scripts/RC/OnRCStatus/028_notification_by_rc_functionality_disallowed_on_hmi_with_allocated_resource.lua index da22089435..47281e255d 100644 --- a/test_scripts/RC/OnRCStatus/028_notification_by_rc_functionality_disallowed_on_hmi_with_allocated_resource.lua +++ b/test_scripts/RC/OnRCStatus/028_notification_by_rc_functionality_disallowed_on_hmi_with_allocated_resource.lua @@ -31,7 +31,7 @@ local allocatedModules = { --[[ Local Functions ]] local function disableRCFromHMI() - common.getHMIconnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) + common.getHMIConnection():SendNotification("RC.OnRemoteControlSettings", { allowed = false }) common.getMobileSession():ExpectNotification("OnRCStatus", { allowed = false, freeModules = {}, allocatedModules = {} }) local pModuleStatusHMI = { diff --git a/test_scripts/RC/OnRCStatus/029_notification_by_revoking_several_modules_by_policy.lua b/test_scripts/RC/OnRCStatus/029_notification_by_revoking_several_modules_by_policy.lua index 56a3fc1c7c..b627ab68ff 100644 --- a/test_scripts/RC/OnRCStatus/029_notification_by_revoking_several_modules_by_policy.lua +++ b/test_scripts/RC/OnRCStatus/029_notification_by_revoking_several_modules_by_policy.lua @@ -46,8 +46,8 @@ local function alocateModule(pModuleType) common.validateOnRCStatusForHMI(1, { pModuleStatus }) end -local function registrationAppWithRevokingModule() - common.raiPTU_n(pTUfunc, 2) +local function ptuWithRevokingModule() + common.policyTableUpdate(pTUfunc) local pModuleStatus = { freeModules = common.getModulesArray(common.getAllModules()), allocatedModules = { } @@ -58,7 +58,7 @@ end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions, { 1 }) +runner.Step("Clean environment", common.preconditions, { true, 1 }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register RC application 1", common.registerRCApplication) runner.Step("Activate App 1", common.activateApp) @@ -66,7 +66,8 @@ runner.Step("Allocating module CLIMATE", alocateModule, { "CLIMATE" }) runner.Step("Allocating module RADIO", alocateModule, { "RADIO" }) runner.Title("Test") -runner.Step("OnRCStatus by PTU with revoking of allocated module", registrationAppWithRevokingModule) +runner.Step("Register RC application 2", common.registerApp, { 2 }) +runner.Step("OnRCStatus by PTU with revoking of allocated module", ptuWithRevokingModule) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua index 398aa440f2..bbe5ff58b6 100644 --- a/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua +++ b/test_scripts/RC/OnRCStatus/commonOnRCStatus.lua @@ -1,182 +1,25 @@ --------------------------------------------------------------------------------------------------- -- OnRCStatus common module --------------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.defaultProtocolVersion = 2 -config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } -config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } -config.checkAllValidations = true -config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 -config.application2.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 - --[[ Required Shared libraries ]] local commonRC = require('test_scripts/RC/commonRC') -local test = require("user_modules/dummy_connecttest") local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') -local json = require("modules/json") local utils = require("user_modules/utils") ---[[ Module ]] -local m = {} - ---[[ Functions ]] -local getRCAppConfigOrigin = commonRC.getRCAppConfig -function commonRC.getRCAppConfig(tbl) - local rcAppConfig = getRCAppConfigOrigin(tbl) - rcAppConfig.moduleType = { "RADIO", "CLIMATE", "SEAT", "AUDIO", "LIGHT", "HMI_SETTINGS" } - return rcAppConfig -end - -function commonRC.getSettableModuleControlData(pModuleType) - local out = commonRC.getModuleControlData(pModuleType) - local params_read_only = commonRC.getModuleParams(commonRC.getReadOnlyParamsByModule(pModuleType)) - if params_read_only then - for p_read_only in pairs(params_read_only) do - commonRC.getModuleParams(out)[p_read_only] = nil - end - end - return out -end - -local function backupPreloadedPT() - local preloadedFile = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") - commonPreconditions:BackupFile(preloadedFile) -end - -local function updatePreloadedPT(pCountOfRCApps) - if not pCountOfRCApps then pCountOfRCApps = 2 end - local preloadedFile = commonPreconditions:GetPathToSDL() - .. commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") - local preloadedTable = commonRC.jsonFileToTable(preloadedFile) - preloadedTable.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null - preloadedTable.policy_table.functional_groupings["RemoteControl"].rpcs.OnRCStatus = { - hmi_levels = { "FULL", "BACKGROUND", "LIMITED", "NONE" } - } - for i = 1, pCountOfRCApps do - local appId = config["application" .. i].registerAppInterfaceParams.appID - preloadedTable.policy_table.app_policies[appId] = commonRC.getRCAppConfig(preloadedTable) - preloadedTable.policy_table.app_policies[appId].AppHMIType = nil - end - commonRC.tableToJsonFile(preloadedTable, preloadedFile) -end - -local origGetModuleControlData = commonRC.getModuleControlData -function commonRC.getModuleControlData(module_type) - local out = { } - if module_type == "SEAT" then - out.moduleType = module_type - out.seatControlData = { - id = "DRIVER", - heatingEnabled = true, - coolingEnabled = true, - heatingLevel = 50, - coolingLevel = 50, - horizontalPosition = 50, - verticalPosition = 50, - frontVerticalPosition = 50, - backVerticalPosition = 50, - backTiltAngle = 50, - headSupportHorizontalPosition = 50, - headSupportVerticalPosition = 50, - massageEnabled = true, - massageMode = { - { - massageZone = "LUMBAR", - massageMode = "HIGH" - }, - { - massageZone = "SEAT_CUSHION", - massageMode = "LOW" - } - }, - massageCushionFirmness = { - { - cushion = "TOP_LUMBAR", - firmness = 30 - }, - { - cushion = "BACK_BOLSTERS", - firmness = 60 - } - }, - memory = { - id = 1, - label = "Label value", - action = "SAVE" - } - } - elseif module_type == "AUDIO" then - out.moduleType = "AUDIO" - out.audioControlData = { - source = "AM", - volume = 50 - } - elseif module_type == "LIGHT" then - out.moduleType = "LIGHT" - out.lightControlData = { - lightState = { - { - id = "FRONT_LEFT_HIGH_BEAM", - status = "ON", - density = 0.2, - color = { - red = 50, - green = 150, - blue = 200 - } - } - } - } - elseif module_type == "HMI_SETTINGS" then - out.moduleType = "HMI_SETTINGS" - out.hmiSettingsControlData = { - displayMode = "DAY", - temperatureUnit = "CELSIUS", - distanceUnit = "KILOMETERS" - } - else - out = origGetModuleControlData(module_type) - end - return out -end - -local function restorePreloadedPT() - local preloadedFile = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") - commonPreconditions:RestoreFile(preloadedFile) -end +--[[ Common Variables ]] +commonRC.wait = utils.wait +commonRC.cloneTable = utils.cloneTable -function m.getModules() +--[[ Common Functions ]] +function commonRC.getModules() return commonFunctions:cloneTable({ "RADIO", "CLIMATE" }) end -function m.getAllModules() +function commonRC.getAllModules() return commonFunctions:cloneTable({ "RADIO", "CLIMATE", "SEAT", "AUDIO", "LIGHT", "HMI_SETTINGS" }) end -function m.getRCAppConfig() - return commonRC.getRCAppConfig() -end - -function m.getMobileSession(pAppId) - return commonRC.getMobileSession(test, pAppId) -end - -function m.getHMIconnection() - return test.hmiConnection -end - -function m.preconditions(pCountOfRCApps) - commonRC.preconditions() - backupPreloadedPT() - updatePreloadedPT(pCountOfRCApps) -end - -function m.start() - commonRC.start(nil, test) -end - -function m.getModulesArray(pModules) +function commonRC.getModulesArray(pModules) local out = {} for _, mod in pairs(pModules) do table.insert(out, { moduleType = mod }) @@ -184,7 +27,7 @@ function m.getModulesArray(pModules) return out end -function m.getHMIAppIdsRC() +function commonRC.getHMIAppIdsRC() local out = {} for appID, hmiAppId in pairs(commonRC.getHMIAppIds()) do for i = 1, 5 do @@ -197,55 +40,24 @@ function m.getHMIAppIdsRC() return out end -function m.registerRCApplication(pAppId, pAllowed) +function commonRC.registerRCApplication(pAppId, pAllowed) if not pAppId then pAppId = 1 end if pAllowed == nil then pAllowed = true end local freeModulesArray = {} if true == pAllowed then - freeModulesArray = m.getModulesArray(m.getAllModules()) + freeModulesArray = commonRC.getModulesArray(commonRC.getAllModules()) end local pModuleStatusForApp = { freeModules = freeModulesArray, allocatedModules = { }, allowed = pAllowed } - commonRC.rai_n(pAppId, test) - m.validateOnRCStatusForApp(pAppId, pModuleStatusForApp) + commonRC.registerAppWOPTU(pAppId) + commonRC.validateOnRCStatusForApp(pAppId, pModuleStatusForApp) EXPECT_HMICALL("RC.OnRCStatus") :Times(0) end -function m.raiPTU_n(ptu_update_func, pAppId) - if not pAppId then pAppId = 1 end - commonRC.rai_ptu_n(pAppId, ptu_update_func, test) -end - -function m.rai_n(pAppId) - commonRC.rai_n(pAppId, test) -end - -function m.subscribeToModule(pModule, pAppId) - if not pAppId then pAppId = 1 end - commonRC.subscribeToModule(pModule, pAppId, test) -end - -function m.activateApp(pAppId) - commonRC.activate_app(pAppId, test) -end - -function m.getHMIAppId(pAppId) - return commonRC.getHMIAppId(pAppId) -end - -function m.getSettableModuleControlData(pModuleType) - return commonRC.getSettableModuleControlData(pModuleType) -end - -function m.postconditions() - commonRC.postconditions() - restorePreloadedPT() -end - local function setAllocationState(pAllocArrays, pAllocApp, pModule) for i=1,#pAllocArrays do for key, value in pairs(pAllocArrays[i]) do @@ -257,7 +69,7 @@ local function setAllocationState(pAllocArrays, pAllocApp, pModule) table.insert(pAllocArrays[pAllocApp], pModule) end -function m.setModuleStatus(pFreeMod, pAllocatedMod, pModule, pAllocApp) +function commonRC.setModuleStatus(pFreeMod, pAllocatedMod, pModule, pAllocApp) if not pAllocApp then pAllocApp = 1 end local modulesStatusAllocatedApp = { } local modulesStatusAnotherApp = { } @@ -267,9 +79,9 @@ function m.setModuleStatus(pFreeMod, pAllocatedMod, pModule, pAllocApp) table.remove(pFreeMod, key) end end - modulesStatusAllocatedApp.freeModules = m.getModulesArray(pFreeMod) - modulesStatusAnotherApp.freeModules = m.getModulesArray(pFreeMod) - modulesStatusAllocatedApp.allocatedModules = m.getModulesArray(pAllocatedMod[pAllocApp]) + modulesStatusAllocatedApp.freeModules = commonRC.getModulesArray(pFreeMod) + modulesStatusAnotherApp.freeModules = commonRC.getModulesArray(pFreeMod) + modulesStatusAllocatedApp.allocatedModules = commonRC.getModulesArray(pAllocatedMod[pAllocApp]) if 1 == pAllocApp then modulesStatusAnotherApp.allocatedModules = pAllocatedMod[2] else @@ -278,7 +90,7 @@ function m.setModuleStatus(pFreeMod, pAllocatedMod, pModule, pAllocApp) return modulesStatusAllocatedApp, modulesStatusAnotherApp end -function m.setModuleStatusByDeallocation(pFreeMod, pAllocatedMod, pModule, pRemoveAllocFromApp) +function commonRC.setModuleStatusByDeallocation(pFreeMod, pAllocatedMod, pModule, pRemoveAllocFromApp) if not pRemoveAllocFromApp then pRemoveAllocFromApp = 1 end local modulesStatusAllocatedApp = { } local modulesStatusAnotherApp = { } @@ -288,9 +100,9 @@ function m.setModuleStatusByDeallocation(pFreeMod, pAllocatedMod, pModule, pRemo table.remove(pAllocatedMod[pRemoveAllocFromApp], key) end end - modulesStatusAllocatedApp.freeModules = m.getModulesArray(pFreeMod) - modulesStatusAnotherApp.freeModules = m.getModulesArray(pFreeMod) - modulesStatusAllocatedApp.allocatedModules = m.getModulesArray(pAllocatedMod[pRemoveAllocFromApp]) + modulesStatusAllocatedApp.freeModules = commonRC.getModulesArray(pFreeMod) + modulesStatusAnotherApp.freeModules = commonRC.getModulesArray(pFreeMod) + modulesStatusAllocatedApp.allocatedModules = commonRC.getModulesArray(pAllocatedMod[pRemoveAllocFromApp]) if 1 == pRemoveAllocFromApp then modulesStatusAnotherApp.allocatedModules = pAllocatedMod[2] else @@ -299,46 +111,13 @@ function m.setModuleStatusByDeallocation(pFreeMod, pAllocatedMod, pModule, pRemo return modulesStatusAllocatedApp, modulesStatusAnotherApp end -function m.unregisterApp(pAppId) +function commonRC.closeSession(pAppId) if not pAppId then pAppId = 1 end commonRC.deleteHMIAppId(pAppId) - commonRC.unregisterApp(pAppId, test) -end - -function m.closeSession(pAppId) - if not pAppId then pAppId = 1 end - commonRC.deleteHMIAppId(pAppId) - m.getMobileSession(pAppId):Stop() -end - -function m.defineRAMode(pAllowed, pAccessMode) - commonRC.defineRAMode(pAllowed, pAccessMode, test) + commonRC.getMobileSession(pAppId):Stop() end -function m.rpcRejectWithConsent(pModuleType, pAppId, pRPC) - commonRC.rpcRejectWithConsent(pModuleType, pAppId, pRPC, test) -end - -function m.rpcAllowedWithConsent(pModuleType, pAppId, pRPC) - commonRC.rpcAllowedWithConsent(pModuleType, pAppId, pRPC, test) -end - -m.getAppEventName = commonRC.getAppEventName -m.getHMIEventName = commonRC.getHMIEventName -m.getAppRequestParams = commonRC.getAppRequestParams -m.getAppResponseParams = commonRC.getAppResponseParams -m.getHMIRequestParams = commonRC.getHMIRequestParams -m.getHMIResponseParams = commonRC.getHMIResponseParams - -function m.rpcAllowed(pModuleType, pAppId, pRPC) - commonRC.rpcAllowed(pModuleType, pAppId, pRPC, test) -end - -function m.cloneTable(...) - commonFunctions:cloneTable(...) -end - -function m.sortModules(pModulesArray) +function commonRC.sortModules(pModulesArray) local function f(a, b) if a.moduleType and b.moduleType then return a.moduleType < b.moduleType @@ -350,15 +129,15 @@ function m.sortModules(pModulesArray) table.sort(pModulesArray, f) end -function m.validateOnRCStatusForApp(pAppId, pExpData) - local ExpData = utils.cloneTable(pExpData) +function commonRC.validateOnRCStatusForApp(pAppId, pExpData) + local ExpData = commonRC.cloneTable(pExpData) if ExpData.allowed == nil then ExpData.allowed = true end - m.getMobileSession(pAppId):ExpectNotification("OnRCStatus") + commonRC.getMobileSession(pAppId):ExpectNotification("OnRCStatus") :ValidIf(function(_, d) - m.sortModules(ExpData.freeModules) - m.sortModules(ExpData.allocatedModules) - m.sortModules(d.payload.freeModules) - m.sortModules(d.payload.allocatedModules) + commonRC.sortModules(ExpData.freeModules) + commonRC.sortModules(ExpData.allocatedModules) + commonRC.sortModules(d.payload.freeModules) + commonRC.sortModules(d.payload.allocatedModules) return compareValues(ExpData, d.payload, "payload") end) :ValidIf(function(_, d) @@ -369,15 +148,15 @@ function m.validateOnRCStatusForApp(pAppId, pExpData) end) end -function m.validateOnRCStatusForHMI(pCountOfRCApps, pExpData, pAllocApp) +function commonRC.validateOnRCStatusForHMI(pCountOfRCApps, pExpData, pAllocApp) local usedHmiAppIds = { } EXPECT_HMINOTIFICATION("RC.OnRCStatus") :ValidIf(function(_, d) - m.sortModules(d.params.freeModules) - m.sortModules(d.params.allocatedModules) + commonRC.sortModules(d.params.freeModules) + commonRC.sortModules(d.params.allocatedModules) for i=1,#pExpData do - m.sortModules(pExpData[i].freeModules) - m.sortModules(pExpData[i].allocatedModules) + commonRC.sortModules(pExpData[i].freeModules) + commonRC.sortModules(pExpData[i].allocatedModules) end local AnotherApp if pAllocApp and pAllocApp == 1 then @@ -402,7 +181,7 @@ function m.validateOnRCStatusForHMI(pCountOfRCApps, pExpData, pAllocApp) usedHmiAppIds = {} end local avlHmiAppIds = {} - for _, appId in pairs(m.getHMIAppIdsRC()) do + for _, appId in pairs(commonRC.getHMIAppIdsRC()) do avlHmiAppIds[appId] = true end local actAppId = d.params.appID @@ -422,78 +201,12 @@ function m.validateOnRCStatusForHMI(pCountOfRCApps, pExpData, pAllocApp) :Times(pCountOfRCApps) end -m.wait = utils.wait - -function m.registerNonRCApp(pAppId) - m.rai_n(pAppId) - m.getMobileSession(pAppId):ExpectNotification("OnRCStatus") +function commonRC.registerNonRCApp(pAppId) + commonRC.registerAppWOPTU(pAppId) + commonRC.getMobileSession(pAppId):ExpectNotification("OnRCStatus") :Times(0) EXPECT_HMINOTIFICATION("RC.OnRCStatus") :Times(0) end -commonRC.actualInteriorDataStateOnHMI = { - CLIMATE = utils.cloneTable(commonRC.getModuleControlData("CLIMATE")), - RADIO = utils.cloneTable(commonRC.getModuleControlData("RADIO")), - SEAT = utils.cloneTable(commonRC.getModuleControlData("SEAT")), - AUDIO = utils.cloneTable(commonRC.getModuleControlData("AUDIO")), - LIGHT = utils.cloneTable(commonRC.getModuleControlData("LIGHT")), - HMI_SETTINGS = utils.cloneTable(commonRC.getModuleControlData("HMI_SETTINGS")) -} - -local setActualInteriorVDorigin = commonRC.setActualInteriorVD -function commonRC.setActualInteriorVD(pModuleType, pParams) - if pModuleType == "SEAT" then - for key, value in pairs(pParams["seatControlData"]) do - if type(value) ~= "table" then - if value ~= commonRC.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] then - commonRC.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] = value - end - else - if false == commonFunctions:is_table_equal(value, commonRC.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key]) then - commonRC.actualInteriorDataStateOnHMI[pModuleType]["seatControlData"][key] = value - end - end - end - elseif pModuleType == "AUDIO" then - for key, value in pairs(pParams["audioControlData"]) do - if type(value) ~= "table" then - if value ~= commonRC.actualInteriorDataStateOnHMI[pModuleType]["audioControlData"][key] then - commonRC.actualInteriorDataStateOnHMI[pModuleType]["audioControlData"][key] = value - end - else - if false == commonFunctions:is_table_equal(value, commonRC.actualInteriorDataStateOnHMI[pModuleType]["audioControlData"][key]) then - commonRC.actualInteriorDataStateOnHMI[pModuleType]["audioControlData"][key] = value - end - end - end - elseif pModuleType == "LIGHT" then - for key, value in pairs(pParams["lightControlData"]) do - if type(value) ~= "table" then - if value ~= commonRC.actualInteriorDataStateOnHMI[pModuleType]["lightControlData"][key] then - commonRC.actualInteriorDataStateOnHMI[pModuleType]["lightControlData"][key] = value - end - else - if false == commonFunctions:is_table_equal(value, commonRC.actualInteriorDataStateOnHMI[pModuleType]["lightControlData"][key]) then - commonRC.actualInteriorDataStateOnHMI[pModuleType]["lightControlData"][key] = value - end - end - end - elseif pModuleType == "HMI_SETTINGS" then - for key, value in pairs(pParams["hmiSettingsControlData"]) do - if type(value) ~= "table" then - if value ~= commonRC.actualInteriorDataStateOnHMI[pModuleType]["hmiSettingsControlData"][key] then - commonRC.actualInteriorDataStateOnHMI[pModuleType]["hmiSettingsControlData"][key] = value - end - else - if false == commonFunctions:is_table_equal(value, commonRC.actualInteriorDataStateOnHMI[pModuleType]["hmiSettingsControlData"][key]) then - commonRC.actualInteriorDataStateOnHMI[pModuleType]["hmiSettingsControlData"][key] = value - end - end - end - else - setActualInteriorVDorigin(pModuleType, pParams) - end -end - -return m +return commonRC From 7c41e85408801337a630d3054c13772970e2080f Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 22 Aug 2018 15:48:33 +0300 Subject: [PATCH 614/681] Update scripts for InteriorVD cache with new initial RC common --- .../000_cache_2_apps_sequence.lua | 16 +- ...GetInteriorVD_without_subscribe_2_apps.lua | 2 +- ...ribe_true_and_without_subscribe_2_apps.lua | 2 +- ...07_GetInteriorVD_subscribe_true_2_apps.lua | 2 +- ...ubscribe_true_2_apps_different_modules.lua | 2 +- ...out_subscribe_2_apps_different_modules.lua | 2 +- ...orVD_subscribe_true_2_apps_same_module.lua | 2 +- ...subscription_after_OnInteriorVD_2_apps.lua | 2 +- ...D_2_apps_subscribed_and_not_subscribed.lua | 2 +- ...bscribe_true_after_OnInteriorVD_2_apps.lua | 2 +- ...9_GetInteriorVD_subscribe_false_2_apps.lua | 2 +- ...bscribe_false_different_modules_2_apps.lua | 2 +- ..._subscribe_false_by_app_unregistration.lua | 2 +- ...y_app_unregistration_different_modules.lua | 2 +- ...alse_by_app_unregistration_same_module.lua | 2 +- ...tion_rejected_different_modules_2_apps.lua | 2 +- .../030_GetInteriorVD_limitation_2_apps.lua | 2 +- .../031_GetInteriorVD_resubscribe_2_apps.lua | 2 +- .../032_OnInteriorVD_2_apps_subscribed.lua | 16 +- ...ibe_false_by_app_unexpected_disconnect.lua | 2 +- ...D_subscribe_false_by_app_disallowed_RC.lua | 2 +- ...rVD_subscribe_false_by_revoking_module.lua | 15 +- ...D_subscribe_false_without_subscribtion.lua | 4 +- .../038_OnInteriorVD_one_parameter.lua | 28 +- ...GetInteriorVD_limitation_time_interval.lua | 15 +- .../common_interiorVDcache.lua | 453 ++---------------- 26 files changed, 110 insertions(+), 475 deletions(-) diff --git a/test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua b/test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua index 7dcc88043f..19ec102972 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua @@ -39,19 +39,9 @@ runner.testSettings.isSelfIncluded = false --[[ Local Function ]] local function OnInteriorVDUpdatedData2Apps(pModuleType) - local params = common.cloneTable(common.actualInteriorDataStateOnHMI[pModuleType]) - for key, value in pairs(params) do - if type(value) == "boolean" then - if value == true then - params[key] = false - else - params[key] = true - end - end - end + local params = common.moduleDataUpdate(pModuleType) common.OnInteriorVD(pModuleType, true, 1, params) - common.getMobileSession(2):ExpectNotification("OnInteriorVehicleData", - common.getResponseParams("OnInteriorVehicleData", pModuleType, params)) + common.getMobileSession(2):ExpectNotification("OnInteriorVehicleData",{moduleData = params}) end --[[ Scenario ]] @@ -61,7 +51,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/003_GetInteriorVD_without_subscribe_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/003_GetInteriorVD_without_subscribe_2_apps.lua index 31f789d6c9..8ac5176175 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/003_GetInteriorVD_without_subscribe_2_apps.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/003_GetInteriorVD_without_subscribe_2_apps.lua @@ -26,7 +26,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/006_GetInteriorVD_subscribe_true_and_without_subscribe_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/006_GetInteriorVD_subscribe_true_and_without_subscribe_2_apps.lua index 9b36886514..a07f9b7ddc 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/006_GetInteriorVD_subscribe_true_and_without_subscribe_2_apps.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/006_GetInteriorVD_subscribe_true_and_without_subscribe_2_apps.lua @@ -26,7 +26,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/007_GetInteriorVD_subscribe_true_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/007_GetInteriorVD_subscribe_true_2_apps.lua index 1bb9368630..25c0e460ff 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/007_GetInteriorVD_subscribe_true_2_apps.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/007_GetInteriorVD_subscribe_true_2_apps.lua @@ -26,7 +26,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/008_GetInteriorVD_subscribe_true_2_apps_different_modules.lua b/test_scripts/RC/InteriorVehicleData_cache/008_GetInteriorVD_subscribe_true_2_apps_different_modules.lua index 1f663b1f29..87c851d247 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/008_GetInteriorVD_subscribe_true_2_apps_different_modules.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/008_GetInteriorVD_subscribe_true_2_apps_different_modules.lua @@ -26,7 +26,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/009_GetInteriorVD_without_subscribe_2_apps_different_modules.lua b/test_scripts/RC/InteriorVehicleData_cache/009_GetInteriorVD_without_subscribe_2_apps_different_modules.lua index 06c315656c..4d8afa31c1 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/009_GetInteriorVD_without_subscribe_2_apps_different_modules.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/009_GetInteriorVD_without_subscribe_2_apps_different_modules.lua @@ -26,7 +26,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/010_GetInteriorVD_subscribe_true_2_apps_same_module.lua b/test_scripts/RC/InteriorVehicleData_cache/010_GetInteriorVD_subscribe_true_2_apps_same_module.lua index 0d48025cac..2aa356890e 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/010_GetInteriorVD_subscribe_true_2_apps_same_module.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/010_GetInteriorVD_subscribe_true_2_apps_same_module.lua @@ -27,7 +27,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/015_GetInteriorVD_with_subscription_after_OnInteriorVD_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/015_GetInteriorVD_with_subscription_after_OnInteriorVD_2_apps.lua index 94d9202558..ab6b151400 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/015_GetInteriorVD_with_subscription_after_OnInteriorVD_2_apps.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/015_GetInteriorVD_with_subscription_after_OnInteriorVD_2_apps.lua @@ -28,7 +28,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/016_OnInteriorVD_2_apps_subscribed_and_not_subscribed.lua b/test_scripts/RC/InteriorVehicleData_cache/016_OnInteriorVD_2_apps_subscribed_and_not_subscribed.lua index 2597050015..f40da98779 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/016_OnInteriorVD_2_apps_subscribed_and_not_subscribed.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/016_OnInteriorVD_2_apps_subscribed_and_not_subscribed.lua @@ -45,7 +45,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/017_GetInteriorVD_subscribe_true_after_OnInteriorVD_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/017_GetInteriorVD_subscribe_true_after_OnInteriorVD_2_apps.lua index a2ae2651fd..162857c0bb 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/017_GetInteriorVD_subscribe_true_after_OnInteriorVD_2_apps.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/017_GetInteriorVD_subscribe_true_after_OnInteriorVD_2_apps.lua @@ -28,7 +28,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/019_GetInteriorVD_subscribe_false_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/019_GetInteriorVD_subscribe_false_2_apps.lua index 555623b7a0..abbcce0bcc 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/019_GetInteriorVD_subscribe_false_2_apps.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/019_GetInteriorVD_subscribe_false_2_apps.lua @@ -29,7 +29,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua index b384113813..ff44a225be 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua @@ -27,7 +27,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/021_GetInteriorVD_subscribe_false_by_app_unregistration.lua b/test_scripts/RC/InteriorVehicleData_cache/021_GetInteriorVD_subscribe_false_by_app_unregistration.lua index e058863243..35b1d79291 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/021_GetInteriorVD_subscribe_false_by_app_unregistration.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/021_GetInteriorVD_subscribe_false_by_app_unregistration.lua @@ -28,7 +28,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/022_GetInteriorVD_subscribe_false_by_app_unregistration_different_modules.lua b/test_scripts/RC/InteriorVehicleData_cache/022_GetInteriorVD_subscribe_false_by_app_unregistration_different_modules.lua index ce8c1ca147..106e93365f 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/022_GetInteriorVD_subscribe_false_by_app_unregistration_different_modules.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/022_GetInteriorVD_subscribe_false_by_app_unregistration_different_modules.lua @@ -29,7 +29,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/023_GetInteriorVD_subscribe_false_by_app_unregistration_same_module.lua b/test_scripts/RC/InteriorVehicleData_cache/023_GetInteriorVD_subscribe_false_by_app_unregistration_same_module.lua index 8ae1583928..bab7ae0d5c 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/023_GetInteriorVD_subscribe_false_by_app_unregistration_same_module.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/023_GetInteriorVD_subscribe_false_by_app_unregistration_same_module.lua @@ -28,7 +28,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/027_GetInteriorVD_limitation_rejected_different_modules_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/027_GetInteriorVD_limitation_rejected_different_modules_2_apps.lua index 60da52e28f..4823ced5af 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/027_GetInteriorVD_limitation_rejected_different_modules_2_apps.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/027_GetInteriorVD_limitation_rejected_different_modules_2_apps.lua @@ -29,7 +29,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/030_GetInteriorVD_limitation_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/030_GetInteriorVD_limitation_2_apps.lua index fb84b35260..2d228c9fda 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/030_GetInteriorVD_limitation_2_apps.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/030_GetInteriorVD_limitation_2_apps.lua @@ -30,7 +30,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/031_GetInteriorVD_resubscribe_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/031_GetInteriorVD_resubscribe_2_apps.lua index 79abca5bdf..4689648d92 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/031_GetInteriorVD_resubscribe_2_apps.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/031_GetInteriorVD_resubscribe_2_apps.lua @@ -28,7 +28,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/032_OnInteriorVD_2_apps_subscribed.lua b/test_scripts/RC/InteriorVehicleData_cache/032_OnInteriorVD_2_apps_subscribed.lua index 06f0099292..db9a28ec24 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/032_OnInteriorVD_2_apps_subscribed.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/032_OnInteriorVD_2_apps_subscribed.lua @@ -23,19 +23,9 @@ runner.testSettings.isSelfIncluded = false --[[ Local Funstions ]] local function OnInteriorVDUpdatedData2Apps(pModuleType) - local params = common.cloneTable(common.actualInteriorDataStateOnHMI[pModuleType]) - for key, value in pairs(params) do - if type(value) == "boolean" then - if value == true then - params[key] = false - else - params[key] = true - end - end - end + local params = common.moduleDataUpdate(pModuleType) common.OnInteriorVD(pModuleType, true, 1, params) - common.getMobileSession(2):ExpectNotification("OnInteriorVehicleData", - common.getResponseParams("OnInteriorVehicleData", pModuleType, params)) + common.getMobileSession(2):ExpectNotification("OnInteriorVehicleData",{moduleData = params}) end --[[ Scenario ]] @@ -45,7 +35,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/034_GetInteriorVD_subscribe_false_by_app_unexpected_disconnect.lua b/test_scripts/RC/InteriorVehicleData_cache/034_GetInteriorVD_subscribe_false_by_app_unexpected_disconnect.lua index bcb5a70269..91caa791a9 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/034_GetInteriorVD_subscribe_false_by_app_unexpected_disconnect.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/034_GetInteriorVD_subscribe_false_by_app_unexpected_disconnect.lua @@ -28,7 +28,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/035_GetInteriorVD_subscribe_false_by_app_disallowed_RC.lua b/test_scripts/RC/InteriorVehicleData_cache/035_GetInteriorVD_subscribe_false_by_app_disallowed_RC.lua index feeaddd94b..ea2ace7cd6 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/035_GetInteriorVD_subscribe_false_by_app_disallowed_RC.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/035_GetInteriorVD_subscribe_false_by_app_disallowed_RC.lua @@ -51,7 +51,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/036_GetInteriorVD_subscribe_false_by_revoking_module.lua b/test_scripts/RC/InteriorVehicleData_cache/036_GetInteriorVD_subscribe_false_by_revoking_module.lua index cecc86a8e7..9fe9731c3d 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/036_GetInteriorVD_subscribe_false_by_revoking_module.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/036_GetInteriorVD_subscribe_false_by_revoking_module.lua @@ -8,40 +8,39 @@ -- Description: -- In case -- 1. Mobile app is subscribed to module_1 --- 2. Mobile app2 is subscribed to module_1 --- 3. Module_1 is revoked during PTU +-- 2. Module_1 is revoked during PTU -- SDL must -- 1. send GetInteriorVD(module_1, subscribe = false) request to HMI --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') -local commonRC = require('test_scripts/RC/commonRC') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function ptuFuncRPC(tbl) +local function ptuFuncRPC2(tbl) tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.appID].moduleType = { common.modules[2] } end local function ptu() local rpc = "GetInteriorVehicleData" - EXPECT_HMICALL(commonRC.getHMIEventName(rpc), common.getHMIRequestParams(rpc, common.modules[1], 1, false)) + EXPECT_HMICALL(common.getHMIEventName(rpc), common.getHMIRequestParams(rpc, common.modules[1], 1, false)) :Do(function(_, data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", common.getHMIResponseParams(rpc, common.modules[1], false)) end) - common.policyTableUpdate(ptuFuncRPC) + common.policyTableUpdate(ptuFuncRPC2) end --[[ Scenario ]] runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) +runner.Step("Clean environment", common.preconditions, { true, 1 }) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("Register app", common.registerApp, { 1 }) +runner.Step("Register app", common.registerAppWOPTU, { 1 }) runner.Step("Activate app", common.activateApp, { 1 }) +runner.Step("Register app2", common.registerApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/037_GetInteriorVD_subscribe_false_without_subscribtion.lua b/test_scripts/RC/InteriorVehicleData_cache/037_GetInteriorVD_subscribe_false_without_subscribtion.lua index ed6e7dcae4..f79d55256f 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/037_GetInteriorVD_subscribe_false_without_subscribtion.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/037_GetInteriorVD_subscribe_false_without_subscribtion.lua @@ -46,7 +46,7 @@ local function GetInteriorVehicleData(pModuleType, isSubscribe) end return true end) - mobSession:ExpectResponse(cid, common.getResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) + mobSession:ExpectResponse(cid, common.getAppResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) end --[[ Scenario ]] @@ -56,7 +56,7 @@ runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) runner.Step("Register app1", common.registerAppWOPTU, { 1 }) runner.Step("Register app2", common.registerAppWOPTU, { 2 }) runner.Step("Activate app1", common.activateApp, { 1 }) -runner.Step("Activate app2", common.activateApp, { 2, "NOT_AUDIBLE" }) +runner.Step("Activate app2", common.activateApp, { 2 }) runner.Title("Test") diff --git a/test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua b/test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua index db837f2b5b..c348586a25 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua @@ -22,10 +22,32 @@ local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interio runner.testSettings.isSelfIncluded = false local OnInteriorVDparams = { - CLIMATE = { fanSpeed = 30 }, - RADIO = { frequencyFraction = 3 } + CLIMATE = { fanSpeed = 30 }, + RADIO = { frequencyFraction = 3 }, + SEAT = { id = "FRONT_PASSENGER" }, + LIGHT = { lightState = { { id = "FRONT_RIGHT_HIGH_BEAM", status = "ON" } } }, + AUDIO = { source = "FM" }, + HMI_SETTINGS = { displayMode = "NIGHT" } } +local function getModuleData(module_type, pParams) + local out = { moduleType = module_type } + if module_type == "CLIMATE" then + out.climateControlData = pParams + elseif module_type == "RADIO" then + out.radioControlData = pParams + elseif module_type == "SEAT" then + out.seatControlData = pParams + elseif module_type == "AUDIO" then + out.audioControlData = pParams + elseif module_type == "LIGHT" then + out.lightControlData = pParams + elseif module_type == "HMI_SETTINGS" then + out.hmiSettingsControlData = pParams + end + return out +end + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) @@ -39,7 +61,7 @@ for _, mod in pairs(common.modules) do runner.Step("App1 GetInteriorVehicleData with subscribe=true " .. mod, common.GetInteriorVehicleData, { mod, true, true, 1 }) runner.Step("App1 OnInteriorVehicleData for " .. mod, common.OnInteriorVD, - { mod, true, 1, OnInteriorVDparams[mod] }) + { mod, true, 1, getModuleData(mod, OnInteriorVDparams[mod]) }) runner.Step("App2 GetInteriorVehicleData without subscribe " .. mod, common.GetInteriorVehicleData, { mod, nil, false, 1 }) end diff --git a/test_scripts/RC/InteriorVehicleData_cache/039_GetInteriorVD_limitation_time_interval.lua b/test_scripts/RC/InteriorVehicleData_cache/039_GetInteriorVD_limitation_time_interval.lua index 4bb58e4bca..a4156b4bb4 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/039_GetInteriorVD_limitation_time_interval.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/039_GetInteriorVD_limitation_time_interval.lua @@ -18,7 +18,6 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache') -local commonRC = require('test_scripts/RC/commonRC') local functionId = require('function_id') --[[ Test Configuration ]] @@ -32,13 +31,13 @@ local function GetInteriorVehicleData(pModuleType, pRequestNubmer) local rpc = "GetInteriorVehicleData" local subscribe = nil local mobSession = common.getMobileSession(1) - local cid = mobSession:SendRPC(commonRC.getAppEventName(rpc), - commonRC.getAppRequestParams(rpc, pModuleType, subscribe)) + local cid = mobSession:SendRPC(common.getAppEventName(rpc), + common.getAppRequestParams(rpc, pModuleType, subscribe)) local hmiRequestParams = common.getHMIRequestParams(rpc, pModuleType, 1, subscribe) timestampArray[pRequestNubmer] = timestamp() hmiRequestParams.subscribe = nil - EXPECT_HMICALL(commonRC.getHMIEventName(rpc), hmiRequestParams) + EXPECT_HMICALL(common.getHMIEventName(rpc), hmiRequestParams) :Do(function(_, data) local hmiResponseParams = common.getHMIResponseParams(rpc, pModuleType, subscribe) hmiResponseParams.subscribe = nil @@ -50,7 +49,7 @@ local function GetInteriorVehicleData(pModuleType, pRequestNubmer) end return true end) - mobSession:ExpectResponse(cid, common.getResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) + mobSession:ExpectResponse(cid, common.getAppResponseParams(rpc, true, "SUCCESS", pModuleType, subscribe)) end local function GetInteriorVehicleDataRejectedSuccess(pModuleType, pCompareRequest) @@ -58,15 +57,15 @@ local function GetInteriorVehicleDataRejectedSuccess(pModuleType, pCompareReques local subscribe = nil local mobSession = common.getMobileSession(1) local function request() - mobSession:SendRPC(commonRC.getAppEventName(rpc), - commonRC.getAppRequestParams(rpc, pModuleType, subscribe)) + mobSession:SendRPC(common.getAppEventName(rpc), + common.getAppRequestParams(rpc, pModuleType, subscribe)) end request() local hmiRequestParams = common.getHMIRequestParams(rpc, pModuleType, 1, subscribe) hmiRequestParams.subscribe = nil - EXPECT_HMICALL(commonRC.getHMIEventName(rpc), hmiRequestParams) + EXPECT_HMICALL(common.getHMIEventName(rpc), hmiRequestParams) :Do(function(_, data) timestampArray[4] = timestamp() local hmiResponseParams = common.getHMIResponseParams(rpc, pModuleType, subscribe) diff --git a/test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache.lua b/test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache.lua index de8aa887e5..eb959002f9 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/common_interiorVDcache.lua @@ -4,174 +4,18 @@ --[[ Required Shared libraries ]] local actions = require("user_modules/sequences/actions") local commonRC = require('test_scripts/RC/commonRC') -local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') -local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local json = require("modules/json") local utils = require("user_modules/utils") --[[ Module ]] -local m = actions -m.cloneTable = utils.cloneTable -m.jsonFileToTable = utils.jsonFileToTable -m.tableToJsonFile = utils.tableToJsonFile -m.wait = utils.wait -m.tableToString = utils.tableToString +commonRC.tableToString = utils.tableToString +commonRC.wait = utils.wait -local preloadedPT = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") -m.preconditionOrigin = m.preconditions -local postconditionOrigin = m.postconditions - -config.application1.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } -config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application1.registerAppInterfaceParams.isMediaApplication = true config.application2.registerAppInterfaceParams.isMediaApplication = false -config.application1.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 -config.application2.registerAppInterfaceParams.syncMsgVersion.majorVersion = 5 - - -m.modules = { "RADIO", "CLIMATE", "SEAT", "AUDIO", "LIGHT", "HMI_SETTINGS" } - -m.actualInteriorDataStateOnHMI = { - CLIMATE = { - fanSpeed = 50, - currentTemperature = { - unit = "FAHRENHEIT", - value = 20.1 - }, - desiredTemperature = { - unit = "CELSIUS", - value = 10.5 - }, - acEnable = true, - circulateAirEnable = true, - autoModeEnable = true, - defrostZone = "FRONT", - dualModeEnable = true, - acMaxEnable = true, - ventilationMode = "BOTH" - }, - RADIO = { - frequencyInteger = 1, - frequencyFraction = 2, - band = "AM", - rdsData = { - PS = "ps", - RT = "rt", - CT = "123456789012345678901234", - PI = "pi", - PTY = 1, - TP = false, - TA = true, - REG = "US" - }, - availableHDs = 1, - hdChannel = 1, - signalStrength = 5, - signalChangeThreshold = 10, - radioEnable = true, - state = "ACQUIRING" - }, - SEAT = { - id = "DRIVER", - heatingEnabled = true, - coolingEnabled = true, - heatingLevel = 50, - coolingLevel = 50, - horizontalPosition = 50, - verticalPosition = 50, - frontVerticalPosition = 50, - backVerticalPosition = 50, - backTiltAngle = 50, - headSupportHorizontalPosition = 50, - headSupportVerticalPosition = 50, - massageEnabled = true, - massageMode = { - { - massageZone = "LUMBAR", - massageMode = "HIGH" - }, - { - massageZone = "SEAT_CUSHION", - massageMode = "LOW" - } - }, - massageCushionFirmness = { - { - cushion = "TOP_LUMBAR", - firmness = 30 - }, - { - cushion = "BACK_BOLSTERS", - firmness = 60 - } - }, - memory = { - id = 1, - label = "Label value", - action = "SAVE" - } - }, - AUDIO = { - source = "AM", - volume = 50, - equalizerSettings = { - { - channelId = 10, - channelName = "Channel 1", - channelSetting = 50 - } - } - }, - LIGHT = { - lightState = { - { - id = "FRONT_LEFT_HIGH_BEAM", - status = "ON", - density = 0.2, - color = { - red = 50, - green = 150, - blue = 200 - } - } - } - }, - HMI_SETTINGS = { - displayMode = "DAY", - temperatureUnit = "CELSIUS", - distanceUnit = "KILOMETERS" - } -} - -function m.setActualInteriorVD(pModuleType, pParams) - for key, value in pairs(pParams) do - if type(value) ~= "table" then - if value ~= m.actualInteriorDataStateOnHMI[pModuleType][key] then - m.actualInteriorDataStateOnHMI[pModuleType][key] = value - end - else - if false == commonFunctions:is_table_equal(value, m.actualInteriorDataStateOnHMI[pModuleType][key]) then - m.actualInteriorDataStateOnHMI[pModuleType][key] = value - end - end - end -end -function m.updatePreloadedPT() - local preloadedFile = commonPreconditions:GetPathToSDL() - .. commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") - local preloadedTable = m.jsonFileToTable(preloadedFile) - preloadedTable.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null - preloadedTable.policy_table.functional_groupings["RemoteControl"].rpcs.OnRCStatus = { - hmi_levels = { "FULL", "BACKGROUND", "LIMITED", "NONE" } - } - preloadedTable.policy_table.app_policies.default.moduleType = m.modules - preloadedTable.policy_table.app_policies.default.groups = { "Base-4", "RemoteControl" } - preloadedTable.policy_table.app_policies.default.AppHMIType = { "REMOTE_CONTROL" } - m.tableToJsonFile(preloadedTable, preloadedFile) -end +commonRC.modules = { "RADIO", "CLIMATE", "SEAT", "AUDIO", "LIGHT", "HMI_SETTINGS" } -function m.GetInteriorVehicleData(pModuleType, isSubscribe, isHMIreqExpect, pAppId) +function commonRC.GetInteriorVehicleData(pModuleType, isSubscribe, isHMIreqExpect, pAppId) if not pAppId then pAppId = 1 end local rpc = "GetInteriorVehicleData" local HMIrequestsNumber @@ -180,22 +24,22 @@ function m.GetInteriorVehicleData(pModuleType, isSubscribe, isHMIreqExpect, pApp else HMIrequestsNumber = 0 end - local cid = m.getMobileSession(pAppId):SendRPC(commonRC.getAppEventName(rpc), + local cid = commonRC.getMobileSession(pAppId):SendRPC(commonRC.getAppEventName(rpc), commonRC.getAppRequestParams(rpc, pModuleType, isSubscribe)) - EXPECT_HMICALL(commonRC.getHMIEventName(rpc), m.getHMIRequestParams(rpc, pModuleType, pAppId, isSubscribe)) + EXPECT_HMICALL(commonRC.getHMIEventName(rpc), commonRC.getHMIRequestParams(rpc, pModuleType, pAppId, isSubscribe)) :Do(function(_, data) - m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", - m.getHMIResponseParams(rpc, pModuleType, isSubscribe)) + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", + commonRC.getHMIResponseParams(rpc, pModuleType, isSubscribe)) end) :Times(HMIrequestsNumber) - m.getMobileSession(pAppId):ExpectResponse(cid, m.getResponseParams(rpc, true, "SUCCESS", pModuleType, isSubscribe)) + commonRC.getMobileSession(pAppId):ExpectResponse(cid, commonRC.getAppResponseParams(rpc, true, "SUCCESS", pModuleType, isSubscribe)) end -function m.GetInteriorVehicleDataRejected(pModuleType, isSubscribe, pAppId) +function commonRC.GetInteriorVehicleDataRejected(pModuleType, isSubscribe, pAppId) if not pAppId then pAppId = 1 end local rpc = "GetInteriorVehicleData" local subscribe = isSubscribe - local mobSession = m.getMobileSession(pAppId) + local mobSession = commonRC.getMobileSession(pAppId) local cid = mobSession:SendRPC(commonRC.getAppEventName(rpc), commonRC.getAppRequestParams(rpc, pModuleType, subscribe)) EXPECT_HMICALL(commonRC.getHMIEventName(rpc)) @@ -203,225 +47,23 @@ function m.GetInteriorVehicleDataRejected(pModuleType, isSubscribe, pAppId) mobSession:ExpectResponse(cid, { success = false, resultCode = "REJECTED"}) end -function m.OnInteriorVD(pModuleType, isExpectNotification, pAppId, pParams) +function commonRC.OnInteriorVD(pModuleType, isExpectNotification, pAppId, pParams) local rpc = "OnInteriorVehicleData" - local mobSession = m.getMobileSession(pAppId) - if not pParams then pParams = m.getAnotherModuleControlData(pModuleType) end + local mobSession = commonRC.getMobileSession(pAppId) + if not pParams then pParams = commonRC.moduleDataUpdate(pModuleType) end local notificationCount if isExpectNotification == true then notificationCount = 1 else notificationCount = 0 end - m.setActualInteriorVD(pModuleType, pParams) - m.getHMIConnection():SendNotification(commonRC.getHMIEventName(rpc), - m.getHMIResponseParams(rpc, pModuleType, pParams)) - mobSession:ExpectNotification(commonRC.getAppEventName(rpc), - m.getResponseParams(rpc, pModuleType, pParams)) + commonRC.setActualInteriorVD(pModuleType, pParams) + commonRC.getHMIConnection():SendNotification(commonRC.getHMIEventName(rpc), {moduleData = pParams}) + mobSession:ExpectNotification(commonRC.getAppEventName(rpc), {moduleData = pParams}) :Times(notificationCount) end -function m.getModuleControlData(module_type, pParams) - local out = { moduleType = module_type } - if module_type == "CLIMATE" then - out.climateControlData = pParams - elseif module_type == "RADIO" then - out.radioControlData = pParams - elseif module_type == "SEAT" then - out.seatControlData = pParams - elseif module_type == "AUDIO" then - out.audioControlData = pParams - elseif module_type == "LIGHT" then - out.lightControlData = pParams - elseif module_type == "HMI_SETTINGS" then - out.hmiSettingsControlData = pParams - end - return out -end - - -- RC RPCs structure - local rcRPCs = { - GetInteriorVehicleData = { - appEventName = "GetInteriorVehicleData", - hmiEventName = "RC.GetInteriorVehicleData", - requestParams = function(pModuleType, pSubscribe) - return { - moduleType = pModuleType, - subscribe = pSubscribe - } - end, - hmiRequestParams = function(pModuleType, pAppId, pSubscribe) - return { - appID = commonRC.getHMIAppId(pAppId), - moduleType = pModuleType, - subscribe = pSubscribe - } - end, - hmiResponseParams = function(pModuleType, pSubscribe) - return { - moduleData = m.getModuleControlData(pModuleType, m.actualInteriorDataStateOnHMI[pModuleType]), - isSubscribed = pSubscribe - } - end, - responseParams = function(success, resultCode, pModuleType, pSubscribe) - return { - success = success, - resultCode = resultCode, - moduleData = m.getModuleControlData(pModuleType, m.actualInteriorDataStateOnHMI[pModuleType]), - isSubscribed = pSubscribe - } - end - }, - OnInteriorVehicleData = { - appEventName = "OnInteriorVehicleData", - hmiEventName = "RC.OnInteriorVehicleData", - hmiResponseParams = function(pModuleType, pParams) - return { - moduleData = m.getModuleControlData(pModuleType, pParams) - } - end, - responseParams = function(pModuleType, pParams) - return { - moduleData = m.getModuleControlData(pModuleType, pParams) - } - end - } -} - -function m.getHMIRequestParams(pRPC, ...) - return rcRPCs[pRPC].hmiRequestParams(...) -end - -function m.getHMIResponseParams(pRPC, ...) - return rcRPCs[pRPC].hmiResponseParams(...) -end - -function m.getResponseParams(pRPC, ...) - return rcRPCs[pRPC].responseParams(...) -end - -function m.getAnotherModuleControlData(module_type) - local out = {} - if module_type == "CLIMATE" then - out = { - fanSpeed = 65, - currentTemperature = { - unit = "FAHRENHEIT", - value = 44.3 - }, - desiredTemperature = { - unit = "CELSIUS", - value = 22.6 - }, - acEnable = false, - circulateAirEnable = false, - autoModeEnable = true, - defrostZone = "ALL", - dualModeEnable = true, - acMaxEnable = false, - ventilationMode = "UPPER" - } - elseif module_type == "RADIO" then - out = { - frequencyInteger = 1, - frequencyFraction = 2, - band = "AM", - rdsData = { - PS = "ps", - RT = "rt", - CT = "123456789012345678901234", - PI = "pi", - PTY = 2, - TP = false, - TA = true, - REG = "US" - }, - availableHDs = 1, - hdChannel = 1, - signalStrength = 5, - signalChangeThreshold = 20, - radioEnable = true, - state = "ACQUIRING" - } - elseif module_type == "SEAT" then - out = { - id = "DRIVER", - heatingEnabled = true, - coolingEnabled = false, - heatingLevel = 35, - coolingLevel = 35, - horizontalPosition = 50, - verticalPosition = 50, - frontVerticalPosition = 50, - backVerticalPosition = 50, - backTiltAngle = 50, - headSupportHorizontalPosition = 50, - headSupportVerticalPosition = 50, - massageEnabled = true, - massageMode = { - { - massageZone = "LUMBAR", - massageMode = "HIGH" - }, - { - massageZone = "SEAT_CUSHION", - massageMode = "LOW" - } - }, - massageCushionFirmness = { - { - cushion = "TOP_LUMBAR", - firmness = 30 - }, - { - cushion = "BACK_BOLSTERS", - firmness = 60 - } - }, - memory = { - id = 1, - label = "Label value", - action = "SAVE" - } - } - elseif module_type == "AUDIO" then - out = { - source = "AM", - volume = 35, - equalizerSettings = { - { - channelId = 10, - channelName = "Channel 1", - channelSetting = 50 - } - } - } - elseif module_type == "LIGHT" then - out = { - lightState = { - { - id = "FRONT_RIGHT_HIGH_BEAM", - status = "ON", - density = 0.4, - color = { - red = 45, - green = 145, - blue = 190 - } - } - } - } - elseif module_type == "HMI_SETTINGS" then - out = { - displayMode = "DAY", - temperatureUnit = "CELSIUS", - distanceUnit = "KILOMETERS" - } - end - return out -end - -function m.unregistrationApp(pAppId, isHMIreqExpect, pModuleType) +function commonRC.unregistrationApp(pAppId, isHMIreqExpect, pModuleType) local rpc = "GetInteriorVehicleData" local HMIrequestsNumber if isHMIreqExpect == true then @@ -429,23 +71,23 @@ function m.unregistrationApp(pAppId, isHMIreqExpect, pModuleType) else HMIrequestsNumber = 0 end - EXPECT_HMICALL(commonRC.getHMIEventName(rpc), m.getHMIRequestParams(rpc, pModuleType, pAppId, false)) + EXPECT_HMICALL(commonRC.getHMIEventName(rpc), commonRC.getHMIRequestParams(rpc, pModuleType, pAppId, false)) :Do(function(_, data) - m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", - m.getHMIResponseParams(rpc, pModuleType, false)) + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", + commonRC.getHMIResponseParams(rpc, pModuleType, false)) end) :Times(HMIrequestsNumber) - local cid = m.getMobileSession(pAppId):SendRPC("UnregisterAppInterface",{}) + local cid = commonRC.getMobileSession(pAppId):SendRPC("UnregisterAppInterface",{}) EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { appID = commonRC.getHMIAppId(pAppId), unexpectedDisconnect = false }) - m.getMobileSession(pAppId):ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) + commonRC.getMobileSession(pAppId):ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) end -function m.setGetInteriorVehicleDataRequestValue(pValue) - m.setSDLIniParameter("GetInteriorVehicleDataRequest", pValue) - m.wait(1000) +function commonRC.setGetInteriorVehicleDataRequestValue(pValue) + actions.setSDLIniParameter("GetInteriorVehicleDataRequest", pValue) + commonRC.wait(1000) end -function m.unexpectedDisconnect(pAppId, isHMIreqExpect, pModuleType) +function commonRC.unexpectedDisconnect(pAppId, isHMIreqExpect, pModuleType) local rpc = "GetInteriorVehicleData" local HMIrequestsNumber if isHMIreqExpect == true then @@ -453,34 +95,27 @@ function m.unexpectedDisconnect(pAppId, isHMIreqExpect, pModuleType) else HMIrequestsNumber = 0 end - EXPECT_HMICALL(commonRC.getHMIEventName(rpc), m.getHMIRequestParams(rpc, pModuleType, pAppId, false)) + EXPECT_HMICALL(commonRC.getHMIEventName(rpc), commonRC.getHMIRequestParams(rpc, pModuleType, pAppId, false)) :Do(function(_, data) - m.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", - m.getHMIResponseParams(rpc, pModuleType, false)) + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", + commonRC.getHMIResponseParams(rpc, pModuleType, false)) end) :Times(HMIrequestsNumber) - m.getMobileSession(pAppId):Stop() + commonRC.getMobileSession(pAppId):Stop() end -function m.activateApp(pAppId, pAudioState) - if not pAppId then pAppId = 1 end - if not pAudioState then pAudioState = "AUDIBLE" end - local requestId = m.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = m.getHMIAppId(pAppId) }) - m.getHMIConnection():ExpectResponse(requestId) - m.getMobileSession(pAppId):ExpectNotification("OnHMIStatus", - { hmiLevel = "FULL", audioStreamingState = pAudioState, systemContext = "MAIN" }) - utils.wait() -end - -function m.preconditions() - m.preconditionOrigin() - commonPreconditions:BackupFile(preloadedPT) - m.updatePreloadedPT() -end - -function m.postconditions() - postconditionOrigin() - commonPreconditions:RestoreFile(preloadedPT) +function commonRC.moduleDataUpdate(pModuleType) + local params = commonRC.cloneTable(commonRC.actualInteriorDataStateOnHMI[pModuleType]) + for key, value in pairs(params) do + if type(value) == "boolean" then + if value == true then + params[key] = false + else + params[key] = true + end + end + end + return params end -return m +return commonRC From 505d37c9ba26a4c7eae3403e5d4ec551b6cec5c1 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Tue, 5 Jun 2018 14:10:07 +0300 Subject: [PATCH 615/681] Initial scripts for LIGHT more names and statuses --- ...etInteriorVD_Success_flow_light_values.lua | 61 +++++++++++++++ ...InteriorVD_Success_flow_light_statuses.lua | 61 +++++++++++++++ .../010_Success_flow_light_values.lua | 75 ++++++++++++++++++ .../011_Success_flow_light_statuses.lua | 76 ++++++++++++++++++ .../018_Success_flow_light_values.lua | 62 +++++++++++++++ ...EAD_ONLY_in_case_statusAvailable_false.lua | 57 ++++++++++++++ ...SOURCE_in_case_statusAvailable_omitted.lua | 77 +++++++++++++++++++ ...NLY_in_case_readOnly_lightStatus_value.lua | 67 ++++++++++++++++ test_scripts/RC/commonRC.lua | 23 ++++++ ...rc_lights_more_names_and_status_values.txt | 9 +++ user_modules/hmi_values.lua | 5 +- 11 files changed, 572 insertions(+), 1 deletion(-) create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/018_GetInteriorVD_Success_flow_light_values.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/019_GetInteriorVD_Success_flow_light_statuses.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/010_Success_flow_light_values.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/011_Success_flow_light_statuses.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/018_Success_flow_light_values.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/019_Light_more_values_READ_ONLY_in_case_statusAvailable_false.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/020_Light_more_values_UNSUPPORTED_RESOURCE_in_case_statusAvailable_omitted.lua create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/021_Light_more_values_READ_ONLY_in_case_readOnly_lightStatus_value.lua create mode 100644 test_sets/rc_lights_more_names_and_status_values.txt diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/018_GetInteriorVD_Success_flow_light_values.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/018_GetInteriorVD_Success_flow_light_values.lua new file mode 100644 index 0000000000..5e1998bb9d --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/018_GetInteriorVD_Success_flow_light_values.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: TRS: GetInteriorVehicleData, #3 +-- In case: +-- 1) RC app sends valid and allowed by policies GetInteriorvehicleData_request +-- 2) and SDL received GetInteriorVehicledata_response with successful result code and current module data from HMI +-- SDL must: +-- 1) transfer GetInteriorVehicleData_response with provided from HMI current module data for allowed module and control items +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/RC/commonRC") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local Module = "LIGHT" + +--[[ Local Functions ]] +local function subscribeToModule(pLightName) + local rpc = "GetInteriorVehicleData" + local subscribe = true + local mobSession = common.getMobileSession() + + local reguestHMIParams = common.getHMIRequestParams(rpc, Module, 1, subscribe) + reguestHMIParams.subscribe = nil + + local responseHMIParams = common.getHMIResponseParams(rpc, Module, subscribe) + responseHMIParams.moduleData.lightControlData.lightState[1].id = pLightName + + local responseParams = common.getAppResponseParams(rpc, true, "SUCCESS", Module, subscribe) + responseParams.moduleData.lightControlData.lightState[1].id = pLightName + + local cid = mobSession:SendRPC(common.getAppEventName(rpc), common.getAppRequestParams(rpc, Module, subscribe)) + EXPECT_HMICALL(common.getHMIEventName(rpc), reguestHMIParams) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", responseHMIParams) + end) + mobSession:ExpectResponse(cid, responseParams) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, lightName in pairs(common.LightsNameList) do + runner.Step("GetInteriorVehicleData Light name " .. lightName, subscribeToModule, { lightName }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/019_GetInteriorVD_Success_flow_light_statuses.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/019_GetInteriorVD_Success_flow_light_statuses.lua new file mode 100644 index 0000000000..2aa6c50230 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/019_GetInteriorVD_Success_flow_light_statuses.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: +-- [SDL_RC] Current module status data GetInteriorVehicleData +-- +-- Description: TRS: GetInteriorVehicleData, #3 +-- In case: +-- 1) RC app sends valid and allowed by policies GetInteriorvehicleData_request +-- 2) and SDL received GetInteriorVehicledata_response with successful result code and current module data from HMI +-- SDL must: +-- 1) transfer GetInteriorVehicleData_response with provided from HMI current module data for allowed module and control items +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/RC/commonRC") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local Module = "LIGHT" + +--[[ Local Functions ]] +local function subscribeToModule(pStatus) + local rpc = "GetInteriorVehicleData" + local subscribe = true + local mobSession = common.getMobileSession() + + local reguestHMIParams = common.getHMIRequestParams(rpc, Module, 1, subscribe) + reguestHMIParams.subscribe = nil + + local responseHMIParams = common.getHMIResponseParams(rpc, Module, subscribe) + responseHMIParams.moduleData.lightControlData.lightState[1].status = pStatus + + local responseParams = common.getAppResponseParams(rpc, true, "SUCCESS", Module, subscribe) + responseParams.moduleData.lightControlData.lightState[1].status = pStatus + + local cid = mobSession:SendRPC(common.getAppEventName(rpc), common.getAppRequestParams(rpc, Module, subscribe)) + EXPECT_HMICALL(common.getHMIEventName(rpc), reguestHMIParams) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", responseHMIParams) + end) + mobSession:ExpectResponse(cid, responseParams) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, status in pairs(common.readOnlyLightStatus) do + runner.Step("GetInteriorVehicleData Light status " .. status, subscribeToModule, { status }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/010_Success_flow_light_values.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/010_Success_flow_light_values.lua new file mode 100644 index 0000000000..c4b34d0463 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/010_Success_flow_light_values.lua @@ -0,0 +1,75 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/4 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/subscription_on_module_status_change_notification.md +-- Item: Use Case 1: Main Flow +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification +-- +-- Description: TRS: GetInteriorVehicleData, #4 +-- In case: +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter +-- 2) and SDL received GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS" from HMI +-- 3) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Internally subscribe this application for requested +-- 2) Transfer GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS", "success:true" to the related app +-- 3) Re-send OnInteriorVehicleData notification to the related app +-- +-- [SDL_RC] Unsubscribe from RC module change notifications +-- +-- Description: TRS: GetInteriorVehicleData, #8 +-- In case: +-- 1) RC app is subscribed to "" +-- 2) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS" from HMI +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Internally un-subscribe this application for requested +-- 2) Transfer GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS", "success:true" to the related app +-- 3) Does not re-send OnInteriorVehicleData notification to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/RC/commonRC") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local Module = "LIGHT" + +--[[ Local Functions ]] +local function isSubscribed(pLightName) + local mobSession = common.getMobileSession() + local rpc = "OnInteriorVehicleData" + + local notificationHMIParams = common.getHMIResponseParams(rpc, Module) + notificationHMIParams.moduleData.lightControlData.lightState[1].id = pLightName + + local notificationParams = common.getAppResponseParams(rpc, Module) + notificationParams.moduleData.lightControlData.lightState[1].id = pLightName + + common.getHMIconnection():SendNotification(common.getHMIEventName(rpc), notificationHMIParams) + mobSession:ExpectNotification(common.getAppEventName(rpc), notificationParams) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Subscribe app to " .. Module, common.subscribeToModule, { Module }) +for _, lightName in pairs(common.LightsNameList) do + runner.Step("Send notification OnInteriorVehicleData Light name " .. lightName, isSubscribed, { lightName }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/011_Success_flow_light_statuses.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/011_Success_flow_light_statuses.lua new file mode 100644 index 0000000000..051464759f --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/011_Success_flow_light_statuses.lua @@ -0,0 +1,76 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/4 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/subscription_on_module_status_change_notification.md +-- Item: Use Case 1: Main Flow +-- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/5 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/unsubscribe_from_module_status_change_notification.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Subscribe on RC module change notification +-- +-- Description: TRS: GetInteriorVehicleData, #4 +-- In case: +-- 1) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:true" parameter +-- 2) and SDL received GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS" from HMI +-- 3) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Internally subscribe this application for requested +-- 2) Transfer GetInteriorVehicleData response with "isSubscribed: true", "resultCode: SUCCESS", "success:true" to the related app +-- 3) Re-send OnInteriorVehicleData notification to the related app +-- +-- [SDL_RC] Unsubscribe from RC module change notifications +-- +-- Description: TRS: GetInteriorVehicleData, #8 +-- In case: +-- 1) RC app is subscribed to "" +-- 2) RC app sends valid and allowed-by-policies GetInteriorVehicleData request with "subscribe:false" parameter +-- 3) and SDL received GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS" from HMI +-- 4) and then SDL received OnInteriorVehicleData notification +-- SDL must: +-- 1) Internally un-subscribe this application for requested +-- 2) Transfer GetInteriorVehicleData response with "isSubscribed: false", "resultCode: SUCCESS", "success:true" to the related app +-- 3) Does not re-send OnInteriorVehicleData notification to the related app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/RC/commonRC") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local Module = "LIGHT" + +--[[ Local Functions ]] +local function isSubscribed(pStatus) + local mobSession = common.getMobileSession() + local rpc = "OnInteriorVehicleData" + + local notificationHMIParams = common.getHMIResponseParams(rpc, Module) + notificationHMIParams.moduleData.lightControlData.lightState[1].status = pStatus + + local notificationParams = common.getAppResponseParams(rpc, Module) + notificationParams.moduleData.lightControlData.lightState[1].status = pStatus + + common.getHMIconnection():SendNotification(common.getHMIEventName(rpc), notificationHMIParams) + mobSession:ExpectNotification(common.getAppEventName(rpc), notificationParams) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") + +runner.Step("Subscribe app to " .. Module, common.subscribeToModule, { Module }) +for _, status in pairs(common.readOnlyLightStatus) do + runner.Step("Send notification OnInteriorVehicleData Light status " .. status, isSubscribed, { status }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/018_Success_flow_light_values.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/018_Success_flow_light_values.lua new file mode 100644 index 0000000000..45c26d96bf --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/018_Success_flow_light_values.lua @@ -0,0 +1,62 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_requirements/issues/3 +-- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/SetInteriorVehicleData.md +-- Item: Use Case 1: Main Flow +-- +-- Requirement summary: +-- [SDL_RC] Set available control module settings SetInteriorVehicleData +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) and sends valid SetInteriorVehicleData RPC with valid parameters +-- SDL must: +-- 1) Transfer this request to HMI +-- 2) Respond with received from HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/RC/commonRC") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local Module = "LIGHT" + +--[[ Local Functions ]] +local function setInteriorVehicleData(pLightName) + local rpc = "SetInteriorVehicleData" + local mobSession = common.getMobileSession() + + local requestParams = common.getAppRequestParams(rpc, Module) + requestParams.moduleData.lightControlData.lightState[1].id = pLightName + + local requestHMIParams = common.getHMIRequestParams(rpc, Module, 1) + requestHMIParams.moduleData.lightControlData.lightState[1].id = pLightName + + local responseHMIParams = common.getHMIResponseParams(rpc, Module) + responseHMIParams.moduleData.lightControlData.lightState[1].id = pLightName + + local cid = mobSession:SendRPC(common.getAppEventName(rpc), requestParams) + EXPECT_HMICALL(common.getHMIEventName(rpc), requestParams) + :Do(function(_, data) + common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", responseHMIParams) + end) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = responseHMIParams.moduleData }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, lightName in pairs(common.LightsNameList) do + runner.Step("SetInteriorVehicleData Light name " .. lightName, setInteriorVehicleData, { lightName }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/019_Light_more_values_READ_ONLY_in_case_statusAvailable_false.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/019_Light_more_values_READ_ONLY_in_case_statusAvailable_false.lua new file mode 100644 index 0000000000..6a861f4c84 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/019_Light_more_values_READ_ONLY_in_case_statusAvailable_false.lua @@ -0,0 +1,57 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0165-rc-lights-more-names-and-status-values.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) HMI sends statusAvailable = false for light_value +-- 3) Application requests SetInteriorVehicleData RPC with light_value +-- SDL must: +-- 1) Reject such request with READ_ONLY result code +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/RC/commonRC") +local hmi_values = require("user_modules/hmi_values") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local Module = "LIGHT" + +--[[ Local Functions ]] +local function setStatusAvailableFalse() + local lightParams = common.getModuleControlData(Module) + local lightName = lightParams.lightControlData.lightState[1].id + local hmiValues = hmi_values.getDefaultHMITable() + for _, value in pairs (hmiValues.RC.GetCapabilities.params.remoteControlCapability.lightControlCapabilities.supportedLights) do + if value.name == lightName then + value.statusAvailable = false + end + end + return hmiValues +end + +local function setInteriorVDreadOnly() + local requestParams = common.getAppRequestParams("SetInteriorVehicleData", Module) + local result = { success = false, resultCode = "READ_ONLY" } + common.rpcUnsuccessResultCode(1, "SetInteriorVehicleData", requestParams, result ) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { setStatusAvailableFalse() }) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData READ_ONLY", setInteriorVDreadOnly) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/020_Light_more_values_UNSUPPORTED_RESOURCE_in_case_statusAvailable_omitted.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/020_Light_more_values_UNSUPPORTED_RESOURCE_in_case_statusAvailable_omitted.lua new file mode 100644 index 0000000000..c908cc9893 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/020_Light_more_values_UNSUPPORTED_RESOURCE_in_case_statusAvailable_omitted.lua @@ -0,0 +1,77 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0165-rc-lights-more-names-and-status-values.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) HMI sends light_value without statusAvailable in capabilities +-- 3) Application requests SetInteriorVehicleData RPC with light_value +-- SDL must: +-- 1) respond with result code UNSUPPORTED_RESOURCE, and info="The requested LightName is not supported by the vehicle." +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/RC/commonRC") +local hmi_values = require("user_modules/hmi_values") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local Module = "LIGHT" + +--[[ Local Functions ]] +local function removeLightValueFromCapabilities() + local lightParams = common.getModuleControlData(Module) + local lightName = lightParams.lightControlData.lightState[1].id + local hmiValues = hmi_values.getDefaultHMITable() + for key, value in pairs (hmiValues.RC.GetCapabilities.params.remoteControlCapability.lightControlCapabilities.supportedLights) do + if value.name == lightName then + table.remove(hmiValues.RC.GetCapabilities.params.remoteControlCapability.lightControlCapabilities.supportedLights, + key) + end + end + return hmiValues +end + +local function setInteriorVDunsupportedResource(pSupportedParam) + local requestParams = common.getAppRequestParams("SetInteriorVehicleData", Module) + if pSupportedParam then + local supportedValue = { + id = removeLightValueFromCapabilities().RC.GetCapabilities.params.remoteControlCapability.lightControlCapabilities.supportedLights[1].name, + status = "ON", + density = 0.5, + sRGBColor = { + red = 50, + green = 50, + blue = 50 + } + } + table.insert (requestParams.moduleData.lightControlData.lightState, supportedValue) + end + local result = { + success = false, + resultCode = "UNSUPPORTED_RESOURCE", + info = "The requested LightName is not supported by the vehicle." + } + common.rpcUnsuccessResultCode(1, "SetInteriorVehicleData", requestParams, result ) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { removeLightValueFromCapabilities() }) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData UNSUPPORTED_RESOURCE with only unsupported value", setInteriorVDunsupportedResource) +runner.Step("SetInteriorVehicleData UNSUPPORTED_RESOURCE with supported and unsupported values", + setInteriorVDunsupportedResource, { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/021_Light_more_values_READ_ONLY_in_case_readOnly_lightStatus_value.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/021_Light_more_values_READ_ONLY_in_case_readOnly_lightStatus_value.lua new file mode 100644 index 0000000000..f7e001f220 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/021_Light_more_values_READ_ONLY_in_case_readOnly_lightStatus_value.lua @@ -0,0 +1,67 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0165-rc-lights-more-names-and-status-values.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) HMI sends statusAvailable = true for light_value in capabilities +-- 3) Application requests SetInteriorVehicleData RPC with light_value and status = "RAMP_UP"/"RAMP_DOWN"/"UNKNOWN"/ "INVALID" +-- SDL must: +-- 1) Reject such request with READ_ONLY result code, and info="The LightStatus enum passed is READ ONLY and cannot be written." +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require("test_scripts/RC/commonRC") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local Module = "LIGHT" + +--[[ Local Functions ]] +local function setInteriorVDunsupportedResource(pStatus, pSupportedParam) + local requestParams = common.getAppRequestParams("SetInteriorVehicleData", Module) + requestParams.moduleData.lightControlData.lightState[1].status = pStatus + if pSupportedParam then + local supportedValue = { + id = "REAR_CARGO_LIGHTS", + status = "ON", + density = 0.5, + sRGBColor = { + red = 50, + green = 50, + blue = 50 + } + } + table.insert (requestParams.moduleData.lightControlData.lightState, supportedValue) + end + local result = { + success = false, + resultCode = "READ_ONLY", + info = "The LightStatus enum passed is READ ONLY and cannot be written." + } + common.rpcUnsuccessResultCode(1, "SetInteriorVehicleData", requestParams, result ) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +for _, value in pairs (common.readOnlyLightStatus) do + runner.Step("SetInteriorVehicleData READ_ONLY with only read only value", + setInteriorVDunsupportedResource, { value }) + runner.Step("SetInteriorVehicleData READ_ONLY with read only and settable values", + setInteriorVDunsupportedResource, { value, true }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index b791b98383..4a82d29ddb 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -71,6 +71,21 @@ commonRC.audioSources = { "DAB" } +commonRC.LightsNameList = { "FRONT_LEFT_HIGH_BEAM", "FRONT_RIGHT_HIGH_BEAM", "FRONT_LEFT_LOW_BEAM", + "FRONT_RIGHT_LOW_BEAM", "FRONT_LEFT_PARKING_LIGHT", "FRONT_RIGHT_PARKING_LIGHT", + "FRONT_LEFT_FOG_LIGHT", "FRONT_RIGHT_FOG_LIGHT", "FRONT_LEFT_DAYTIME_RUNNING_LIGHT", + "FRONT_RIGHT_DAYTIME_RUNNING_LIGHT", "FRONT_LEFT_TURN_LIGHT", "FRONT_RIGHT_TURN_LIGHT", + "REAR_LEFT_FOG_LIGHT", "REAR_RIGHT_FOG_LIGHT", "REAR_LEFT_TAIL_LIGHT", "REAR_RIGHT_TAIL_LIGHT", + "REAR_LEFT_BRAKE_LIGHT", "REAR_RIGHT_BRAKE_LIGHT", "REAR_LEFT_TURN_LIGHT", "REAR_RIGHT_TURN_LIGHT", + "REAR_REGISTRATION_PLATE_LIGHT", "HIGH_BEAMS", "LOW_BEAMS", "FOG_LIGHTS", "RUNNING_LIGHTS", + "PARKING_LIGHTS", "BRAKE_LIGHTS", "REAR_REVERSING_LIGHTS", "SIDE_MARKER_LIGHTS", "LEFT_TURN_LIGHTS", + "RIGHT_TURN_LIGHTS", "HAZARD_LIGHTS", "AMBIENT_LIGHTS", "OVERHEAD_LIGHTS", "READING_LIGHTS", + "TRUNK_LIGHTS", "EXTERIOR_FRONT_LIGHTS", "EXTERIOR_REAR_LIGHTS", "EXTERIOR_LEFT_LIGHTS", + "EXTERIOR_RIGHT_LIGHTS", "REAR_CARGO_LIGHTS", "REAR_TRUCK_BED_LIGHTS", "REAR_TRAILER_LIGHTS", + "LEFT_SPOT_LIGHTS", "RIGHT_SPOT_LIGHTS", "LEFT_PUDDLE_LIGHTS", "RIGHT_PUDDLE_LIGHTS", + "EXTERIOR_ALL_LIGHTS" } +commonRC.readOnlyLightStatus = { "RAMP_UP", "RAMP_DOWN", "UNKNOWN", "INVALID" } + --[[ Common Functions ]] function commonRC.getRCAppConfig(tbl) if tbl then @@ -989,4 +1004,12 @@ function commonRC.getModuleControlDataForResponse(pModuleType) return moduleData end +function commonRC.rpcUnsuccessResultCode(pAppId, pRPC, pRequestParams, pResult) + local mobSession = commonRC.getMobileSession(pAppId) + local cid = mobSession:SendRPC(commonRC.getAppEventName(pRPC), pRequestParams) + EXPECT_HMICALL(commonRC.getHMIEventName(pRPC)) + :Times(0) + mobSession:ExpectResponse(cid, pResult) +end + return commonRC diff --git a/test_sets/rc_lights_more_names_and_status_values.txt b/test_sets/rc_lights_more_names_and_status_values.txt new file mode 100644 index 0000000000..3223b1826e --- /dev/null +++ b/test_sets/rc_lights_more_names_and_status_values.txt @@ -0,0 +1,9 @@ +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/001_Success_flow.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/018_GetInteriorVD_Success_flow_light_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/019_GetInteriorVD_Success_flow_light_statuses.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/018_Success_flow_light_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/019_Light_more_values_READ_ONLY_in_case_statusAvailable_false.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/020_Light_more_values_UNSUPPORTED_RESOURCE_in_case_statusAvailable_omitted.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/021_Light_more_values_READ_ONLY_in_case_readOnly_lightStatus_value.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/010_Success_flow_light_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/011_Success_flow_light_statuses.lua diff --git a/user_modules/hmi_values.lua b/user_modules/hmi_values.lua index 26b454421c..2c9cc176da 100644 --- a/user_modules/hmi_values.lua +++ b/user_modules/hmi_values.lua @@ -419,12 +419,15 @@ function module.getDefaultHMITable() "PARKING_LIGHTS", "BRAKE_LIGHTS", "REAR_REVERSING_LIGHTS", "SIDE_MARKER_LIGHTS", "LEFT_TURN_LIGHTS", "RIGHT_TURN_LIGHTS", "HAZARD_LIGHTS", "AMBIENT_LIGHTS", "OVERHEAD_LIGHTS", "READING_LIGHTS", "TRUNK_LIGHTS", "EXTERIOR_FRONT_LIGHTS", "EXTERIOR_REAR_LIGHTS", "EXTERIOR_LEFT_LIGHTS", - "EXTERIOR_RIGHT_LIGHTS" } + "EXTERIOR_RIGHT_LIGHTS", "REAR_CARGO_LIGHTS", "REAR_TRUCK_BED_LIGHTS", "REAR_TRAILER_LIGHTS", + "LEFT_SPOT_LIGHTS", "RIGHT_SPOT_LIGHTS", "LEFT_PUDDLE_LIGHTS", "RIGHT_PUDDLE_LIGHTS", + "EXTERIOR_ALL_LIGHTS" } local out = { } for _, name in pairs(lights) do local item = { name = name, densityAvailable = true, + statusAvailable = true, rgbColorSpaceAvailable = true } table.insert(out, item) From 548abc0874de4e643353bc7f95916849e2a4d09e Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 21 Jun 2018 10:28:44 +0300 Subject: [PATCH 616/681] One more case for UNSUPPORTED_RESOURCE, fixed info messages --- ...EAD_ONLY_in_case_statusAvailable_false.lua | 8 +- ...SOURCE_in_case_statusAvailable_omitted.lua | 7 +- ...ED_RESOURCE_in_case_light_name_omitted.lua | 78 +++++++++++++++++++ ...rc_lights_more_names_and_status_values.txt | 1 + 4 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/022_Light_more_values_UNSUPPORTED_RESOURCE_in_case_light_name_omitted.lua diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/019_Light_more_values_READ_ONLY_in_case_statusAvailable_false.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/019_Light_more_values_READ_ONLY_in_case_statusAvailable_false.lua index 6a861f4c84..45edff5c63 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/019_Light_more_values_READ_ONLY_in_case_statusAvailable_false.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/019_Light_more_values_READ_ONLY_in_case_statusAvailable_false.lua @@ -11,7 +11,7 @@ -- 2) HMI sends statusAvailable = false for light_value -- 3) Application requests SetInteriorVehicleData RPC with light_value -- SDL must: --- 1) Reject such request with READ_ONLY result code +-- 1) respond with result code READ_ONLY, and info= "The requested parameter is read-only" --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -39,7 +39,11 @@ end local function setInteriorVDreadOnly() local requestParams = common.getAppRequestParams("SetInteriorVehicleData", Module) - local result = { success = false, resultCode = "READ_ONLY" } + local result = { + success = false, + resultCode = "READ_ONLY", + info = "The requested parameter is read-only." + } common.rpcUnsuccessResultCode(1, "SetInteriorVehicleData", requestParams, result ) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/020_Light_more_values_UNSUPPORTED_RESOURCE_in_case_statusAvailable_omitted.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/020_Light_more_values_UNSUPPORTED_RESOURCE_in_case_statusAvailable_omitted.lua index c908cc9893..813a9ec3cf 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/020_Light_more_values_UNSUPPORTED_RESOURCE_in_case_statusAvailable_omitted.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/020_Light_more_values_UNSUPPORTED_RESOURCE_in_case_statusAvailable_omitted.lua @@ -11,7 +11,7 @@ -- 2) HMI sends light_value without statusAvailable in capabilities -- 3) Application requests SetInteriorVehicleData RPC with light_value -- SDL must: --- 1) respond with result code UNSUPPORTED_RESOURCE, and info="The requested LightName is not supported by the vehicle." +-- 1) respond with result code UNSUPPORTED_RESOURCE, and info="The requested parameter of the given LightName is not supported by the vehicle." --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -31,8 +31,7 @@ local function removeLightValueFromCapabilities() local hmiValues = hmi_values.getDefaultHMITable() for key, value in pairs (hmiValues.RC.GetCapabilities.params.remoteControlCapability.lightControlCapabilities.supportedLights) do if value.name == lightName then - table.remove(hmiValues.RC.GetCapabilities.params.remoteControlCapability.lightControlCapabilities.supportedLights, - key) + hmiValues.RC.GetCapabilities.params.remoteControlCapability.lightControlCapabilities.supportedLights[key].statusAvailable = nil end end return hmiValues @@ -56,7 +55,7 @@ local function setInteriorVDunsupportedResource(pSupportedParam) local result = { success = false, resultCode = "UNSUPPORTED_RESOURCE", - info = "The requested LightName is not supported by the vehicle." + info = "The requested parameter of the given LightName is not supported by the vehicle." } common.rpcUnsuccessResultCode(1, "SetInteriorVehicleData", requestParams, result ) end diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/022_Light_more_values_UNSUPPORTED_RESOURCE_in_case_light_name_omitted.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/022_Light_more_values_UNSUPPORTED_RESOURCE_in_case_light_name_omitted.lua new file mode 100644 index 0000000000..17b85e2041 --- /dev/null +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/022_Light_more_values_UNSUPPORTED_RESOURCE_in_case_light_name_omitted.lua @@ -0,0 +1,78 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0165-rc-lights-more-names-and-status-values.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1) Application is registered with REMOTE_CONTROL appHMIType +-- 2) HMI does not send light_value in capabilities +-- 3) Application requests SetInteriorVehicleData RPC with light_value +-- SDL must: +-- 1) respond with result code UNSUPPORTED_RESOURCE, and info="The requested LightName is not supported by the vehicle." +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] + +local runner = require('user_modules/script_runner') +local common = require("test_scripts/RC/commonRC") +local hmi_values = require("user_modules/hmi_values") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local Module = "LIGHT" + +--[[ Local Functions ]] +local function removeLightValueFromCapabilities() + local lightParams = common.getModuleControlData(Module) + local lightName = lightParams.lightControlData.lightState[1].id + local hmiValues = hmi_values.getDefaultHMITable() + for key, value in pairs (hmiValues.RC.GetCapabilities.params.remoteControlCapability.lightControlCapabilities.supportedLights) do + if value.name == lightName then + table.remove(hmiValues.RC.GetCapabilities.params.remoteControlCapability.lightControlCapabilities.supportedLights, + key) + end + end + return hmiValues +end + +local function setInteriorVDunsupportedResource(pSupportedParam) + local requestParams = common.getAppRequestParams("SetInteriorVehicleData", Module) + if pSupportedParam then + local supportedValue = { + id = removeLightValueFromCapabilities().RC.GetCapabilities.params.remoteControlCapability.lightControlCapabilities.supportedLights[1].name, + status = "ON", + density = 0.5, + sRGBColor = { + red = 50, + green = 50, + blue = 50 + } + } + table.insert (requestParams.moduleData.lightControlData.lightState, supportedValue) + end + local result = { + success = false, + resultCode = "UNSUPPORTED_RESOURCE", + info = "The requested LightName is not supported by the vehicle." + } + common.rpcUnsuccessResultCode(1, "SetInteriorVehicleData", requestParams, result ) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { removeLightValueFromCapabilities() }) +runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("SetInteriorVehicleData UNSUPPORTED_RESOURCE with only unsupported value", setInteriorVDunsupportedResource) +runner.Step("SetInteriorVehicleData UNSUPPORTED_RESOURCE with supported and unsupported values", + setInteriorVDunsupportedResource, { true }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) diff --git a/test_sets/rc_lights_more_names_and_status_values.txt b/test_sets/rc_lights_more_names_and_status_values.txt index 3223b1826e..0e163c7ca7 100644 --- a/test_sets/rc_lights_more_names_and_status_values.txt +++ b/test_sets/rc_lights_more_names_and_status_values.txt @@ -5,5 +5,6 @@ ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/019_Light_more_values_READ_ONLY_in_case_statusAvailable_false.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/020_Light_more_values_UNSUPPORTED_RESOURCE_in_case_statusAvailable_omitted.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/021_Light_more_values_READ_ONLY_in_case_readOnly_lightStatus_value.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/022_Light_more_values_UNSUPPORTED_RESOURCE_in_case_light_name_omitted.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/010_Success_flow_light_values.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/011_Success_flow_light_statuses.lua From 4f88addfc7dd8952c74b985cb397cc815e7fa86a Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Wed, 22 Aug 2018 20:32:56 +0300 Subject: [PATCH 617/681] Update scripts for 'lights more name' with new initial RC common --- .../018_GetInteriorVD_Success_flow_light_values.lua | 7 ++++--- .../019_GetInteriorVD_Success_flow_light_statuses.lua | 6 +++--- .../010_Success_flow_light_values.lua | 4 ++-- .../011_Success_flow_light_statuses.lua | 4 ++-- .../018_Success_flow_light_values.lua | 4 ++-- ...more_values_READ_ONLY_in_case_statusAvailable_false.lua | 2 +- ...NSUPPORTED_RESOURCE_in_case_statusAvailable_omitted.lua | 2 +- ...values_READ_ONLY_in_case_readOnly_lightStatus_value.lua | 2 +- ...ues_UNSUPPORTED_RESOURCE_in_case_light_name_omitted.lua | 2 +- test_scripts/RC/commonRC.lua | 1 + 10 files changed, 18 insertions(+), 16 deletions(-) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/018_GetInteriorVD_Success_flow_light_values.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/018_GetInteriorVD_Success_flow_light_values.lua index 5e1998bb9d..7bc404462a 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/018_GetInteriorVD_Success_flow_light_values.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/018_GetInteriorVD_Success_flow_light_values.lua @@ -25,7 +25,7 @@ local Module = "LIGHT" --[[ Local Functions ]] local function subscribeToModule(pLightName) local rpc = "GetInteriorVehicleData" - local subscribe = true + local subscribe = false local mobSession = common.getMobileSession() local reguestHMIParams = common.getHMIRequestParams(rpc, Module, 1, subscribe) @@ -40,16 +40,17 @@ local function subscribeToModule(pLightName) local cid = mobSession:SendRPC(common.getAppEventName(rpc), common.getAppRequestParams(rpc, Module, subscribe)) EXPECT_HMICALL(common.getHMIEventName(rpc), reguestHMIParams) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", responseHMIParams) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", responseHMIParams) end) mobSession:ExpectResponse(cid, responseParams) + common.wait(300) end --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI, PTU", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/019_GetInteriorVD_Success_flow_light_statuses.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/019_GetInteriorVD_Success_flow_light_statuses.lua index 2aa6c50230..f63e3aa58e 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/019_GetInteriorVD_Success_flow_light_statuses.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/019_GetInteriorVD_Success_flow_light_statuses.lua @@ -25,7 +25,7 @@ local Module = "LIGHT" --[[ Local Functions ]] local function subscribeToModule(pStatus) local rpc = "GetInteriorVehicleData" - local subscribe = true + local subscribe = false local mobSession = common.getMobileSession() local reguestHMIParams = common.getHMIRequestParams(rpc, Module, 1, subscribe) @@ -40,7 +40,7 @@ local function subscribeToModule(pStatus) local cid = mobSession:SendRPC(common.getAppEventName(rpc), common.getAppRequestParams(rpc, Module, subscribe)) EXPECT_HMICALL(common.getHMIEventName(rpc), reguestHMIParams) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", responseHMIParams) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", responseHMIParams) end) mobSession:ExpectResponse(cid, responseParams) end @@ -49,7 +49,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI, PTU", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/010_Success_flow_light_values.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/010_Success_flow_light_values.lua index c4b34d0463..c288a17273 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/010_Success_flow_light_values.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/010_Success_flow_light_values.lua @@ -54,7 +54,7 @@ local function isSubscribed(pLightName) local notificationParams = common.getAppResponseParams(rpc, Module) notificationParams.moduleData.lightControlData.lightState[1].id = pLightName - common.getHMIconnection():SendNotification(common.getHMIEventName(rpc), notificationHMIParams) + common.getHMIConnection():SendNotification(common.getHMIEventName(rpc), notificationHMIParams) mobSession:ExpectNotification(common.getAppEventName(rpc), notificationParams) end @@ -62,7 +62,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI, PTU", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/011_Success_flow_light_statuses.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/011_Success_flow_light_statuses.lua index 051464759f..27993daf5e 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/011_Success_flow_light_statuses.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/011_Success_flow_light_statuses.lua @@ -54,7 +54,7 @@ local function isSubscribed(pStatus) local notificationParams = common.getAppResponseParams(rpc, Module) notificationParams.moduleData.lightControlData.lightState[1].status = pStatus - common.getHMIconnection():SendNotification(common.getHMIEventName(rpc), notificationHMIParams) + common.getHMIConnection():SendNotification(common.getHMIEventName(rpc), notificationHMIParams) mobSession:ExpectNotification(common.getAppEventName(rpc), notificationParams) end @@ -62,7 +62,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI, PTU", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/018_Success_flow_light_values.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/018_Success_flow_light_values.lua index 45c26d96bf..e447e0c6c5 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/018_Success_flow_light_values.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/018_Success_flow_light_values.lua @@ -41,7 +41,7 @@ local function setInteriorVehicleData(pLightName) local cid = mobSession:SendRPC(common.getAppEventName(rpc), requestParams) EXPECT_HMICALL(common.getHMIEventName(rpc), requestParams) :Do(function(_, data) - common.getHMIconnection():SendResponse(data.id, data.method, "SUCCESS", responseHMIParams) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", responseHMIParams) end) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", moduleData = responseHMIParams.moduleData }) end @@ -50,7 +50,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI, PTU", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/019_Light_more_values_READ_ONLY_in_case_statusAvailable_false.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/019_Light_more_values_READ_ONLY_in_case_statusAvailable_false.lua index 45edff5c63..acb61ece78 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/019_Light_more_values_READ_ONLY_in_case_statusAvailable_false.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/019_Light_more_values_READ_ONLY_in_case_statusAvailable_false.lua @@ -51,7 +51,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { setStatusAvailableFalse() }) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI, PTU", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/020_Light_more_values_UNSUPPORTED_RESOURCE_in_case_statusAvailable_omitted.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/020_Light_more_values_UNSUPPORTED_RESOURCE_in_case_statusAvailable_omitted.lua index 813a9ec3cf..413eeeb765 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/020_Light_more_values_UNSUPPORTED_RESOURCE_in_case_statusAvailable_omitted.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/020_Light_more_values_UNSUPPORTED_RESOURCE_in_case_statusAvailable_omitted.lua @@ -64,7 +64,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { removeLightValueFromCapabilities() }) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI, PTU", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/021_Light_more_values_READ_ONLY_in_case_readOnly_lightStatus_value.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/021_Light_more_values_READ_ONLY_in_case_readOnly_lightStatus_value.lua index f7e001f220..a13ba80feb 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/021_Light_more_values_READ_ONLY_in_case_readOnly_lightStatus_value.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/021_Light_more_values_READ_ONLY_in_case_readOnly_lightStatus_value.lua @@ -52,7 +52,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI, PTU", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/022_Light_more_values_UNSUPPORTED_RESOURCE_in_case_light_name_omitted.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/022_Light_more_values_UNSUPPORTED_RESOURCE_in_case_light_name_omitted.lua index 17b85e2041..32ce37b637 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/022_Light_more_values_UNSUPPORTED_RESOURCE_in_case_light_name_omitted.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/022_Light_more_values_UNSUPPORTED_RESOURCE_in_case_light_name_omitted.lua @@ -66,7 +66,7 @@ end runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start, { removeLightValueFromCapabilities() }) -runner.Step("RAI, PTU", common.raiPTUn) +runner.Step("RAI, PTU", common.registerAppWOPTU) runner.Step("Activate App", common.activateApp) runner.Title("Test") diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 4a82d29ddb..5ae88b7c87 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -40,6 +40,7 @@ commonRC.getHMIAppId = actions.getHMIAppId commonRC.jsonFileToTable = utils.jsonFileToTable commonRC.tableToJsonFile = utils.tableToJsonFile commonRC.cloneTable = utils.cloneTable +commonRC.wait = utils.wait commonRC.modules = { "RADIO", "CLIMATE" } commonRC.allModules = { "RADIO", "CLIMATE", "SEAT", "AUDIO", "LIGHT", "HMI_SETTINGS" } From 0dcc638634f4788c2a2a5972705989f47fdc74b5 Mon Sep 17 00:00:00 2001 From: Myza Taras Date: Fri, 17 Aug 2018 12:45:04 +0300 Subject: [PATCH 618/681] Script for defect 2446 --- ...E_HMI_with_isActive_is_true_then_false.lua | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 test_scripts/Defects/5_0/2446_SDL_doesn_t_resume_HMILevel_when_DEACTIVATE_HMI_with_isActive_is_true_then_false.lua diff --git a/test_scripts/Defects/5_0/2446_SDL_doesn_t_resume_HMILevel_when_DEACTIVATE_HMI_with_isActive_is_true_then_false.lua b/test_scripts/Defects/5_0/2446_SDL_doesn_t_resume_HMILevel_when_DEACTIVATE_HMI_with_isActive_is_true_then_false.lua new file mode 100644 index 0000000000..0c32936e97 --- /dev/null +++ b/test_scripts/Defects/5_0/2446_SDL_doesn_t_resume_HMILevel_when_DEACTIVATE_HMI_with_isActive_is_true_then_false.lua @@ -0,0 +1,114 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/2446 +-- +-- Description: +-- In smartDeviceLink.ini file: set ApplicationResumingTimeout = 5000 +-- Steps to reproduce: +-- 1) Register Non-Media app +-- 2) Activate app +-- 3) Ignition Off +-- 4) Ignition On +-- 5) Register APP (in step 1) and set Deactivate_HMI=true +-- 6) Wait more than 5 seconds and set Deactivate_HMI = false +-- Expected: +-- 1) App is resumed to HMI level FULL +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('user_modules/sequences/actions') +local utils = require("user_modules/utils") +local commonFunctions = require('user_modules/shared_testcases/commonFunctions') +local test = require("user_modules/dummy_connecttest") + +-- [[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "NAVIGATION" } +config.application1.registerAppInterfaceParams.isMediaApplication = false + +-- [[ Local Functions ]] +local function updateSDLfile() + commonFunctions:write_parameter_to_smart_device_link_ini("ApplicationResumingTimeout", 5000) +end + +local function cleanSessions() + for i = 1, common.getAppsCount() do + test.mobileSession[i] = nil + end + utils.wait() +end + +local function ignitionOff() + common.getHMIConnection():SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnSDLPersistenceComplete") + :Do(function() + common.getHMIConnection():SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) + common.getMobileSession():ExpectNotification("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnSDLClose") + :Do(function() + StopSDL() + end) + end) +end + +function registerAppWithDeactivatedHMI(pAppId) + if not pAppId then pAppId = 1 end + common.getMobileSession(pAppId):StartService(7) + :Do(function() + local corId = common.getMobileSession(pAppId):SendRPC("RegisterAppInterface", common.getConfigAppParams(pAppId)) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", + { application = { appName = common.getConfigAppParams(pAppId).appName } }) + :Do(function(_, d1) + common.setHMIAppId(d1.params.application.appID, pAppId) + common.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") + :Do(function(_, d2) + common.getHMIConnection():SendResponse(d2.id, d2.method, "SUCCESS", { }) + ptuTable = utils.jsonFileToTable(d2.params.file) + end) + end) + common.getMobileSession(pAppId):ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + common.getMobileSession(pAppId):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + common.getMobileSession(pAppId):ExpectNotification("OnPermissionsChange") + :Times(AnyNumber()) + end) + end) +utils.wait(6000) +end + +local function hmiDeactivation() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { eventName = "DEACTIVATE_HMI", isActive = true }) +end + +local function checkResumingActivationApp() + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", { eventName = "DEACTIVATE_HMI", isActive = false }) + common.getHMIConnection():ExpectRequest("BasicCommunication.ActivateApp", {}) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Replase parameter in smartDeviceLink.ini file", updateSDLfile) +runner.Step("Start SDL, init HMI, connect Mobile", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Activate App", common.activateApp) +runner.Step("ShutDown IGNITION_OFF", ignitionOff) +runner.Step("Clean sessions", cleanSessions) +runner.Step("Start SDL, init HMI, connect Mobile", common.start) + + +-- [[ Test ]] +runner.Title("Test") +runner.Step("Deactivate HMI", hmiDeactivation) +runner.Step("Reregister App", registerAppWithDeactivatedHMI) +runner.Step("Activate HMI and check resuming activate App", checkResumingActivationApp) + +-- [[ Postconditions ]] +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From 298fab15232f8e3a8a863d67f930fa8428ca1c67 Mon Sep 17 00:00:00 2001 From: "Ira Lytvynenko (GitHub)" Date: Tue, 19 Jun 2018 14:28:41 +0300 Subject: [PATCH 619/681] Merge pull request #1904 from LitvinenkoIra/fix/rc_disabling Verifies that SDL does not put RC apps to NONE state when user disables RC in HMI --- .../008_Allowed_false.lua | 21 +++++++++---------- .../024_Allowed_false_no_PTU.lua | 18 +++++++--------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua index 61d150e569..4274f92349 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 -- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md --- Item: Use Case 1: Main Flow +-- Item: Use Case 1: Main Flow (updates https://github.com/smartdevicelink/sdl_core/issues/2173) -- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode @@ -12,9 +12,8 @@ -- -- SDL must: -- 1) store RC state allowed:false internally --- 2) assign HMILevel none to all registered applications with appHMIType REMOTE_CONTROL and send OnHMIStatus (NONE) to such apps --- 3) keep all applications with appHMIType REMOTE_CONTROL registered --- 4) unsubscribe all REMOTE_CONTROL applications from OnInteriorVehicleData notifications for all HMI modules internally +-- 2) keep all applications with appHMIType REMOTE_CONTROL registered and in current HMI levels +-- 3) unsubscribe all REMOTE_CONTROL applications from OnInteriorVehicleData notifications for all HMI modules internally --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -50,8 +49,8 @@ local function disableRcFromHmi() commonRC.defineRAMode(false, nil) - mobileSession1:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE"}):Times(AtLeast(1)) -- issue with SDL --> notification is sent twice - mobileSession2:ExpectNotification("OnHMIStatus", {hmiLevel = "NONE"}):Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + mobileSession1:ExpectNotification("OnHMIStatus"):Times(0) + mobileSession2:ExpectNotification("OnHMIStatus"):Times(0) mobileSession3:ExpectNotification("OnHMIStatus"):Times(0) -- NAVIGATION app commonTestCases:DelayedExp(commonRC.timeout) @@ -78,11 +77,11 @@ for _, mod in pairs(commonRC.modules) do -- Apps are not subscribed from RC modules runner.Step("Check App1 is not subscribed on " .. mod, commonRC.isUnsubscribed, { mod, 1 }) runner.Step("Check App2 is not subscribed on " .. mod, commonRC.isUnsubscribed, { mod, 2 }) - -- -- All RC RPCs denied - need clarification - -- for _, rpc in pairs(rcRpcs) do - -- runner.Step("Check module " .. mod .." App1 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 1, rpc, "DISALLOWED" }) - -- runner.Step("Check module " .. mod .." App2 " .. rpc .. " denied", commonRC.rpcDenied, { mod, 2, rpc, "DISALLOWED" }) - -- end + -- All RC RPCs rejected + for _, rpc in pairs(rcRpcs) do + runner.Step("Check module " .. mod .." App1 " .. rpc .. " rejected", commonRC.rpcDenied, { mod, 1, rpc, "USER_DISALLOWED" }) + runner.Step("Check module " .. mod .." App2 " .. rpc .. " rejected", commonRC.rpcDenied, { mod, 2, rpc, "USER_DISALLOWED" }) + end end diff --git a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua index 10ee97a21e..f87585e865 100644 --- a/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua +++ b/test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------------------------------- -- User story: https://github.com/smartdevicelink/sdl_requirements/issues/11 -- Use case: https://github.com/smartdevicelink/sdl_requirements/blob/master/detailed_docs/rc_enabling_disabling.md --- Item: Use Case 1: Main Flow +-- Item: Use Case 1: Main Flow (updates https://github.com/smartdevicelink/sdl_core/issues/2173) -- -- Requirement summary: -- [SDL_RC] Resource allocation based on access mode @@ -12,9 +12,7 @@ -- -- SDL must: -- 1) store RC state allowed:false internally --- 2) assign HMILevel none to all registered applications with appHMIType REMOTE_CONTROL --- and send OnHMIStatus (NONE) to such apps --- 3) keep all applications with appHMIType REMOTE_CONTROL registered +-- 2) keep all applications with appHMIType REMOTE_CONTROL registered and in current HMI levels --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -30,13 +28,13 @@ config.application2.registerAppInterfaceParams.appHMIType = { "REMOTE_CONTROL" } config.application3.registerAppInterfaceParams.appHMIType = { "DEFAULT" } --[[ Local Functions ]] -local function disableRCFromHMI(self) - commonRC.defineRAMode(false, nil, self) +local function disableRCFromHMI() + commonRC.defineRAMode(false, nil) - commonRC.getMobileSession():ExpectNotification("OnHMIStatus", { hmiLevel = "NONE" }) - :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice - commonRC.getMobileSession(2):ExpectNotification("OnHMIStatus", { hmiLevel = "NONE" }) - :Times(AtLeast(1)) -- issue with SDL --> notification is sent twice + commonRC.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) + commonRC.getMobileSession(2):ExpectNotification("OnHMIStatus") + :Times(0) commonRC.getMobileSession(3):ExpectNotification("OnHMIStatus") :Times(0) From a3097dbbd9cc63e67196a11f0863154312131271 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Thu, 23 Aug 2018 11:03:48 -0400 Subject: [PATCH 620/681] Fix merge conflicts --- files/PTU_NewPermissionsForUserConsent.json | 4 --- .../Policy_Table_Update/endpoints_appId.json | 4 --- .../Policies/appID_Management/ptu_0.json | 5 --- .../Policies/appID_Management/ptu_013_1.json | 11 ------ .../OnAppPermissionConsent_1.json | 36 ++++++------------- ...preloaded_pt_AlertOnlyNotifications_1.json | 4 --- test_scripts/API/ATF_Show.lua | 4 --- .../066_ATF_PTU_Validation_Failure_HTTP.lua | 5 --- .../testCasesForPolicyTableSnapshot.lua | 4 --- 9 files changed, 10 insertions(+), 67 deletions(-) diff --git a/files/PTU_NewPermissionsForUserConsent.json b/files/PTU_NewPermissionsForUserConsent.json index bd3dd2f676..ecb9b93989 100644 --- a/files/PTU_NewPermissionsForUserConsent.json +++ b/files/PTU_NewPermissionsForUserConsent.json @@ -2294,12 +2294,8 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4"], -<<<<<<< HEAD "RequestType": [], "RequestSubType": [] -======= - "RequestType": [] ->>>>>>> origin/develop }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/Policy_Table_Update/endpoints_appId.json b/files/jsons/Policies/Policy_Table_Update/endpoints_appId.json index 368c9f1ead..ef216abf0a 100644 --- a/files/jsons/Policies/Policy_Table_Update/endpoints_appId.json +++ b/files/jsons/Policies/Policy_Table_Update/endpoints_appId.json @@ -2247,12 +2247,8 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4"], -<<<<<<< HEAD "RequestType": [], "RequestSubType": [] -======= - "RequestType": [] ->>>>>>> origin/develop }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/appID_Management/ptu_0.json b/files/jsons/Policies/appID_Management/ptu_0.json index 551a6e309c..68310b9924 100644 --- a/files/jsons/Policies/appID_Management/ptu_0.json +++ b/files/jsons/Policies/appID_Management/ptu_0.json @@ -16,14 +16,9 @@ "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", -<<<<<<< HEAD "groups": ["Base-4"], "RequestType": [], "RequestSubType": [] -======= - "groups": ["Base-4"], - "RequestType": [] ->>>>>>> origin/develop }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/appID_Management/ptu_013_1.json b/files/jsons/Policies/appID_Management/ptu_013_1.json index 3c14847196..3aa4b9bfbc 100644 --- a/files/jsons/Policies/appID_Management/ptu_013_1.json +++ b/files/jsons/Policies/appID_Management/ptu_013_1.json @@ -4,18 +4,11 @@ "0000001": { "groups": ["Base-4", "Base-6"], "priority": "NONE", -<<<<<<< HEAD - "keep_context": false, - "steal_focus": false, - "default_hmi": "NONE", - "nicknames": ["App1"] -======= "keep_context": false, "steal_focus": false, "default_hmi": "NONE", "nicknames": ["App1"], "RequestType": [] ->>>>>>> origin/develop }, "default": { "keep_context": false, @@ -23,12 +16,8 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4"], -<<<<<<< HEAD "RequestType": [], "RequestSubType": [] -======= - "RequestType": [] ->>>>>>> origin/develop }, "device": { "keep_context": false, diff --git a/files/jsons/Policies/user_consent/OnAppPermissionConsent_1.json b/files/jsons/Policies/user_consent/OnAppPermissionConsent_1.json index 0a62ac428e..72cd4b06b9 100644 --- a/files/jsons/Policies/user_consent/OnAppPermissionConsent_1.json +++ b/files/jsons/Policies/user_consent/OnAppPermissionConsent_1.json @@ -2243,40 +2243,24 @@ } }, "app_policies": { -<<<<<<< HEAD - "0000001": { - "keep_context": false, - "steal_focus": false, - "priority": "NONE", - "default_hmi": "NONE", - "groups": [ - "Base-4", "Notifications", "Location-1" - ] - }, -======= - "0000001": { - "keep_context": false, - "steal_focus": false, - "priority": "NONE", - "default_hmi": "NONE", - "groups": [ - "Base-4", "Notifications", "Location-1" - ], - "RequestType": [] - }, ->>>>>>> origin/develop + "0000001": { + "keep_context": false, + "steal_focus": false, + "priority": "NONE", + "default_hmi": "NONE", + "groups": [ + "Base-4", "Notifications", "Location-1" + ], + "RequestType": [] + }, "default": { "keep_context": false, "steal_focus": false, "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4"], -<<<<<<< HEAD "RequestType": [], "RequestSubType": [] -======= - "RequestType": [] ->>>>>>> origin/develop }, "device": { "keep_context": false, diff --git a/files/sdl_preloaded_pt_AlertOnlyNotifications_1.json b/files/sdl_preloaded_pt_AlertOnlyNotifications_1.json index 02784dd351..3cecb6a16d 100644 --- a/files/sdl_preloaded_pt_AlertOnlyNotifications_1.json +++ b/files/sdl_preloaded_pt_AlertOnlyNotifications_1.json @@ -2253,12 +2253,8 @@ "priority": "NONE", "default_hmi": "NONE", "groups": ["Base-4"], -<<<<<<< HEAD "RequestType": [], "RequestSubType": [] -======= - "RequestType": [] ->>>>>>> origin/develop }, "device": { "keep_context": false, diff --git a/test_scripts/API/ATF_Show.lua b/test_scripts/API/ATF_Show.lua index 593beda44b..9a757c6192 100644 --- a/test_scripts/API/ATF_Show.lua +++ b/test_scripts/API/ATF_Show.lua @@ -38,12 +38,8 @@ require('user_modules/AppTypes') --------------------------------------------------------------------------------------------- APIName = "Show" -- set request name strMaxLengthFileName255 = string.rep("a", 251) .. ".png" -- set max length file name -<<<<<<< HEAD ---local storagePath = config.pathToSDL .. SDLConfig:GetValue("AppStorageFolder") .. "/" .. tostring(config.application1.registerAppInterfaceParams.fullAppID .. "_" .. tostring(config.deviceMAC) .. "/") -======= strMaxLengthInvalidFileName255 = string.rep("a", 251) .. ".png" -- set max length file name --local storagePath = config.pathToSDL .. SDLConfig:GetValue("AppStorageFolder") .. "/" .. tostring(config.application1.registerAppInterfaceParams.appID .. "_" .. tostring(config.deviceMAC) .. "/") ->>>>>>> origin/develop --Debug = {"graphic", "value"} --use to print request before sending to SDL. Debug = {} -- empty {}: script will do not print request on console screen. diff --git a/test_scripts/Policies/build_options/066_ATF_PTU_Validation_Failure_HTTP.lua b/test_scripts/Policies/build_options/066_ATF_PTU_Validation_Failure_HTTP.lua index 394d193f4f..97ade7495c 100644 --- a/test_scripts/Policies/build_options/066_ATF_PTU_Validation_Failure_HTTP.lua +++ b/test_scripts/Policies/build_options/066_ATF_PTU_Validation_Failure_HTTP.lua @@ -124,13 +124,8 @@ function Test:RAI_PTU() :Do( function(_, d1) log("SDL->HMI: N: BC.OnAppRegistered") -<<<<<<< HEAD self.applications[config.application1.registerAppInterfaceParams.fullAppID] = d1.params.application.appID - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UPDATE_NEEDED" }, { status = "UPDATING" }) -======= - self.applications[config.application1.registerAppInterfaceParams.appID] = d1.params.application.appID EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATE_NEEDED" }, { status = "UPDATING" }, { status = "UPDATE_NEEDED" }) ->>>>>>> origin/develop :Do( function(_, d2) log("SDL->HMI: N: SDL.OnStatusUpdate", d2.params.status) diff --git a/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua b/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua index 50176d6738..0bb2cccaa3 100644 --- a/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua +++ b/user_modules/shared_testcases/testCasesForPolicyTableSnapshot.lua @@ -131,11 +131,7 @@ function testCasesForPolicyTableSnapshot:verify_PTS(is_created, app_IDs, device_ { name = "module_config.notifications_per_minute_by_priority.COMMUNICATION", elem_required = "required"}, { name = "module_config.notifications_per_minute_by_priority.NORMAL", elem_required = "required"}, { name = "module_config.notifications_per_minute_by_priority.NONE", elem_required = "required"}, -<<<<<<< HEAD - { name = "module_config.notifications_per_minute_by_priority.PROJECTION", elem_required = "required"}, -======= { name = "module_config.notifications_per_minute_by_priority.PROJECTION", elem_required = "optional"}, ->>>>>>> origin/develop { name = "module_config.certificate", elem_required = "optional"}, { name = "module_config.vehicle_make", elem_required = "optional"}, { name = "module_config.vehicle_model", elem_required = "optional"}, From 6b96d1e0a825620b676f810a9b2bdb26d2fc2ba1 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Fri, 24 Aug 2018 14:51:20 -0400 Subject: [PATCH 621/681] Remove duplicate play_pause --- files/hmi_capabilities_SearchButton.json | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/files/hmi_capabilities_SearchButton.json b/files/hmi_capabilities_SearchButton.json index e9c77ffca4..7263732512 100644 --- a/files/hmi_capabilities_SearchButton.json +++ b/files/hmi_capabilities_SearchButton.json @@ -379,12 +379,6 @@ "longPressAvailable": true, "upDownAvailable": true }, - { - "name":"PLAY_PAUSE", - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true - }, { "name": "SEEKLEFT", "shortPressAvailable": true, @@ -426,4 +420,4 @@ "majorVersion": 3, "minorVersion": 0 } -} \ No newline at end of file +} From a2ca9c4872a1b844696c678768a1816eb82dd311 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Fri, 24 Aug 2018 14:52:26 -0400 Subject: [PATCH 622/681] Remove duplicate play_pause --- files/hmi_capabilities_Without_PRESET9.json | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/files/hmi_capabilities_Without_PRESET9.json b/files/hmi_capabilities_Without_PRESET9.json index 12051caf74..a8baf3d057 100644 --- a/files/hmi_capabilities_Without_PRESET9.json +++ b/files/hmi_capabilities_Without_PRESET9.json @@ -373,12 +373,6 @@ "longPressAvailable": true, "upDownAvailable": true }, - { - "name":"PLAY_PAUSE", - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true - }, { "name": "SEEKLEFT", "shortPressAvailable": true, @@ -414,4 +408,4 @@ "majorVersion": 3, "minorVersion": 0 } -} \ No newline at end of file +} From 2021a9c9774373b67dbc0e1ccf956dfad946413e Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 28 Aug 2018 12:18:26 +0300 Subject: [PATCH 623/681] Make safeguard in getPTUFromPTS --- .../Security/SSLHandshakeFlow/common.lua | 1 - user_modules/sequences/actions.lua | 51 +++++++++++-------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/test_scripts/Security/SSLHandshakeFlow/common.lua b/test_scripts/Security/SSLHandshakeFlow/common.lua index e2c606f9bc..432448fe3c 100644 --- a/test_scripts/Security/SSLHandshakeFlow/common.lua +++ b/test_scripts/Security/SSLHandshakeFlow/common.lua @@ -186,7 +186,6 @@ function m.policyTableUpdateSuccess(pPTUpdateFunc) :Do(function(e, d) if e.occurences == 1 then m.getHMIConnection():SendResponse(d.id, d.method, "SUCCESS", { }) - m.setPTUTable(utils.jsonFileToTable(d.params.file)) m.policyTableUpdate(pPTUpdateFunc, expNotificationFunc) end end) diff --git a/user_modules/sequences/actions.lua b/user_modules/sequences/actions.lua index c59c655d85..fbd251db42 100644 --- a/user_modules/sequences/actions.lua +++ b/user_modules/sequences/actions.lua @@ -20,7 +20,6 @@ local m = {} m.minTimeout = 500 --[[ Variables ]] -local ptuTable = {} local hmiAppIds = {} local originalValuesInSDLIni = {} @@ -33,14 +32,36 @@ test.mobileSession = {} --! pTbl - table with policy table snapshot (PTS) --! @return: table with PTU --]] -local function getPTUFromPTS(pTbl) - pTbl.policy_table.consumer_friendly_messages.messages = nil - pTbl.policy_table.device_data = nil - pTbl.policy_table.module_meta = nil - pTbl.policy_table.usage_and_error_counts = nil - pTbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null - pTbl.policy_table.module_config.preloaded_pt = nil - pTbl.policy_table.module_config.preloaded_date = nil +local function getPTUFromPTS() + local pTbl = {} + local ptsFileName = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" + .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + if utils.isFileExist(ptsFileName) then + pTbl = utils.jsonFileToTable(ptsFileName) + else + utils.cprint(35, "PTS file was not found, PreloadedPT is used instead") + local appConfigFolder = commonFunctions:read_parameter_from_smart_device_link_ini("AppConfigFolder") + if appConfigFolder == nil or appConfigFolder == "" then + appConfigFolder = commonPreconditions:GetPathToSDL() + end + local preloadedPT = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + local ptsFile = appConfigFolder .. preloadedPT + if utils.isFileExist(ptsFile) then + pTbl = utils.jsonFileToTable(ptsFile) + else + utils.cprint(35, "PreloadedPT was not found, PTS is not created") + end + end + if next(pTbl) ~= nil then + pTbl.policy_table.consumer_friendly_messages.messages = nil + pTbl.policy_table.device_data = nil + pTbl.policy_table.module_meta = nil + pTbl.policy_table.usage_and_error_counts = nil + pTbl.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + pTbl.policy_table.module_config.preloaded_pt = nil + pTbl.policy_table.module_config.preloaded_date = nil + end + return pTbl end --[[ @getAppDataForPTU: provide application data for PTU @@ -77,7 +98,7 @@ function m.policyTableUpdate(pPTUpdateFunc, pExpNotificationFunc) :Do(function() m.getHMIConnection():SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", fileName = ptsFileName }) - getPTUFromPTS(ptuTable) + local ptuTable = getPTUFromPTS() for i = 1, m.getAppsCount() do ptuTable.policy_table.app_policies[m.getConfigAppParams(i).fullAppID] = m.getAppDataForPTU(i) end @@ -211,7 +232,6 @@ function m.registerApp(pAppId) m.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") :Do(function(_, d2) m.getHMIConnection():SendResponse(d2.id, d2.method, "SUCCESS", { }) - ptuTable = utils.jsonFileToTable(d2.params.file) end) end) m.getMobileSession(pAppId):ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) @@ -469,15 +489,6 @@ function m.getPathToFileInStorage(pFileName, pAppId) .. utils.getDeviceMAC() .. "/" .. pFileName end ---[[ @setPTUTable: set PTU table that is used in Policy Table Update sequence ---! @parameters: ---! @pPTUTable - PTU table ---! @return: none ---]] -function m.setPTUTable(pPTUTable) - ptuTable = pPTUTable -end - --[[ @setHMIAppId: set HMI application identifier --! @parameters: --! pHMIAppId - HMI application identifier From 34deedd5b08b580308782c379f0c52f40a9c0721 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 28 Aug 2018 16:22:14 +0300 Subject: [PATCH 624/681] Updating scripts according to changes in proposal --- ...l_vrCommands_in_one_addCommand_request.lua | 4 +- ...n_one_addCommand_request_by_resumption.lua | 4 +- ...ing_30_commands_several_in_one_command.lua | 20 ++-- ...s_several_in_one_command_by_resumption.lua | 20 ++-- .../033_SetGlobalProp_delete_last_command.lua | 92 ++++--------------- .../commonVRhelp.lua | 32 +++---- 6 files changed, 58 insertions(+), 114 deletions(-) diff --git a/test_scripts/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua b/test_scripts/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua index b429cdecd7..1b6dd64a20 100644 --- a/test_scripts/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua +++ b/test_scripts/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua @@ -7,9 +7,9 @@ -- -- Description: -- In case: --- 1. Command1 commands with vrCommands Command1_1, Command2_1, Command3_1 is added +-- 1. Command1 commands with Command1_1, Command2_1, Command3_1 synonyms is added -- SDL does: --- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands. +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using 1st synonym --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') diff --git a/test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua b/test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua index 7a1af6be24..bedf5992af 100644 --- a/test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua @@ -7,11 +7,11 @@ -- -- Description: -- In case: --- 1. Command1 commands with vrCommands Command1_1, Command2_1, Command3_1 is added +-- 1. Command1 commands with Command1_1, Command2_1, Command3_1 synonyms is added -- 2. Perform reconnect -- 3. SDL resumes commands -- SDL does: --- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using added vrCommands +-- send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using 1st synonym -- by command resumption --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] diff --git a/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua b/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua index e470028986..ff2f82df0f 100644 --- a/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua +++ b/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua @@ -7,12 +7,15 @@ -- -- Description: -- In case: --- 1. Mobile application sets 29 command one by one --- 2. Mobile application sets 2 commands in one request +-- 1. Mobile application sets 28 command one by one +-- 2. Mobile application sets 2 commands in one request (29) with 2 synonyms +-- 3. Mobile application sets 1 command in one request (30) +-- 4. Mobile application sets 1 command in one request (31) -- SDL does: --- 1. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters for 30 VR commands --- and exclude 31th VR command from list --- 2. not send SetGlobalProperties after added 31 command +-- 1. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters for 28 VR commands +-- 2. send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using 1st synonym from list +-- 3. send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters +-- 4. not send SetGlobalProperties after added 31 command --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -22,7 +25,7 @@ local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local AddCommandParams = common.getAddCommandParams(30) +local AddCommandParams = common.getAddCommandParams(29) AddCommandParams.vrCommands = { "Command_30_1", "Command_30_2" } --[[ Scenario ]] @@ -33,12 +36,13 @@ runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) runner.Title("Test") -for i = 1, 29 do +for i = 1, 28 do runner.Step("SetGlobalProperties from SDL after added command " .. i, common.addCommandWithSetGP, { i }) end runner.Step("SetGlobalProperties after AddCommand with several vrCommand", common.addCommandWithSetGP, { nil, AddCommandParams }) -runner.Step("Absence SetGlobalProperties from SDL after adding 32 VR command", common.addCommandWithoutSetGP, { 31 }) +runner.Step("SetGlobalProperties from SDL after added command 30", common.addCommandWithSetGP, { 30 }) +runner.Step("Absence SetGlobalProperties from SDL after adding 31 VR command", common.addCommandWithoutSetGP, { 31 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua b/test_scripts/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua index d47b6094f0..8d4e7ae58a 100644 --- a/test_scripts/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua +++ b/test_scripts/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua @@ -7,14 +7,17 @@ -- -- Description: -- In case: --- 1. Mobile application sets 29 command one by one +-- 1. Mobile application sets 28 command one by one -- 2. Perform reconnect -- 3. SDL resumes commands --- 4. Mobile application sets 2 commands in one request +-- 4. Mobile application sets 1 command in one request (29) with 2 synonyms +-- 5. Mobile application sets 1 command in one request (30) +-- 6. Mobile application sets 1 command in one request (31) -- SDL does: --- 1. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters for 30 VR commands --- and exclude 31th VR command from list --- 2. not send SetGlobalProperties after added 31 command +-- 1. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters for 28 VR commands +-- 4. send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters using 1st synonym from list +-- 5. send SetGlobalProperties with constructed the vrHelp and helpPrompt parameters +-- 6. not send SetGlobalProperties after added 31 command --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -24,7 +27,7 @@ local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') runner.testSettings.isSelfIncluded = false --[[ Local Variables ]] -local AddCommandParams = common.getAddCommandParams(30) +local AddCommandParams = common.getAddCommandParams(29) AddCommandParams.vrCommands = { "Command_30_1", "Command_30_2" } --[[ Scenario ]] @@ -36,7 +39,7 @@ runner.Step("Pin OnHashChange", common.pinOnHashChange) runner.Step("App activation", common.activateApp) runner.Title("Test") -for i = 1, 29 do +for i = 1, 28 do runner.Step("SetGlobalProperties from SDL after added command " .. i, common.addCommandWithSetGP, { i }) end runner.Step("App reconnect", common.reconnect) @@ -44,7 +47,8 @@ runner.Step("App resumption", common.registrationWithResumption, { 1, common.resumptionLevelFull, common.resumptionDataAddCommands }) runner.Step("SetGlobalProperties after AddCommand with several vrCommand", common.addCommandWithSetGP, { nil, AddCommandParams }) -runner.Step("Absence SetGlobalProperties from SDL after adding 32 VR command", common.addCommandWithoutSetGP, { 31 }) +runner.Step("SetGlobalProperties from SDL after added command 30", common.addCommandWithSetGP, { 30 }) +runner.Step("Absence SetGlobalProperties from SDL after adding 31 VR command", common.addCommandWithoutSetGP, { 31 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua b/test_scripts/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua index f118270003..64239ec6d6 100644 --- a/test_scripts/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua +++ b/test_scripts/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua @@ -7,18 +7,18 @@ -- -- Description: -- In case: --- 1. Mobile application sets 30 commands in requests #1, #2, #3 --- 2. Mobile application sets 10 commands in requests #4 and #5 --- 3. Mobile application removes commands +-- 1. Mobile application sets 30 commands +-- 2. Mobile application sets 31st command +-- 3. Mobile application removes 31st command +-- 4. Mobile application removes 1st command +-- 5. Mobile application sets 32nd command -- SDL does: -- 1. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters for 30 VR commands --- after processing request #1, #2, #3 --- 2. not send SetGlobalProperties after processing requests #4, #5 --- 3. not send SetGlobalProperties when commands from request #4 and #5 were removed +-- 2. not send SetGlobalProperties for 31st VR command +-- 3. not send SetGlobalProperties when 31st VR command is removed -- 4. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters for 30 VR commands --- after removing commands from requests #1, #2 --- 5. send SetGlobalProperties with empty array for helpPrompt parameter and omitted vrHelp parameter --- after removing commands from requests #3 +-- when 1st VR command is removed +-- 5. send SetGlobalProperties with full list of command values for vrHelp and helpPrompt parameters for 32nd VR command --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -27,55 +27,6 @@ local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false ---[[ Local Variables ]] -local function getVRCommandsList(pCmdId, pN) - local out = {} - for _ = 1, pN do - table.insert(out, "Command_" .. pCmdId .. "_" .. pN) - end - return out -end - -local params1 = common.getAddCommandParams(1) -params1.vrCommands = getVRCommandsList(1, 10) - -local params2 = common.getAddCommandParams(2) -params2.vrCommands = getVRCommandsList(2, 10) - -local params3 = common.getAddCommandParams(3) -params3.vrCommands = getVRCommandsList(3, 10) - -local params4 = common.getAddCommandParams(4) -params4.vrCommands = getVRCommandsList(4, 5) - -local params5 = common.getAddCommandParams(5) -params5.vrCommands = getVRCommandsList(5, 5) - - -local function deleteLastCommand(pN) - common.deleteCommand({ cmdID = pN }, true) - local requestUiParams = { - vrHelpTitle = common.getConfigAppParams().appName - } - EXPECT_HMICALL("UI.SetGlobalProperties", requestUiParams) - :Do(function(_,data) - common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) - end) - :ValidIf(function(_, data) - if data.params.vrHelp ~= nil then - return false, "'vrHelp' is not expected" - end - return true - end) - local requestTtsParams = { - helpPrompt = {} - } - EXPECT_HMICALL("TTS.SetGlobalProperties", requestTtsParams) - :Do(function(_,data) - common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) - end) -end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", common.preconditions) @@ -84,24 +35,13 @@ runner.Step("App registration", common.registerAppWOPTU) runner.Step("App activation", common.activateApp) runner.Title("Test") -runner.Step("SetGlobalProperties from SDL after added cmd_id 1 with 10 commands", common.addCommandWithSetGP, - { nil, params1 }) -runner.Step("SetGlobalProperties from SDL after added cmd_id 2 with 10 commands", common.addCommandWithSetGP, - { nil, params2 }) -runner.Step("SetGlobalProperties from SDL after added cmd_id 3 with 10 commands", common.addCommandWithSetGP, - { nil, params3 }) - -runner.Step("Absence SetGlobalProperties from SDL after adding cmd_id 4 with 5 commands", common.addCommandWithoutSetGP, - { nil, params4 }) -runner.Step("Absence SetGlobalProperties from SDL after adding cmd_id 5 with 5 commands", common.addCommandWithoutSetGP, - { nil, params5 }) - -runner.Step("No SetGlobalProperties from SDL after deleted cmd_id 4", common.deleteCommandWithoutSetGP, { 4 }) -runner.Step("No SetGlobalProperties from SDL after deleted cmd_id 5", common.deleteCommandWithoutSetGP, { 5 }) - -runner.Step("SetGlobalProperties from SDL after deleted cmd_id 1", common.deleteCommandWithSetGP, { 1 }) -runner.Step("SetGlobalProperties from SDL after deleted cmd_id 2", common.deleteCommandWithSetGP, { 2 }) -runner.Step("SetGlobalProperties from SDL after deleted cmd_id 3", deleteLastCommand, { 3 }) +for i = 1, 30 do + runner.Step("SetGlobalProperties from SDL after added command " .. i, common.addCommandWithSetGP, { i }) +end +runner.Step("No SetGlobalProperties from SDL after added command 31", common.addCommandWithoutSetGP, { 31 }) +runner.Step("No SetGlobalProperties from SDL after deleted command 31", common.deleteCommandWithoutSetGP, { 31 }) +runner.Step("SetGlobalProperties from SDL after deleted command 1", common.deleteCommandWithSetGP, { 1 }) +runner.Step("SetGlobalProperties from SDL after added command 32", common.addCommandWithSetGP, { 32 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/Handling_VR_help_requests/commonVRhelp.lua b/test_scripts/Handling_VR_help_requests/commonVRhelp.lua index 9bbaa820d7..cab38daff3 100644 --- a/test_scripts/Handling_VR_help_requests/commonVRhelp.lua +++ b/test_scripts/Handling_VR_help_requests/commonVRhelp.lua @@ -172,15 +172,13 @@ function m.vrHelp(pCommandArray) local out = {} local counter = 0 for _, value in pairs(pCommandArray) do - for _, sub_v in pairs(value.vrCommand) do - counter = counter + 1 - local item = { - text = sub_v, - position = counter - } - table.insert(out, item) - if counter == m.commandsLimit then return out end - end + counter = counter + 1 + local item = { + text = value.vrCommand[1], + position = counter + } + table.insert(out, item) + if counter == m.commandsLimit then return out end end return out end @@ -189,15 +187,13 @@ function m.vrHelpPrompt(pVrCommandArray) local out = {} local counter = 0 for _, value in pairs(pVrCommandArray) do - for _, sub_v in pairs(value.vrCommand) do - counter = counter + 1 - local item = { - text = sub_v, - type = "TEXT" - } - table.insert(out, item) - if counter == m.commandsLimit then return out end - end + counter = counter + 1 + local item = { + text = value.vrCommand[1], + type = "TEXT" + } + table.insert(out, item) + if counter == m.commandsLimit then return out end end return out end From 9510d6b298692a4543cd50d374d0393a5fb93316 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 28 Aug 2018 10:18:50 -0400 Subject: [PATCH 625/681] Update expectation to PLAY_PAUSE --- .../PlayPauseButton/002_play_pause_v4_invalid_data.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua b/test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua index 6a823ff310..a6bdf9a865 100644 --- a/test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua +++ b/test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua @@ -39,7 +39,7 @@ config.application1.registerAppInterfaceParams.syncMsgVersion = { local function subscribeButtonSuccess(pButName, self) local cid = self.mobileSession1:SendRPC("SubscribeButton", { buttonName = pButName }) local appIDvalue = commonSmoke.getHMIAppId() - EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", { appID = appIDvalue, name = pButName, isSubscribed = true }) + EXPECT_HMINOTIFICATION("Buttons.OnButtonSubscription", { appID = appIDvalue, name = "PLAY_PAUSE", isSubscribed = true }) self.mobileSession1:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) self.mobileSession1:ExpectNotification("OnHashChange") end From 873f03ed7a65e6cdf0d371e0f03f00a4b39ff6f8 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 28 Aug 2018 10:20:45 -0400 Subject: [PATCH 626/681] Update test set --- test_sets/mobile_api_versioning.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test_sets/mobile_api_versioning.txt b/test_sets/mobile_api_versioning.txt index 238631db85..d3b44fe130 100644 --- a/test_sets/mobile_api_versioning.txt +++ b/test_sets/mobile_api_versioning.txt @@ -5,3 +5,6 @@ ./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/001_create_interaction_choice_success_legacy_app.lua ./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/002_create_interaction_choice_invalid_data_legacy_app.lua ./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/003_perform_interaction_success_legacy_app.lua +./test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/001_play_pause_v5_allowed.lua +./test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua + From ed0f374b6cf996a79f63183e9fab7582ac5cbf79 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 29 Aug 2018 13:05:35 +0300 Subject: [PATCH 627/681] Update SetAppIcon scripts --- ...Mobile_App_received_response_SetAppIcon_DISALLOWED.lua | 2 +- test_scripts/API/SetAppIcon/commonIconResumed.lua | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/test_scripts/API/SetAppIcon/009_Mobile_App_received_response_SetAppIcon_DISALLOWED.lua b/test_scripts/API/SetAppIcon/009_Mobile_App_received_response_SetAppIcon_DISALLOWED.lua index 6020ebae36..5e2c8956c0 100644 --- a/test_scripts/API/SetAppIcon/009_Mobile_App_received_response_SetAppIcon_DISALLOWED.lua +++ b/test_scripts/API/SetAppIcon/009_Mobile_App_received_response_SetAppIcon_DISALLOWED.lua @@ -42,7 +42,7 @@ local function updatePTU(tbl) local CustomGroup = commonFunctions:cloneTable(tbl.policy_table.functional_groupings["Base-4"]) CustomGroup.rpcs.SetAppIcon = nil tbl.policy_table.functional_groupings.GroupWithoutSetAppIcon = CustomGroup - tbl.policy_table.app_policies[common.getConfigAppParams().appID].groups = { "GroupWithoutSetAppIcon" } + tbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].groups = { "GroupWithoutSetAppIcon" } end --[[ Scenario ]] diff --git a/test_scripts/API/SetAppIcon/commonIconResumed.lua b/test_scripts/API/SetAppIcon/commonIconResumed.lua index 82f505a5c5..9ba91a125c 100644 --- a/test_scripts/API/SetAppIcon/commonIconResumed.lua +++ b/test_scripts/API/SetAppIcon/commonIconResumed.lua @@ -16,7 +16,6 @@ local mobile_session = require('mobile_session') local m = actions --[[ Variables ]] -local hmiAppIds = {} --[[ @getPathToFileInStorage: Get path of app icon from storage --! @parameters: @@ -27,7 +26,7 @@ local hmiAppIds = {} function m.getPathToFileInStorage(pFileName, pAppId) if not pAppId then pAppId = 1 end return commonPreconditions:GetPathToSDL() .. "storage/" - .. m.getConfigAppParams(pAppId).appID .. "_" + .. m.getConfigAppParams(pAppId).fullAppID .. "_" .. utils.getDeviceMAC() .. "/" .. pFileName end @@ -38,7 +37,7 @@ end --]] function m.getIconValueForResumption(pAppId) if not pAppId then pAppId = 1 end - return commonPreconditions:GetPathToSDL() .. "storage/" .. m.getConfigAppParams(pAppId).appID + return commonPreconditions:GetPathToSDL() .. "storage/" .. m.getConfigAppParams(pAppId).fullAppID end --[[ @registerAppWOPTU: register mobile application @@ -62,9 +61,6 @@ function m.registerAppWOPTU(pAppId, pIconResumed, pReconnection) icon = pIconValue } }) - :Do(function(_, d1) - hmiAppIds[m.getConfigAppParams(pAppId).appID] = d1.params.application.appID - end) :ValidIf(function(_,data) if false == pIconResumed and data.params.application.icon then From 43fb887126ab5039cd6c001906f04b3e16d240dc Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 28 Aug 2018 15:34:48 +0300 Subject: [PATCH 628/681] Update TTSChunks scripts --- test_scripts/SDL4_6/TTSChunks/009_AlertManeuver.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/SDL4_6/TTSChunks/009_AlertManeuver.lua b/test_scripts/SDL4_6/TTSChunks/009_AlertManeuver.lua index 6560da0314..43c639fde5 100644 --- a/test_scripts/SDL4_6/TTSChunks/009_AlertManeuver.lua +++ b/test_scripts/SDL4_6/TTSChunks/009_AlertManeuver.lua @@ -45,7 +45,7 @@ runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] local function pTUpdateFunc(pTbl) - table.insert(pTbl.policy_table.app_policies[common.getConfigAppParams().appID].groups, "Navigation-1") + table.insert(pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].groups, "Navigation-1") end local function sendAlertManeuver_FILE_NOT_FOUND() From b6fceafb22ee4184eb56f912b600acf5605405b7 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 28 Aug 2018 16:54:02 +0300 Subject: [PATCH 629/681] Update DataExchange scripts --- .../Expanded_proprietary_data_exchange/commonDataExchange.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua b/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua index 90120dbc41..cf2b4d8519 100644 --- a/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua +++ b/test_scripts/API/Expanded_proprietary_data_exchange/commonDataExchange.lua @@ -105,7 +105,7 @@ function m.policyTableUpdate(pPTUpdateFunc, pExpNotificationFunc, pRequestSubTyp { requestType = "PROPRIETARY", fileName = ptsFileName, requestSubType = pRequestSubType }) getPTUFromPTS(ptuTable) for i = 1, m.getAppsCount() do - ptuTable.policy_table.app_policies[m.getConfigAppParams(i).appID] = m.getAppDataForPTU(i) + ptuTable.policy_table.app_policies[m.getConfigAppParams(i).fullAppID] = m.getAppDataForPTU(i) end if pPTUpdateFunc then pPTUpdateFunc(ptuTable) From 1a7474203d30f10469e2b06be96412faeb9e1014 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 28 Aug 2018 16:54:18 +0300 Subject: [PATCH 630/681] Update SubMenuIcon scripts --- test_scripts/API/SubMenuIcon/commonSubMenuIcon.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/API/SubMenuIcon/commonSubMenuIcon.lua b/test_scripts/API/SubMenuIcon/commonSubMenuIcon.lua index 076e9dc91e..311f0702be 100644 --- a/test_scripts/API/SubMenuIcon/commonSubMenuIcon.lua +++ b/test_scripts/API/SubMenuIcon/commonSubMenuIcon.lua @@ -24,7 +24,7 @@ m.cloneTable = utils.cloneTable function m.getPathToFileInStorage(pFileName, pAppId) if not pAppId then pAppId = 1 end return commonPreconditions:GetPathToSDL() .. "storage/" - .. m.getConfigAppParams(pAppId).appID .. "_" + .. m.getConfigAppParams(pAppId).fullAppID .. "_" .. utils.getDeviceMAC() .. "/" .. pFileName end From 2f4f9a2617b80f9a63c170b0b7afd52db909689b Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 29 Aug 2018 12:45:50 +0300 Subject: [PATCH 631/681] Update iAP2TransportSwitch scripts --- .../iAP2TransportSwitch/003_resume_failed_remove_data_check.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua b/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua index 8548e9c2eb..7c4ca80439 100644 --- a/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua +++ b/test_scripts/iAP2TransportSwitch/003_resume_failed_remove_data_check.lua @@ -50,7 +50,7 @@ local iconFileName = "icon.png" --[[ Local Functions ]] local function isFileExisting(pFileName) local device_id = "ac355aa5275c7388743f1bd27761ab5fa79ec876927347b97bd6e0361ae04699" - return commonFunctions:File_exists(config.pathToSDL .. "storage/" .. common.appParams.appID + return commonFunctions:File_exists(config.pathToSDL .. "storage/" .. common.appParams.fullAppID .. "_" .. device_id .. "/" .. pFileName) end From dd1f62ad74906ff69f49d1f4cde9550f5379b185 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 29 Aug 2018 12:53:34 +0300 Subject: [PATCH 632/681] Update MobileProjection1 scripts --- .../MobileProjection/Phase1/001_Start_video_audio_service.lua | 2 +- .../MobileProjection/Phase1/002_Start_video_streaming.lua | 2 +- .../MobileProjection/Phase1/003_Start_audio_streaming.lua | 2 +- .../Phase1/004_OnTouchEvent_while_streamings.lua | 4 ++-- .../Phase1/005_Start_video_service_streaming_in_LIMITED.lua | 2 +- .../Phase1/006_Start_audio_service_streaming_in_LIMITED.lua | 2 +- .../Phase1/007_Rejecting_audio_video_service_in_NONE.lua | 2 +- .../008_Rejecting_audio_video_service_in_BACKGROUND.lua | 2 +- .../009_Rejecting_audio_video_service_in_FULL_2_protocol.lua | 2 +- ...10_Rejecting_audio_video_service_in_LIMITED_2_protocol.lua | 2 +- ...equence_of_StartAudioStream_during_audio_service_start.lua | 2 +- ...try_sequence_of_StartStream_during_video_service_start.lua | 2 +- ..._Rejecting_StartAudioStream_during_audio_service_start.lua | 2 +- .../014_Rejecting_StartStream_during_video_service_start.lua | 2 +- .../Phase1/015_Restore_video_streaming_from_NONE.lua | 2 +- .../Phase1/016_Restore_audio_streaming_from_NONE.lua | 2 +- .../Phase1/017_HappyPath_flow_with_audio_video_streamings.lua | 4 ++-- 17 files changed, 19 insertions(+), 19 deletions(-) diff --git a/test_scripts/MobileProjection/Phase1/001_Start_video_audio_service.lua b/test_scripts/MobileProjection/Phase1/001_Start_video_audio_service.lua index 0f4971af2c..5635149e54 100644 --- a/test_scripts/MobileProjection/Phase1/001_Start_video_audio_service.lua +++ b/test_scripts/MobileProjection/Phase1/001_Start_video_audio_service.lua @@ -27,7 +27,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].AppHMIType = { appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/MobileProjection/Phase1/002_Start_video_streaming.lua b/test_scripts/MobileProjection/Phase1/002_Start_video_streaming.lua index 70415d5db2..e319e89421 100644 --- a/test_scripts/MobileProjection/Phase1/002_Start_video_streaming.lua +++ b/test_scripts/MobileProjection/Phase1/002_Start_video_streaming.lua @@ -28,7 +28,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].AppHMIType = { appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/MobileProjection/Phase1/003_Start_audio_streaming.lua b/test_scripts/MobileProjection/Phase1/003_Start_audio_streaming.lua index 4bb9302703..a985ef32b6 100644 --- a/test_scripts/MobileProjection/Phase1/003_Start_audio_streaming.lua +++ b/test_scripts/MobileProjection/Phase1/003_Start_audio_streaming.lua @@ -28,7 +28,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].AppHMIType = { appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/MobileProjection/Phase1/004_OnTouchEvent_while_streamings.lua b/test_scripts/MobileProjection/Phase1/004_OnTouchEvent_while_streamings.lua index 9ecee2ccd3..f368692735 100644 --- a/test_scripts/MobileProjection/Phase1/004_OnTouchEvent_while_streamings.lua +++ b/test_scripts/MobileProjection/Phase1/004_OnTouchEvent_while_streamings.lua @@ -38,8 +38,8 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].groups = { "Base-4", "OnTouchEventOnlyGroup" } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].groups = { "Base-4", "OnTouchEventOnlyGroup" } end local function OnTouchEvent(parameters) diff --git a/test_scripts/MobileProjection/Phase1/005_Start_video_service_streaming_in_LIMITED.lua b/test_scripts/MobileProjection/Phase1/005_Start_video_service_streaming_in_LIMITED.lua index fcececa077..1e4cda2233 100644 --- a/test_scripts/MobileProjection/Phase1/005_Start_video_service_streaming_in_LIMITED.lua +++ b/test_scripts/MobileProjection/Phase1/005_Start_video_service_streaming_in_LIMITED.lua @@ -30,7 +30,7 @@ config.application1.registerAppInterfaceParams.isMediaApplication = true --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].AppHMIType = { appHMIType } end local function bringAppToLimited() diff --git a/test_scripts/MobileProjection/Phase1/006_Start_audio_service_streaming_in_LIMITED.lua b/test_scripts/MobileProjection/Phase1/006_Start_audio_service_streaming_in_LIMITED.lua index 17d6f5184a..b9f83ab755 100644 --- a/test_scripts/MobileProjection/Phase1/006_Start_audio_service_streaming_in_LIMITED.lua +++ b/test_scripts/MobileProjection/Phase1/006_Start_audio_service_streaming_in_LIMITED.lua @@ -30,7 +30,7 @@ config.application1.registerAppInterfaceParams.isMediaApplication = true --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].AppHMIType = { appHMIType } end local function bringAppToLimited() diff --git a/test_scripts/MobileProjection/Phase1/007_Rejecting_audio_video_service_in_NONE.lua b/test_scripts/MobileProjection/Phase1/007_Rejecting_audio_video_service_in_NONE.lua index 9ed3605a67..1505c9b4a3 100644 --- a/test_scripts/MobileProjection/Phase1/007_Rejecting_audio_video_service_in_NONE.lua +++ b/test_scripts/MobileProjection/Phase1/007_Rejecting_audio_video_service_in_NONE.lua @@ -28,7 +28,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].AppHMIType = { appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/MobileProjection/Phase1/008_Rejecting_audio_video_service_in_BACKGROUND.lua b/test_scripts/MobileProjection/Phase1/008_Rejecting_audio_video_service_in_BACKGROUND.lua index b302af208e..d78279554f 100644 --- a/test_scripts/MobileProjection/Phase1/008_Rejecting_audio_video_service_in_BACKGROUND.lua +++ b/test_scripts/MobileProjection/Phase1/008_Rejecting_audio_video_service_in_BACKGROUND.lua @@ -29,7 +29,7 @@ config.application2.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].AppHMIType = { appHMIType } end local function BringAppToBackground() diff --git a/test_scripts/MobileProjection/Phase1/009_Rejecting_audio_video_service_in_FULL_2_protocol.lua b/test_scripts/MobileProjection/Phase1/009_Rejecting_audio_video_service_in_FULL_2_protocol.lua index cf57d8ce32..938a5f97e7 100644 --- a/test_scripts/MobileProjection/Phase1/009_Rejecting_audio_video_service_in_FULL_2_protocol.lua +++ b/test_scripts/MobileProjection/Phase1/009_Rejecting_audio_video_service_in_FULL_2_protocol.lua @@ -29,7 +29,7 @@ config.defaultProtocolVersion = 2 --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].AppHMIType = { appHMIType } end --[[ Scenario ]] diff --git a/test_scripts/MobileProjection/Phase1/010_Rejecting_audio_video_service_in_LIMITED_2_protocol.lua b/test_scripts/MobileProjection/Phase1/010_Rejecting_audio_video_service_in_LIMITED_2_protocol.lua index 3296e8f104..33d36157e1 100644 --- a/test_scripts/MobileProjection/Phase1/010_Rejecting_audio_video_service_in_LIMITED_2_protocol.lua +++ b/test_scripts/MobileProjection/Phase1/010_Rejecting_audio_video_service_in_LIMITED_2_protocol.lua @@ -29,7 +29,7 @@ config.defaultProtocolVersion = 2 --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].AppHMIType = { appHMIType } end local function bringAppToLimited() diff --git a/test_scripts/MobileProjection/Phase1/011_Retry_sequence_of_StartAudioStream_during_audio_service_start.lua b/test_scripts/MobileProjection/Phase1/011_Retry_sequence_of_StartAudioStream_during_audio_service_start.lua index 1f2940d2d2..804056cd1d 100644 --- a/test_scripts/MobileProjection/Phase1/011_Retry_sequence_of_StartAudioStream_during_audio_service_start.lua +++ b/test_scripts/MobileProjection/Phase1/011_Retry_sequence_of_StartAudioStream_during_audio_service_start.lua @@ -28,7 +28,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].AppHMIType = { appHMIType } end local function startService() diff --git a/test_scripts/MobileProjection/Phase1/012_Retry_sequence_of_StartStream_during_video_service_start.lua b/test_scripts/MobileProjection/Phase1/012_Retry_sequence_of_StartStream_during_video_service_start.lua index 4e8a4bb04a..d082499264 100644 --- a/test_scripts/MobileProjection/Phase1/012_Retry_sequence_of_StartStream_during_video_service_start.lua +++ b/test_scripts/MobileProjection/Phase1/012_Retry_sequence_of_StartStream_during_video_service_start.lua @@ -28,7 +28,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].AppHMIType = { appHMIType } end local function startService() diff --git a/test_scripts/MobileProjection/Phase1/013_Rejecting_StartAudioStream_during_audio_service_start.lua b/test_scripts/MobileProjection/Phase1/013_Rejecting_StartAudioStream_during_audio_service_start.lua index 54a8da463a..03c52ac239 100644 --- a/test_scripts/MobileProjection/Phase1/013_Rejecting_StartAudioStream_during_audio_service_start.lua +++ b/test_scripts/MobileProjection/Phase1/013_Rejecting_StartAudioStream_during_audio_service_start.lua @@ -30,7 +30,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].AppHMIType = { appHMIType } end local function startService() diff --git a/test_scripts/MobileProjection/Phase1/014_Rejecting_StartStream_during_video_service_start.lua b/test_scripts/MobileProjection/Phase1/014_Rejecting_StartStream_during_video_service_start.lua index fc236a73cd..0d217132ff 100644 --- a/test_scripts/MobileProjection/Phase1/014_Rejecting_StartStream_during_video_service_start.lua +++ b/test_scripts/MobileProjection/Phase1/014_Rejecting_StartStream_during_video_service_start.lua @@ -30,7 +30,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].AppHMIType = { appHMIType } end local function startService() diff --git a/test_scripts/MobileProjection/Phase1/015_Restore_video_streaming_from_NONE.lua b/test_scripts/MobileProjection/Phase1/015_Restore_video_streaming_from_NONE.lua index bd36dc023a..f2cd9d197b 100644 --- a/test_scripts/MobileProjection/Phase1/015_Restore_video_streaming_from_NONE.lua +++ b/test_scripts/MobileProjection/Phase1/015_Restore_video_streaming_from_NONE.lua @@ -33,7 +33,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].AppHMIType = { appHMIType } end local function EndServiceByUserExit() diff --git a/test_scripts/MobileProjection/Phase1/016_Restore_audio_streaming_from_NONE.lua b/test_scripts/MobileProjection/Phase1/016_Restore_audio_streaming_from_NONE.lua index b8f4e6adf0..5c3aa8b354 100644 --- a/test_scripts/MobileProjection/Phase1/016_Restore_audio_streaming_from_NONE.lua +++ b/test_scripts/MobileProjection/Phase1/016_Restore_audio_streaming_from_NONE.lua @@ -33,7 +33,7 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].AppHMIType = { appHMIType } end local function EndServiceByUserExit() diff --git a/test_scripts/MobileProjection/Phase1/017_HappyPath_flow_with_audio_video_streamings.lua b/test_scripts/MobileProjection/Phase1/017_HappyPath_flow_with_audio_video_streamings.lua index dc691ce6df..14d847ed56 100644 --- a/test_scripts/MobileProjection/Phase1/017_HappyPath_flow_with_audio_video_streamings.lua +++ b/test_scripts/MobileProjection/Phase1/017_HappyPath_flow_with_audio_video_streamings.lua @@ -44,8 +44,8 @@ config.application1.registerAppInterfaceParams.appHMIType = { appHMIType } --[[ Local Functions ]] local function ptUpdate(pTbl) - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].AppHMIType = { appHMIType } - pTbl.policy_table.app_policies[common.getConfigAppParams().appID].groups = { "Base-4", "OnTouchEventOnlyGroup" } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].AppHMIType = { appHMIType } + pTbl.policy_table.app_policies[common.getConfigAppParams().fullAppID].groups = { "Base-4", "OnTouchEventOnlyGroup" } end local function OnTouchEvent(parameters) From b1f79d311c04cb18edfacc5ede0b8ea1d697ea1c Mon Sep 17 00:00:00 2001 From: Myza Taras Date: Wed, 29 Aug 2018 16:51:20 +0300 Subject: [PATCH 633/681] Script for defect 2457 --- ...iceList_notification_on_device_connect.lua | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 test_scripts/Defects/5_0/2457_Needed_fixes_sending_of_UpdateDeviceList_notification_on_device_connect.lua diff --git a/test_scripts/Defects/5_0/2457_Needed_fixes_sending_of_UpdateDeviceList_notification_on_device_connect.lua b/test_scripts/Defects/5_0/2457_Needed_fixes_sending_of_UpdateDeviceList_notification_on_device_connect.lua new file mode 100644 index 0000000000..76fb1de497 --- /dev/null +++ b/test_scripts/Defects/5_0/2457_Needed_fixes_sending_of_UpdateDeviceList_notification_on_device_connect.lua @@ -0,0 +1,72 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/2381 +-- +-- Precondition: +-- SDL Core and HMI are started. App is registered, HMI level = FULL +-- Description: +-- Steps to reproduce: +-- 1) SDL currently notifies system by using another transport listener API - OnDeviceAdded/OnDeviceRemoved. +-- Expected: +-- 1) SDL has to notify system with BC.UpdateDeviceList on device connect even if device does not have any SDL-enabled applications running. +--------------------------------------------------------------------------------------------------- +-- [[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('user_modules/sequences/actions') +local utils = require("user_modules/utils") +local events = require("events") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local test = require("user_modules/dummy_connecttest") + +-- [[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +-- [[ Local function ]] +local function allowSDL(self) + common.getHMIConnection():SendNotification("SDL.OnAllowSDLFunctionality", { + allowed = true, + source = "GUI", + device = { + id = utils.getDeviceMAC(), + name = utils.getDeviceName() + } + }) +end + +local function start(pHMIParams) + local event = events.Event() + event.matches = function(e1, e2) return e1 == e2 end + test:runSDL() + commonFunctions:waitForSDLStart(test) + :Do(function() + test:initHMI() + :Do(function() + utils.cprint(35, "HMI initialized") + test:initHMI_onReady(pHMIParams) + :Do(function() + utils.cprint(35, "HMI is ready") + common.getHMIConnection():ExpectNotification("BasicCommunication.UpdateDeviceList") + common.getHMIConnection():ExpectNotification("OnDeviceAdded") + :Times(0) + test:connectMobile() + :Do(function() + utils.cprint(35, "Mobile connected") + allowSDL(test) + common.getHMIConnection():RaiseEvent(event, "Start event") + end) + end) + end) + end) + return common.getHMIConnection():ExpectEvent(event, "Start event") +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) + +-- [[ Test ]] +runner.Title("Test") +runner.Step("Start SDL, HMI, connect Mobile, start Session", start) + +-- [[ Postconditions ]] +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) \ No newline at end of file From 8a64503ee135368225160aee8a23761c9b6c16af Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 30 Aug 2018 10:22:12 +0300 Subject: [PATCH 634/681] Remove new line --- test_sets/mobile_api_versioning.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/test_sets/mobile_api_versioning.txt b/test_sets/mobile_api_versioning.txt index d3b44fe130..09ed0c8bee 100644 --- a/test_sets/mobile_api_versioning.txt +++ b/test_sets/mobile_api_versioning.txt @@ -7,4 +7,3 @@ ./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/003_perform_interaction_success_legacy_app.lua ./test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/001_play_pause_v5_allowed.lua ./test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua - From a283d1bf483c249710e9b209e0ff0b80b110a7d1 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 30 Aug 2018 12:16:55 +0300 Subject: [PATCH 635/681] Add additional timeout for ActivateApp --- test_scripts/RC/commonRC.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 9e115d369b..0a9b246a34 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -942,6 +942,7 @@ function commonRC.activateApp(pAppId) EXPECT_HMIRESPONSE(requestId) mobSession:ExpectNotification("OnHMIStatus", { hmiLevel = "FULL", audioStreamingState = audibleState(pAppId), systemContext = "MAIN" }) + utils.wait() end function commonRC.updateDefaultCapabilities(pDisabledModuleTypes) From 713d16efbd135d7e4002b9b9f688bbfd50e08e68 Mon Sep 17 00:00:00 2001 From: Myza Taras Date: Mon, 20 Aug 2018 16:00:24 +0300 Subject: [PATCH 636/681] Script for Defect 2443 --- ...ot_check_for_non_manadatory_parameters.lua | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 test_scripts/Defects/5_0/2443_SDL_does_not_check_for_non_manadatory_parameters.lua diff --git a/test_scripts/Defects/5_0/2443_SDL_does_not_check_for_non_manadatory_parameters.lua b/test_scripts/Defects/5_0/2443_SDL_does_not_check_for_non_manadatory_parameters.lua new file mode 100644 index 0000000000..1425b28fce --- /dev/null +++ b/test_scripts/Defects/5_0/2443_SDL_does_not_check_for_non_manadatory_parameters.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/2443 +-- +-- Description: +-- SDL does not check for non-manadatory parameters +-- Steps to reproduce: +-- 1) Send OnPutFile notification with no-mandatory parameters fileSize and length. +-- Actuchual: +-- If the mobile application has no provided appropriate parameters SDL sends fileSize: null as json value to HMI +-- Expected: +-- 1) SDL sends correct no-mandatory fileSize parameter to HMI. + +--------------------------------------------------------------------------------------------------- +-- [[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('user_modules/sequences/actions') + +-- [[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +-- [[ Local functions ]] +function fsize (file) + f = io.open(file,"r") + local current = f:seek() + local size = f:seek("end") + f:seek("set", current) + f:close() + return size +end + +local function onPutFile() + local paramsSend = { + syncFileName = "icon_png.png", + fileType = "GRAPHIC_PNG", + systemFile = true + } + local calcFileSize = fsize("files/icon_png.png") + local cid = common.getMobileSession():SendRPC( "PutFile", paramsSend, "files/icon_png.png") + common.getHMIConnection():ExpectNotification("BasicCommunication.OnPutFile") + :ValidIf(function(_, data) + if data.params.fileSize == calcFileSize then + return true + end + return false, "SDL can't determinate non mandatory fileSize parameter" + end) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", info = "File was downloaded"}) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) + +-- [[ Test ]] +runner.Title("Test") +runner.Step("Upload file", onPutFile) + +-- [[ Postconditions ]] +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From 9278c4969223ac88569df75dad662c668e05b2e6 Mon Sep 17 00:00:00 2001 From: HSavynetska Date: Mon, 3 Sep 2018 12:41:20 +0300 Subject: [PATCH 637/681] Scripts to check issue 2464 --- ...switching_off_with_reason_IGNITION_OFF.lua | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 test_scripts/Defects/5_0/2464_SDL_does_not_send_OnSDLClose_notification_by_switching_off_with_reason_IGNITION_OFF.lua diff --git a/test_scripts/Defects/5_0/2464_SDL_does_not_send_OnSDLClose_notification_by_switching_off_with_reason_IGNITION_OFF.lua b/test_scripts/Defects/5_0/2464_SDL_does_not_send_OnSDLClose_notification_by_switching_off_with_reason_IGNITION_OFF.lua new file mode 100644 index 0000000000..f75b35b4f4 --- /dev/null +++ b/test_scripts/Defects/5_0/2464_SDL_does_not_send_OnSDLClose_notification_by_switching_off_with_reason_IGNITION_OFF.lua @@ -0,0 +1,51 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/2464 +-- +-- Description: +-- SDL must send OnSDLClose by IGNITION_OFF +-- Precondition: +-- SDL and HMI are started. +-- App is registered. +-- In case: +-- 1) Perform IGNITION_OFF +-- Expected result: +-- 1) SDL receives OnExitAllApplications(SUSPEND) from HMI and sends OnSDLPersistenceComplete to HMI. +-- 2) SDL received OnExitAllApplications(IGNITION_OFF) from HMI, sends to mobile application OnAppInterfaceUnregistered(IGNITION_OFF) and OnAppUnregistered(unexpectedDisconnect = false) +-- 3) SDL sends to HMI OnSDLClose notification. +-- Actual result: +-- SDL does not send OnSDLClose notification to HMI by switching off with reason IGNITION_OFF. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('user_modules/sequences/actions') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function ignitionOff() + common.getHMIConnection():SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnSDLPersistenceComplete") + :Do(function() + common.getHMIConnection():SendNotification("BasicCommunication.OnExitAllApplications", { reason = "IGNITION_OFF" }) + common.getMobileSession():ExpectNotification("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnSDLClose") + :Do(function() + StopSDL() + end) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) + +-- [[ Test ]] +runner.Step("IGNITION_OFF", ignitionOff) + +-- [[ Postconditions ]] +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From 1a29651ab087e5bff8d392162b19609b1a4f39f5 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 4 Sep 2018 13:52:45 -0400 Subject: [PATCH 638/681] Fix merge conflict --- .../008_Resumption_heartbeat_disconnect.lua | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/test_scripts/Smoke/Resumption/008_Resumption_heartbeat_disconnect.lua b/test_scripts/Smoke/Resumption/008_Resumption_heartbeat_disconnect.lua index 99a199374b..226fa7214e 100644 --- a/test_scripts/Smoke/Resumption/008_Resumption_heartbeat_disconnect.lua +++ b/test_scripts/Smoke/Resumption/008_Resumption_heartbeat_disconnect.lua @@ -100,19 +100,8 @@ function Test:Wait_20_sec() EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", {appID = self.applications[default_app_params], unexpectedDisconnect = true }) :Timeout(20000) EXPECT_EVENT(events.disconnectedEvent, "Disconnected") -<<<<<<< HEAD:test_scripts/Smoke/Resumption/ATF_Resumption_heartbeat_disconnect.lua :Times(0) delayedExp(20000, self) -======= - :Do(function() - print("Disconnected!!!") - end) - :Timeout(20000) -end - -function Test:Connect_Mobile() - connectMobile(self) ->>>>>>> origin/develop:test_scripts/Smoke/Resumption/008_Resumption_heartbeat_disconnect.lua end function Test:Register_And_Resume_App_And_Data() From f4169a644e0f3fb527c51ce456c6f9630df64761 Mon Sep 17 00:00:00 2001 From: Jacob Keeler Date: Tue, 4 Sep 2018 13:54:31 -0400 Subject: [PATCH 639/681] Remove outdated KnownIssues.md --- KnownIssues.md | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 KnownIssues.md diff --git a/KnownIssues.md b/KnownIssues.md deleted file mode 100644 index fdbd01c7fb..0000000000 --- a/KnownIssues.md +++ /dev/null @@ -1,31 +0,0 @@ -# Known FAILS in test scripts: - -* ATF_Speak.lua: - * Speak_ttsChunks_IsUpperBound_SUCCESS - * Speak_ttsChunks_IsOutUpperBound_INVALID_DATA - * Speak_CorrelationID_IsDuplicated - * Speak_Response_resultCode_IsValidValue_UNSUPPORTED_RESOURCE_SendError - * Speak_Response_resultCode_IsValidValue_WARNINGS_SendError - * Activation_App // (sometimes) - -* ATF_AddSubMenu.lua: - * AddSubMenu_InvalidDataSuccessFalse - * AddSubMenu_OutOfMemorySuccessFalse - * AddSubMenu_GenericErrorSuccessFalse - * AddSubMenu_RejectedSuccessFalse - * AddSubMenu_REJECTED - * Activation_App // (sometimes) - -* ATF_OnDriverDistraction.lua: - * Activate_Media_App2 // (sometimes) - -* ATF_SetMediaClockTimer.lua: - * UI_SetMediaClockTimer_Response* - -* ATF_Slider.lua: - * Slider_AllParametersUpperBound_SUCCESS - * Slider_sliderFooter_IsOutLowerBound_IsEmpty_INVALID_DATA - * Slider_sliderFooter_IsUpperBound_SUCCESS - * Activation_App // (sometimes) - -Checked on SDL commit SDL commit [85918cb](https://github.com/smartdevicelink/sdl_core/commit/85918cb) From 96b3fc2f5e6b23cc1a48d57dcb34c3d78ecfa791 Mon Sep 17 00:00:00 2001 From: Myza Taras Date: Wed, 5 Sep 2018 14:48:52 +0300 Subject: [PATCH 640/681] Script for defect 2479 --- ..._1_SDL_does_not_respond_NACK_Navi_Type.lua | 43 +++ ...2_SDL_does_not_respond_NACK_Audio_Type.lua | 43 +++ .../common.lua | 247 ++++++++++++++++++ 3 files changed, 333 insertions(+) create mode 100644 test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_1_SDL_does_not_respond_NACK_Navi_Type.lua create mode 100644 test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_2_SDL_does_not_respond_NACK_Audio_Type.lua create mode 100644 test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/common.lua diff --git a/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_1_SDL_does_not_respond_NACK_Navi_Type.lua b/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_1_SDL_does_not_respond_NACK_Navi_Type.lua new file mode 100644 index 0000000000..8fa3882313 --- /dev/null +++ b/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_1_SDL_does_not_respond_NACK_Navi_Type.lua @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/2379 +-- +-- Description: +-- SDL does not respond NACK to second request +-- Steps to reproduce: +-- 1) In case mobile side send two start VIDEO secure service requests +-- Expected: +-- 1) Respond NACK to second request keep active VIDEO service that was already started +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Security/DTLS/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +-- [[ Local function ]] +function startServiceProtectedSecond(pServiceId) + common.getMobileSession():StartSecureService(pServiceId) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + common.getMobileSession():ExpectControlMessage(pServiceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set DTLS protocol in SDL", common.setSDLIniParameter, { "Protocol", "DTLSv1.0" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Policy Table Update Certificate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Start RPC Service protected", common.startServiceProtected, { 11 }) +runner.Step("Start seconde RPC Service protected", startServiceProtectedSecond, { 11 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL, restore SDL settings", common.postconditions) diff --git a/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_2_SDL_does_not_respond_NACK_Audio_Type.lua b/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_2_SDL_does_not_respond_NACK_Audio_Type.lua new file mode 100644 index 0000000000..56dee88791 --- /dev/null +++ b/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_2_SDL_does_not_respond_NACK_Audio_Type.lua @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/2379 +-- +-- Description: +-- SDL does not respond NACK to second request +-- Steps to reproduce: +-- 1) In case mobile side send two start AUDIO secure service requests +-- Expected: +-- 1) Respond NACK to second request keep active AUDIO service that was already started +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Security/DTLS/common') +local runner = require('user_modules/script_runner') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +-- [[ Local function ]] +function startServiceProtectedSecond(pServiceId) + common.getMobileSession():StartSecureService(pServiceId) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + common.getMobileSession():ExpectControlMessage(pServiceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set DTLS protocol in SDL", common.setSDLIniParameter, { "Protocol", "DTLSv1.0" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Policy Table Update Certificate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Start RPC Service protected", common.startServiceProtected, { 10 }) +runner.Step("Start seconde RPC Service protected", startServiceProtectedSecond, { 10 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL, restore SDL settings", common.postconditions) diff --git a/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/common.lua b/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/common.lua new file mode 100644 index 0000000000..639231c97a --- /dev/null +++ b/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/common.lua @@ -0,0 +1,247 @@ +--------------------------------------------------------------------------------------------------- +-- Navigation common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.SecurityProtocol = "DTLS" +config.application1.registerAppInterfaceParams.appName = "server" +config.application1.registerAppInterfaceParams.fullAppID = "SPT" +-- config.cipherListString = ":SSLv2:AES256-GCM-SHA384" + +--[[ Required Shared libraries ]] +local actions = require("user_modules/sequences/actions") +local security = require("user_modules/sequences/security") +local utils = require("user_modules/utils") +local json = require("modules/json") +local constants = require('protocol_handler/ford_protocol_constants') +local common = require("test_scripts/Security/SSLHandshakeFlow/common") +constants.FRAME_SIZE["P9"] = 131084 -- add unsupported SDL protocol version + +--[[ Module ]] +local m = actions + +m.frameInfo = security.frameInfo + +--[[ Constants ]] +local fileName = "files/action.png" + +--[[ Variables ]] +local msgId = 1000 + +--[[ Functions ]] + +--[[ @ptUpdate: add certificate to policy table +--! @parameters: +--! pTbl - policy table to update +--! @return: none +--]] +function m.ptUpdate(pTbl) + local filePath = "./files/Security/client_credential.pem" + local crt = utils.readFile(filePath) + pTbl.policy_table.module_config.certificate = crt +end + +--[[ @bytesToInt32: convert bytes to int32 +--! @parameters: +--! val - value to convert +--! offset - offset +--! @return: value in int32 +--]] +local function bytesToInt32(pVal, pOffset) + local res = bit32.lshift(string.byte(pVal, pOffset), 24) + + bit32.lshift(string.byte(pVal, pOffset + 1), 16) + + bit32.lshift(string.byte(pVal, pOffset + 2), 8) + + string.byte(pVal, pOffset + 3) + return res +end + +--[[ @int32ToBytes: convert int32 to bytes +--! @parameters: +--! val - value to convert +--! @return: value in bytes +--]] +local function int32ToBytes(pVal) + local res = string.char( + bit32.rshift(bit32.band(pVal, 0xff000000), 24), + bit32.rshift(bit32.band(pVal, 0xff0000), 16), + bit32.rshift(bit32.band(pVal, 0xff00), 8), + bit32.band(pVal, 0xff) + ) + return res +end + +--[[ @rpcPayload: create payload for RPC +--! @parameters: +--! msg - message table to populate +--! @return: populated message +--]] +local function rpcPayload(pMsg) + pMsg.payload = pMsg.payload or "" + pMsg.binaryData = pMsg.binaryData or "" + local res = string.char( + bit32.lshift(pMsg.rpcType, 4) + bit32.band(bit32.rshift(pMsg.rpcFunctionId, 24), 0x0f), + bit32.rshift(bit32.band(pMsg.rpcFunctionId, 0xff0000), 16), + bit32.rshift(bit32.band(pMsg.rpcFunctionId, 0xff00), 8), + bit32.band(pMsg.rpcFunctionId, 0xff)) .. + int32ToBytes(pMsg.rpcCorrelationId) .. + int32ToBytes(#pMsg.payload) .. + pMsg.payload .. pMsg.binaryData + return res +end + +--[[ @putFileByFrames: process PutFile RPC frame by frame +--! @parameters: +--! pParams - table with parameters (file, isSentDataEncrypted, isUnexpectedFrameInserted, isMalformedFrameInserted) +--]] +function m.putFileByFrames(pParams) + msgId = msgId + 1 + + local putFileParams = { + syncFileName = "action_" .. msgId .. " .png", + fileType = "GRAPHIC_PNG", + persistentFile = true, + systemFile = false, + } + + local correlationId = m.getMobileSession().correlationId + 1 + + local msg = { + version = config.defaultProtocolVersion, + encryption = pParams.isSentDataEncrypted, + frameType = 0x01, + serviceType = 0x07, + frameInfo = 0x0, + sessionId = m.getMobileSession().sessionId, + messageId = msgId, + rpcType = 0x0, + rpcFunctionId = 32, -- PutFile + rpcCorrelationId = correlationId, + payload = json.encode(putFileParams) + } + + local file = fileName + if pParams.file then file = pParams.file end + + local f = assert(io.open(file)) + msg.binaryData = f:read("*all") + io.close(f) + + msg.binaryData = rpcPayload(msg) + + local frames = {} + local binaryDataSize = #msg.binaryData + local max_size = 1400 + local frameMessage = { + version = msg.version, + encryption = msg.encryption, + serviceType = msg.serviceType, + sessionId = msg.sessionId, + messageId = msg.messageId + } + if binaryDataSize > max_size then + local countOfDataFrames = 0 + -- Create messages consecutive frames + while #msg.binaryData > 0 do + countOfDataFrames = countOfDataFrames + 1 + + local dataPart = string.sub(msg.binaryData, 1, max_size) + msg.binaryData = string.sub(msg.binaryData, max_size + 1) + + local frame_info = 0 -- last frame + if #msg.binaryData > 0 then + frame_info = ((countOfDataFrames - 1) % 255) + 1 + end + + local consecutiveFrameMessage = utils.cloneTable(frameMessage) + consecutiveFrameMessage.frameType = 0x03 + consecutiveFrameMessage.frameInfo = frame_info + consecutiveFrameMessage.binaryData = dataPart + table.insert(frames, consecutiveFrameMessage) + end + + -- Create message firstframe + local firstFrameMessage = utils.cloneTable(frameMessage) + firstFrameMessage.frameType = 0x02 + firstFrameMessage.frameInfo = 0 + firstFrameMessage.binaryData = int32ToBytes(binaryDataSize) .. int32ToBytes(countOfDataFrames) + if pParams.isFirstFrameEncrypted ~= nil then + firstFrameMessage.encryption = pParams.isFirstFrameEncrypted + end + table.insert(frames, 1, firstFrameMessage) + else + table.insert(frames, msg) + end + + m.getMobileSession().mobile_session_impl.rpc_services:CheckCorrelationID(msg) + + if pParams.isUnexpectedFrameInserted == true then + frames[4] = frames[3] + frames[3] = utils.cloneTable(frames[2]) + frames[3].binaryData = '123' + end + + if pParams.isMalformedFrameInserted == true then + frames[4] = frames[3] + frames[3] = utils.cloneTable(frames[2]) + frames[2].version = 9 -- incorrect protocol version + end + + for _, frame in pairs(frames) do + m.getMobileSession():SendPacket(frame) + end + + if pParams.isSessionEncrypted == false then + m.getMobileSession():ExpectResponse(correlationId, { success = true, resultCode = "SUCCESS"}) + else + m.getMobileSession():ExpectEncryptedResponse(correlationId, { success = true, resultCode = "SUCCESS"}) + end + + m.getMobileSession():ExpectPacket({ + sessionId = m.getMobileSession().sessionId, + frameType = 0x01, + serviceType = 0x07 + }, + function(binaryData) + local rpcFunctionId = bit32.band(bytesToInt32(binaryData, 1), 0x0fffffff) + local rpcCorrelationId = bytesToInt32(binaryData, 5) + if rpcFunctionId ~= 32 or rpcCorrelationId ~= correlationId then return false end + return true + end) +end + +--[[ @startServiceProtected: start (or switch) service in protected mode +--! @parameters: +--! pServiceId - service id +--! @return: none +--]] +function m.startServiceProtected(pServiceId) + m.getMobileSession():StartSecureService(pServiceId) + m.getMobileSession():ExpectHandshakeMessage() + m.getMobileSession():ExpectControlMessage(pServiceId, { + frameInfo = m.frameInfo.START_SERVICE_ACK, + encryption = true + }) +end + +m.postconditions = common.postconditions + +local preconditionsOrig = m.preconditions +function m.preconditions() + preconditionsOrig() + common.initSDLCertificates("./files/Security/client_credential.pem", false) +end + +local policyTableUpdate_orig = m.policyTableUpdate + +function m.policyTableUpdate(pPTUpdateFunc) + local function expNotificationFunc() + m.getHMIConnection():ExpectRequest("BasicCommunication.DecryptCertificate") + :Do(function(_, d) + m.getHMIConnection():SendResponse(d.id, d.method, "SUCCESS", { }) + end) + :Times(AnyNumber()) + m.getHMIConnection():ExpectRequest("VehicleInfo.GetVehicleData", { odometer = true }) + end + policyTableUpdate_orig(pPTUpdateFunc, expNotificationFunc) +end + +return m From 1e5588469bafd5ea15109f7a31d8d52b2652e529 Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Wed, 5 Sep 2018 09:41:46 -0400 Subject: [PATCH 641/681] Gather SDL 5.0.0 test sets and scripts Also adds new test sets which were previously missing --- ...001_DuplicateCorrelationIDs_INVALID_ID.lua | 0 .../FullAppID/001_PTU_full_app_ID_true.lua | 0 .../FullAppID/002_PTU_full_app_ID_false.lua | 0 .../{SDL4_6 => SDL5_0}/FullAppID/common.lua | 0 .../001_SetGlobalProp_by_adding_commands.lua | 0 ...op_commands_with_and_without_vrCommand.lua | 0 ...SetGlobalProp_without_deleted_commands.lua | 0 ...4_SetGlobalProp_processing_30_commands.lua | 0 ...p_apply_limitation_only_for_addcommand.lua | 0 ...SetGlobalProp_processing_added_choices.lua | 0 .../007_SetGlobalProp_absence_in_NONE.lua | 0 ...08_SetGlobalProp_absence_in_BACKGROUND.lua | 0 ...bsence_addCommand_after_custom_request.lua | 0 ...nce_deleteCommand_after_custom_request.lua | 0 ...1_SetGlobalProp_custom_helpPrompt_only.lua | 0 .../012_SetGlobalProp_custom_vrHelp_only.lua | 0 ...rompt_and_vrHelp_in_different_requests.lua | 0 ..._request_without_helpPrompt_and_vrHelp.lua | 0 ...Prop_with_added_commands_by_resumption.lua | 0 ...th_and_without_vrCommand_by_resumption.lua | 0 ...without_deleted_commands_by_resumption.lua | 0 ...p_processing_30_commands_by_resumption.lua | 0 ...processing_added_choices_by_resumption.lua | 0 ..._after_custom_request_after_resumption.lua | 0 ...after_custom_request_before_resumption.lua | 0 ...p_custom_helpPrompt_only_by_resumption.lua | 0 ...lProp_custom_vrHelp_only_by_resumption.lua | 0 ...ut_helpPrompt_and_vrHelp_by_resumption.lua | 0 ...l_vrCommands_in_one_addCommand_request.lua | 0 ...n_one_addCommand_request_by_resumption.lua | 0 ...7_SetGlobalProp_invalid_custom_request.lua | 0 ..._SetGlobalProp_rejected_custom_request.lua | 0 ...balProp_only_successful_added_commands.lua | 0 ...ly_without_successful_deleted_commands.lua | 0 ...ing_30_commands_several_in_one_command.lua | 0 ...s_several_in_one_command_by_resumption.lua | 0 .../033_SetGlobalProp_delete_last_command.lua | 0 .../commonVRhelp.lua | 0 .../Image_template/001_isTemplate_is_true.lua | 0 .../002_isTemplate_is_false.lua | 0 .../003_isTemplate_is_absent.lua | 0 .../004_isTemplate_invalid_type.lua | 0 ..._isTemplate_is_true_with_not_png_image.lua | 0 ...6_isTemplate_is_true_with_STATIC_image.lua | 0 .../Image_template/commonImageTemplate.lua | 0 .../001_Low_Voltage_and_Wake_Up.lua | 0 .../002_Low_Voltage_and_Ignition_Off.lua | 0 ...ake_Up_and_Ignition_Off_wo_Low_Voltage.lua | 0 .../004_App_unregister_itself_gracefully.lua | 0 ...ow_Voltage_and_Wake_Up_RPC_in_progress.lua | 0 ..._and_Wake_Up_resumption_FULL_hmi_level.lua | 0 ..._hmi_level_in_case_existed_app_in_full.lua | 0 ...L_hmi_level_in_case_more_30_sec_before.lua | 0 ...LL_hmi_level_in_case_more_30_sec_after.lua | 0 ...i_level_in_case_existed_app_in_limited.lua | 0 ...d_Wake_Up_resumption_LIMITED_hmi_level.lua | 0 ..._hmi_level_in_case_existed_app_in_full.lua | 0 ...D_hmi_level_in_case_more_30_sec_before.lua | 0 ...ED_hmi_level_in_case_more_30_sec_after.lua | 0 ...i_level_in_case_existed_app_in_limited.lua | 0 ...Ignition_Off_resumption_FULL_hmi_level.lua | 0 ...ition_Off_resumption_LIMITED_hmi_level.lua | 0 ..._without_disconnect_before_low_voltage.lua | 0 ..._without_disconnect_before_low_voltage.lua | 0 ...level_in_case_more_30_sec_after_ing_on.lua | 0 ...level_in_case_more_30_sec_after_ing_on.lua | 0 ...e_and_Wake_Up_no_timeout_no_resumption.lua | 0 ...tage_and_Wake_Up_no_timeout_resumption.lua | 0 .../{ => SDL5_0}/LowVoltage/common.lua | 0 .../001_play_pause_v5_allowed.lua | 0 .../002_play_pause_v4_invalid_data.lua | 0 .../001_register_legacy_app.lua | 0 .../002_register_app_on_legacy_module.lua | 0 ..._interaction_choice_success_legacy_app.lua | 0 ...raction_choice_invalid_data_legacy_app.lua | 0 ...perform_interaction_success_legacy_app.lua | 0 .../TTSChunks/001_RegisterAppInterface.lua | 0 .../TTSChunks/002_SetGlobalProperties.lua | 0 .../TTSChunks/003_OnAppRegistered.lua | 0 .../TTSChunks/004_Alert.lua | 0 .../TTSChunks/005_ChangeRegistration.lua | 0 .../TTSChunks/006_PerformInteraction.lua | 0 .../TTSChunks/007_Speak.lua | 0 .../TTSChunks/008_PerformAudioPassThru.lua | 0 .../TTSChunks/009_AlertManeuver.lua | 0 .../{SDL4_6 => SDL5_0}/TTSChunks/common.lua | 0 ...etDisplayWithColorsAndNewLayoutSuccess.lua | 0 ...orSchemes_setDisplayWithColorsRejected.lua | 0 ...chemes_setDisplayWithSameColorsSuccess.lua | 0 .../001_AddCommand.lua | 0 .../002_AddSubMenu.lua | 0 .../003_Alert.lua | 0 .../004_CreateInteractionChoiceSet.lua | 0 .../005_PerfomInteraction.lua | 0 .../006_ScrollableMessage.lua | 0 .../007_Show.lua | 0 .../008_ShowConstantTBT.lua | 0 .../009_SendLocation.lua | 0 .../010_SetAppIcon.lua | 0 .../011_UpdateTurnList.lua | 0 .../012_AlertManeuver.lua | 0 .../013_GetWayPoints.lua | 0 .../014_OnWayPointChange.lua | 0 .../015_SetGlobalProperties.lua | 0 .../common.lua | 0 ...te_interaction_choice_set_invalid_data.lua | 0 .../002_perform_interaction_invalid_data.lua | 0 .../{ => SDL5_0}/app_icon_resumption.txt | 0 .../SDL5_0/audio_file_playback_tts_chunks.txt | 9 + .../{ => SDL5_0}/audio_source_am_fm_xm.txt | 0 test_sets/{ => SDL5_0}/dtls_encryption.txt | 0 .../SDL5_0/duplicate_correlation_ids.txt | 1 + test_sets/{ => SDL5_0}/expand_put_file.txt | 0 ...e_design_for_proprietary_data_exchange.txt | 0 test_sets/SDL5_0/full_app_id.txt | 2 + test_sets/{ => SDL5_0}/get_system_time.txt | 0 .../SDL5_0/handling_VR_help_requests.txt | 33 + .../interior_vehicle_data_management.txt | 0 test_sets/SDL5_0/low_voltage.txt | 23 + test_sets/SDL5_0/mobile_api_versioning.txt | 12 + .../{ => SDL5_0}/mobile_projection_2.txt | 0 .../mobile_projection_2_smoke.txt | 0 .../SDL5_0/rc_AUDIO_LIGHT_HMI_SETTINGS.txt | 57 ++ test_sets/SDL5_0/rc_CLIMATE_RADIO.txt | 107 ++++ test_sets/{ => SDL5_0}/rc_OnRCStatus.txt | 0 test_sets/SDL5_0/rc_SEAT.txt | 32 + ...rc_lights_more_names_and_status_values.txt | 0 .../rc_radio_parameter_update.txt | 0 test_sets/SDL5_0/sdl_5_0_test_suite.txt | 575 ++++++++++++++++++ test_sets/{ => SDL5_0}/submenu_icon.txt | 0 test_sets/SDL5_0/template_color_schemes.txt | 3 + test_sets/SDL5_0/template_images.txt | 6 + .../transfer_rpc_with_invalid_image.txt | 15 + .../{ => SDL5_0}/updating_dop_value_range.txt | 0 .../vehicle_data.txt} | 0 test_sets/SDL5_0/vr_command_optional.txt | 2 + ...L_0042_Transfer_RPC_with_Invalid_Image.txt | 15 - test_sets/audio_file_playback_tts_chunks.txt | 9 - test_sets/handling_VR_help_requests.txt | 33 - test_sets/low_voltage.txt | 23 - test_sets/mobile_api_versioning.txt | 9 - test_sets/template_images.txt | 6 - test_sets/vehicle_data.txt | 16 + 143 files changed, 893 insertions(+), 95 deletions(-) rename test_scripts/{SDL4.6/SDL-0162 => SDL5_0/DuplicateCorrIDs}/001_DuplicateCorrelationIDs_INVALID_ID.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/FullAppID/001_PTU_full_app_ID_true.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/FullAppID/002_PTU_full_app_ID_false.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/FullAppID/common.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua (100%) rename test_scripts/{ => SDL5_0}/Handling_VR_help_requests/commonVRhelp.lua (100%) rename test_scripts/{ => SDL5_0}/Image_template/001_isTemplate_is_true.lua (100%) rename test_scripts/{ => SDL5_0}/Image_template/002_isTemplate_is_false.lua (100%) rename test_scripts/{ => SDL5_0}/Image_template/003_isTemplate_is_absent.lua (100%) rename test_scripts/{ => SDL5_0}/Image_template/004_isTemplate_invalid_type.lua (100%) rename test_scripts/{ => SDL5_0}/Image_template/005_isTemplate_is_true_with_not_png_image.lua (100%) rename test_scripts/{ => SDL5_0}/Image_template/006_isTemplate_is_true_with_STATIC_image.lua (100%) rename test_scripts/{ => SDL5_0}/Image_template/commonImageTemplate.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/001_Low_Voltage_and_Wake_Up.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/004_App_unregister_itself_gracefully.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua (100%) rename test_scripts/{ => SDL5_0}/LowVoltage/common.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/MobileVersioning/PlayPauseButton/001_play_pause_v5_allowed.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/MobileVersioning/vrCommandOptional/001_create_interaction_choice_success_legacy_app.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/MobileVersioning/vrCommandOptional/002_create_interaction_choice_invalid_data_legacy_app.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/MobileVersioning/vrCommandOptional/003_perform_interaction_success_legacy_app.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/TTSChunks/001_RegisterAppInterface.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/TTSChunks/002_SetGlobalProperties.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/TTSChunks/003_OnAppRegistered.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/TTSChunks/004_Alert.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/TTSChunks/005_ChangeRegistration.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/TTSChunks/006_PerformInteraction.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/TTSChunks/007_Speak.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/TTSChunks/008_PerformAudioPassThru.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/TTSChunks/009_AlertManeuver.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/TTSChunks/common.lua (100%) rename test_scripts/{SDL4.6 => SDL5_0}/TemplateColorSchemes/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua (100%) rename test_scripts/{SDL4.6 => SDL5_0}/TemplateColorSchemes/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua (100%) rename test_scripts/{SDL4.6 => SDL5_0}/TemplateColorSchemes/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua (100%) rename test_scripts/{API => SDL5_0}/Transfer_RPC_with_invalid_image/001_AddCommand.lua (100%) rename test_scripts/{API => SDL5_0}/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua (100%) rename test_scripts/{API => SDL5_0}/Transfer_RPC_with_invalid_image/003_Alert.lua (100%) rename test_scripts/{API => SDL5_0}/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua (100%) rename test_scripts/{API => SDL5_0}/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua (100%) rename test_scripts/{API => SDL5_0}/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua (100%) rename test_scripts/{API => SDL5_0}/Transfer_RPC_with_invalid_image/007_Show.lua (100%) rename test_scripts/{API => SDL5_0}/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua (100%) rename test_scripts/{API => SDL5_0}/Transfer_RPC_with_invalid_image/009_SendLocation.lua (100%) rename test_scripts/{API => SDL5_0}/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua (100%) rename test_scripts/{API => SDL5_0}/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua (100%) rename test_scripts/{API => SDL5_0}/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua (100%) rename test_scripts/{API => SDL5_0}/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua (100%) rename test_scripts/{API => SDL5_0}/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua (100%) rename test_scripts/{API => SDL5_0}/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua (100%) rename test_scripts/{API => SDL5_0}/Transfer_RPC_with_invalid_image/common.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/vrCommandOptional/001_create_interaction_choice_set_invalid_data.lua (100%) rename test_scripts/{SDL4_6 => SDL5_0}/vrCommandOptional/002_perform_interaction_invalid_data.lua (100%) rename test_sets/{ => SDL5_0}/app_icon_resumption.txt (100%) create mode 100644 test_sets/SDL5_0/audio_file_playback_tts_chunks.txt rename test_sets/{ => SDL5_0}/audio_source_am_fm_xm.txt (100%) rename test_sets/{ => SDL5_0}/dtls_encryption.txt (100%) create mode 100644 test_sets/SDL5_0/duplicate_correlation_ids.txt rename test_sets/{ => SDL5_0}/expand_put_file.txt (100%) rename test_sets/{ => SDL5_0}/expandable_design_for_proprietary_data_exchange.txt (100%) create mode 100644 test_sets/SDL5_0/full_app_id.txt rename test_sets/{ => SDL5_0}/get_system_time.txt (100%) create mode 100644 test_sets/SDL5_0/handling_VR_help_requests.txt rename test_sets/{ => SDL5_0}/interior_vehicle_data_management.txt (100%) create mode 100644 test_sets/SDL5_0/low_voltage.txt create mode 100644 test_sets/SDL5_0/mobile_api_versioning.txt rename test_sets/{ => SDL5_0}/mobile_projection_2.txt (100%) rename test_sets/{ => SDL5_0}/mobile_projection_2_smoke.txt (100%) create mode 100644 test_sets/SDL5_0/rc_AUDIO_LIGHT_HMI_SETTINGS.txt create mode 100644 test_sets/SDL5_0/rc_CLIMATE_RADIO.txt rename test_sets/{ => SDL5_0}/rc_OnRCStatus.txt (100%) create mode 100644 test_sets/SDL5_0/rc_SEAT.txt rename test_sets/{ => SDL5_0}/rc_lights_more_names_and_status_values.txt (100%) rename test_sets/{ => SDL5_0}/rc_radio_parameter_update.txt (100%) create mode 100644 test_sets/SDL5_0/sdl_5_0_test_suite.txt rename test_sets/{ => SDL5_0}/submenu_icon.txt (100%) create mode 100644 test_sets/SDL5_0/template_color_schemes.txt create mode 100644 test_sets/SDL5_0/template_images.txt create mode 100644 test_sets/SDL5_0/transfer_rpc_with_invalid_image.txt rename test_sets/{ => SDL5_0}/updating_dop_value_range.txt (100%) rename test_sets/{VehicleData.txt => SDL5_0/vehicle_data.txt} (100%) create mode 100644 test_sets/SDL5_0/vr_command_optional.txt delete mode 100644 test_sets/SDL_0042_Transfer_RPC_with_Invalid_Image.txt delete mode 100644 test_sets/audio_file_playback_tts_chunks.txt delete mode 100644 test_sets/handling_VR_help_requests.txt delete mode 100644 test_sets/low_voltage.txt delete mode 100644 test_sets/mobile_api_versioning.txt delete mode 100644 test_sets/template_images.txt create mode 100644 test_sets/vehicle_data.txt diff --git a/test_scripts/SDL4.6/SDL-0162/001_DuplicateCorrelationIDs_INVALID_ID.lua b/test_scripts/SDL5_0/DuplicateCorrIDs/001_DuplicateCorrelationIDs_INVALID_ID.lua similarity index 100% rename from test_scripts/SDL4.6/SDL-0162/001_DuplicateCorrelationIDs_INVALID_ID.lua rename to test_scripts/SDL5_0/DuplicateCorrIDs/001_DuplicateCorrelationIDs_INVALID_ID.lua diff --git a/test_scripts/SDL4_6/FullAppID/001_PTU_full_app_ID_true.lua b/test_scripts/SDL5_0/FullAppID/001_PTU_full_app_ID_true.lua similarity index 100% rename from test_scripts/SDL4_6/FullAppID/001_PTU_full_app_ID_true.lua rename to test_scripts/SDL5_0/FullAppID/001_PTU_full_app_ID_true.lua diff --git a/test_scripts/SDL4_6/FullAppID/002_PTU_full_app_ID_false.lua b/test_scripts/SDL5_0/FullAppID/002_PTU_full_app_ID_false.lua similarity index 100% rename from test_scripts/SDL4_6/FullAppID/002_PTU_full_app_ID_false.lua rename to test_scripts/SDL5_0/FullAppID/002_PTU_full_app_ID_false.lua diff --git a/test_scripts/SDL4_6/FullAppID/common.lua b/test_scripts/SDL5_0/FullAppID/common.lua similarity index 100% rename from test_scripts/SDL4_6/FullAppID/common.lua rename to test_scripts/SDL5_0/FullAppID/common.lua diff --git a/test_scripts/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua diff --git a/test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua diff --git a/test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua diff --git a/test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua diff --git a/test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua diff --git a/test_scripts/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua diff --git a/test_scripts/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua diff --git a/test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua diff --git a/test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua diff --git a/test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua diff --git a/test_scripts/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua diff --git a/test_scripts/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua diff --git a/test_scripts/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua diff --git a/test_scripts/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua diff --git a/test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua diff --git a/test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua diff --git a/test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua diff --git a/test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua diff --git a/test_scripts/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua diff --git a/test_scripts/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua diff --git a/test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua diff --git a/test_scripts/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua diff --git a/test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua diff --git a/test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua diff --git a/test_scripts/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua diff --git a/test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua diff --git a/test_scripts/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua diff --git a/test_scripts/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua diff --git a/test_scripts/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua diff --git a/test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua diff --git a/test_scripts/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua diff --git a/test_scripts/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua diff --git a/test_scripts/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua diff --git a/test_scripts/Handling_VR_help_requests/commonVRhelp.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp.lua similarity index 100% rename from test_scripts/Handling_VR_help_requests/commonVRhelp.lua rename to test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp.lua diff --git a/test_scripts/Image_template/001_isTemplate_is_true.lua b/test_scripts/SDL5_0/Image_template/001_isTemplate_is_true.lua similarity index 100% rename from test_scripts/Image_template/001_isTemplate_is_true.lua rename to test_scripts/SDL5_0/Image_template/001_isTemplate_is_true.lua diff --git a/test_scripts/Image_template/002_isTemplate_is_false.lua b/test_scripts/SDL5_0/Image_template/002_isTemplate_is_false.lua similarity index 100% rename from test_scripts/Image_template/002_isTemplate_is_false.lua rename to test_scripts/SDL5_0/Image_template/002_isTemplate_is_false.lua diff --git a/test_scripts/Image_template/003_isTemplate_is_absent.lua b/test_scripts/SDL5_0/Image_template/003_isTemplate_is_absent.lua similarity index 100% rename from test_scripts/Image_template/003_isTemplate_is_absent.lua rename to test_scripts/SDL5_0/Image_template/003_isTemplate_is_absent.lua diff --git a/test_scripts/Image_template/004_isTemplate_invalid_type.lua b/test_scripts/SDL5_0/Image_template/004_isTemplate_invalid_type.lua similarity index 100% rename from test_scripts/Image_template/004_isTemplate_invalid_type.lua rename to test_scripts/SDL5_0/Image_template/004_isTemplate_invalid_type.lua diff --git a/test_scripts/Image_template/005_isTemplate_is_true_with_not_png_image.lua b/test_scripts/SDL5_0/Image_template/005_isTemplate_is_true_with_not_png_image.lua similarity index 100% rename from test_scripts/Image_template/005_isTemplate_is_true_with_not_png_image.lua rename to test_scripts/SDL5_0/Image_template/005_isTemplate_is_true_with_not_png_image.lua diff --git a/test_scripts/Image_template/006_isTemplate_is_true_with_STATIC_image.lua b/test_scripts/SDL5_0/Image_template/006_isTemplate_is_true_with_STATIC_image.lua similarity index 100% rename from test_scripts/Image_template/006_isTemplate_is_true_with_STATIC_image.lua rename to test_scripts/SDL5_0/Image_template/006_isTemplate_is_true_with_STATIC_image.lua diff --git a/test_scripts/Image_template/commonImageTemplate.lua b/test_scripts/SDL5_0/Image_template/commonImageTemplate.lua similarity index 100% rename from test_scripts/Image_template/commonImageTemplate.lua rename to test_scripts/SDL5_0/Image_template/commonImageTemplate.lua diff --git a/test_scripts/LowVoltage/001_Low_Voltage_and_Wake_Up.lua b/test_scripts/SDL5_0/LowVoltage/001_Low_Voltage_and_Wake_Up.lua similarity index 100% rename from test_scripts/LowVoltage/001_Low_Voltage_and_Wake_Up.lua rename to test_scripts/SDL5_0/LowVoltage/001_Low_Voltage_and_Wake_Up.lua diff --git a/test_scripts/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua b/test_scripts/SDL5_0/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua similarity index 100% rename from test_scripts/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua rename to test_scripts/SDL5_0/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua diff --git a/test_scripts/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua b/test_scripts/SDL5_0/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua similarity index 100% rename from test_scripts/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua rename to test_scripts/SDL5_0/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua diff --git a/test_scripts/LowVoltage/004_App_unregister_itself_gracefully.lua b/test_scripts/SDL5_0/LowVoltage/004_App_unregister_itself_gracefully.lua similarity index 100% rename from test_scripts/LowVoltage/004_App_unregister_itself_gracefully.lua rename to test_scripts/SDL5_0/LowVoltage/004_App_unregister_itself_gracefully.lua diff --git a/test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua b/test_scripts/SDL5_0/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua similarity index 100% rename from test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua rename to test_scripts/SDL5_0/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua diff --git a/test_scripts/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua b/test_scripts/SDL5_0/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua similarity index 100% rename from test_scripts/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua rename to test_scripts/SDL5_0/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua diff --git a/test_scripts/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua b/test_scripts/SDL5_0/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua similarity index 100% rename from test_scripts/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua rename to test_scripts/SDL5_0/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua diff --git a/test_scripts/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua b/test_scripts/SDL5_0/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua similarity index 100% rename from test_scripts/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua rename to test_scripts/SDL5_0/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua diff --git a/test_scripts/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua b/test_scripts/SDL5_0/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua similarity index 100% rename from test_scripts/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua rename to test_scripts/SDL5_0/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua diff --git a/test_scripts/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua b/test_scripts/SDL5_0/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua similarity index 100% rename from test_scripts/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua rename to test_scripts/SDL5_0/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua diff --git a/test_scripts/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua b/test_scripts/SDL5_0/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua similarity index 100% rename from test_scripts/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua rename to test_scripts/SDL5_0/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua diff --git a/test_scripts/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua b/test_scripts/SDL5_0/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua similarity index 100% rename from test_scripts/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua rename to test_scripts/SDL5_0/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua diff --git a/test_scripts/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua b/test_scripts/SDL5_0/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua similarity index 100% rename from test_scripts/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua rename to test_scripts/SDL5_0/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua diff --git a/test_scripts/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua b/test_scripts/SDL5_0/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua similarity index 100% rename from test_scripts/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua rename to test_scripts/SDL5_0/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua diff --git a/test_scripts/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua b/test_scripts/SDL5_0/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua similarity index 100% rename from test_scripts/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua rename to test_scripts/SDL5_0/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua diff --git a/test_scripts/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua b/test_scripts/SDL5_0/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua similarity index 100% rename from test_scripts/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua rename to test_scripts/SDL5_0/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua diff --git a/test_scripts/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua b/test_scripts/SDL5_0/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua similarity index 100% rename from test_scripts/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua rename to test_scripts/SDL5_0/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua diff --git a/test_scripts/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua b/test_scripts/SDL5_0/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua similarity index 100% rename from test_scripts/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua rename to test_scripts/SDL5_0/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua diff --git a/test_scripts/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua b/test_scripts/SDL5_0/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua similarity index 100% rename from test_scripts/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua rename to test_scripts/SDL5_0/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua diff --git a/test_scripts/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua b/test_scripts/SDL5_0/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua similarity index 100% rename from test_scripts/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua rename to test_scripts/SDL5_0/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua diff --git a/test_scripts/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua b/test_scripts/SDL5_0/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua similarity index 100% rename from test_scripts/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua rename to test_scripts/SDL5_0/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua diff --git a/test_scripts/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua b/test_scripts/SDL5_0/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua similarity index 100% rename from test_scripts/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua rename to test_scripts/SDL5_0/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua diff --git a/test_scripts/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua b/test_scripts/SDL5_0/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua similarity index 100% rename from test_scripts/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua rename to test_scripts/SDL5_0/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua diff --git a/test_scripts/LowVoltage/common.lua b/test_scripts/SDL5_0/LowVoltage/common.lua similarity index 100% rename from test_scripts/LowVoltage/common.lua rename to test_scripts/SDL5_0/LowVoltage/common.lua diff --git a/test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/001_play_pause_v5_allowed.lua b/test_scripts/SDL5_0/MobileVersioning/PlayPauseButton/001_play_pause_v5_allowed.lua similarity index 100% rename from test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/001_play_pause_v5_allowed.lua rename to test_scripts/SDL5_0/MobileVersioning/PlayPauseButton/001_play_pause_v5_allowed.lua diff --git a/test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua b/test_scripts/SDL5_0/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua similarity index 100% rename from test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua rename to test_scripts/SDL5_0/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua diff --git a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua b/test_scripts/SDL5_0/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua similarity index 100% rename from test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua rename to test_scripts/SDL5_0/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua diff --git a/test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua b/test_scripts/SDL5_0/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua similarity index 100% rename from test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua rename to test_scripts/SDL5_0/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua diff --git a/test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/001_create_interaction_choice_success_legacy_app.lua b/test_scripts/SDL5_0/MobileVersioning/vrCommandOptional/001_create_interaction_choice_success_legacy_app.lua similarity index 100% rename from test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/001_create_interaction_choice_success_legacy_app.lua rename to test_scripts/SDL5_0/MobileVersioning/vrCommandOptional/001_create_interaction_choice_success_legacy_app.lua diff --git a/test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/002_create_interaction_choice_invalid_data_legacy_app.lua b/test_scripts/SDL5_0/MobileVersioning/vrCommandOptional/002_create_interaction_choice_invalid_data_legacy_app.lua similarity index 100% rename from test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/002_create_interaction_choice_invalid_data_legacy_app.lua rename to test_scripts/SDL5_0/MobileVersioning/vrCommandOptional/002_create_interaction_choice_invalid_data_legacy_app.lua diff --git a/test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/003_perform_interaction_success_legacy_app.lua b/test_scripts/SDL5_0/MobileVersioning/vrCommandOptional/003_perform_interaction_success_legacy_app.lua similarity index 100% rename from test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/003_perform_interaction_success_legacy_app.lua rename to test_scripts/SDL5_0/MobileVersioning/vrCommandOptional/003_perform_interaction_success_legacy_app.lua diff --git a/test_scripts/SDL4_6/TTSChunks/001_RegisterAppInterface.lua b/test_scripts/SDL5_0/TTSChunks/001_RegisterAppInterface.lua similarity index 100% rename from test_scripts/SDL4_6/TTSChunks/001_RegisterAppInterface.lua rename to test_scripts/SDL5_0/TTSChunks/001_RegisterAppInterface.lua diff --git a/test_scripts/SDL4_6/TTSChunks/002_SetGlobalProperties.lua b/test_scripts/SDL5_0/TTSChunks/002_SetGlobalProperties.lua similarity index 100% rename from test_scripts/SDL4_6/TTSChunks/002_SetGlobalProperties.lua rename to test_scripts/SDL5_0/TTSChunks/002_SetGlobalProperties.lua diff --git a/test_scripts/SDL4_6/TTSChunks/003_OnAppRegistered.lua b/test_scripts/SDL5_0/TTSChunks/003_OnAppRegistered.lua similarity index 100% rename from test_scripts/SDL4_6/TTSChunks/003_OnAppRegistered.lua rename to test_scripts/SDL5_0/TTSChunks/003_OnAppRegistered.lua diff --git a/test_scripts/SDL4_6/TTSChunks/004_Alert.lua b/test_scripts/SDL5_0/TTSChunks/004_Alert.lua similarity index 100% rename from test_scripts/SDL4_6/TTSChunks/004_Alert.lua rename to test_scripts/SDL5_0/TTSChunks/004_Alert.lua diff --git a/test_scripts/SDL4_6/TTSChunks/005_ChangeRegistration.lua b/test_scripts/SDL5_0/TTSChunks/005_ChangeRegistration.lua similarity index 100% rename from test_scripts/SDL4_6/TTSChunks/005_ChangeRegistration.lua rename to test_scripts/SDL5_0/TTSChunks/005_ChangeRegistration.lua diff --git a/test_scripts/SDL4_6/TTSChunks/006_PerformInteraction.lua b/test_scripts/SDL5_0/TTSChunks/006_PerformInteraction.lua similarity index 100% rename from test_scripts/SDL4_6/TTSChunks/006_PerformInteraction.lua rename to test_scripts/SDL5_0/TTSChunks/006_PerformInteraction.lua diff --git a/test_scripts/SDL4_6/TTSChunks/007_Speak.lua b/test_scripts/SDL5_0/TTSChunks/007_Speak.lua similarity index 100% rename from test_scripts/SDL4_6/TTSChunks/007_Speak.lua rename to test_scripts/SDL5_0/TTSChunks/007_Speak.lua diff --git a/test_scripts/SDL4_6/TTSChunks/008_PerformAudioPassThru.lua b/test_scripts/SDL5_0/TTSChunks/008_PerformAudioPassThru.lua similarity index 100% rename from test_scripts/SDL4_6/TTSChunks/008_PerformAudioPassThru.lua rename to test_scripts/SDL5_0/TTSChunks/008_PerformAudioPassThru.lua diff --git a/test_scripts/SDL4_6/TTSChunks/009_AlertManeuver.lua b/test_scripts/SDL5_0/TTSChunks/009_AlertManeuver.lua similarity index 100% rename from test_scripts/SDL4_6/TTSChunks/009_AlertManeuver.lua rename to test_scripts/SDL5_0/TTSChunks/009_AlertManeuver.lua diff --git a/test_scripts/SDL4_6/TTSChunks/common.lua b/test_scripts/SDL5_0/TTSChunks/common.lua similarity index 100% rename from test_scripts/SDL4_6/TTSChunks/common.lua rename to test_scripts/SDL5_0/TTSChunks/common.lua diff --git a/test_scripts/SDL4.6/TemplateColorSchemes/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua b/test_scripts/SDL5_0/TemplateColorSchemes/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua similarity index 100% rename from test_scripts/SDL4.6/TemplateColorSchemes/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua rename to test_scripts/SDL5_0/TemplateColorSchemes/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua diff --git a/test_scripts/SDL4.6/TemplateColorSchemes/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua b/test_scripts/SDL5_0/TemplateColorSchemes/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua similarity index 100% rename from test_scripts/SDL4.6/TemplateColorSchemes/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua rename to test_scripts/SDL5_0/TemplateColorSchemes/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua diff --git a/test_scripts/SDL4.6/TemplateColorSchemes/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua b/test_scripts/SDL5_0/TemplateColorSchemes/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua similarity index 100% rename from test_scripts/SDL4.6/TemplateColorSchemes/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua rename to test_scripts/SDL5_0/TemplateColorSchemes/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/001_AddCommand.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/001_AddCommand.lua similarity index 100% rename from test_scripts/API/Transfer_RPC_with_invalid_image/001_AddCommand.lua rename to test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/001_AddCommand.lua diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua similarity index 100% rename from test_scripts/API/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua rename to test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/003_Alert.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/003_Alert.lua similarity index 100% rename from test_scripts/API/Transfer_RPC_with_invalid_image/003_Alert.lua rename to test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/003_Alert.lua diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua similarity index 100% rename from test_scripts/API/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua rename to test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua similarity index 100% rename from test_scripts/API/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua rename to test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua similarity index 100% rename from test_scripts/API/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua rename to test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/007_Show.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/007_Show.lua similarity index 100% rename from test_scripts/API/Transfer_RPC_with_invalid_image/007_Show.lua rename to test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/007_Show.lua diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua similarity index 100% rename from test_scripts/API/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua rename to test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/009_SendLocation.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/009_SendLocation.lua similarity index 100% rename from test_scripts/API/Transfer_RPC_with_invalid_image/009_SendLocation.lua rename to test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/009_SendLocation.lua diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua similarity index 100% rename from test_scripts/API/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua rename to test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua similarity index 100% rename from test_scripts/API/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua rename to test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua similarity index 100% rename from test_scripts/API/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua rename to test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua similarity index 100% rename from test_scripts/API/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua rename to test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua similarity index 100% rename from test_scripts/API/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua rename to test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua similarity index 100% rename from test_scripts/API/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua rename to test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua diff --git a/test_scripts/API/Transfer_RPC_with_invalid_image/common.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common.lua similarity index 100% rename from test_scripts/API/Transfer_RPC_with_invalid_image/common.lua rename to test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common.lua diff --git a/test_scripts/SDL4_6/vrCommandOptional/001_create_interaction_choice_set_invalid_data.lua b/test_scripts/SDL5_0/vrCommandOptional/001_create_interaction_choice_set_invalid_data.lua similarity index 100% rename from test_scripts/SDL4_6/vrCommandOptional/001_create_interaction_choice_set_invalid_data.lua rename to test_scripts/SDL5_0/vrCommandOptional/001_create_interaction_choice_set_invalid_data.lua diff --git a/test_scripts/SDL4_6/vrCommandOptional/002_perform_interaction_invalid_data.lua b/test_scripts/SDL5_0/vrCommandOptional/002_perform_interaction_invalid_data.lua similarity index 100% rename from test_scripts/SDL4_6/vrCommandOptional/002_perform_interaction_invalid_data.lua rename to test_scripts/SDL5_0/vrCommandOptional/002_perform_interaction_invalid_data.lua diff --git a/test_sets/app_icon_resumption.txt b/test_sets/SDL5_0/app_icon_resumption.txt similarity index 100% rename from test_sets/app_icon_resumption.txt rename to test_sets/SDL5_0/app_icon_resumption.txt diff --git a/test_sets/SDL5_0/audio_file_playback_tts_chunks.txt b/test_sets/SDL5_0/audio_file_playback_tts_chunks.txt new file mode 100644 index 0000000000..8cab045ded --- /dev/null +++ b/test_sets/SDL5_0/audio_file_playback_tts_chunks.txt @@ -0,0 +1,9 @@ +./test_scripts/SDL5_0/TTSChunks/001_RegisterAppInterface.lua +./test_scripts/SDL5_0/TTSChunks/002_SetGlobalProperties.lua +./test_scripts/SDL5_0/TTSChunks/003_OnAppRegistered.lua +./test_scripts/SDL5_0/TTSChunks/004_Alert.lua +./test_scripts/SDL5_0/TTSChunks/005_ChangeRegistration.lua +./test_scripts/SDL5_0/TTSChunks/006_PerformInteraction.lua +./test_scripts/SDL5_0/TTSChunks/007_Speak.lua +./test_scripts/SDL5_0/TTSChunks/008_PerformAudioPassThru.lua +./test_scripts/SDL5_0/TTSChunks/009_AlertManeuver.lua diff --git a/test_sets/audio_source_am_fm_xm.txt b/test_sets/SDL5_0/audio_source_am_fm_xm.txt similarity index 100% rename from test_sets/audio_source_am_fm_xm.txt rename to test_sets/SDL5_0/audio_source_am_fm_xm.txt diff --git a/test_sets/dtls_encryption.txt b/test_sets/SDL5_0/dtls_encryption.txt similarity index 100% rename from test_sets/dtls_encryption.txt rename to test_sets/SDL5_0/dtls_encryption.txt diff --git a/test_sets/SDL5_0/duplicate_correlation_ids.txt b/test_sets/SDL5_0/duplicate_correlation_ids.txt new file mode 100644 index 0000000000..78a3c9e7e1 --- /dev/null +++ b/test_sets/SDL5_0/duplicate_correlation_ids.txt @@ -0,0 +1 @@ +./test_scripts/SDL5_0/DuplicateCorrIDs/001_DuplicateCorrelationIDs_INVALID_ID.lua \ No newline at end of file diff --git a/test_sets/expand_put_file.txt b/test_sets/SDL5_0/expand_put_file.txt similarity index 100% rename from test_sets/expand_put_file.txt rename to test_sets/SDL5_0/expand_put_file.txt diff --git a/test_sets/expandable_design_for_proprietary_data_exchange.txt b/test_sets/SDL5_0/expandable_design_for_proprietary_data_exchange.txt similarity index 100% rename from test_sets/expandable_design_for_proprietary_data_exchange.txt rename to test_sets/SDL5_0/expandable_design_for_proprietary_data_exchange.txt diff --git a/test_sets/SDL5_0/full_app_id.txt b/test_sets/SDL5_0/full_app_id.txt new file mode 100644 index 0000000000..e2fc12c9ab --- /dev/null +++ b/test_sets/SDL5_0/full_app_id.txt @@ -0,0 +1,2 @@ +./test_scripts/SDL5_0/FullAppID/001_PTU_full_app_ID_true.lua +./test_scripts/SDL5_0/FullAppID/002_PTU_full_app_ID_false.lua \ No newline at end of file diff --git a/test_sets/get_system_time.txt b/test_sets/SDL5_0/get_system_time.txt similarity index 100% rename from test_sets/get_system_time.txt rename to test_sets/SDL5_0/get_system_time.txt diff --git a/test_sets/SDL5_0/handling_VR_help_requests.txt b/test_sets/SDL5_0/handling_VR_help_requests.txt new file mode 100644 index 0000000000..fd3d53c53f --- /dev/null +++ b/test_sets/SDL5_0/handling_VR_help_requests.txt @@ -0,0 +1,33 @@ +./test_scripts/SDL5_0/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua diff --git a/test_sets/interior_vehicle_data_management.txt b/test_sets/SDL5_0/interior_vehicle_data_management.txt similarity index 100% rename from test_sets/interior_vehicle_data_management.txt rename to test_sets/SDL5_0/interior_vehicle_data_management.txt diff --git a/test_sets/SDL5_0/low_voltage.txt b/test_sets/SDL5_0/low_voltage.txt new file mode 100644 index 0000000000..715e5550b2 --- /dev/null +++ b/test_sets/SDL5_0/low_voltage.txt @@ -0,0 +1,23 @@ +./test_scripts/SDL5_0/LowVoltage/001_Low_Voltage_and_Wake_Up.lua +./test_scripts/SDL5_0/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua +./test_scripts/SDL5_0/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua +./test_scripts/SDL5_0/LowVoltage/004_App_unregister_itself_gracefully.lua +./test_scripts/SDL5_0/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua +./test_scripts/SDL5_0/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua +./test_scripts/SDL5_0/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua +./test_scripts/SDL5_0/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua +./test_scripts/SDL5_0/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua +./test_scripts/SDL5_0/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua +./test_scripts/SDL5_0/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua +./test_scripts/SDL5_0/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua +./test_scripts/SDL5_0/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua +./test_scripts/SDL5_0/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua +./test_scripts/SDL5_0/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua +./test_scripts/SDL5_0/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua +./test_scripts/SDL5_0/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua +./test_scripts/SDL5_0/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua +./test_scripts/SDL5_0/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua +./test_scripts/SDL5_0/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua +./test_scripts/SDL5_0/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua +./test_scripts/SDL5_0/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua +./test_scripts/SDL5_0/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua diff --git a/test_sets/SDL5_0/mobile_api_versioning.txt b/test_sets/SDL5_0/mobile_api_versioning.txt new file mode 100644 index 0000000000..452ef6305b --- /dev/null +++ b/test_sets/SDL5_0/mobile_api_versioning.txt @@ -0,0 +1,12 @@ +;Version Negotiation +./test_scripts/SDL5_0/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua +./test_scripts/SDL5_0/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua +./test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua +;VR-Command Optional +./test_scripts/SDL5_0/MobileVersioning/vrCommandOptional/001_create_interaction_choice_success_legacy_app.lua +./test_scripts/SDL5_0/MobileVersioning/vrCommandOptional/002_create_interaction_choice_invalid_data_legacy_app.lua +./test_scripts/SDL5_0/MobileVersioning/vrCommandOptional/003_perform_interaction_success_legacy_app.lua +;Play/Pause Button +./test_scripts/SDL5_0/MobileVersioning/PlayPauseButton/001_play_pause_v5_allowed.lua +./test_scripts/SDL5_0/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua diff --git a/test_sets/mobile_projection_2.txt b/test_sets/SDL5_0/mobile_projection_2.txt similarity index 100% rename from test_sets/mobile_projection_2.txt rename to test_sets/SDL5_0/mobile_projection_2.txt diff --git a/test_sets/mobile_projection_2_smoke.txt b/test_sets/SDL5_0/mobile_projection_2_smoke.txt similarity index 100% rename from test_sets/mobile_projection_2_smoke.txt rename to test_sets/SDL5_0/mobile_projection_2_smoke.txt diff --git a/test_sets/SDL5_0/rc_AUDIO_LIGHT_HMI_SETTINGS.txt b/test_sets/SDL5_0/rc_AUDIO_LIGHT_HMI_SETTINGS.txt new file mode 100644 index 0000000000..faae0fd39d --- /dev/null +++ b/test_sets/SDL5_0/rc_AUDIO_LIGHT_HMI_SETTINGS.txt @@ -0,0 +1,57 @@ +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/004_HMI_no_response_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/005_HMI_invalid_response_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/001_Success_flow.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/003_UNSUPPORTED_RESOURCE_in_case_RC_interface_is_unavailable.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/004_Allowed_true_accessMode_AUTO_DENY.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/005_Allowed_true_accessMode_ASK_DRIVER.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/006_Default_accessMode.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/008_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_without_keepContext.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_false.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua diff --git a/test_sets/SDL5_0/rc_CLIMATE_RADIO.txt b/test_sets/SDL5_0/rc_CLIMATE_RADIO.txt new file mode 100644 index 0000000000..d39912361e --- /dev/null +++ b/test_sets/SDL5_0/rc_CLIMATE_RADIO.txt @@ -0,0 +1,107 @@ +./test_scripts/RC/CLIMATE_RADIO/Capabilities/001_All_modules_all_params.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/002_Only_CLIMATE_all_params.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/003_Only_RADIO_all_params.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/005_Resend_only_supported_parameters.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/006_RPC_parameters_values.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/001_success_flow_for_climate_and_radio.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/003_disallow_flow_by_policy_for_radio.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/006_check_rpc_parameters_for_button_press.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/010_generic_error_if_no_response_from_hmi.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/016_RPC_parameters_values.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/012_Default_accessMode.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/015_Empty_data_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/025_IN_USE_in_case_3_requests.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/006_RPC_parameters_values.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua diff --git a/test_sets/rc_OnRCStatus.txt b/test_sets/SDL5_0/rc_OnRCStatus.txt similarity index 100% rename from test_sets/rc_OnRCStatus.txt rename to test_sets/SDL5_0/rc_OnRCStatus.txt diff --git a/test_sets/SDL5_0/rc_SEAT.txt b/test_sets/SDL5_0/rc_SEAT.txt new file mode 100644 index 0000000000..91c5bf122c --- /dev/null +++ b/test_sets/SDL5_0/rc_SEAT.txt @@ -0,0 +1,32 @@ +./test_scripts/RC/SEAT/Capabilities/001_SEAT_all_params_SUCCESS.lua +./test_scripts/RC/SEAT/Capabilities/002_SEAT_all_params_UNSUPPORTED_RESOURCE.lua +./test_scripts/RC/SEAT/Capabilities/003_Resend_only_supported_parameters.lua +./test_scripts/RC/SEAT/Capabilities/004_Reject_request_with_both_supported_and_not_supported_parameters.lua +./test_scripts/RC/SEAT/Capabilities/005_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua +./test_scripts/RC/SEAT/Capabilities/006_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/002_Transfering_of_HMI_resultCode_to_mobile.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/003_RPC_parameters_values.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/004_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/005_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/003_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Seat.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/005_Existence_of_OnIVD_for_module_Seat_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Climate.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/006_RPC_parameters_values.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_SEAT.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/003_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/004_RPC_parameters_values.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/005_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/006_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/008_Transfering_of_HMI_resultCode_to_mobile.lua diff --git a/test_sets/rc_lights_more_names_and_status_values.txt b/test_sets/SDL5_0/rc_lights_more_names_and_status_values.txt similarity index 100% rename from test_sets/rc_lights_more_names_and_status_values.txt rename to test_sets/SDL5_0/rc_lights_more_names_and_status_values.txt diff --git a/test_sets/rc_radio_parameter_update.txt b/test_sets/SDL5_0/rc_radio_parameter_update.txt similarity index 100% rename from test_sets/rc_radio_parameter_update.txt rename to test_sets/SDL5_0/rc_radio_parameter_update.txt diff --git a/test_sets/SDL5_0/sdl_5_0_test_suite.txt b/test_sets/SDL5_0/sdl_5_0_test_suite.txt new file mode 100644 index 0000000000..bbb56bbf17 --- /dev/null +++ b/test_sets/SDL5_0/sdl_5_0_test_suite.txt @@ -0,0 +1,575 @@ +; +;App Icon Resumption +; +./test_scripts/API/SetAppIcon/001_Mobile_app_First_Registration.lua +./test_scripts/API/SetAppIcon/002_Mobile_app_registration_with_param_iconResumed_true.lua +./test_scripts/API/SetAppIcon/003_Icon_resumption_by_disconnect.lua +./test_scripts/API/SetAppIcon/004_Remove_icon_and_reregistered_Mobile_app.lua +./test_scripts/API/SetAppIcon/005_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_false.lua +./test_scripts/API/SetAppIcon/006_Two_apps_are_registered_App1_iconResumed_true_App2_iconResumed_true.lua +./test_scripts/API/SetAppIcon/007_HMI_did_not_respond_to_SetAppIcon_request_GENERIC_ERROR.lua +./test_scripts/API/SetAppIcon/008_Mobile_App_received_response_SetAppIcon_INVALID_DATA.lua +./test_scripts/API/SetAppIcon/009_Mobile_App_received_response_SetAppIcon_DISALLOWED.lua +./test_scripts/API/SetAppIcon/010_Mobile_App_received_response_SetAppIcon_REJECTED.lua +./test_scripts/API/SetAppIcon/011_App_re_sets_custom_icon_iconResumed_true.lua +; +;Audio File TTSChunks +; +./test_scripts/SDL5_0/TTSChunks/001_RegisterAppInterface.lua +./test_scripts/SDL5_0/TTSChunks/002_SetGlobalProperties.lua +./test_scripts/SDL5_0/TTSChunks/003_OnAppRegistered.lua +./test_scripts/SDL5_0/TTSChunks/004_Alert.lua +./test_scripts/SDL5_0/TTSChunks/005_ChangeRegistration.lua +./test_scripts/SDL5_0/TTSChunks/006_PerformInteraction.lua +./test_scripts/SDL5_0/TTSChunks/007_Speak.lua +./test_scripts/SDL5_0/TTSChunks/008_PerformAudioPassThru.lua +./test_scripts/SDL5_0/TTSChunks/009_AlertManeuver.lua +; +;Choice-VR Optional +; +./test_scripts/SDL5_0/vrCommandOptional/001_create_interaction_choice_set_invalid_data.lua +./test_scripts/SDL5_0/vrCommandOptional/002_perform_interaction_invalid_data.lua +; +;DTLS Encryption +; +./test_scripts/Security/DTLS/001_StartRPC_service.lua +./test_scripts/Security/DTLS/002_Start_Audio_service.lua +./test_scripts/Security/DTLS/003_Start_Video_service.lua +./test_scripts/Security/DTLS/004_Processing_of_RPC.lua +./test_scripts/Security/DTLS/005_Ignore_malformed_packet.lua +./test_scripts/Security/DTLS/006_Ignore_unexpected_packet.lua +./test_scripts/Security/DTLS/007_Processing_multiple_frames.lua +; +;Duplicate Correlation ID handling +; +./test_scripts/SDL5_0/DuplicateCorrIDs/001_DuplicateCorrelationIDs_INVALID_ID.lua +; +;Expand PutFile +; +./test_scripts/API/Expand_PutFile/001_PutFile_with_crc_singleFrame.lua +./test_scripts/API/Expand_PutFile/002_PutFile_with_crc_MultiFrame.lua +./test_scripts/API/Expand_PutFile/003_PutFile_without_crc.lua +./test_scripts/API/Expand_PutFile/004_PutFile_chunks.lua +./test_scripts/API/Expand_PutFile/005_PutFile_with_negative_crc_singleFrame.lua +./test_scripts/API/Expand_PutFile/006_PutFile_with_negative_crc_multiFrame.lua +./test_scripts/API/Expand_PutFile/007_PutFile_with_crc_more_than_maxvalue.lua +./test_scripts/API/Expand_PutFile/008_PutFile_corrupted_data.lua +;Expandable Design for Proprietary Data Exchange +./test_scripts/API/Expanded_proprietary_data_exchange/001_SystemRequest_with_OEM_SPECIFIC_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/002_onSystemRequest_with_OEM_SPECIFIC_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/003_requestSubType_with_requestType_PROPRIETARY.lua +./test_scripts/API/Expanded_proprietary_data_exchange/004_requestSubType_with_requestType_HTTP.lua +./test_scripts/API/Expanded_proprietary_data_exchange/005_System_onSystemRequest_requestSubType_with_empty_array_in_ptu.lua +./test_scripts/API/Expanded_proprietary_data_exchange/006_System_onSystemRequest_requestSubType_with_array_of_values_in_ptu.lua +./test_scripts/API/Expanded_proprietary_data_exchange/007_System_onSystemRequest_without_requestSubType_in_ptu.lua +./test_scripts/API/Expanded_proprietary_data_exchange/008_OnAppRegistered_with_value_list_in_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/009_OnAppRegistered_with_empty_array_in_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/010_OnAppRegistered_without_requestSubType.lua +./test_scripts/API/Expanded_proprietary_data_exchange/011_OnAppRegistered_by_fist_registration.lua +./test_scripts/API/Expanded_proprietary_data_exchange/012_System_onSystemRequest_OEM_SPECIFIC_type_not_allowed.lua +./test_scripts/API/Expanded_proprietary_data_exchange/013_System_onSystemRequest_requestType_with_empty_array_in_ptu.lua +./test_scripts/API/Expanded_proprietary_data_exchange/014_System_onSystemRequest_requestType_with_list_of_values_ptu.lua +./test_scripts/API/Expanded_proprietary_data_exchange/015_System_onSystemRequest_requestType_without_parameter_in_pt.lua +./test_scripts/API/Expanded_proprietary_data_exchange/016_System_onSystemRequest_requestType_without_parameter_in_preloadedPT_DISALLOWED.lua +./test_scripts/API/Expanded_proprietary_data_exchange/017_System_onSystemRequest_requestSubType_without_parameter_in_preloadedPT_DISALLOWED.lua +;Full App ID +./test_scripts/SDL5_0/FullAppID/001_PTU_full_app_ID_true.lua +./test_scripts/SDL5_0/FullAppID/002_PTU_full_app_ID_false.lua +;GetSystemTime RPC +./test_scripts/Security/GetSystemTime/001_GetSystemTime_is_sent.lua +./test_scripts/Security/GetSystemTime/002_GetSystemTime_is_not_sent.lua +./test_scripts/Security/GetSystemTime/003_GetSystemTime_mobile_sdl_cer_are_expired.lua +./test_scripts/Security/GetSystemTime/004_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_is_not_valid.lua +./test_scripts/Security/GetSystemTime/005_GetSystemTime_mobile_is_not_valid_sdl_cer_becomes_valid.lua +./test_scripts/Security/GetSystemTime/006_GetSystemTime_mobile_sdl_cer_become_valid.lua +./test_scripts/Security/GetSystemTime/007_GetSystemTime_mobile_sdl_cer_become_valid_after_PTU.lua +./test_scripts/Security/GetSystemTime/008_GetSystemTime_mobile_cer_expired_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/009_GetSystemTime_mobile_cer_not_valid_yet_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/010_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/011_GetSystemTime_mobile_cer_not_valid_sdl_becomes_invalid.lua +./test_scripts/Security/GetSystemTime/012_GetSystemTime_mobile_cer_becomes_valid_sdl_cer_becomes_not_valid.lua +./test_scripts/Security/GetSystemTime/013_GetSystemTime_mobile_cer_valid_sdl_cer_not_valid.lua +./test_scripts/Security/GetSystemTime/014_GetSystemTime_mobile_cer_valid_sdl_cer_becomes_valid.lua +./test_scripts/Security/GetSystemTime/015_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_not_valid.lua +./test_scripts/Security/GetSystemTime/016_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid.lua +./test_scripts/Security/GetSystemTime/017_GetSystemTime_mobile_cer_becomes_not_valid_sdl_cer_becomes_valid_with_PTU.lua +./test_scripts/Security/GetSystemTime/018_GetSystemTime_mobile_cer_and_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/019_GetSystemTime_mobile_cer_becomes_not_valid_and_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/020_GetSystemTime_mobile_cer_becomes_yet_not_valid_and_sdl_cer_valid.lua +./test_scripts/Security/GetSystemTime/021_GetSystemTime_mobile_cer_valid_and_sdl_cer_becomes_not_valid.lua +./test_scripts/Security/GetSystemTime/022_GetSystemTime_mobile_cer_and_sdl_cer_become_expired.lua +./test_scripts/Security/GetSystemTime/023_GetSystemTime_without_response_from_HMI.lua +./test_scripts/Security/GetSystemTime/024_GetSystemTime_with_response_from_HMI_in_9_sec.lua +./test_scripts/Security/GetSystemTime/025_GetSystemTime_is_sent_later.lua +; +;Handling VR Help Requests +; +./test_scripts/SDL5_0/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua +./test_scripts/SDL5_0/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua +; +;Interior Vehicle Data Caching +; +./test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua +./test_scripts/RC/InteriorVehicleData_cache/001_GetInteriorVD_without_subscribe.lua +./test_scripts/RC/InteriorVehicleData_cache/002_GetInteriorVD_without_subscribe_2_requests.lua +./test_scripts/RC/InteriorVehicleData_cache/003_GetInteriorVD_without_subscribe_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/004_GetInteriorVD_subscribe_true.lua +./test_scripts/RC/InteriorVehicleData_cache/005_GetInteriorVD_subscribe_true_2_requests.lua +./test_scripts/RC/InteriorVehicleData_cache/006_GetInteriorVD_subscribe_true_and_without_subscribe_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/007_GetInteriorVD_subscribe_true_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/008_GetInteriorVD_subscribe_true_2_apps_different_modules.lua +./test_scripts/RC/InteriorVehicleData_cache/009_GetInteriorVD_without_subscribe_2_apps_different_modules.lua +./test_scripts/RC/InteriorVehicleData_cache/010_GetInteriorVD_subscribe_true_2_apps_same_module.lua +./test_scripts/RC/InteriorVehicleData_cache/011_OnInteriorVD_without_subscription.lua +./test_scripts/RC/InteriorVehicleData_cache/012_OnInteriorVD_app_unsubscribed.lua +./test_scripts/RC/InteriorVehicleData_cache/013_GetInteriorVD_without_subscription_after_OnInteriorVD.lua +./test_scripts/RC/InteriorVehicleData_cache/014_GetInteriorVD_with_subscription_after_OnInteriorVD.lua +./test_scripts/RC/InteriorVehicleData_cache/015_GetInteriorVD_with_subscription_after_OnInteriorVD_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/016_OnInteriorVD_2_apps_subscribed_and_not_subscribed.lua +./test_scripts/RC/InteriorVehicleData_cache/017_GetInteriorVD_subscribe_true_after_OnInteriorVD_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/018_GetInteriorVD_subscribe_false.lua +./test_scripts/RC/InteriorVehicleData_cache/019_GetInteriorVD_subscribe_false_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/021_GetInteriorVD_subscribe_false_by_app_unregistration.lua +./test_scripts/RC/InteriorVehicleData_cache/022_GetInteriorVD_subscribe_false_by_app_unregistration_different_modules.lua +./test_scripts/RC/InteriorVehicleData_cache/023_GetInteriorVD_subscribe_false_by_app_unregistration_same_module.lua +./test_scripts/RC/InteriorVehicleData_cache/024_GetInteriorVD_limitation.lua +./test_scripts/RC/InteriorVehicleData_cache/025_GetInteriorVD_limitation_rejected.lua +./test_scripts/RC/InteriorVehicleData_cache/026_GetInteriorVD_limitation_rejected_different_modules.lua +./test_scripts/RC/InteriorVehicleData_cache/027_GetInteriorVD_limitation_rejected_different_modules_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/028_GetInteriorVD_limitation_after_subscription.lua +./test_scripts/RC/InteriorVehicleData_cache/029_GetInteriorVD_limitation_rejected_after_unsubscribing.lua +./test_scripts/RC/InteriorVehicleData_cache/030_GetInteriorVD_limitation_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/031_GetInteriorVD_resubscribe_2_apps.lua +./test_scripts/RC/InteriorVehicleData_cache/032_OnInteriorVD_2_apps_subscribed.lua +./test_scripts/RC/InteriorVehicleData_cache/033_GetInteriorVD_subscribe_false_by_app_unregistration_2_modules.lua +./test_scripts/RC/InteriorVehicleData_cache/034_GetInteriorVD_subscribe_false_by_app_unexpected_disconnect.lua +./test_scripts/RC/InteriorVehicleData_cache/035_GetInteriorVD_subscribe_false_by_app_disallowed_RC.lua +./test_scripts/RC/InteriorVehicleData_cache/036_GetInteriorVD_subscribe_false_by_revoking_module.lua +./test_scripts/RC/InteriorVehicleData_cache/037_GetInteriorVD_subscribe_false_without_subscribtion.lua +./test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua +./test_scripts/RC/InteriorVehicleData_cache/039_GetInteriorVD_limitation_time_interval.lua +; +;Low Voltage +; +./test_scripts/SDL5_0/LowVoltage/001_Low_Voltage_and_Wake_Up.lua +./test_scripts/SDL5_0/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua +./test_scripts/SDL5_0/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua +./test_scripts/SDL5_0/LowVoltage/004_App_unregister_itself_gracefully.lua +./test_scripts/SDL5_0/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua +./test_scripts/SDL5_0/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua +./test_scripts/SDL5_0/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua +./test_scripts/SDL5_0/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua +./test_scripts/SDL5_0/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua +./test_scripts/SDL5_0/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua +./test_scripts/SDL5_0/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua +./test_scripts/SDL5_0/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua +./test_scripts/SDL5_0/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua +./test_scripts/SDL5_0/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua +./test_scripts/SDL5_0/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua +./test_scripts/SDL5_0/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua +./test_scripts/SDL5_0/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua +./test_scripts/SDL5_0/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua +./test_scripts/SDL5_0/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua +./test_scripts/SDL5_0/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua +./test_scripts/SDL5_0/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua +./test_scripts/SDL5_0/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua +./test_scripts/SDL5_0/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua +; +;Mobile API Versioning +; +;;Version Negotiation +./test_scripts/SDL5_0/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua +./test_scripts/SDL5_0/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua +./test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua +./test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua +;;VR-Command Optional +./test_scripts/SDL5_0/MobileVersioning/vrCommandOptional/001_create_interaction_choice_success_legacy_app.lua +./test_scripts/SDL5_0/MobileVersioning/vrCommandOptional/002_create_interaction_choice_invalid_data_legacy_app.lua +./test_scripts/SDL5_0/MobileVersioning/vrCommandOptional/003_perform_interaction_success_legacy_app.lua +;;Play/Pause Button +./test_scripts/SDL5_0/MobileVersioning/PlayPauseButton/001_play_pause_v5_allowed.lua +./test_scripts/SDL5_0/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua +; +;Mobile Projection Phase 2 +; +./test_scripts/MobileProjection/Phase2/001_audioStreamingState_001-009.lua +./test_scripts/MobileProjection/Phase2/002_audioStreamingState_010-068.lua +./test_scripts/MobileProjection/Phase2/003_audioStreamingState_069-103.lua +./test_scripts/MobileProjection/Phase2/004_audioStreamingState_104-110.lua +./test_scripts/MobileProjection/Phase2/005_audioStreamingState_111-118.lua +./test_scripts/MobileProjection/Phase2/006_videoStreamingState_001-006.lua +./test_scripts/MobileProjection/Phase2/007_videoStreamingState_007-030.lua +./test_scripts/MobileProjection/Phase2/008_videoStreamingState_031-042.lua +./test_scripts/MobileProjection/Phase2/009_hmiLevel_001-032.lua +./test_scripts/MobileProjection/Phase2/010_single_app_audio_and_video_streaming.lua +./test_scripts/MobileProjection/Phase2/011_single_app_video_streaming.lua +./test_scripts/MobileProjection/Phase2/012_single_app_deactivation.lua +./test_scripts/MobileProjection/Phase2/013_two_apps_interaction.lua +./test_scripts/MobileProjection/Phase2/014_audio_010-068_video_007-030_states_LIMITED.lua +./test_scripts/MobileProjection/Phase2/015_audio_083-089_097-103_video_031-038_states_not_FULL.lua +./test_scripts/MobileProjection/Phase2/016_BACKGROUND_not_changed.lua +./test_scripts/MobileProjection/Phase2/017_two_apps_and_one_app_exits.lua +./test_scripts/MobileProjection/Phase2/018_two_apps_and_one_app_unregister.lua +./test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua +./test_scripts/MobileProjection/Phase2/020_different_types_apps_interactions.lua +./test_scripts/MobileProjection/Phase2/021_two_apps_and_deactivation.lua +./test_scripts/MobileProjection/Phase2/022_two_apps_proj_media_and_deactivation_streaming.lua +./test_scripts/MobileProjection/Phase2/023_two_apps_navi_comm_and_deactivation_streaming.lua +; +;RC CLIMATE and RADIO modules +; +./test_scripts/RC/CLIMATE_RADIO/Capabilities/001_All_modules_all_params.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/002_Only_CLIMATE_all_params.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/003_Only_RADIO_all_params.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/004_Resend_only_supported_parameter_and_reject_others.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/005_Resend_only_supported_parameters.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/006_Reject_request_with_both_supported_and_not_supported_parameters.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/007_Reject_GIVD_SIVD_BP_if_HMI_respond_to_RC_IsReady_with_false.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/008_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/009_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/010_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/011_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/012_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/Capabilities/013_Sent_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_responds_to_RC_GetCapabilities_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/005_Transfering_of_HMI_resultCode_to_mobile.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/006_RPC_parameters_values.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/001_success_flow_for_climate_and_radio.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/003_disallow_flow_by_policy_for_radio.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/004_check_processing_button_press_for_nonRC_App.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/005_not_matached_buttonName_and_moduleType_for_radio_and_climate.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/006_check_rpc_parameters_for_button_press.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/007_button_press_allowed_if_moduleType_is_empty.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/008_button_press_disallowed_if_moduleType_is_absent.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/009_button_press_disallowed_if_moduleType_is_disallowed_by_policies.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/010_generic_error_if_no_response_from_hmi.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/011_generic_error_if_read_only_response_come_from_hmi.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/012_generic_error_if_invalid_response_from_hmi.lua +./test_scripts/RC/CLIMATE_RADIO/ButtonPress/013_Transfering_of_HMI_resultCode_to_mobile.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/002_Consent_true_BP.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/003_Consent_false_SIVD.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/004_Consent_false_BP.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/005_TIMED_OUT_from_HMI_SIVD.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/006_TIMED_OUT_from_HMI_BP.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/007_HMI_no_response_SIVD.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/008_HMI_no_response_BP.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/009_HMI_invalid_response_SIVD.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/010_HMI_invalid_response_BP.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleDataConsent/011_TIMED_OUT_after_default_timeout.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/006_Absence_of_OnIVD_in_case_of_subscribing_with_error_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/007_Absence_of_OnIVD_in_case_of_subscribing_with_no_response_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/008_Absence_of_OnIVD_in_case_of_subscribing_with_invalid_response_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/009_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/010_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/011_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/012_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Climate_and_without_one_for_module_Radio.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/013_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Climate.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/014_Existence_of_OnIVD_for_module_Climate_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Radio.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/015_Existence_of_OnIVD_for_module_Radio_in_case_exists_active_subscription_for_module_Radio_and_after_unsubscribe_from_module_Climate.lua +./test_scripts/RC/CLIMATE_RADIO/OnInteriorVehicleData/016_RPC_parameters_values.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/002_SUCCESS_in_case_AUTO_ALLOW_seq_2.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/003_SUCCESS_in_case_AUTO_ALLOW_seq_3.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/004_SUCCESS_in_case_AUTO_ALLOW_seq_4.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/005_REJECTED_in_case_nonFULL_HMI_level.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/006_IN_USE_in_case_2_requests.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/007_IN_USE_in_case_AUTO_DENY.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/008_Allowed_false.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/009_Allowed_true_accessMode_AUTO_ALLOW.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/010_Allowed_true_accessMode_AUTO_DENY.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/011_Allowed_true_accessMode_ASK_DRIVER.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/012_Default_accessMode.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/013_sequence_switches_of_accessMode.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/014_Invalid_data_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/015_Empty_data_from_HMI.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/016_Allow_in_AUTO_ALLOW_deny_in_AUTO_DENY_for_app_with_reject_in_ASK_DRIVER.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/017_Release_resource_on_unregister_app.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/018_Release_resource_and_allow_for_rejected_app_on_unregister_app.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/019_Release_resource_on_RC_disable.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/020_Restore_accessMode_after_RC_disable.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/021_Release_resource_on_exit_app.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/022_Release_resource_on_PTU_with_module_disallow.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/023_Release_resource_on_PTU_with_app_revoked.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/024_Allowed_false_no_PTU.lua +./test_scripts/RC/CLIMATE_RADIO/OnRemoteControlSettings/025_IN_USE_in_case_3_requests.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/003_Disallow_flow_by_policy_RADIO.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/004_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/005_INVALID_DATA_in_case_params_does_not_correspond_to_moduleType.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/006_RPC_parameters_values.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/007_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/008_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/009_Cut-off_of_fake_parameters_from_App.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/010_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/011_Cut-off_read-only_parameters_in_case_request_with_read-only_and_not_read-only_parameters.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/012_READ_ONLY_in_case_request_with_read-only_and_not_read-only_parameters_and_HMI_returns_READ_ONLY.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/013_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/014_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/015_Transfering_of_HMI_resultCode_to_mobile.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/016_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_false.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/017_UNSUPPORTED_RESOURCE_hdRadioEnableAvailable_omitted.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/018_Success_flow_band_setting.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/019_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_false.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/020_UNSUPPORTED_RESOURCE_siriusxmRadioAvailable_omitted.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/021_INVALID_DATA_in_case_invalid_data_in_hdRadioEnable.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/022_availableHDs_hdChannel_upper_bound.lua +./test_scripts/RC/CLIMATE_RADIO/SetInteriorVehicleData/023_availableHDs_hdChannel_out_of_upper_bound.lua +; +;RC SEAT module +; +./test_scripts/RC/SEAT/Capabilities/001_SEAT_all_params_SUCCESS.lua +./test_scripts/RC/SEAT/Capabilities/002_SEAT_all_params_UNSUPPORTED_RESOURCE.lua +./test_scripts/RC/SEAT/Capabilities/003_Resend_only_supported_parameters.lua +./test_scripts/RC/SEAT/Capabilities/004_Reject_request_with_both_supported_and_not_supported_parameters.lua +./test_scripts/RC/SEAT/Capabilities/005_Default_capabilities_if_HMI_doesnt_respond_to_RC_IsReady_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua +./test_scripts/RC/SEAT/Capabilities/006_Default_capabilities_if_HMI_responds_to_RC_IsReady_with_true_and_doesnt_respond_to_RC_GetCapabilities_SEAT.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/002_Transfering_of_HMI_resultCode_to_mobile.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/003_RPC_parameters_values.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/004_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/005_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/003_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/004_Absence_of_OnIVD_in_case_exists_active_subscription_for_module_Radio_and_without_one_for_module_Seat.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/005_Existence_of_OnIVD_for_module_Seat_in_case_exists_active_subscription_for_module_Climate_and_after_unsubscribe_from_module_Climate.lua +./test_scripts/RC/SEAT/OnInteriorVehicleData/006_RPC_parameters_values.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/002_Disallow_flow_by_policy_SEAT.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/003_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/004_RPC_parameters_values.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/005_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/006_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/SEAT/SetInteriorVehicleData/008_Transfering_of_HMI_resultCode_to_mobile.lua +; +;RC AUDIO, LIGHT, and HMI_SETTINGS modules +; +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/005_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/006_RPC_parameters_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/007_GENERIC_ERROR_in_case_HMI_did_not_respond.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/008_GENERIC_ERROR_in_case_HMI_respond_with_invalid_data.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/009_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/017_Success_audio_source_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/018_GetInteriorVD_Success_flow_light_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/019_GetInteriorVD_Success_flow_light_statuses.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/001_Consent_true_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/002_Consent_false_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/003_TIMED_OUT_from_HMI_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/004_HMI_no_response_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleDataConsent/005_HMI_invalid_response_SIVD.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/001_Success_flow.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/002_Disallow_flow_in_case_appHMIType_is_not_REMOTE_CONTROL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetSystemCapability/003_UNSUPPORTED_RESOURCE_in_case_RC_interface_is_unavailable.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/002_Disallow_flow_by_policy_AUDIO.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/003_Disallow_flow_by_policy_LIGHT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/004_Disallow_flow_by_policy_HMI_SETTINGS.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/005_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/006_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_with_isSubscribe_true_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/007_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_unsuccessfull_unsubscribing_without_isSubscribe_from_HMI.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/009_Success_audio_source_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/010_Success_flow_light_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnInteriorVehicleData/011_Success_flow_light_statuses.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/001_SUCCESS_in_case_AUTO_ALLOW_seq_1.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/002_REJECTED_in_case_nonFULL_HMI_level.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/003_Allowed_true_accessMode_AUTO_ALLOW.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/004_Allowed_true_accessMode_AUTO_DENY.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/005_Allowed_true_accessMode_ASK_DRIVER.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/OnRemoteControlSettings/006_Default_accessMode.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/001_Success_flow.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/002_Disallow_flow_by_policy_CLIMATE.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/003_Disallow_flow_by_policy_AUDIO.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/004_Disallow_flow_by_policy_LIGHT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/005_Disallow_flow_by_policy_HMI_SETTINGS.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/006_Success_flow_in_case_moduleType_is_an_empty_array_in_LPT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/007_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/008_Read_only_response_for_set_interior_vehicle_data_if_read_only_params_requested.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/009_Change_audio_source_in_FULL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/010_Change_audio_source_in_LIMITED.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/011_Change_audio_source_in_BACKGROUND.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/012_Change_audio_source_in_FULL_rc_non_media_app.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/013_Change_audio_source_from_MOBILE_APP_without_keepContext.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/014_Change_audio_source_from_MOBILE_APP_keepContext_false.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/015_Change_audio_source_from_MOBILE_APP_keepContext_true_FULL.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/017_Change_audio_source_from_any_type_except_MOBILE_APP_keepContext_true.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/018_Success_flow_light_values.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/019_Light_more_values_READ_ONLY_in_case_statusAvailable_false.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/020_Light_more_values_UNSUPPORTED_RESOURCE_in_case_statusAvailable_omitted.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/021_Light_more_values_READ_ONLY_in_case_readOnly_lightStatus_value.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/022_Light_more_values_UNSUPPORTED_RESOURCE_in_case_light_name_omitted.lua +; +;RC OnRCStatus RPC +; +./test_scripts/RC/OnRCStatus/001_notification_by_apps_registration.lua +./test_scripts/RC/OnRCStatus/002_notification_by_rc_functionality_disallowed_on_hmi.lua +./test_scripts/RC/OnRCStatus/003_registration_non_rc_app.lua +./test_scripts/RC/OnRCStatus/004_notification_by_module_subscription_GetInteriorVehicleData.lua +./test_scripts/RC/OnRCStatus/005_notification_by_module_allocation_ButtonPress.lua +./test_scripts/RC/OnRCStatus/006_notification_by_module_allocation_SetInteriorVehicleData.lua +./test_scripts/RC/OnRCStatus/007_notification_by_module_subscription_GetInteriorVehicleData_two_apps.lua +./test_scripts/RC/OnRCStatus/008_notification_by_module_allocation_ButtonPress_two_apps.lua +./test_scripts/RC/OnRCStatus/009_notification_by_module_allocation_SetInteriorVehicleData_two_apps.lua +./test_scripts/RC/OnRCStatus/010_notification_by_module_allocation_two_apps_one_app_not_rc.lua +./test_scripts/RC/OnRCStatus/011_notification_by_app_unregistration.lua +./test_scripts/RC/OnRCStatus/012_notification_by_revoking_module_by_policy.lua +./test_scripts/RC/OnRCStatus/013_notification_by_reallocation_module_by_the_same_app.lua +./test_scripts/RC/OnRCStatus/014_notification_by_reallocation_module_by_second_app.lua +./test_scripts/RC/OnRCStatus/015_notification_by_user_exit.lua +./test_scripts/RC/OnRCStatus/016_notification_by_DRIVER_DISTRACTION_VIOLATION.lua +./test_scripts/RC/OnRCStatus/017_notification_by_rejecting_consent_by_driver.lua +./test_scripts/RC/OnRCStatus/018_notification_by_driver_consent.lua +./test_scripts/RC/OnRCStatus/019_notification_by_app_disconnect.lua +./test_scripts/RC/OnRCStatus/020_notification_in_case_of_policy_permissions_absence.lua +./test_scripts/RC/OnRCStatus/021_notification_in_case_AUTO_DENY_mode.lua +./test_scripts/RC/OnRCStatus/022_notification_by_rc_functionality_disallowed_on_hmi_with_registered_app.lua +./test_scripts/RC/OnRCStatus/023_notification_by_rc_functionality_allowed_on_hmi_with_registered_app.lua +./test_scripts/RC/OnRCStatus/024_notification_by_apps_registration_several_apps.lua +./test_scripts/RC/OnRCStatus/025_notification_by_rc_functionality_disallowed_on_hmi_several_apps.lua +./test_scripts/RC/OnRCStatus/026_registration_non_rc_app_several_apps.lua +./test_scripts/RC/OnRCStatus/027_registration_non_rc_app_several_apps_rc_disallowed.lua +./test_scripts/RC/OnRCStatus/028_notification_by_rc_functionality_disallowed_on_hmi_with_allocated_resource.lua +./test_scripts/RC/OnRCStatus/029_notification_by_revoking_several_modules_by_policy.lua +; +;SubMenu Icon +; +./test_scripts/API/SubMenuIcon/001_menuIcon_is_SUCCESS.lua +./test_scripts/API/SubMenuIcon/002_menuIcon_invalid_type.lua +./test_scripts/API/SubMenuIcon/003_menuIcon_selected_not_existing_file.lua +./test_scripts/API/SubMenuIcon/004_menuIcon_is_absent.lua +; +;Template Color Schemes +; +./test_scripts/SDL5_0/TemplateColorSchemes/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua +./test_scripts/SDL5_0/TemplateColorSchemes/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua +./test_scripts/SDL5_0/TemplateColorSchemes/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua +; +;Template Images +; +./test_scripts/SDL5_0/Image_template/001_isTemplate_is_true.lua +./test_scripts/SDL5_0/Image_template/002_isTemplate_is_false.lua +./test_scripts/SDL5_0/Image_template/003_isTemplate_is_absent.lua +./test_scripts/SDL5_0/Image_template/004_isTemplate_invalid_type.lua +./test_scripts/SDL5_0/Image_template/005_isTemplate_is_true_with_not_png_image.lua +./test_scripts/SDL5_0/Image_template/006_isTemplate_is_true_with_STATIC_image.lua +; +;Transfer RPCs with invalid image references +; +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/001_AddCommand.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/003_Alert.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/007_Show.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/009_SendLocation.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua +; +;Update DOP Value Range +; +./test_scripts/API/VehicleData/DOP/001_GVD_max_value_SUCCESS.lua +./test_scripts/API/VehicleData/DOP/002_GVD_beyond_max_value_GENERIC_ERROR.lua +./test_scripts/API/VehicleData/DOP/003_GVD_missing_one_parameter_SUCCESS.lua +./test_scripts/API/VehicleData/DOP/004_OVD_max_value_SUCCESS.lua +./test_scripts/API/VehicleData/DOP/005_OVD_beyond_max_value_ignored.lua +./test_scripts/API/VehicleData/DOP/006_OVD_missing_one_parameter_SUCCESS.lua +./test_scripts/API/VehicleData/DOP/007_GVD_all_parameters_SUCCESS.lua +./test_scripts/API/VehicleData/DOP/008_GVD_missing_all_parameters_SUCCESS.lua +./test_scripts/API/VehicleData/DOP/009_OVD_all_parameters_SUCCESS.lua +./test_scripts/API/VehicleData/DOP/010_OVD_missing_all_parameters_SUCCESS.lua +; +;New Vehicle Data +; +./test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua +./test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +./test_scripts/API/VehicleData/GetVehicleData/003_GetVD_gps_mandatory_parameters.lua +./test_scripts/API/VehicleData/GetVehicleData/004_Success_deviceStatus_primaryAudioSource.lua +./test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua +./test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua +;./test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua +./test_scripts/API/VehicleData/OnVehicleData/004_OnVD_gps_mandatory_parameters.lua +./test_scripts/API/VehicleData/OnVehicleData/005_Success_flow_deviceStatus_primaryAudioSource.lua +./test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua +;./test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +;./test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua +./test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua +./test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua +./test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua +./test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua \ No newline at end of file diff --git a/test_sets/submenu_icon.txt b/test_sets/SDL5_0/submenu_icon.txt similarity index 100% rename from test_sets/submenu_icon.txt rename to test_sets/SDL5_0/submenu_icon.txt diff --git a/test_sets/SDL5_0/template_color_schemes.txt b/test_sets/SDL5_0/template_color_schemes.txt new file mode 100644 index 0000000000..8863fed70a --- /dev/null +++ b/test_sets/SDL5_0/template_color_schemes.txt @@ -0,0 +1,3 @@ +./test_scripts/SDL5_0/TemplateColorSchemes/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua +./test_scripts/SDL5_0/TemplateColorSchemes/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua +./test_scripts/SDL5_0/TemplateColorSchemes/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua \ No newline at end of file diff --git a/test_sets/SDL5_0/template_images.txt b/test_sets/SDL5_0/template_images.txt new file mode 100644 index 0000000000..5cfc0d15ba --- /dev/null +++ b/test_sets/SDL5_0/template_images.txt @@ -0,0 +1,6 @@ +./test_scripts/SDL5_0/Image_template/001_isTemplate_is_true.lua +./test_scripts/SDL5_0/Image_template/002_isTemplate_is_false.lua +./test_scripts/SDL5_0/Image_template/003_isTemplate_is_absent.lua +./test_scripts/SDL5_0/Image_template/004_isTemplate_invalid_type.lua +./test_scripts/SDL5_0/Image_template/005_isTemplate_is_true_with_not_png_image.lua +./test_scripts/SDL5_0/Image_template/006_isTemplate_is_true_with_STATIC_image.lua diff --git a/test_sets/SDL5_0/transfer_rpc_with_invalid_image.txt b/test_sets/SDL5_0/transfer_rpc_with_invalid_image.txt new file mode 100644 index 0000000000..3313ef8d0d --- /dev/null +++ b/test_sets/SDL5_0/transfer_rpc_with_invalid_image.txt @@ -0,0 +1,15 @@ +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/001_AddCommand.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/003_Alert.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/007_Show.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/009_SendLocation.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua +./test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua diff --git a/test_sets/updating_dop_value_range.txt b/test_sets/SDL5_0/updating_dop_value_range.txt similarity index 100% rename from test_sets/updating_dop_value_range.txt rename to test_sets/SDL5_0/updating_dop_value_range.txt diff --git a/test_sets/VehicleData.txt b/test_sets/SDL5_0/vehicle_data.txt similarity index 100% rename from test_sets/VehicleData.txt rename to test_sets/SDL5_0/vehicle_data.txt diff --git a/test_sets/SDL5_0/vr_command_optional.txt b/test_sets/SDL5_0/vr_command_optional.txt new file mode 100644 index 0000000000..ff3d7090d7 --- /dev/null +++ b/test_sets/SDL5_0/vr_command_optional.txt @@ -0,0 +1,2 @@ +./test_scripts/SDL5_0/vrCommandOptional/001_create_interaction_choice_set_invalid_data.lua +./test_scripts/SDL5_0/vrCommandOptional/002_perform_interaction_invalid_data.lua \ No newline at end of file diff --git a/test_sets/SDL_0042_Transfer_RPC_with_Invalid_Image.txt b/test_sets/SDL_0042_Transfer_RPC_with_Invalid_Image.txt deleted file mode 100644 index 32d81ba275..0000000000 --- a/test_sets/SDL_0042_Transfer_RPC_with_Invalid_Image.txt +++ /dev/null @@ -1,15 +0,0 @@ -./test_scripts/API/Transfer_RPC_with_invalid_image/001_AddCommand.lua -./test_scripts/API/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua -./test_scripts/API/Transfer_RPC_with_invalid_image/003_Alert.lua -./test_scripts/API/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua -./test_scripts/API/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua -./test_scripts/API/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua -./test_scripts/API/Transfer_RPC_with_invalid_image/007_Show.lua -./test_scripts/API/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua -./test_scripts/API/Transfer_RPC_with_invalid_image/009_SendLocation.lua -./test_scripts/API/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua -./test_scripts/API/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua -./test_scripts/API/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua -./test_scripts/API/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua -./test_scripts/API/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua -./test_scripts/API/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua diff --git a/test_sets/audio_file_playback_tts_chunks.txt b/test_sets/audio_file_playback_tts_chunks.txt deleted file mode 100644 index f7b72404d6..0000000000 --- a/test_sets/audio_file_playback_tts_chunks.txt +++ /dev/null @@ -1,9 +0,0 @@ -./test_scripts/SDL4_6/TTSChunks/001_RegisterAppInterface.lua -./test_scripts/SDL4_6/TTSChunks/002_SetGlobalProperties.lua -./test_scripts/SDL4_6/TTSChunks/003_OnAppRegistered.lua -./test_scripts/SDL4_6/TTSChunks/004_Alert.lua -./test_scripts/SDL4_6/TTSChunks/005_ChangeRegistration.lua -./test_scripts/SDL4_6/TTSChunks/006_PerformInteraction.lua -./test_scripts/SDL4_6/TTSChunks/007_Speak.lua -./test_scripts/SDL4_6/TTSChunks/008_PerformAudioPassThru.lua -./test_scripts/SDL4_6/TTSChunks/009_AlertManeuver.lua diff --git a/test_sets/handling_VR_help_requests.txt b/test_sets/handling_VR_help_requests.txt deleted file mode 100644 index 140068cbac..0000000000 --- a/test_sets/handling_VR_help_requests.txt +++ /dev/null @@ -1,33 +0,0 @@ -./test_scripts/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua -./test_scripts/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua -./test_scripts/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua -./test_scripts/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua -./test_scripts/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua -./test_scripts/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua -./test_scripts/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua -./test_scripts/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua -./test_scripts/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua -./test_scripts/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua -./test_scripts/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua -./test_scripts/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua -./test_scripts/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua -./test_scripts/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua -./test_scripts/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua -./test_scripts/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua -./test_scripts/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua -./test_scripts/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua -./test_scripts/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua -./test_scripts/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua -./test_scripts/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua -./test_scripts/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua -./test_scripts/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua -./test_scripts/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua -./test_scripts/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua -./test_scripts/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua -./test_scripts/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua -./test_scripts/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua -./test_scripts/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua -./test_scripts/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua -./test_scripts/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua -./test_scripts/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua -./test_scripts/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua diff --git a/test_sets/low_voltage.txt b/test_sets/low_voltage.txt deleted file mode 100644 index bb807c2130..0000000000 --- a/test_sets/low_voltage.txt +++ /dev/null @@ -1,23 +0,0 @@ -./test_scripts/LowVoltage/001_Low_Voltage_and_Wake_Up.lua -./test_scripts/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua -./test_scripts/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua -./test_scripts/LowVoltage/004_App_unregister_itself_gracefully.lua -./test_scripts/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua -./test_scripts/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua -./test_scripts/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua -./test_scripts/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua -./test_scripts/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua -./test_scripts/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua -./test_scripts/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua -./test_scripts/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua -./test_scripts/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua -./test_scripts/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua -./test_scripts/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua -./test_scripts/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua -./test_scripts/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua -./test_scripts/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua -./test_scripts/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua -./test_scripts/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua -./test_scripts/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua -./test_scripts/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua -./test_scripts/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua diff --git a/test_sets/mobile_api_versioning.txt b/test_sets/mobile_api_versioning.txt deleted file mode 100644 index 09ed0c8bee..0000000000 --- a/test_sets/mobile_api_versioning.txt +++ /dev/null @@ -1,9 +0,0 @@ -./test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua -./test_scripts/SDL4_6/MobileVersioning/VersionNegotiation/002_register_app_on_legacy_module.lua -./test_scripts/Smoke/API/008_CreateInteractionChoiceSet_PositiveCase_SUCCESS.lua -./test_scripts/Smoke/API/012_PerfomInteraction_PositiveCase_SUCCESS.lua -./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/001_create_interaction_choice_success_legacy_app.lua -./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/002_create_interaction_choice_invalid_data_legacy_app.lua -./test_scripts/SDL4_6/MobileVersioning/vrCommandOptional/003_perform_interaction_success_legacy_app.lua -./test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/001_play_pause_v5_allowed.lua -./test_scripts/SDL4_6/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua diff --git a/test_sets/template_images.txt b/test_sets/template_images.txt deleted file mode 100644 index b3e6680665..0000000000 --- a/test_sets/template_images.txt +++ /dev/null @@ -1,6 +0,0 @@ -./test_scripts/Image_template/001_isTemplate_is_true.lua -./test_scripts/Image_template/002_isTemplate_is_false.lua -./test_scripts/Image_template/003_isTemplate_is_absent.lua -./test_scripts/Image_template/004_isTemplate_invalid_type.lua -./test_scripts/Image_template/005_isTemplate_is_true_with_not_png_image.lua -./test_scripts/Image_template/006_isTemplate_is_true_with_STATIC_image.lua diff --git a/test_sets/vehicle_data.txt b/test_sets/vehicle_data.txt new file mode 100644 index 0000000000..105559f2a9 --- /dev/null +++ b/test_sets/vehicle_data.txt @@ -0,0 +1,16 @@ +./test_scripts/API/VehicleData/GetVehicleData/001_Success_flow.lua +./test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +./test_scripts/API/VehicleData/GetVehicleData/003_GetVD_gps_mandatory_parameters.lua +./test_scripts/API/VehicleData/GetVehicleData/004_Success_deviceStatus_primaryAudioSource.lua +./test_scripts/API/VehicleData/OnVehicleData/001_Success_flow.lua +./test_scripts/API/VehicleData/OnVehicleData/002_NotificationForUnsubsribedParameter_Ignored_flow.lua +;./test_scripts/API/VehicleData/OnVehicleData/003_NotificationParameterDisallowedByPolicies_Ignored_flow.lua +./test_scripts/API/VehicleData/OnVehicleData/004_OnVD_gps_mandatory_parameters.lua +./test_scripts/API/VehicleData/OnVehicleData/005_Success_flow_deviceStatus_primaryAudioSource.lua +./test_scripts/API/VehicleData/SubscribeVehicleData/001_Success_flow.lua +;./test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +;./test_scripts/API/VehicleData/SubscribeVehicleData/003_RPC_parameter_already_subscribed_Result_IGNORED_flow.lua +./test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua +./test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua +./test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua +./test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua From f7e6f9cdecfe08bfa4492535578380d0a05fda1b Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Wed, 5 Sep 2018 13:00:16 -0400 Subject: [PATCH 642/681] Fix broken links after folder restructuring --- test_scripts/SDL5_0/FullAppID/001_PTU_full_app_ID_true.lua | 2 +- test_scripts/SDL5_0/FullAppID/002_PTU_full_app_ID_false.lua | 2 +- .../001_SetGlobalProp_by_adding_commands.lua | 2 +- .../002_SetGlobalProp_commands_with_and_without_vrCommand.lua | 2 +- .../003_SetGlobalProp_without_deleted_commands.lua | 2 +- .../004_SetGlobalProp_processing_30_commands.lua | 2 +- .../005_SetGlobalProp_apply_limitation_only_for_addcommand.lua | 2 +- .../006_SetGlobalProp_processing_added_choices.lua | 2 +- .../007_SetGlobalProp_absence_in_NONE.lua | 2 +- .../008_SetGlobalProp_absence_in_BACKGROUND.lua | 2 +- ...09_SetGlobalProp_absence_addCommand_after_custom_request.lua | 2 +- ...SetGlobalProp_absence_deleteCommand_after_custom_request.lua | 2 +- .../011_SetGlobalProp_custom_helpPrompt_only.lua | 2 +- .../012_SetGlobalProp_custom_vrHelp_only.lua | 2 +- ...lProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua | 2 +- ...tGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua | 2 +- .../015_SetGlobalProp_with_added_commands_by_resumption.lua | 2 +- ...alProp_commands_with_and_without_vrCommand_by_resumption.lua | 2 +- ...017_SetGlobalProp_without_deleted_commands_by_resumption.lua | 2 +- .../018_SetGlobalProp_processing_30_commands_by_resumption.lua | 2 +- ...019_SetGlobalProp_processing_added_choices_by_resumption.lua | 2 +- ...GlobalProp_absence_after_custom_request_after_resumption.lua | 2 +- ...lobalProp_absence_after_custom_request_before_resumption.lua | 2 +- .../022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua | 2 +- .../023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua | 2 +- ...stom_request_without_helpPrompt_and_vrHelp_by_resumption.lua | 2 +- ...alProp_with_several_vrCommands_in_one_addCommand_request.lua | 2 +- ...veral_vrCommands_in_one_addCommand_request_by_resumption.lua | 2 +- .../027_SetGlobalProp_invalid_custom_request.lua | 2 +- .../028_SetGlobalProp_rejected_custom_request.lua | 2 +- .../029_SetGlobalProp_only_successful_added_commands.lua | 2 +- ...0_SetGlobalProp_only_without_successful_deleted_commands.lua | 2 +- ...GlobalProp_processing_30_commands_several_in_one_command.lua | 2 +- ...cessing_30_commands_several_in_one_command_by_resumption.lua | 2 +- .../033_SetGlobalProp_delete_last_command.lua | 2 +- test_scripts/SDL5_0/Image_template/001_isTemplate_is_true.lua | 2 +- test_scripts/SDL5_0/Image_template/002_isTemplate_is_false.lua | 2 +- test_scripts/SDL5_0/Image_template/003_isTemplate_is_absent.lua | 2 +- .../SDL5_0/Image_template/004_isTemplate_invalid_type.lua | 2 +- .../005_isTemplate_is_true_with_not_png_image.lua | 2 +- .../Image_template/006_isTemplate_is_true_with_STATIC_image.lua | 2 +- test_scripts/SDL5_0/LowVoltage/001_Low_Voltage_and_Wake_Up.lua | 2 +- .../SDL5_0/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua | 2 +- .../LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua | 2 +- .../SDL5_0/LowVoltage/004_App_unregister_itself_gracefully.lua | 2 +- .../LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua | 2 +- .../006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua | 2 +- ...ce_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua | 2 +- ...nce_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua | 2 +- ...ence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua | 2 +- ...resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua | 2 +- ...011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua | 2 +- ...resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua | 2 +- ..._resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua | 2 +- ...e_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua | 2 +- ...umption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua | 2 +- ...6_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua | 2 +- ...ow_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua | 2 +- ...ion_FULL_hmi_level_without_disconnect_before_low_voltage.lua | 2 +- ..._LIMITED_hmi_level_without_disconnect_before_low_voltage.lua | 2 +- ...sumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua | 2 +- ...ption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua | 2 +- .../022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua | 2 +- .../023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua | 2 +- test_scripts/SDL5_0/TTSChunks/001_RegisterAppInterface.lua | 2 +- test_scripts/SDL5_0/TTSChunks/002_SetGlobalProperties.lua | 2 +- test_scripts/SDL5_0/TTSChunks/003_OnAppRegistered.lua | 2 +- test_scripts/SDL5_0/TTSChunks/004_Alert.lua | 2 +- test_scripts/SDL5_0/TTSChunks/005_ChangeRegistration.lua | 2 +- test_scripts/SDL5_0/TTSChunks/006_PerformInteraction.lua | 2 +- test_scripts/SDL5_0/TTSChunks/007_Speak.lua | 2 +- test_scripts/SDL5_0/TTSChunks/008_PerformAudioPassThru.lua | 2 +- test_scripts/SDL5_0/TTSChunks/009_AlertManeuver.lua | 2 +- .../SDL5_0/Transfer_RPC_with_invalid_image/001_AddCommand.lua | 2 +- .../SDL5_0/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua | 2 +- .../SDL5_0/Transfer_RPC_with_invalid_image/003_Alert.lua | 2 +- .../004_CreateInteractionChoiceSet.lua | 2 +- .../Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua | 2 +- .../Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua | 2 +- .../SDL5_0/Transfer_RPC_with_invalid_image/007_Show.lua | 2 +- .../Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua | 2 +- .../SDL5_0/Transfer_RPC_with_invalid_image/009_SendLocation.lua | 2 +- .../SDL5_0/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua | 2 +- .../Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua | 2 +- .../Transfer_RPC_with_invalid_image/012_AlertManeuver.lua | 2 +- .../SDL5_0/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua | 2 +- .../Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua | 2 +- .../Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua | 2 +- 88 files changed, 88 insertions(+), 88 deletions(-) diff --git a/test_scripts/SDL5_0/FullAppID/001_PTU_full_app_ID_true.lua b/test_scripts/SDL5_0/FullAppID/001_PTU_full_app_ID_true.lua index 71e8cf9f82..14ffb70221 100644 --- a/test_scripts/SDL5_0/FullAppID/001_PTU_full_app_ID_true.lua +++ b/test_scripts/SDL5_0/FullAppID/001_PTU_full_app_ID_true.lua @@ -14,7 +14,7 @@ local sdl = require("SDL") local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonSmoke = require('test_scripts/Smoke/commonSmoke') -local common = require("test_scripts/SDL4_6/FullAppID/common") +local common = require("test_scripts/SDL5_0/FullAppID/common") local full_app_id_supported = "true" diff --git a/test_scripts/SDL5_0/FullAppID/002_PTU_full_app_ID_false.lua b/test_scripts/SDL5_0/FullAppID/002_PTU_full_app_ID_false.lua index 0f84a95359..77578294e8 100644 --- a/test_scripts/SDL5_0/FullAppID/002_PTU_full_app_ID_false.lua +++ b/test_scripts/SDL5_0/FullAppID/002_PTU_full_app_ID_false.lua @@ -14,7 +14,7 @@ local sdl = require("SDL") local commonSteps = require("user_modules/shared_testcases/commonSteps") local commonSmoke = require('test_scripts/Smoke/commonSmoke') -local common = require("test_scripts/SDL4_6/FullAppID/common") +local common = require("test_scripts/SDL5_0/FullAppID/common") local full_app_id_supported = "false" diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua index 274f0e7086..927f922ad1 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua @@ -14,7 +14,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua index d60a139cc5..1ffe306835 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua @@ -14,7 +14,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua index 7687a8876f..d4ffa579c8 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua index 7e52a4ade3..7b33b1f46c 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua index 9109b55ff0..62fc6e4336 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua @@ -14,7 +14,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua index 8958fa0151..d5cbbacfd7 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua index 9a4bb26678..4e0e4bd74e 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua index babbb974d5..34b7d81e6e 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua @@ -18,7 +18,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua index 4f136c30cd..4d5606be62 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua index 671aa61f31..c6b6d0c136 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua index f68bb1bd49..69cb867163 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua index cf2f512578..50eba12152 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua index f5e6353485..92502310d7 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua @@ -18,7 +18,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua index da542bb189..3f49d00613 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua index 0b9e4fc46e..3217d57105 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua index 996e7eebad..3d70bb2456 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') local commonFunctions = require("user_modules/shared_testcases/commonFunctions") --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua index 838c06d93b..f19026dc6a 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua @@ -17,7 +17,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua index 8095faf73b..ed2546e0a0 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua index 0b65c6407e..ac23d91bff 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') local commonFunctions = require("user_modules/shared_testcases/commonFunctions") --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua index 364e52cc20..3e92a60b59 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua index 8d1fee561a..8185bb18ff 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') local commonFunctions = require("user_modules/shared_testcases/commonFunctions") --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua index 7768ab427f..fe508f43bf 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua index c25baee33a..abd062bca4 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua index a3dab98cdd..f39d71a0b0 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua index 1b6dd64a20..99d1510eb5 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua @@ -13,7 +13,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua index bedf5992af..6448290b25 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua index 080461a781..b14f8f81e7 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua index e047ccb8cc..cfb1fbaa74 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua index d8791ee2d6..2aa9707e3c 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua @@ -14,7 +14,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua index 56df8c6269..6df317ec10 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua @@ -14,7 +14,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua index ff2f82df0f..96c760d1ec 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua @@ -19,7 +19,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua index 8d4e7ae58a..bc6483a3d1 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua @@ -21,7 +21,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua index 64239ec6d6..403571a8e8 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua @@ -22,7 +22,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Image_template/001_isTemplate_is_true.lua b/test_scripts/SDL5_0/Image_template/001_isTemplate_is_true.lua index a048a2f57c..284abcbdd0 100644 --- a/test_scripts/SDL5_0/Image_template/001_isTemplate_is_true.lua +++ b/test_scripts/SDL5_0/Image_template/001_isTemplate_is_true.lua @@ -12,7 +12,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Image_template/commonImageTemplate') +local common = require('test_scripts/SDL5_0/Image_template/commonImageTemplate') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Image_template/002_isTemplate_is_false.lua b/test_scripts/SDL5_0/Image_template/002_isTemplate_is_false.lua index 619eb8d913..da73126dc1 100644 --- a/test_scripts/SDL5_0/Image_template/002_isTemplate_is_false.lua +++ b/test_scripts/SDL5_0/Image_template/002_isTemplate_is_false.lua @@ -12,7 +12,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Image_template/commonImageTemplate') +local common = require('test_scripts/SDL5_0/Image_template/commonImageTemplate') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Image_template/003_isTemplate_is_absent.lua b/test_scripts/SDL5_0/Image_template/003_isTemplate_is_absent.lua index 69f3da93ae..620655a74f 100644 --- a/test_scripts/SDL5_0/Image_template/003_isTemplate_is_absent.lua +++ b/test_scripts/SDL5_0/Image_template/003_isTemplate_is_absent.lua @@ -12,7 +12,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Image_template/commonImageTemplate') +local common = require('test_scripts/SDL5_0/Image_template/commonImageTemplate') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Image_template/004_isTemplate_invalid_type.lua b/test_scripts/SDL5_0/Image_template/004_isTemplate_invalid_type.lua index ef0ace5190..d6a401acb5 100644 --- a/test_scripts/SDL5_0/Image_template/004_isTemplate_invalid_type.lua +++ b/test_scripts/SDL5_0/Image_template/004_isTemplate_invalid_type.lua @@ -12,7 +12,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Image_template/commonImageTemplate') +local common = require('test_scripts/SDL5_0/Image_template/commonImageTemplate') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Image_template/005_isTemplate_is_true_with_not_png_image.lua b/test_scripts/SDL5_0/Image_template/005_isTemplate_is_true_with_not_png_image.lua index b864aa6319..f21fde0ad1 100644 --- a/test_scripts/SDL5_0/Image_template/005_isTemplate_is_true_with_not_png_image.lua +++ b/test_scripts/SDL5_0/Image_template/005_isTemplate_is_true_with_not_png_image.lua @@ -12,7 +12,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Image_template/commonImageTemplate') +local common = require('test_scripts/SDL5_0/Image_template/commonImageTemplate') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Image_template/006_isTemplate_is_true_with_STATIC_image.lua b/test_scripts/SDL5_0/Image_template/006_isTemplate_is_true_with_STATIC_image.lua index 7774c95d6f..d2b49ef796 100644 --- a/test_scripts/SDL5_0/Image_template/006_isTemplate_is_true_with_STATIC_image.lua +++ b/test_scripts/SDL5_0/Image_template/006_isTemplate_is_true_with_STATIC_image.lua @@ -12,7 +12,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Image_template/commonImageTemplate') +local common = require('test_scripts/SDL5_0/Image_template/commonImageTemplate') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/LowVoltage/001_Low_Voltage_and_Wake_Up.lua b/test_scripts/SDL5_0/LowVoltage/001_Low_Voltage_and_Wake_Up.lua index fa38332a5b..94fead740f 100644 --- a/test_scripts/SDL5_0/LowVoltage/001_Low_Voltage_and_Wake_Up.lua +++ b/test_scripts/SDL5_0/LowVoltage/001_Low_Voltage_and_Wake_Up.lua @@ -23,7 +23,7 @@ -- Not resume HMI level for App3 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/SDL5_0/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua b/test_scripts/SDL5_0/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua index 34d9372084..24e7ce7b77 100644 --- a/test_scripts/SDL5_0/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua +++ b/test_scripts/SDL5_0/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua @@ -20,7 +20,7 @@ -- Not resume HMI level for App3 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua b/test_scripts/SDL5_0/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua index ecbc0555f6..49fcc27ced 100644 --- a/test_scripts/SDL5_0/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua +++ b/test_scripts/SDL5_0/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua @@ -7,7 +7,7 @@ -- 2) Ignore IGNITION_OFF signal and continue working as usual --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/004_App_unregister_itself_gracefully.lua b/test_scripts/SDL5_0/LowVoltage/004_App_unregister_itself_gracefully.lua index 67b1ea46a4..83442ba160 100644 --- a/test_scripts/SDL5_0/LowVoltage/004_App_unregister_itself_gracefully.lua +++ b/test_scripts/SDL5_0/LowVoltage/004_App_unregister_itself_gracefully.lua @@ -8,7 +8,7 @@ -- 2) Not resume app HMI level --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua b/test_scripts/SDL5_0/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua index 8766a905f2..b5839757cb 100644 --- a/test_scripts/SDL5_0/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua +++ b/test_scripts/SDL5_0/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua @@ -9,7 +9,7 @@ -- 2) Discard processing of RPC --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua b/test_scripts/SDL5_0/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua index fb85d3a092..03758a56bd 100644 --- a/test_scripts/SDL5_0/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua +++ b/test_scripts/SDL5_0/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua b/test_scripts/SDL5_0/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua index cd40747138..6477c29774 100644 --- a/test_scripts/SDL5_0/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua +++ b/test_scripts/SDL5_0/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua b/test_scripts/SDL5_0/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua index c988870d77..05f639e21b 100644 --- a/test_scripts/SDL5_0/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua +++ b/test_scripts/SDL5_0/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua b/test_scripts/SDL5_0/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua index f551ba69c3..67731caf28 100644 --- a/test_scripts/SDL5_0/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua +++ b/test_scripts/SDL5_0/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua @@ -11,7 +11,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua b/test_scripts/SDL5_0/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua index 948f4a9920..926fc83a24 100644 --- a/test_scripts/SDL5_0/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua +++ b/test_scripts/SDL5_0/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua @@ -11,7 +11,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua b/test_scripts/SDL5_0/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua index f3ab8d1fd1..38af3aa472 100644 --- a/test_scripts/SDL5_0/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua +++ b/test_scripts/SDL5_0/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua b/test_scripts/SDL5_0/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua index 9e4759ca03..4d60414f17 100644 --- a/test_scripts/SDL5_0/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua +++ b/test_scripts/SDL5_0/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua b/test_scripts/SDL5_0/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua index a9291ac3f6..c836e61b92 100644 --- a/test_scripts/SDL5_0/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua +++ b/test_scripts/SDL5_0/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua b/test_scripts/SDL5_0/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua index dc1ed0ff06..c08cf6d0e4 100644 --- a/test_scripts/SDL5_0/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua +++ b/test_scripts/SDL5_0/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua b/test_scripts/SDL5_0/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua index 85c39cf812..fcf557425a 100644 --- a/test_scripts/SDL5_0/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua +++ b/test_scripts/SDL5_0/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua b/test_scripts/SDL5_0/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua index 83733614fb..4d5242b187 100644 --- a/test_scripts/SDL5_0/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua +++ b/test_scripts/SDL5_0/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua @@ -12,7 +12,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua b/test_scripts/SDL5_0/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua index ae645a2993..1925f78900 100644 --- a/test_scripts/SDL5_0/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua +++ b/test_scripts/SDL5_0/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua @@ -12,7 +12,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua b/test_scripts/SDL5_0/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua index 9469564e94..c1241849f1 100644 --- a/test_scripts/SDL5_0/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua +++ b/test_scripts/SDL5_0/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua b/test_scripts/SDL5_0/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua index 235c505a2e..e821b2d20a 100644 --- a/test_scripts/SDL5_0/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua +++ b/test_scripts/SDL5_0/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua b/test_scripts/SDL5_0/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua index ccd622d064..189f10d202 100644 --- a/test_scripts/SDL5_0/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua +++ b/test_scripts/SDL5_0/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua @@ -12,7 +12,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua b/test_scripts/SDL5_0/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua index 53cd000655..2eef3153d5 100644 --- a/test_scripts/SDL5_0/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua +++ b/test_scripts/SDL5_0/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua @@ -12,7 +12,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua b/test_scripts/SDL5_0/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua index b12c18edd9..e15133ba83 100644 --- a/test_scripts/SDL5_0/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua +++ b/test_scripts/SDL5_0/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua @@ -10,7 +10,7 @@ -- 2. not resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua b/test_scripts/SDL5_0/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua index cf7615f118..d7fe303e29 100644 --- a/test_scripts/SDL5_0/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua +++ b/test_scripts/SDL5_0/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua @@ -10,7 +10,7 @@ -- 3. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/TTSChunks/001_RegisterAppInterface.lua b/test_scripts/SDL5_0/TTSChunks/001_RegisterAppInterface.lua index de8b190f21..3a47359112 100644 --- a/test_scripts/SDL5_0/TTSChunks/001_RegisterAppInterface.lua +++ b/test_scripts/SDL5_0/TTSChunks/001_RegisterAppInterface.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/TTSChunks/002_SetGlobalProperties.lua b/test_scripts/SDL5_0/TTSChunks/002_SetGlobalProperties.lua index 8b5718b00e..f4f875a382 100644 --- a/test_scripts/SDL5_0/TTSChunks/002_SetGlobalProperties.lua +++ b/test_scripts/SDL5_0/TTSChunks/002_SetGlobalProperties.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Local Variables ]] local putFileParams = { diff --git a/test_scripts/SDL5_0/TTSChunks/003_OnAppRegistered.lua b/test_scripts/SDL5_0/TTSChunks/003_OnAppRegistered.lua index 77c3c4f2bf..fa37dbf719 100644 --- a/test_scripts/SDL5_0/TTSChunks/003_OnAppRegistered.lua +++ b/test_scripts/SDL5_0/TTSChunks/003_OnAppRegistered.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/TTSChunks/004_Alert.lua b/test_scripts/SDL5_0/TTSChunks/004_Alert.lua index 95a1aac831..7d31dde0c1 100644 --- a/test_scripts/SDL5_0/TTSChunks/004_Alert.lua +++ b/test_scripts/SDL5_0/TTSChunks/004_Alert.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Local Variables ]] local putFileParams = { diff --git a/test_scripts/SDL5_0/TTSChunks/005_ChangeRegistration.lua b/test_scripts/SDL5_0/TTSChunks/005_ChangeRegistration.lua index b98034368e..8a6fac4142 100644 --- a/test_scripts/SDL5_0/TTSChunks/005_ChangeRegistration.lua +++ b/test_scripts/SDL5_0/TTSChunks/005_ChangeRegistration.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Local Variables ]] local putFileParams = { diff --git a/test_scripts/SDL5_0/TTSChunks/006_PerformInteraction.lua b/test_scripts/SDL5_0/TTSChunks/006_PerformInteraction.lua index f18c59c50f..1737a75bb0 100644 --- a/test_scripts/SDL5_0/TTSChunks/006_PerformInteraction.lua +++ b/test_scripts/SDL5_0/TTSChunks/006_PerformInteraction.lua @@ -17,7 +17,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Local Variables ]] local putFileParams = { diff --git a/test_scripts/SDL5_0/TTSChunks/007_Speak.lua b/test_scripts/SDL5_0/TTSChunks/007_Speak.lua index 70cd8c63e9..9a9649253d 100644 --- a/test_scripts/SDL5_0/TTSChunks/007_Speak.lua +++ b/test_scripts/SDL5_0/TTSChunks/007_Speak.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Local Variables ]] local putFileParams = { diff --git a/test_scripts/SDL5_0/TTSChunks/008_PerformAudioPassThru.lua b/test_scripts/SDL5_0/TTSChunks/008_PerformAudioPassThru.lua index c09d8ee6ab..8271267989 100644 --- a/test_scripts/SDL5_0/TTSChunks/008_PerformAudioPassThru.lua +++ b/test_scripts/SDL5_0/TTSChunks/008_PerformAudioPassThru.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Local Variables ]] local putFileParams = { diff --git a/test_scripts/SDL5_0/TTSChunks/009_AlertManeuver.lua b/test_scripts/SDL5_0/TTSChunks/009_AlertManeuver.lua index 43c639fde5..9bfd30fa5a 100644 --- a/test_scripts/SDL5_0/TTSChunks/009_AlertManeuver.lua +++ b/test_scripts/SDL5_0/TTSChunks/009_AlertManeuver.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Local Variables ]] local putFileParams = { diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/001_AddCommand.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/001_AddCommand.lua index ec134c1136..f051b00ccf 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/001_AddCommand.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/001_AddCommand.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua index e86c374b8d..02ab723fb7 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/003_Alert.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/003_Alert.lua index 706990849c..6baf52f31c 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/003_Alert.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/003_Alert.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua index 2d08639f0a..adbabba587 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua index 840e94e609..674b5df3bb 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua index 4450c85d73..50188f4086 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/007_Show.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/007_Show.lua index 233fb211d6..3780699b10 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/007_Show.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/007_Show.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua index 5312ba2880..935eaff9f0 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/009_SendLocation.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/009_SendLocation.lua index 7c7cbc933d..2f624925d1 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/009_SendLocation.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/009_SendLocation.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua index a4dbf8258f..e69486dc40 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua @@ -12,7 +12,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua index 6467b4824d..83691fc4e7 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') local commonFunctions = require("user_modules/shared_testcases/commonFunctions") --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua index 290b1d98a5..cce54966a1 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') local commonFunctions = require("user_modules/shared_testcases/commonFunctions") --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua index be843b551b..7baa2021f0 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua index 6be4db6d92..47c7c49386 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua @@ -12,7 +12,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua index ac62e3a942..7921b66304 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua @@ -12,7 +12,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false From d02715ceb711b7a8cd0bfb90a8e929d8fa7dd4a8 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Thu, 6 Sep 2018 11:48:01 +0300 Subject: [PATCH 643/681] Updated common path in moved to SDL5_0 folder scripts --- .../SDL5_0/FullAppID/001_PTU_full_app_ID_true.lua | 12 ++---------- .../SDL5_0/FullAppID/002_PTU_full_app_ID_false.lua | 12 ++---------- .../001_SetGlobalProp_by_adding_commands.lua | 2 +- ...lobalProp_commands_with_and_without_vrCommand.lua | 2 +- .../003_SetGlobalProp_without_deleted_commands.lua | 2 +- .../004_SetGlobalProp_processing_30_commands.lua | 2 +- ...obalProp_apply_limitation_only_for_addcommand.lua | 2 +- .../006_SetGlobalProp_processing_added_choices.lua | 2 +- .../007_SetGlobalProp_absence_in_NONE.lua | 2 +- .../008_SetGlobalProp_absence_in_BACKGROUND.lua | 2 +- ...lProp_absence_addCommand_after_custom_request.lua | 2 +- ...op_absence_deleteCommand_after_custom_request.lua | 2 +- .../011_SetGlobalProp_custom_helpPrompt_only.lua | 2 +- .../012_SetGlobalProp_custom_vrHelp_only.lua | 2 +- ...m_helpPrompt_and_vrHelp_in_different_requests.lua | 2 +- ..._custom_request_without_helpPrompt_and_vrHelp.lua | 2 +- ...tGlobalProp_with_added_commands_by_resumption.lua | 2 +- ...ands_with_and_without_vrCommand_by_resumption.lua | 2 +- ...alProp_without_deleted_commands_by_resumption.lua | 2 +- ...obalProp_processing_30_commands_by_resumption.lua | 2 +- ...alProp_processing_added_choices_by_resumption.lua | 2 +- ...absence_after_custom_request_after_resumption.lua | 2 +- ...bsence_after_custom_request_before_resumption.lua | 2 +- ...obalProp_custom_helpPrompt_only_by_resumption.lua | 2 +- ...etGlobalProp_custom_vrHelp_only_by_resumption.lua | 2 +- ...t_without_helpPrompt_and_vrHelp_by_resumption.lua | 2 +- ..._several_vrCommands_in_one_addCommand_request.lua | 2 +- ...mands_in_one_addCommand_request_by_resumption.lua | 2 +- .../027_SetGlobalProp_invalid_custom_request.lua | 2 +- .../028_SetGlobalProp_rejected_custom_request.lua | 2 +- ..._SetGlobalProp_only_successful_added_commands.lua | 2 +- ...Prop_only_without_successful_deleted_commands.lua | 2 +- ...processing_30_commands_several_in_one_command.lua | 2 +- ...commands_several_in_one_command_by_resumption.lua | 2 +- .../033_SetGlobalProp_delete_last_command.lua | 2 +- .../SDL5_0/Image_template/001_isTemplate_is_true.lua | 2 +- .../Image_template/002_isTemplate_is_false.lua | 2 +- .../Image_template/003_isTemplate_is_absent.lua | 2 +- .../Image_template/004_isTemplate_invalid_type.lua | 2 +- .../005_isTemplate_is_true_with_not_png_image.lua | 2 +- .../006_isTemplate_is_true_with_STATIC_image.lua | 2 +- .../LowVoltage/001_Low_Voltage_and_Wake_Up.lua | 2 +- .../LowVoltage/002_Low_Voltage_and_Ignition_Off.lua | 2 +- .../003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua | 2 +- .../004_App_unregister_itself_gracefully.lua | 2 +- .../005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua | 2 +- ...Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua | 2 +- ...on_FULL_hmi_level_in_case_existed_app_in_full.lua | 2 +- ...ion_FULL_hmi_level_in_case_more_30_sec_before.lua | 2 +- ...tion_FULL_hmi_level_in_case_more_30_sec_after.lua | 2 +- ...FULL_hmi_level_in_case_existed_app_in_limited.lua | 2 +- ...tage_and_Wake_Up_resumption_LIMITED_hmi_level.lua | 2 +- ...LIMITED_hmi_level_in_case_existed_app_in_full.lua | 2 +- ..._LIMITED_hmi_level_in_case_more_30_sec_before.lua | 2 +- ...n_LIMITED_hmi_level_in_case_more_30_sec_after.lua | 2 +- ...ITED_hmi_level_in_case_existed_app_in_limited.lua | 2 +- ...ge_and_Ignition_Off_resumption_FULL_hmi_level.lua | 2 +- ...and_Ignition_Off_resumption_LIMITED_hmi_level.lua | 2 +- ...i_level_without_disconnect_before_low_voltage.lua | 2 +- ...i_level_without_disconnect_before_low_voltage.lua | 2 +- ...LL_hmi_level_in_case_more_30_sec_after_ing_on.lua | 2 +- ...ED_hmi_level_in_case_more_30_sec_after_ing_on.lua | 2 +- ..._Voltage_and_Wake_Up_no_timeout_no_resumption.lua | 2 +- ...Low_Voltage_and_Wake_Up_no_timeout_resumption.lua | 2 +- .../SDL5_0/TTSChunks/001_RegisterAppInterface.lua | 2 +- .../SDL5_0/TTSChunks/002_SetGlobalProperties.lua | 2 +- .../SDL5_0/TTSChunks/003_OnAppRegistered.lua | 8 ++++---- test_scripts/SDL5_0/TTSChunks/004_Alert.lua | 2 +- .../SDL5_0/TTSChunks/005_ChangeRegistration.lua | 2 +- .../SDL5_0/TTSChunks/006_PerformInteraction.lua | 2 +- test_scripts/SDL5_0/TTSChunks/007_Speak.lua | 2 +- .../SDL5_0/TTSChunks/008_PerformAudioPassThru.lua | 2 +- test_scripts/SDL5_0/TTSChunks/009_AlertManeuver.lua | 2 +- .../001_AddCommand.lua | 2 +- .../002_AddSubMenu.lua | 2 +- .../Transfer_RPC_with_invalid_image/003_Alert.lua | 2 +- .../004_CreateInteractionChoiceSet.lua | 2 +- .../005_PerfomInteraction.lua | 2 +- .../006_ScrollableMessage.lua | 2 +- .../Transfer_RPC_with_invalid_image/007_Show.lua | 2 +- .../008_ShowConstantTBT.lua | 2 +- .../009_SendLocation.lua | 2 +- .../010_SetAppIcon.lua | 2 +- .../011_UpdateTurnList.lua | 2 +- .../012_AlertManeuver.lua | 2 +- .../013_GetWayPoints.lua | 2 +- .../014_OnWayPointChange.lua | 2 +- .../015_SetGlobalProperties.lua | 2 +- 88 files changed, 93 insertions(+), 109 deletions(-) diff --git a/test_scripts/SDL5_0/FullAppID/001_PTU_full_app_ID_true.lua b/test_scripts/SDL5_0/FullAppID/001_PTU_full_app_ID_true.lua index 71e8cf9f82..e0c7d7d13c 100644 --- a/test_scripts/SDL5_0/FullAppID/001_PTU_full_app_ID_true.lua +++ b/test_scripts/SDL5_0/FullAppID/001_PTU_full_app_ID_true.lua @@ -1,20 +1,12 @@ --------------------------------------------------------------------------------------------- -- Script verifies that a PT snapshot contains the correct full_app_id_supported flag --- Supports PROPRIETARY +-- Supports PROPRIETARY --------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local commonPreconditions = require("user_modules/shared_testcases/commonPreconditions") -local mobile_session = require("mobile_session") local actions = require("user_modules/sequences/actions") -local json = require("modules/json") -local atf_logger = require("atf_logger") -local sdl = require("SDL") -local commonSteps = require("user_modules/shared_testcases/commonSteps") -local commonSmoke = require('test_scripts/Smoke/commonSmoke') -local common = require("test_scripts/SDL4_6/FullAppID/common") +local common = require("test_scripts/SDL5_0/FullAppID/common") local full_app_id_supported = "true" diff --git a/test_scripts/SDL5_0/FullAppID/002_PTU_full_app_ID_false.lua b/test_scripts/SDL5_0/FullAppID/002_PTU_full_app_ID_false.lua index 0f84a95359..a7822cee03 100644 --- a/test_scripts/SDL5_0/FullAppID/002_PTU_full_app_ID_false.lua +++ b/test_scripts/SDL5_0/FullAppID/002_PTU_full_app_ID_false.lua @@ -1,20 +1,12 @@ --------------------------------------------------------------------------------------------- -- Script verifies that a PT snapshot contains the correct full_app_id_supported flag --- Supports PROPRIETARY +-- Supports PROPRIETARY --------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local commonPreconditions = require("user_modules/shared_testcases/commonPreconditions") -local mobile_session = require("mobile_session") local actions = require("user_modules/sequences/actions") -local json = require("modules/json") -local atf_logger = require("atf_logger") -local sdl = require("SDL") -local commonSteps = require("user_modules/shared_testcases/commonSteps") -local commonSmoke = require('test_scripts/Smoke/commonSmoke') -local common = require("test_scripts/SDL4_6/FullAppID/common") +local common = require("test_scripts/SDL5_0/FullAppID/common") local full_app_id_supported = "false" diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua index 274f0e7086..927f922ad1 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/001_SetGlobalProp_by_adding_commands.lua @@ -14,7 +14,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua index d60a139cc5..1ffe306835 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/002_SetGlobalProp_commands_with_and_without_vrCommand.lua @@ -14,7 +14,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua index 7687a8876f..d4ffa579c8 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/003_SetGlobalProp_without_deleted_commands.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua index 7e52a4ade3..7b33b1f46c 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/004_SetGlobalProp_processing_30_commands.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua index 9109b55ff0..62fc6e4336 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/005_SetGlobalProp_apply_limitation_only_for_addcommand.lua @@ -14,7 +14,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua index 8958fa0151..d5cbbacfd7 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/006_SetGlobalProp_processing_added_choices.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua index 9a4bb26678..4e0e4bd74e 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/007_SetGlobalProp_absence_in_NONE.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua index babbb974d5..34b7d81e6e 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/008_SetGlobalProp_absence_in_BACKGROUND.lua @@ -18,7 +18,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua index 4f136c30cd..4d5606be62 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/009_SetGlobalProp_absence_addCommand_after_custom_request.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua index 671aa61f31..c6b6d0c136 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/010_SetGlobalProp_absence_deleteCommand_after_custom_request.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua index f68bb1bd49..69cb867163 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/011_SetGlobalProp_custom_helpPrompt_only.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua index cf2f512578..50eba12152 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/012_SetGlobalProp_custom_vrHelp_only.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua index f5e6353485..92502310d7 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/013_SetGlobalProp_custom_helpPrompt_and_vrHelp_in_different_requests.lua @@ -18,7 +18,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua index da542bb189..3f49d00613 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/014_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua index 0b9e4fc46e..3217d57105 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/015_SetGlobalProp_with_added_commands_by_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua index 996e7eebad..3d70bb2456 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/016_SetGlobalProp_commands_with_and_without_vrCommand_by_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') local commonFunctions = require("user_modules/shared_testcases/commonFunctions") --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua index 838c06d93b..f19026dc6a 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/017_SetGlobalProp_without_deleted_commands_by_resumption.lua @@ -17,7 +17,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua index 8095faf73b..ed2546e0a0 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/018_SetGlobalProp_processing_30_commands_by_resumption.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua index 0b65c6407e..ac23d91bff 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/019_SetGlobalProp_processing_added_choices_by_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') local commonFunctions = require("user_modules/shared_testcases/commonFunctions") --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua index 364e52cc20..3e92a60b59 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/020_SetGlobalProp_absence_after_custom_request_after_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua index 8d1fee561a..8185bb18ff 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/021_SetGlobalProp_absence_after_custom_request_before_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') local commonFunctions = require("user_modules/shared_testcases/commonFunctions") --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua index 7768ab427f..fe508f43bf 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/022_SetGlobalProp_custom_helpPrompt_only_by_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua index c25baee33a..abd062bca4 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/023_SetGlobalProp_custom_vrHelp_only_by_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua index a3dab98cdd..f39d71a0b0 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/024_SetGlobalProp_custom_request_without_helpPrompt_and_vrHelp_by_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua index 1b6dd64a20..99d1510eb5 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/025_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request.lua @@ -13,7 +13,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua index bedf5992af..6448290b25 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/026_SetGlobalProp_with_several_vrCommands_in_one_addCommand_request_by_resumption.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua index 080461a781..b14f8f81e7 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/027_SetGlobalProp_invalid_custom_request.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua index e047ccb8cc..cfb1fbaa74 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/028_SetGlobalProp_rejected_custom_request.lua @@ -16,7 +16,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua index d8791ee2d6..2aa9707e3c 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/029_SetGlobalProp_only_successful_added_commands.lua @@ -14,7 +14,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua index 56df8c6269..6df317ec10 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/030_SetGlobalProp_only_without_successful_deleted_commands.lua @@ -14,7 +14,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua index ff2f82df0f..96c760d1ec 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/031_SetGlobalProp_processing_30_commands_several_in_one_command.lua @@ -19,7 +19,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua index 8d4e7ae58a..bc6483a3d1 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/032_SetGlobalProp_processing_30_commands_several_in_one_command_by_resumption.lua @@ -21,7 +21,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua b/test_scripts/SDL5_0/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua index 64239ec6d6..403571a8e8 100644 --- a/test_scripts/SDL5_0/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua +++ b/test_scripts/SDL5_0/Handling_VR_help_requests/033_SetGlobalProp_delete_last_command.lua @@ -22,7 +22,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Handling_VR_help_requests/commonVRhelp') +local common = require('test_scripts/SDL5_0/Handling_VR_help_requests/commonVRhelp') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Image_template/001_isTemplate_is_true.lua b/test_scripts/SDL5_0/Image_template/001_isTemplate_is_true.lua index a048a2f57c..284abcbdd0 100644 --- a/test_scripts/SDL5_0/Image_template/001_isTemplate_is_true.lua +++ b/test_scripts/SDL5_0/Image_template/001_isTemplate_is_true.lua @@ -12,7 +12,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Image_template/commonImageTemplate') +local common = require('test_scripts/SDL5_0/Image_template/commonImageTemplate') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Image_template/002_isTemplate_is_false.lua b/test_scripts/SDL5_0/Image_template/002_isTemplate_is_false.lua index 619eb8d913..da73126dc1 100644 --- a/test_scripts/SDL5_0/Image_template/002_isTemplate_is_false.lua +++ b/test_scripts/SDL5_0/Image_template/002_isTemplate_is_false.lua @@ -12,7 +12,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Image_template/commonImageTemplate') +local common = require('test_scripts/SDL5_0/Image_template/commonImageTemplate') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Image_template/003_isTemplate_is_absent.lua b/test_scripts/SDL5_0/Image_template/003_isTemplate_is_absent.lua index 69f3da93ae..620655a74f 100644 --- a/test_scripts/SDL5_0/Image_template/003_isTemplate_is_absent.lua +++ b/test_scripts/SDL5_0/Image_template/003_isTemplate_is_absent.lua @@ -12,7 +12,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Image_template/commonImageTemplate') +local common = require('test_scripts/SDL5_0/Image_template/commonImageTemplate') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Image_template/004_isTemplate_invalid_type.lua b/test_scripts/SDL5_0/Image_template/004_isTemplate_invalid_type.lua index ef0ace5190..d6a401acb5 100644 --- a/test_scripts/SDL5_0/Image_template/004_isTemplate_invalid_type.lua +++ b/test_scripts/SDL5_0/Image_template/004_isTemplate_invalid_type.lua @@ -12,7 +12,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Image_template/commonImageTemplate') +local common = require('test_scripts/SDL5_0/Image_template/commonImageTemplate') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Image_template/005_isTemplate_is_true_with_not_png_image.lua b/test_scripts/SDL5_0/Image_template/005_isTemplate_is_true_with_not_png_image.lua index b864aa6319..f21fde0ad1 100644 --- a/test_scripts/SDL5_0/Image_template/005_isTemplate_is_true_with_not_png_image.lua +++ b/test_scripts/SDL5_0/Image_template/005_isTemplate_is_true_with_not_png_image.lua @@ -12,7 +12,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Image_template/commonImageTemplate') +local common = require('test_scripts/SDL5_0/Image_template/commonImageTemplate') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Image_template/006_isTemplate_is_true_with_STATIC_image.lua b/test_scripts/SDL5_0/Image_template/006_isTemplate_is_true_with_STATIC_image.lua index 7774c95d6f..d2b49ef796 100644 --- a/test_scripts/SDL5_0/Image_template/006_isTemplate_is_true_with_STATIC_image.lua +++ b/test_scripts/SDL5_0/Image_template/006_isTemplate_is_true_with_STATIC_image.lua @@ -12,7 +12,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/Image_template/commonImageTemplate') +local common = require('test_scripts/SDL5_0/Image_template/commonImageTemplate') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/LowVoltage/001_Low_Voltage_and_Wake_Up.lua b/test_scripts/SDL5_0/LowVoltage/001_Low_Voltage_and_Wake_Up.lua index fa38332a5b..94fead740f 100644 --- a/test_scripts/SDL5_0/LowVoltage/001_Low_Voltage_and_Wake_Up.lua +++ b/test_scripts/SDL5_0/LowVoltage/001_Low_Voltage_and_Wake_Up.lua @@ -23,7 +23,7 @@ -- Not resume HMI level for App3 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') local commonFunctions = require('user_modules/shared_testcases/commonFunctions') diff --git a/test_scripts/SDL5_0/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua b/test_scripts/SDL5_0/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua index 34d9372084..24e7ce7b77 100644 --- a/test_scripts/SDL5_0/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua +++ b/test_scripts/SDL5_0/LowVoltage/002_Low_Voltage_and_Ignition_Off.lua @@ -20,7 +20,7 @@ -- Not resume HMI level for App3 --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua b/test_scripts/SDL5_0/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua index ecbc0555f6..49fcc27ced 100644 --- a/test_scripts/SDL5_0/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua +++ b/test_scripts/SDL5_0/LowVoltage/003_Wake_Up_and_Ignition_Off_wo_Low_Voltage.lua @@ -7,7 +7,7 @@ -- 2) Ignore IGNITION_OFF signal and continue working as usual --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/004_App_unregister_itself_gracefully.lua b/test_scripts/SDL5_0/LowVoltage/004_App_unregister_itself_gracefully.lua index 67b1ea46a4..83442ba160 100644 --- a/test_scripts/SDL5_0/LowVoltage/004_App_unregister_itself_gracefully.lua +++ b/test_scripts/SDL5_0/LowVoltage/004_App_unregister_itself_gracefully.lua @@ -8,7 +8,7 @@ -- 2) Not resume app HMI level --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua b/test_scripts/SDL5_0/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua index 8766a905f2..b5839757cb 100644 --- a/test_scripts/SDL5_0/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua +++ b/test_scripts/SDL5_0/LowVoltage/005_Low_Voltage_and_Wake_Up_RPC_in_progress.lua @@ -9,7 +9,7 @@ -- 2) Discard processing of RPC --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua b/test_scripts/SDL5_0/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua index fb85d3a092..03758a56bd 100644 --- a/test_scripts/SDL5_0/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua +++ b/test_scripts/SDL5_0/LowVoltage/006_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua b/test_scripts/SDL5_0/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua index cd40747138..6477c29774 100644 --- a/test_scripts/SDL5_0/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua +++ b/test_scripts/SDL5_0/LowVoltage/007_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_existed_app_in_full.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua b/test_scripts/SDL5_0/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua index c988870d77..05f639e21b 100644 --- a/test_scripts/SDL5_0/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua +++ b/test_scripts/SDL5_0/LowVoltage/008_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_before.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua b/test_scripts/SDL5_0/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua index f551ba69c3..67731caf28 100644 --- a/test_scripts/SDL5_0/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua +++ b/test_scripts/SDL5_0/LowVoltage/009_Low_Voltage_and_Wake_Up_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after.lua @@ -11,7 +11,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua b/test_scripts/SDL5_0/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua index 948f4a9920..926fc83a24 100644 --- a/test_scripts/SDL5_0/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua +++ b/test_scripts/SDL5_0/LowVoltage/010_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_in_case_existed_app_in_limited.lua @@ -11,7 +11,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua b/test_scripts/SDL5_0/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua index f3ab8d1fd1..38af3aa472 100644 --- a/test_scripts/SDL5_0/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua +++ b/test_scripts/SDL5_0/LowVoltage/011_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua b/test_scripts/SDL5_0/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua index 9e4759ca03..4d60414f17 100644 --- a/test_scripts/SDL5_0/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua +++ b/test_scripts/SDL5_0/LowVoltage/012_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_full.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua b/test_scripts/SDL5_0/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua index a9291ac3f6..c836e61b92 100644 --- a/test_scripts/SDL5_0/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua +++ b/test_scripts/SDL5_0/LowVoltage/013_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_before.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua b/test_scripts/SDL5_0/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua index dc1ed0ff06..c08cf6d0e4 100644 --- a/test_scripts/SDL5_0/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua +++ b/test_scripts/SDL5_0/LowVoltage/014_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua b/test_scripts/SDL5_0/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua index 85c39cf812..fcf557425a 100644 --- a/test_scripts/SDL5_0/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua +++ b/test_scripts/SDL5_0/LowVoltage/015_Low_Voltage_and_Wake_Up_absence_resumption_LIMITED_hmi_level_in_case_existed_app_in_limited.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua b/test_scripts/SDL5_0/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua index 83733614fb..4d5242b187 100644 --- a/test_scripts/SDL5_0/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua +++ b/test_scripts/SDL5_0/LowVoltage/016_Low_Voltage_and_Ignition_Off_resumption_FULL_hmi_level.lua @@ -12,7 +12,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua b/test_scripts/SDL5_0/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua index ae645a2993..1925f78900 100644 --- a/test_scripts/SDL5_0/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua +++ b/test_scripts/SDL5_0/LowVoltage/017_Low_Voltage_and_Ignition_Off_resumption_LIMITED_hmi_level.lua @@ -12,7 +12,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua b/test_scripts/SDL5_0/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua index 9469564e94..c1241849f1 100644 --- a/test_scripts/SDL5_0/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua +++ b/test_scripts/SDL5_0/LowVoltage/018_Low_Voltage_and_Wake_Up_resumption_FULL_hmi_level_without_disconnect_before_low_voltage.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua b/test_scripts/SDL5_0/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua index 235c505a2e..e821b2d20a 100644 --- a/test_scripts/SDL5_0/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua +++ b/test_scripts/SDL5_0/LowVoltage/019_Low_Voltage_and_Wake_Up_resumption_LIMITED_hmi_level_without_disconnect_before_low_voltage.lua @@ -10,7 +10,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua b/test_scripts/SDL5_0/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua index ccd622d064..189f10d202 100644 --- a/test_scripts/SDL5_0/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua +++ b/test_scripts/SDL5_0/LowVoltage/020_Low_Voltage_and_Ignition_Off_absence_resumption_FULL_hmi_level_in_case_more_30_sec_after_ing_on.lua @@ -12,7 +12,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua b/test_scripts/SDL5_0/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua index 53cd000655..2eef3153d5 100644 --- a/test_scripts/SDL5_0/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua +++ b/test_scripts/SDL5_0/LowVoltage/021_Low_Voltage_and_Ignition_Off_absence_resumption_LIMITED_hmi_level_in_case_more_30_sec_after_ing_on.lua @@ -12,7 +12,7 @@ -- 2. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua b/test_scripts/SDL5_0/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua index b12c18edd9..e15133ba83 100644 --- a/test_scripts/SDL5_0/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua +++ b/test_scripts/SDL5_0/LowVoltage/022_Low_Voltage_and_Wake_Up_no_timeout_no_resumption.lua @@ -10,7 +10,7 @@ -- 2. not resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua b/test_scripts/SDL5_0/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua index cf7615f118..d7fe303e29 100644 --- a/test_scripts/SDL5_0/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua +++ b/test_scripts/SDL5_0/LowVoltage/023_Low_Voltage_and_Wake_Up_no_timeout_resumption.lua @@ -10,7 +10,7 @@ -- 3. resume persistent data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] -local common = require('test_scripts/LowVoltage/common') +local common = require('test_scripts/SDL5_0/LowVoltage/common') local runner = require('user_modules/script_runner') --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/TTSChunks/001_RegisterAppInterface.lua b/test_scripts/SDL5_0/TTSChunks/001_RegisterAppInterface.lua index de8b190f21..3a47359112 100644 --- a/test_scripts/SDL5_0/TTSChunks/001_RegisterAppInterface.lua +++ b/test_scripts/SDL5_0/TTSChunks/001_RegisterAppInterface.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/TTSChunks/002_SetGlobalProperties.lua b/test_scripts/SDL5_0/TTSChunks/002_SetGlobalProperties.lua index 8b5718b00e..f4f875a382 100644 --- a/test_scripts/SDL5_0/TTSChunks/002_SetGlobalProperties.lua +++ b/test_scripts/SDL5_0/TTSChunks/002_SetGlobalProperties.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Local Variables ]] local putFileParams = { diff --git a/test_scripts/SDL5_0/TTSChunks/003_OnAppRegistered.lua b/test_scripts/SDL5_0/TTSChunks/003_OnAppRegistered.lua index 77c3c4f2bf..026cbd124e 100644 --- a/test_scripts/SDL5_0/TTSChunks/003_OnAppRegistered.lua +++ b/test_scripts/SDL5_0/TTSChunks/003_OnAppRegistered.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false @@ -29,10 +29,10 @@ local function registerApp() { type = common.type, text = "pathToFile" } } local corId = common.getMobileSession():SendRPC("RegisterAppInterface", params) - common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", { - ttsName = { + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", { + ttsName = { { type = common.type, text = common.getPathToFileInStorage("pathToFile") } - } + } }) -- WARNINGS response is received since `pathToFile` is not a valid file common.getMobileSession():ExpectResponse(corId, { success = true, resultCode = "WARNINGS" }) diff --git a/test_scripts/SDL5_0/TTSChunks/004_Alert.lua b/test_scripts/SDL5_0/TTSChunks/004_Alert.lua index 95a1aac831..7d31dde0c1 100644 --- a/test_scripts/SDL5_0/TTSChunks/004_Alert.lua +++ b/test_scripts/SDL5_0/TTSChunks/004_Alert.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Local Variables ]] local putFileParams = { diff --git a/test_scripts/SDL5_0/TTSChunks/005_ChangeRegistration.lua b/test_scripts/SDL5_0/TTSChunks/005_ChangeRegistration.lua index b98034368e..8a6fac4142 100644 --- a/test_scripts/SDL5_0/TTSChunks/005_ChangeRegistration.lua +++ b/test_scripts/SDL5_0/TTSChunks/005_ChangeRegistration.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Local Variables ]] local putFileParams = { diff --git a/test_scripts/SDL5_0/TTSChunks/006_PerformInteraction.lua b/test_scripts/SDL5_0/TTSChunks/006_PerformInteraction.lua index f18c59c50f..1737a75bb0 100644 --- a/test_scripts/SDL5_0/TTSChunks/006_PerformInteraction.lua +++ b/test_scripts/SDL5_0/TTSChunks/006_PerformInteraction.lua @@ -17,7 +17,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Local Variables ]] local putFileParams = { diff --git a/test_scripts/SDL5_0/TTSChunks/007_Speak.lua b/test_scripts/SDL5_0/TTSChunks/007_Speak.lua index 70cd8c63e9..9a9649253d 100644 --- a/test_scripts/SDL5_0/TTSChunks/007_Speak.lua +++ b/test_scripts/SDL5_0/TTSChunks/007_Speak.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Local Variables ]] local putFileParams = { diff --git a/test_scripts/SDL5_0/TTSChunks/008_PerformAudioPassThru.lua b/test_scripts/SDL5_0/TTSChunks/008_PerformAudioPassThru.lua index c09d8ee6ab..8271267989 100644 --- a/test_scripts/SDL5_0/TTSChunks/008_PerformAudioPassThru.lua +++ b/test_scripts/SDL5_0/TTSChunks/008_PerformAudioPassThru.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Local Variables ]] local putFileParams = { diff --git a/test_scripts/SDL5_0/TTSChunks/009_AlertManeuver.lua b/test_scripts/SDL5_0/TTSChunks/009_AlertManeuver.lua index 43c639fde5..9bfd30fa5a 100644 --- a/test_scripts/SDL5_0/TTSChunks/009_AlertManeuver.lua +++ b/test_scripts/SDL5_0/TTSChunks/009_AlertManeuver.lua @@ -15,7 +15,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/SDL4_6/TTSChunks/common') +local common = require('test_scripts/SDL5_0/TTSChunks/common') --[[ Local Variables ]] local putFileParams = { diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/001_AddCommand.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/001_AddCommand.lua index ec134c1136..f051b00ccf 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/001_AddCommand.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/001_AddCommand.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua index e86c374b8d..02ab723fb7 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/002_AddSubMenu.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/003_Alert.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/003_Alert.lua index 706990849c..6baf52f31c 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/003_Alert.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/003_Alert.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua index 2d08639f0a..adbabba587 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/004_CreateInteractionChoiceSet.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua index 840e94e609..674b5df3bb 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/005_PerfomInteraction.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua index 4450c85d73..50188f4086 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/006_ScrollableMessage.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/007_Show.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/007_Show.lua index 233fb211d6..3780699b10 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/007_Show.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/007_Show.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua index 5312ba2880..935eaff9f0 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/008_ShowConstantTBT.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/009_SendLocation.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/009_SendLocation.lua index 7c7cbc933d..2f624925d1 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/009_SendLocation.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/009_SendLocation.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua index a4dbf8258f..e69486dc40 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/010_SetAppIcon.lua @@ -12,7 +12,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua index 6467b4824d..83691fc4e7 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/011_UpdateTurnList.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') local commonFunctions = require("user_modules/shared_testcases/commonFunctions") --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua index 290b1d98a5..cce54966a1 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/012_AlertManeuver.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') local commonFunctions = require("user_modules/shared_testcases/commonFunctions") --[[ Test Configuration ]] diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua index be843b551b..7baa2021f0 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/013_GetWayPoints.lua @@ -13,7 +13,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua index 6be4db6d92..47c7c49386 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/014_OnWayPointChange.lua @@ -12,7 +12,7 @@ --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false diff --git a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua index ac62e3a942..7921b66304 100644 --- a/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua +++ b/test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/015_SetGlobalProperties.lua @@ -12,7 +12,7 @@ --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') -local common = require('test_scripts/API/Transfer_RPC_with_invalid_image/common') +local common = require('test_scripts/SDL5_0/Transfer_RPC_with_invalid_image/common') --[[ Test Configuration ]] runner.testSettings.isSelfIncluded = false From 32454a0e556e0c56701ed489183c182457e2d4b5 Mon Sep 17 00:00:00 2001 From: HSavynetska Date: Thu, 6 Sep 2018 12:33:49 +0300 Subject: [PATCH 644/681] Scripts to check issue 1887 --- ...rams_in_case_parameters_field_is_empty.lua | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 test_scripts/Defects/5_0/1887_PoliciesManager_allows_all_requested_params_in_case_parameters_field_is_empty.lua diff --git a/test_scripts/Defects/5_0/1887_PoliciesManager_allows_all_requested_params_in_case_parameters_field_is_empty.lua b/test_scripts/Defects/5_0/1887_PoliciesManager_allows_all_requested_params_in_case_parameters_field_is_empty.lua new file mode 100644 index 0000000000..6dd4b06331 --- /dev/null +++ b/test_scripts/Defects/5_0/1887_PoliciesManager_allows_all_requested_params_in_case_parameters_field_is_empty.lua @@ -0,0 +1,95 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/1887 +-- +-- Description: +-- PoliciesManager allows all requested params in case "parameters" field is empty +-- Precondition: +-- SDL and HMI are started. +-- App is registered and activated. +-- In case: +-- 1) In case SDL receives OnVehicleData notification from HMI +-- and this notification is allowed by Policies for this mobile app +-- and "parameters" field is empty at PolicyTable for OnVehicleData notification +-- Expected result: +-- 1) SDL must log corresponding error internally +-- SDL must NOT transfer this notification to mobile app +-- Actual result: +-- N/A +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('user_modules/sequences/actions') +local runner = require('user_modules/script_runner') +local json = require("json") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local gpsDataResponse = { + longitudeDegrees = 100, + latitudeDegrees = 20, + utcYear = 2050, + utcMonth = 10, + utcDay = 30, + utcHours = 20, + utcMinutes = 50, + utcSeconds = 50, + compassDirection = "NORTH", + pdop = 5, + hdop = 5, + vdop = 5, + actual = false, + satellites = 30, + dimension = "2D", + altitude = 9500, + heading = 350, + speed = 450 +} + +--[[ Local Functions ]] +local function pTUpdateFunc(tbl) + local VDgroup = { + rpcs = { + SubscribeVehicleData = { + hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, + parameters = {"gps"} + }, + OnVehicleData = { + hmi_levels = {"BACKGROUND", "FULL", "LIMITED"}, + parameters = json.EMPTY_ARRAY + } + } + } + tbl.policy_table.functional_groupings["NewTestCaseGroup"] = VDgroup + tbl.policy_table.app_policies[config.application1.registerAppInterfaceParams.fullAppID].groups = {"Base-4", "NewTestCaseGroup"} +end + +local function SubscribeVD() + local cid = common.getMobileSession():SendRPC("SubscribeVehicleData", {gps = true}) + EXPECT_HMICALL("VehicleInfo.SubscribeVehicleData") + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) +end + +local function onVehicleData() + common.getHMIConnection():SendNotification("VehicleInfo.OnVehicleData", {gps = gpsDataResponse} ) + common.getMobileSession():ExpectNotification("OnVehicleData") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("PTU", common.policyTableUpdate, { pTUpdateFunc }) +runner.Step("Activate App", common.activateApp) +runner.Step("SubscribeVD", SubscribeVD) + +runner.Title("Test") +runner.Step("OnVD_parameters_empty_in_policy_table", onVehicleData) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From 23288f236e4f9ea39d56bbf3d1070b9b81c9626c Mon Sep 17 00:00:00 2001 From: JackLivio Date: Fri, 7 Sep 2018 14:26:36 -0400 Subject: [PATCH 645/681] Correctly update all functional groups for vehicle data disallowed test cases --- .../002_RPC_parameter_DISALLOWED_by_policies_flow.lua | 7 +++++++ .../002_RPC_parameter_DISALLOWED_by_policies_flow.lua | 7 +++++++ ...meter_disallowed_by_policies_Result_DISALLOWED_flow.lua | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index 48a9ebf54f..691dc8a66d 100644 --- a/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/GetVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -64,6 +64,13 @@ local function ptu_update_func(tbl) if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value) or ("turnSignal" == value) or ("electronicParkBrakeStatus" == value)) then table.insert(newParams, value) end end tbl.policy_table.functional_groupings["Emergency-1"].rpcs["GetVehicleData"].parameters = newParams + + params = tbl.policy_table.functional_groupings["VehicleInfo-3"].rpcs["GetVehicleData"].parameters + newParams = {} + for index, value in pairs(params) do + if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value) or ("turnSignal" == value) or ("electronicParkBrakeStatus" == value)) then table.insert(newParams, value) end + end + tbl.policy_table.functional_groupings["VehicleInfo-3"].rpcs["GetVehicleData"].parameters = newParams end local function processRPCSuccess(self) diff --git a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua index 5cb78e763e..40547744ce 100644 --- a/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua +++ b/test_scripts/API/VehicleData/SubscribeVehicleData/002_RPC_parameter_DISALLOWED_by_policies_flow.lua @@ -63,6 +63,13 @@ local function ptu_update_func(tbl) if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value) or ("turnSignal" == value) or ("electronicParkBrakeStatus" == value)) then table.insert(newParams, value) end end tbl.policy_table.functional_groupings["Emergency-1"].rpcs["SubscribeVehicleData"].parameters = newParams + + params = tbl.policy_table.functional_groupings["VehicleInfo-3"].rpcs["SubscribeVehicleData"].parameters + newParams = {} + for index, value in pairs(params) do + if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value) or ("turnSignal" == value) or ("electronicParkBrakeStatus" == value)) then table.insert(newParams, value) end + end + tbl.policy_table.functional_groupings["VehicleInfo-3"].rpcs["SubscribeVehicleData"].parameters = newParams end local function processRPCFailure(self) diff --git a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua index ac2665d35e..74248f6239 100644 --- a/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua +++ b/test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua @@ -62,6 +62,13 @@ local function ptu_update_func(tbl) if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value) or ("turnSignal" == value) or ("electronicParkBrakeStatus" == value)) then table.insert(newParams, value) end end tbl.policy_table.functional_groupings["Emergency-1"].rpcs["UnsubscribeVehicleData"].parameters = newParams + + params = tbl.policy_table.functional_groupings["VehicleInfo-3"].rpcs["UnsubscribeVehicleData"].parameters + newParams = {} + for index, value in pairs(params) do + if not (("engineOilLife" == value) or ("fuelRange" == value) or ("tirePressure" == value) or ("turnSignal" == value) or ("electronicParkBrakeStatus" == value)) then table.insert(newParams, value) end + end + tbl.policy_table.functional_groupings["VehicleInfo-3"].rpcs["UnsubscribeVehicleData"].parameters = newParams end local function processRPCFailure(self) From da476b1881ecbc5d68db155b0b0cc55678ca42a0 Mon Sep 17 00:00:00 2001 From: Myza Taras Date: Thu, 13 Sep 2018 17:41:34 +0300 Subject: [PATCH 646/681] Additional scripts for defect --- ...d_NACK_from_protected_to_not_protected.lua | 79 +++++++++++++++++++ ...spond_NACK_from_protected_to_protected.lua | 64 +++++++++++++++ ...CK_from_not_protected_to_not_protected.lua | 73 +++++++++++++++++ ...nd_ACK_from_not_protected_to_protected.lua | 61 ++++++++++++++ 4 files changed, 277 insertions(+) create mode 100644 test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_3_SDL_respond_NACK_from_protected_to_not_protected.lua create mode 100644 test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_4_SDL_respond_NACK_from_protected_to_protected.lua create mode 100644 test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_5_SDL_respond_NACK_from_not_protected_to_not_protected.lua create mode 100644 test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_6_SDL_respond_ACK_from_not_protected_to_protected.lua diff --git a/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_3_SDL_respond_NACK_from_protected_to_not_protected.lua b/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_3_SDL_respond_NACK_from_protected_to_not_protected.lua new file mode 100644 index 0000000000..50c0b14783 --- /dev/null +++ b/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_3_SDL_respond_NACK_from_protected_to_not_protected.lua @@ -0,0 +1,79 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/2379 +-- +-- Description: +-- 1. SDL does not respond NACK on second service. +-- Steps to reproduce: +-- 1 First service started as Protected. +-- 1 Start video sreaming. +-- 1 Second service starting as NOT Protected. +-- Expected: +-- 1. SDL respond NACK on second service. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Security/DTLS/common') +local runner = require('user_modules/script_runner') +local utils = require("user_modules/utils") +local constants = require('protocol_handler/ford_protocol_constants') +local events = require('events') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "NAVIGATION" } + +-- [[ Local functions]] +local function StartVideoServiceVia2Protocol() + local StartServiceResponseEvent = events.Event() + StartServiceResponseEvent.matches = + function(_, data) + return data.frameType == constants.FRAME_TYPE.CONTROL_FRAME and + data.serviceType == constants.SERVICE_TYPE.VIDEO and + data.sessionId == common.getMobileSession().sessionId and + (data.frameInfo == constants.FRAME_INFO.START_SERVICE_NACK or + data.frameInfo == constants.FRAME_INFO.START_SERVICE_ACK) + end + common.getMobileSession():Send({ + frameType = constants.FRAME_TYPE.CONTROL_FRAME, + serviceType = constants.SERVICE_TYPE.VIDEO, + frameInfo = constants.FRAME_INFO.START_SERVICE + }) + common.getMobileSession():ExpectEvent(StartServiceResponseEvent, "Expect StartServiceNACK") + :ValidIf(function(_, data) + if data.frameInfo == constants.FRAME_INFO.START_SERVICE_NACK then + return true + else + return false, "StartService ACK received" + end + end) + utils.wait(7000) +end + +local function appStartVideoStreaming(pServiceId) + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(pServiceId, "files/SampleVideo_5mb.mp4") + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = true }) + end) +common.getMobileSession():ExpectNotification("OnHMIStatus") +:Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set DTLS protocol in SDL", common.setSDLIniParameter, { "Protocol", "DTLSv1.0" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Policy Table Update Certificate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +-- [[ Test ]] +runner.Title("Test") +runner.Step("Start Protected Service", common.startServiceProtected, { 11 }) +runner.Step("Start Stream", appStartVideoStreaming, { 11 }) +runner.Step("Start video service via 2 protocol with expectation of StartServiceNACK", StartVideoServiceVia2Protocol ) + +-- [[ Postconditions ]] +runner.Title("Postconditions") +runner.Step("Stop SDL, restore SDL settings", common.postconditions) diff --git a/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_4_SDL_respond_NACK_from_protected_to_protected.lua b/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_4_SDL_respond_NACK_from_protected_to_protected.lua new file mode 100644 index 0000000000..dcd1a9b673 --- /dev/null +++ b/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_4_SDL_respond_NACK_from_protected_to_protected.lua @@ -0,0 +1,64 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/2379 +-- +-- Description: +-- 1. SDL does not respond NACK on second service. +-- Steps to reproduce: +-- 1 First service started as Protected. +-- 1 Start video sreaming. +-- 1 Second service starting as Protected. +-- Expected: +-- 1. SDL respond NACK on second service. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Security/DTLS/common') +local runner = require('user_modules/script_runner') +local utils = require("user_modules/utils") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "NAVIGATION" } + +-- [[ Local functions ]] +local function startServiceProtectedSecond(pServiceId) + common.getMobileSession():StartSecureService(pServiceId) + common.getMobileSession():ExpectHandshakeMessage() + :Times(0) + common.getMobileSession():ExpectControlMessage(pServiceId, { + frameInfo = common.frameInfo.START_SERVICE_NACK, + encryption = false + }) + common.getMobileSession():ExpectNotification("OnAppInterfaceUnregistered") + :Times(0) + utils.wait(7000) +end + +local function appStartVideoStreaming(pServiceId) + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(pServiceId, "files/SampleVideo_5mb.mp4") + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = true }) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set DTLS protocol in SDL", common.setSDLIniParameter, { "Protocol", "DTLSv1.0" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Policy Table Update Certificate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +-- [[ Test ]] +runner.Title("Test") +runner.Step("Start Protected Service", common.startServiceProtected, { 11 }) +runner.Step("Start Stream", appStartVideoStreaming, { 11 }) +runner.Step("Start second Protected Service", startServiceProtectedSecond, { 11 }) + +-- [[ Postconditions ]] +runner.Title("Postconditions") +runner.Step("Stop SDL, restore SDL settings", common.postconditions) diff --git a/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_5_SDL_respond_NACK_from_not_protected_to_not_protected.lua b/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_5_SDL_respond_NACK_from_not_protected_to_not_protected.lua new file mode 100644 index 0000000000..4503226fbb --- /dev/null +++ b/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_5_SDL_respond_NACK_from_not_protected_to_not_protected.lua @@ -0,0 +1,73 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/2379 +-- +-- Description: +-- 1) SDL does not respond NACK on second service: if first service NOT Protected started, second service NOT Protected too. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Security/DTLS/common') +local runner = require('user_modules/script_runner') +local utils = require("user_modules/utils") +local constants = require('protocol_handler/ford_protocol_constants') +local events = require('events') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false +config.application1.registerAppInterfaceParams.appHMIType = { "NAVIGATION" } + +-- [[ Local functions ]] +local function appStartVideoStreamingNotProtected(pServiceId) + common.getMobileSession():StartService(pServiceId) + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(pServiceId, "files/SampleVideo_5mb.mp4") + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = true }) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function StartVideoServiceVia2Protocol() + local StartServiceResponseEvent = events.Event() + StartServiceResponseEvent.matches = + function(_, data) + return data.frameType == constants.FRAME_TYPE.CONTROL_FRAME and + data.serviceType == constants.SERVICE_TYPE.VIDEO and + data.sessionId == common.getMobileSession().sessionId and + (data.frameInfo == constants.FRAME_INFO.START_SERVICE_NACK or + data.frameInfo == constants.FRAME_INFO.START_SERVICE_ACK) + end + common.getMobileSession():Send({ + frameType = constants.FRAME_TYPE.CONTROL_FRAME, + serviceType = constants.SERVICE_TYPE.VIDEO, + frameInfo = constants.FRAME_INFO.START_SERVICE + }) + common.getMobileSession():ExpectEvent(StartServiceResponseEvent, "Expect StartServiceNACK") + :ValidIf(function(_, data) + if data.frameInfo == constants.FRAME_INFO.START_SERVICE_NACK then + return true + else + return false, "StartService ACK received" + end + end) + utils.wait(7000) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set DTLS protocol in SDL", common.setSDLIniParameter, { "Protocol", "DTLSv1.0" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Policy Table Update Certificate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +-- [[ Test ]] +runner.Title("Test") +runner.Step("Start first Service NOT protected and start Stream", appStartVideoStreamingNotProtected, { 11 }) +runner.Step("Start video service via 2 protocol with expectation of StartServiceNACK", StartVideoServiceVia2Protocol ) + +-- [[ Postconditions ]] +runner.Title("Postconditions") +runner.Step("Stop SDL, restore SDL settings", common.postconditions) diff --git a/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_6_SDL_respond_ACK_from_not_protected_to_protected.lua b/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_6_SDL_respond_ACK_from_not_protected_to_protected.lua new file mode 100644 index 0000000000..024d95b5f7 --- /dev/null +++ b/test_scripts/Defects/5_0/2479_SDL_does_not_respond_NACK_to_second_request/2479_6_SDL_respond_ACK_from_not_protected_to_protected.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/2379 +-- +-- Description: +-- 1) SDL does not respond ACK on second service. +-- Steps to reproduce: +-- 1) First service started as NOT Protected. +-- 2) Start video sreaming. +-- 3) Second service starting as Protected. +-- Expected: +-- 1) SDL respond ACK on second service and will continuous stream through the encrypted channel. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local common = require('test_scripts/Security/DTLS/common') +local runner = require('user_modules/script_runner') +local utils = require("user_modules/utils") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +-- [[ Local functions ]] +local function appStartVideoStreamingNotProtected(pServiceId) + common.getMobileSession():StartService(pServiceId) + common.getHMIConnection():ExpectRequest("Navigation.StartStream") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + common.getMobileSession():StartStreaming(pServiceId, "files/SampleVideo_5mb.mp4") + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = true }) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus") + :Times(0) +end + +local function startServiceProtectedSecond(pServiceId) + common.getMobileSession():StartSecureService(pServiceId) + common.getMobileSession():ExpectHandshakeMessage() + :Times(1) + common.getMobileSession():ExpectControlMessage(pServiceId, { + frameInfo = common.frameInfo.START_SERVICE_ACK, + encryption = true + }) + common.getMobileSession():ExpectNotification("OnAppInterfaceUnregistered") + :Times(0) + utils.wait(10000) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Set DTLS protocol in SDL", common.setSDLIniParameter, { "Protocol", "DTLSv1.0" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App", common.registerApp) +runner.Step("Policy Table Update Certificate", common.policyTableUpdate, { common.ptUpdate }) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("Start Service NOT protected and start Stream", appStartVideoStreamingNotProtected, { 11 }) +runner.Step("Start Protected Service protected", startServiceProtectedSecond, { 11 }) + +runner.Title("Postconditions") +runner.Step("Stop SDL, restore SDL settings", common.postconditions) From cec17813ad6165f0138f804d1fa8033856b523d1 Mon Sep 17 00:00:00 2001 From: theresalech Date: Thu, 13 Sep 2018 15:11:07 -0400 Subject: [PATCH 647/681] add third_party.md Resolves issue #2060 --- third_party.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 third_party.md diff --git a/third_party.md b/third_party.md new file mode 100644 index 0000000000..44bdcc8b01 --- /dev/null +++ b/third_party.md @@ -0,0 +1,33 @@ +### SDL ATF TEST SCRIPTS + +Copyright (C) 2018 SmartDeviceLink Consortium, Inc. + +#### License +Copyright (c) 2017 - 2018, SmartDeviceLink Consortium, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +* Neither the name of SmartDeviceLink Consortium, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#### Third Party Licenses + +Both the source and binary distributions of this software contain +some third party software. All the third party software included +or linked is redistributed under the terms and conditions of their +original licenses. + +The third party software included and used by this project is: + +**Lua** + +* Licensed under MIT License +* The library is included in the build folder +* See [https://github.com/facebook/react](https://github.com/facebook/react) \ No newline at end of file From 6da90a157d9e0da773d52d47a9542bfa562a3fa5 Mon Sep 17 00:00:00 2001 From: HSavynetska Date: Mon, 17 Sep 2018 17:48:20 +0300 Subject: [PATCH 648/681] Scripts to check issue 1905 --- ...ated_during_active_embedded_navigation.lua | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 test_scripts/Defects/5_0/1905_Navigation_app_must_be_activated_during_active_embedded_navigation.lua diff --git a/test_scripts/Defects/5_0/1905_Navigation_app_must_be_activated_during_active_embedded_navigation.lua b/test_scripts/Defects/5_0/1905_Navigation_app_must_be_activated_during_active_embedded_navigation.lua new file mode 100644 index 0000000000..e759e8a9b0 --- /dev/null +++ b/test_scripts/Defects/5_0/1905_Navigation_app_must_be_activated_during_active_embedded_navigation.lua @@ -0,0 +1,55 @@ +-- User story: https://github.com/SmartDeviceLink/sdl_core/issues/1905 +-- +-- Precondition: +-- 1) SDL and HMI are started. +-- 2) Navigation app is registered. +-- 3) Navigation app in BACKGROUND and NOT_AUDIBLE due to active embedded navigation . +-- Description: +-- Navigation app must be activated during active embedded navigation +-- Steps to reproduce: +-- 1) User activates this navigation app and SDL receives from HMI: +-- a) OnEventChanged(EMBEDDED_NAVI, isActive=false) +-- b) SDL.ActivateApp () +-- Expected result: +-- SDL must respond SDL.ActivateApp (SUCCESS) to HMI send OnHMIStatus (FULL, AUDIBLE) to mobile app. +-- a. Navigation app activation is the trigger for HMI to switch off embedded navigation +-- b. HMI switches off embedded navigation and sends OnEventChanged (EMBEDDED_NAVI, isActive=false) to SDL +-- Actual result: +-- SDL does not set required HMILevel and audioStreamingState. +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/Defects/commonDefects') + +--[[ Local Variables ]] +config.application1.registerAppInterfaceParams.appHMIType = { "NAVIGATION" } +config.application1.registerAppInterfaceParams.isMediaApplication = false + +--[[ Local Variables ]] +local function onEventChange(self) + self.hmiConnection:SendNotification("BasicCommunication.OnEventChanged", {eventName = "EMBEDDED_NAVI", isActive = true}) + self.mobileSession1:ExpectNotification("OnHMIStatus", + { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, + { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + :Times(2) + :Do(function(exp) + if exp.occurences == 1 then + self.hmiConnection:SendNotification("BasicCommunication.OnEventChanged", {eventName = "EMBEDDED_NAVI", isActive = false}) + local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId(1) }) + EXPECT_HMIRESPONSE(requestId) + end + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI", common.rai_n) +runner.Step("Activate App", common.activate_app) + +runner.Title("Test") +runner.Step("onEventChange EMBEDDED_NAVI true", onEventChange) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From e62451c4c5d9b7352d11d562c49790939b49195f Mon Sep 17 00:00:00 2001 From: Mykola Korniichuk Date: Tue, 18 Sep 2018 19:33:00 +0300 Subject: [PATCH 649/681] ATF test script for reproducing defect #1898 --- ...f_media_app_after_unexpectedDisconnect.lua | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 test_scripts/Defects/5_0/1898_Canceling_HMILevel_resumption_of_media_app_after_unexpectedDisconnect.lua diff --git a/test_scripts/Defects/5_0/1898_Canceling_HMILevel_resumption_of_media_app_after_unexpectedDisconnect.lua b/test_scripts/Defects/5_0/1898_Canceling_HMILevel_resumption_of_media_app_after_unexpectedDisconnect.lua new file mode 100644 index 0000000000..dd46c00880 --- /dev/null +++ b/test_scripts/Defects/5_0/1898_Canceling_HMILevel_resumption_of_media_app_after_unexpectedDisconnect.lua @@ -0,0 +1,85 @@ +-- User story: https://github.com/SmartDeviceLink/sdl_core/issues/1898 +-- +-- Precondition: +-- 1) SDL and HMI are started. +-- 2) Media app is registered. +-- 3) Media app in FULL. +-- Description: +-- Media HMI Level resumption is not canceled after unexpected disconnect during active embedded audio source. +-- Steps to reproduce: +-- 1) Media app is disconnected unexpectedly +-- 2) Embeded audio is active (OnEventChanged(AUDIO_SOURCE, isActive=true)) +-- 3) Media app is re-registered and SDL does not receive OnEventChanged(AUDIO_SOURCE, isActive=true during ApplicationResumingTimeout. +-- Expected result: +-- SDL must cancel HMILevel resumption for this media app (meaning: media app must be in NONE) +-- Actual result: +-- SDL does not cancel HMILevel resumption. +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('user_modules/sequences/actions') +local connect = require("user_modules/dummy_connecttest") +local commonDefects = require('test_scripts/Defects/commonDefects') + +runner.testSettings.isSelfIncluded = false + +--[[ Configuration Modifications ]] +config.application1.registerAppInterfaceParams.appHMIType = { "DEFAULT" } +config.application1.registerAppInterfaceParams.isMediaApplication = true + +--[[ Local Functions ]] +local function activateAudioSource(self) + common.getHMIConnection():SendNotification("BasicCommunication.OnEventChanged", {eventName = "AUDIO_SOURCE", isActive = true}) +end + +local function cleanSessions() + for i = 1, common.getAppsCount() do + connect.mobileSession[i] = nil + end +end + +local function unexpectedDisconnect() + common.getMobileSession():Stop() + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppUnregistered", + { appID = common.getHMIAppId(), unexpectedDisconnect = true }) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + cleanSessions() + end) +end + +local function reRegisterApp() + local mobSession = common.getMobileSession(1) + mobSession:StartService(7) + :Do(function() + local params = common.getConfigAppParams(1) + params.hashID = commonDefects.hashId + local corId = mobSession:SendRPC("RegisterAppInterface", common.getConfigAppParams(1)) + mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Do(function() + common.getHMIConnection():ExpectNotification("BasicCommunication.ActivateApp") + :Times(0) + commonDefects.delayedExp(5000) + end) + end) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Register App1", common.registerAppWOPTU) +runner.Step("Activate App1", common.activateApp) + +runner.Title("Test") +runner.Step("unexpected disconnect app1", unexpectedDisconnect) +runner.Step("Activate audio source", activateAudioSource) +runner.Step("Re register App1", reRegisterApp) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) \ No newline at end of file From 52f5a28a1303267b1b4efe321dadae89232aba7e Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Sun, 23 Sep 2018 03:16:48 +0300 Subject: [PATCH 650/681] Fix issues related to fullAppId in policies scripts --- .../ptu_file_with_full_app_id_supported.json | 3 ++- .../146_ATF_HMILvl_on_PTU_affected_in_FULL_or_LIMITED.lua | 2 ++ .../169_ATF_HMILvl_on_PTU_affected_app_in_LIMITED.lua | 2 ++ .../303_ATF_HP_Usage_And_Error_Counts_For_AppID.lua | 2 +- .../304_ATF_HP_Validation_Count_Of_User_Selections.lua | 2 +- .../308_ATF_Check_app_registration_language_gui.lua | 1 + .../188_ATF_HP_Device_Data_Section_Validation.lua | 2 +- user_modules/shared_testcases/testCasesForExternalUCS.lua | 2 +- 8 files changed, 11 insertions(+), 5 deletions(-) diff --git a/files/jsons/Policies/Policy_Table_Update/ptu_file_with_full_app_id_supported.json b/files/jsons/Policies/Policy_Table_Update/ptu_file_with_full_app_id_supported.json index ce6100a0f8..1f694a1119 100644 --- a/files/jsons/Policies/Policy_Table_Update/ptu_file_with_full_app_id_supported.json +++ b/files/jsons/Policies/Policy_Table_Update/ptu_file_with_full_app_id_supported.json @@ -9,7 +9,8 @@ "groups": ["Base-4", "Base-6"], "heart_beat_timeout_ms": 0, "memory_kb": 0, - "nicknames": ["Test Application"] + "nicknames": ["Test Application"], + "RequestType": [] }, "default": { "keep_context": false, diff --git a/test_scripts/Policies/Policy_Table_Update/146_ATF_HMILvl_on_PTU_affected_in_FULL_or_LIMITED.lua b/test_scripts/Policies/Policy_Table_Update/146_ATF_HMILvl_on_PTU_affected_in_FULL_or_LIMITED.lua index 77a0d44ea6..71524760ce 100644 --- a/test_scripts/Policies/Policy_Table_Update/146_ATF_HMILvl_on_PTU_affected_in_FULL_or_LIMITED.lua +++ b/test_scripts/Policies/Policy_Table_Update/146_ATF_HMILvl_on_PTU_affected_in_FULL_or_LIMITED.lua @@ -44,6 +44,7 @@ local applications = hmiDisplayLanguageDesired = 'EN-US', appHMIType = { "NAVIGATION" }, appID = "0000001", + fullAppID = "0000001", deviceInfo = { os = "Android", @@ -68,6 +69,7 @@ local applications = hmiDisplayLanguageDesired = 'EN-US', appHMIType = { "MEDIA" }, appID = "0000002", + fullAppID = "0000002", deviceInfo = { os = "Android", diff --git a/test_scripts/Policies/Policy_Table_Update/169_ATF_HMILvl_on_PTU_affected_app_in_LIMITED.lua b/test_scripts/Policies/Policy_Table_Update/169_ATF_HMILvl_on_PTU_affected_app_in_LIMITED.lua index 217ef20de6..aea1390d5e 100644 --- a/test_scripts/Policies/Policy_Table_Update/169_ATF_HMILvl_on_PTU_affected_app_in_LIMITED.lua +++ b/test_scripts/Policies/Policy_Table_Update/169_ATF_HMILvl_on_PTU_affected_app_in_LIMITED.lua @@ -43,6 +43,7 @@ local applications = hmiDisplayLanguageDesired = 'EN-US', appHMIType = { "NAVIGATION" }, appID = "0000001", + fullAppID = "0000001", deviceInfo = { os = "Android", @@ -67,6 +68,7 @@ local applications = hmiDisplayLanguageDesired = 'EN-US', appHMIType = { "MEDIA" }, appID = "0000002", + fullAppID = "0000002", deviceInfo = { os = "Android", diff --git a/test_scripts/Policies/Validation_of_PolicyTables/303_ATF_HP_Usage_And_Error_Counts_For_AppID.lua b/test_scripts/Policies/Validation_of_PolicyTables/303_ATF_HP_Usage_And_Error_Counts_For_AppID.lua index 8a03780882..d9394800c7 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/303_ATF_HP_Usage_And_Error_Counts_For_AppID.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/303_ATF_HP_Usage_And_Error_Counts_For_AppID.lua @@ -34,7 +34,7 @@ commonSteps:DeletePolicyTable() --[[ Local Variables ]] local pathToSnapshot -local appID = config.application1.registerAppInterfaceParams["appID"] +local appID = config.application1.registerAppInterfaceParams["fullAppID"] --[[ Local Functions ]] local function isAppPresentInUsageAndErrorCountsSection(pathToFile) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/304_ATF_HP_Validation_Count_Of_User_Selections.lua b/test_scripts/Policies/Validation_of_PolicyTables/304_ATF_HP_Validation_Count_Of_User_Selections.lua index 760f98686d..2782e63e8d 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/304_ATF_HP_Validation_Count_Of_User_Selections.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/304_ATF_HP_Validation_Count_Of_User_Selections.lua @@ -37,7 +37,7 @@ commonSteps:DeleteLogsFiles() commonSteps:DeletePolicyTable() --[[ Local Variables ]] -local appID = config.application1.registerAppInterfaceParams["appID"] +local appID = config.application1.registerAppInterfaceParams["fullAppID"] local countAppActivation = 0 --[[ Preconditions ]] diff --git a/test_scripts/Policies/Validation_of_PolicyTables/308_ATF_Check_app_registration_language_gui.lua b/test_scripts/Policies/Validation_of_PolicyTables/308_ATF_Check_app_registration_language_gui.lua index bc1e7ecb5a..a8cd2c3cd5 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/308_ATF_Check_app_registration_language_gui.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/308_ATF_Check_app_registration_language_gui.lua @@ -64,6 +64,7 @@ local application1 = hmiDisplayLanguageDesired = language_desired, appHMIType = { "NAVIGATION" }, appID = "0000001", + fullAppID = "0000001", deviceInfo = { os = "Android", diff --git a/test_scripts/Policies/user_consent_of_Policies/188_ATF_HP_Device_Data_Section_Validation.lua b/test_scripts/Policies/user_consent_of_Policies/188_ATF_HP_Device_Data_Section_Validation.lua index e165a2fc49..c70a1247ac 100644 --- a/test_scripts/Policies/user_consent_of_Policies/188_ATF_HP_Device_Data_Section_Validation.lua +++ b/test_scripts/Policies/user_consent_of_Policies/188_ATF_HP_Device_Data_Section_Validation.lua @@ -56,7 +56,7 @@ local pathToSnapshot local consentDeviceSystemTimeStamp local consentGroupSystemTimeStamp local MACHash -local appID = config.application1.registerAppInterfaceParams["appID"] +local appID = config.application1.registerAppInterfaceParams["fullAppID"] --[[ Local Functions ]] local function GetCurrentTimeStampDeviceConsent() diff --git a/user_modules/shared_testcases/testCasesForExternalUCS.lua b/user_modules/shared_testcases/testCasesForExternalUCS.lua index cf81b1c17b..e2cf3500f5 100644 --- a/user_modules/shared_testcases/testCasesForExternalUCS.lua +++ b/user_modules/shared_testcases/testCasesForExternalUCS.lua @@ -144,7 +144,7 @@ local m = { } EXPECT_HMINOTIFICATION("BasicCommunication.OnAppRegistered", { application = { appName = RAIParams.appName } }) :Do(function(_, d) - m.HMIAppIds[RAIParams.appID] = d.params.application.appID + m.HMIAppIds[RAIParams.fullAppID] = d.params.application.appID end) test["mobileSession"..id]:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) :Do(function() From 4588d63a0b7394105e70b9d82207a19cad2a5617 Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Mon, 17 Sep 2018 11:12:41 -0400 Subject: [PATCH 651/681] Fixes ATF sending notifications/requests that it was supposed to be expecting --- .../Phase2/019_SDL_stop_audio_video.lua | 14 ++++++++++---- .../Phase2/smoke/019_SDL_stop_audio_video.lua | 14 ++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua b/test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua index 67b8c2ce32..a443c6ae1a 100644 --- a/test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua +++ b/test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua @@ -89,10 +89,16 @@ local function changeAudioSource() videoStreamingState = "NOT_STREAMABLE" }) common.wait(2000) - common.getHMIConnection():SendNotification("Navigation.OnAudioDataStreaming", { available = false }) - common.getHMIConnection():SendNotification("Navigation.OnVideoDataStreaming", { available = false }) - common.getHMIConnection():SendNotification("Navigation.StopAudioStream", { appID = common.getHMIAppId() }) - common.getHMIConnection():SendNotification("Navigation.StopStream", { appID = common.getHMIAppId() }) + common.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = false }) + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = false }) + common.getHMIConnection():ExpectRequest("Navigation.StopAudioStream", { appID = common.getHMIAppId() }) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getHMIConnection():ExpectRequest("Navigation.StopStream", { appID = common.getHMIAppId() }) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) expectEndService(10) expectEndService(11) end diff --git a/test_scripts/MobileProjection/Phase2/smoke/019_SDL_stop_audio_video.lua b/test_scripts/MobileProjection/Phase2/smoke/019_SDL_stop_audio_video.lua index 67b8c2ce32..a443c6ae1a 100644 --- a/test_scripts/MobileProjection/Phase2/smoke/019_SDL_stop_audio_video.lua +++ b/test_scripts/MobileProjection/Phase2/smoke/019_SDL_stop_audio_video.lua @@ -89,10 +89,16 @@ local function changeAudioSource() videoStreamingState = "NOT_STREAMABLE" }) common.wait(2000) - common.getHMIConnection():SendNotification("Navigation.OnAudioDataStreaming", { available = false }) - common.getHMIConnection():SendNotification("Navigation.OnVideoDataStreaming", { available = false }) - common.getHMIConnection():SendNotification("Navigation.StopAudioStream", { appID = common.getHMIAppId() }) - common.getHMIConnection():SendNotification("Navigation.StopStream", { appID = common.getHMIAppId() }) + common.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = false }) + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = false }) + common.getHMIConnection():ExpectRequest("Navigation.StopAudioStream", { appID = common.getHMIAppId() }) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getHMIConnection():ExpectRequest("Navigation.StopStream", { appID = common.getHMIAppId() }) + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) expectEndService(10) expectEndService(11) end From 6969a0cf5f56002cc0e44fb272685c7928496928 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 25 Sep 2018 11:24:46 -0400 Subject: [PATCH 652/681] Fix test 227_ATF_usage_and_error_counts_update_count_sync_out_of_memory.lua --- ...TF_usage_and_error_counts_update_count_sync_out_of_memory.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/227_ATF_usage_and_error_counts_update_count_sync_out_of_memory.lua b/test_scripts/Policies/Validation_of_PolicyTables/227_ATF_usage_and_error_counts_update_count_sync_out_of_memory.lua index 1353f34252..9c02158037 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/227_ATF_usage_and_error_counts_update_count_sync_out_of_memory.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/227_ATF_usage_and_error_counts_update_count_sync_out_of_memory.lua @@ -251,6 +251,7 @@ commonFunctions:newTestCasesGroup("Postconditions") function Test.Postcondition_StopSDL() StopSDL() + commonSteps:DeletePolicyTable() end return Test From 509128344418bf83b20c8a895d529e85e0c62df2 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Tue, 25 Sep 2018 19:06:11 +0300 Subject: [PATCH 653/681] Remove script not applicable for PROPRIETARY flow --- ...ck_STATUS_vai_USER_Request_PROPRIETARY.lua | 117 ------------------ .../policies_happy_paths_PROPRIETARY.txt | 1 - 2 files changed, 118 deletions(-) delete mode 100644 test_scripts/Policies/build_options/092_ATF_Check_STATUS_vai_USER_Request_PROPRIETARY.lua diff --git a/test_scripts/Policies/build_options/092_ATF_Check_STATUS_vai_USER_Request_PROPRIETARY.lua b/test_scripts/Policies/build_options/092_ATF_Check_STATUS_vai_USER_Request_PROPRIETARY.lua deleted file mode 100644 index e0210a8ef6..0000000000 --- a/test_scripts/Policies/build_options/092_ATF_Check_STATUS_vai_USER_Request_PROPRIETARY.lua +++ /dev/null @@ -1,117 +0,0 @@ ---------------------------------------------------------------------------------------------- - -- Requirements summary: - -- [PolicyTableUpdate] OnStatusUpdate(UPDATE_NEEDED) on new PTU request - -- - -- Note: copy PTUfilename - ptu.json on this way /tmp/fs/mp/images/ivsu_cache/ - -- Description: - -- SDL should request PTU in case new application is registered and is not listed in PT - -- 1. Used preconditions - -- SDL is built with "-DEXTENDED_POLICY: PROPRIETARY" flag - -- Connect mobile phone over WiFi. - -- 2. Performed steps - -- Register new application - -- Send user request SDL.UpdateSDL - -- - -- Expected result: - -- PTU is requested. PTS is created. - -- SDL->HMI: SDL.OnStatusUpdate(UPDATING) - -- SDL->HMI: BasicCommunication.PolicyUpdate - ------------------------------------------------------------------------------------------- ---[[ General configuration parameters ]] -config.defaultProtocolVersion = 2 - ---[[ Required Shared libraries ]] -local commonFunctions = require ('user_modules/shared_testcases/commonFunctions') -local commonSteps = require('user_modules/shared_testcases/commonSteps') -local utils = require ('user_modules/utils') - ---[[ General Precondition before ATF start]] -commonSteps:DeleteLogsFileAndPolicyTable() - ---[[ General Settings for configuration ]] -Test = require('connecttest') -require('user_modules/AppTypes') - ---[[ Local Functions ]] -local function policyUpdate(self) - local pathToSnaphot = "files/ptu.json" - local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestIdGetURLS) - :Do(function(_,_) - self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", - { - requestType = "PROPRIETARY", - appID = self.applications ["Test Application"], - fileName = "PTU" - } - ) - end) - EXPECT_NOTIFICATION("OnSystemRequest", {requestType = "PROPRIETARY" }) - :Do(function(_,_) - local CorIdSystemRequest = self.mobileSession:SendRPC ("SystemRequest", - { - requestType = "PROPRIETARY", - fileName = "PTU" - }, - pathToSnaphot - ) - EXPECT_HMICALL("BasicCommunication.SystemRequest") - :Do(function(_,data) - self.hmiConnection:SendResponse(data.id,"BasicCommunication.SystemRequest", "SUCCESS", {}) - end) - EXPECT_RESPONSE(CorIdSystemRequest, {success = true, resultCode = "SUCCESS"}) - :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", - { - policyfile = "/tmp/fs/mp/images/ivsu_cache/PTU" - }) - end) - :Do(function(_,_) - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UP_TO_DATE"}) - end) - end) -end - --- [[ Preconditions ]] -commonFunctions:newTestCasesGroup("Preconditions") -function Test:Preconditions_ActivateApplication() - local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", {appID = self.applications["Test Application"]}) - EXPECT_HMIRESPONSE(RequestId) - :Do(function(_,data) - if data.result.isSDLAllowed ~= true then - RequestId = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) - EXPECT_HMIRESPONSE(RequestId) - :Do(function(_,_) - self.hmiConnection:SendNotification("SDL.OnAllowSDLFunctionality", {allowed = true, source = "GUI", device = {id = utils.getDeviceMAC(), name = utils.getDeviceName()}}) - EXPECT_HMICALL("BasicCommunication.ActivateApp") - :Do(function(_,_) - self.hmiConnection:SendResponse(data.id,"BasicCommunication.ActivateApp", "SUCCESS", {}) - end) - :Times(2) - end) - end - end) - EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN"}) -end - -function Test:Preconditions_MoveSystem_UP_TO_DATE() - policyUpdate(self) -end - ---[[ Test ]] -commonFunctions:newTestCasesGroup ("Test") -function Test:TestStep_Check_User_Request_UpdateSDL() - local RequestIdUpdateSDL = self.hmiConnection:SendRequest("SDL.UpdateSDL") - EXPECT_HMIRESPONSE(RequestIdUpdateSDL,{result = {code = 0, method = "SDL.UpdateSDL", result = "UPDATE_NEEDED" }}) - - EXPECT_HMICALL("BasicCommunication.PolicyUpdate", {file = "/tmp/fs/mp/images/ivsu_cache/sdl_snapshot.json"}) - :Do(function(_,data) self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) - - EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", {status = "UPDATE_NEEDED"}, {status = "UPDATING"}):Times(2) -end - ---[[ Postconditions ]] -commonFunctions:newTestCasesGroup("Postconditions") -function Test.Postcondition_SDLStop() - StopSDL() -end diff --git a/test_sets/policies_happy_paths_PROPRIETARY.txt b/test_sets/policies_happy_paths_PROPRIETARY.txt index 5a81ed9f5a..9afb19e82a 100644 --- a/test_sets/policies_happy_paths_PROPRIETARY.txt +++ b/test_sets/policies_happy_paths_PROPRIETARY.txt @@ -2,7 +2,6 @@ ./test_scripts/Policies/build_options/088_ATF_Apply_UpdatedPT_after_OnReceivedPolicyUpdate_from_HMI_PROPRIETARY.lua ./test_scripts/Policies/build_options/089_ATF_Check_SDL_respond_GetURLs_Request_fromHMI_PROPRIETARY.lua ./test_scripts/Policies/build_options/091_ATF_Check_STATUS_UPDATE_NEEDED_PROPRIETARY.lua -./test_scripts/Policies/build_options/092_ATF_Check_STATUS_vai_USER_Request_PROPRIETARY.lua ./test_scripts/Policies/build_options/093_ATF_OnStatusUpdate_Trigger_PROPRIETARY.lua ./test_scripts/Policies/build_options/094_ATF_PTS_creation_rule_PROPRIETARY.lua ./test_scripts/Policies/build_options/095_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua From 8d9f96e6a58c25e787d8234301d0623b63344bb4 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Tue, 25 Sep 2018 12:40:45 -0400 Subject: [PATCH 654/681] Fix PT clean up for 264_ATF_pt_snapshot_creation_rule.lua --- .../264_ATF_pt_snapshot_creation_rule.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/test_scripts/Policies/Validation_of_PolicyTables/264_ATF_pt_snapshot_creation_rule.lua b/test_scripts/Policies/Validation_of_PolicyTables/264_ATF_pt_snapshot_creation_rule.lua index 1be471a1fc..9423b2be6a 100644 --- a/test_scripts/Policies/Validation_of_PolicyTables/264_ATF_pt_snapshot_creation_rule.lua +++ b/test_scripts/Policies/Validation_of_PolicyTables/264_ATF_pt_snapshot_creation_rule.lua @@ -77,6 +77,7 @@ end commonFunctions:newTestCasesGroup("Postconditions") function Test.Postcondition_StopSDL() StopSDL() + commonSteps:DeletePolicyTable() end return Test From 6d1afa8fd888513522a95e872069cd7000080849 Mon Sep 17 00:00:00 2001 From: Myza Taras Date: Wed, 26 Sep 2018 14:52:39 +0300 Subject: [PATCH 655/681] Changes accordance with the comments to PR --- ...iceList_notification_on_device_connect.lua | 59 ++++--------------- 1 file changed, 12 insertions(+), 47 deletions(-) diff --git a/test_scripts/Defects/5_0/2457_Needed_fixes_sending_of_UpdateDeviceList_notification_on_device_connect.lua b/test_scripts/Defects/5_0/2457_Needed_fixes_sending_of_UpdateDeviceList_notification_on_device_connect.lua index 76fb1de497..7594af1232 100644 --- a/test_scripts/Defects/5_0/2457_Needed_fixes_sending_of_UpdateDeviceList_notification_on_device_connect.lua +++ b/test_scripts/Defects/5_0/2457_Needed_fixes_sending_of_UpdateDeviceList_notification_on_device_connect.lua @@ -1,63 +1,28 @@ --------------------------------------------------------------------------------------------------- --- User story: https://github.com/smartdevicelink/sdl_core/issues/2381 +-- User story: https://github.com/smartdevicelink/sdl_core/issues/2457 -- --- Precondition: --- SDL Core and HMI are started. App is registered, HMI level = FULL -- Description: -- Steps to reproduce: --- 1) SDL currently notifies system by using another transport listener API - OnDeviceAdded/OnDeviceRemoved. +-- 1) HMI and SDL started, connect device. -- Expected: -- 1) SDL has to notify system with BC.UpdateDeviceList on device connect even if device does not have any SDL-enabled applications running. --------------------------------------------------------------------------------------------------- -- [[ Required Shared libraries ]] local runner = require('user_modules/script_runner') local common = require('user_modules/sequences/actions') -local utils = require("user_modules/utils") -local events = require("events") -local commonFunctions = require("user_modules/shared_testcases/commonFunctions") -local test = require("user_modules/dummy_connecttest") +local utils = require ('user_modules/utils') -- [[ Test Configuration ]] runner.testSettings.isSelfIncluded = false -- [[ Local function ]] -local function allowSDL(self) - common.getHMIConnection():SendNotification("SDL.OnAllowSDLFunctionality", { - allowed = true, - source = "GUI", - device = { - id = utils.getDeviceMAC(), - name = utils.getDeviceName() - } - }) -end - -local function start(pHMIParams) - local event = events.Event() - event.matches = function(e1, e2) return e1 == e2 end - test:runSDL() - commonFunctions:waitForSDLStart(test) - :Do(function() - test:initHMI() - :Do(function() - utils.cprint(35, "HMI initialized") - test:initHMI_onReady(pHMIParams) - :Do(function() - utils.cprint(35, "HMI is ready") - common.getHMIConnection():ExpectNotification("BasicCommunication.UpdateDeviceList") - common.getHMIConnection():ExpectNotification("OnDeviceAdded") - :Times(0) - test:connectMobile() - :Do(function() - utils.cprint(35, "Mobile connected") - allowSDL(test) - common.getHMIConnection():RaiseEvent(event, "Start event") - end) - end) - end) - end) - return common.getHMIConnection():ExpectEvent(event, "Start event") -end +local function start () + common.start() + common.getHMIConnection():ExpectRequest("BasicCommunication.UpdateDeviceList", + { deviceList = { { id = utils.getDeviceMAC(), name = utils.getDeviceName()} } }) + common.getHMIConnection():ExpectRequest("BasicCommunication.OnDeviceAdded") + :Times(0) + end --[[ Scenario ]] runner.Title("Preconditions") @@ -65,8 +30,8 @@ runner.Step("Clean environment", common.preconditions) -- [[ Test ]] runner.Title("Test") -runner.Step("Start SDL, HMI, connect Mobile, start Session", start) +runner.Step("Start SDL, HMI, connect Mobile", start) -- [[ Postconditions ]] runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions) \ No newline at end of file +runner.Step("Stop SDL", common.postconditions) From ea3bc2c91dbfcf831aa68be560ef11c271e6997c Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Wed, 26 Sep 2018 15:29:40 -0400 Subject: [PATCH 656/681] Create tests for conditional hmi level resumption --- .../001_conditional_resumption_allowed.lua | 56 +++++ .../002_conditional_resumption_denied.lua | 59 +++++ ...nal_resumption_specific_hmi_level_navi.lua | 61 +++++ ...sumption_specific_hmi_level_projection.lua | 61 +++++ ...al_resumption_specific_hmi_level_media.lua | 60 +++++ ...tion_specific_hmi_level_choose_highest.lua | 63 +++++ .../SDL5_0/ConditionalResumption/common.lua | 228 ++++++++++++++++++ test_sets/SDL5_0/conditional_resumption.txt | 6 + test_sets/SDL5_0/sdl_5_0_test_suite.txt | 9 + 9 files changed, 603 insertions(+) create mode 100644 test_scripts/SDL5_0/ConditionalResumption/001_conditional_resumption_allowed.lua create mode 100644 test_scripts/SDL5_0/ConditionalResumption/002_conditional_resumption_denied.lua create mode 100644 test_scripts/SDL5_0/ConditionalResumption/003_conditional_resumption_specific_hmi_level_navi.lua create mode 100644 test_scripts/SDL5_0/ConditionalResumption/004_conditional_resumption_specific_hmi_level_projection.lua create mode 100644 test_scripts/SDL5_0/ConditionalResumption/005_conditional_resumption_specific_hmi_level_media.lua create mode 100644 test_scripts/SDL5_0/ConditionalResumption/006_conditional_resumption_specific_hmi_level_choose_highest.lua create mode 100644 test_scripts/SDL5_0/ConditionalResumption/common.lua create mode 100644 test_sets/SDL5_0/conditional_resumption.txt diff --git a/test_scripts/SDL5_0/ConditionalResumption/001_conditional_resumption_allowed.lua b/test_scripts/SDL5_0/ConditionalResumption/001_conditional_resumption_allowed.lua new file mode 100644 index 0000000000..b40063e471 --- /dev/null +++ b/test_scripts/SDL5_0/ConditionalResumption/001_conditional_resumption_allowed.lua @@ -0,0 +1,56 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0149-mt-registration-limitation.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Session is restarted +-- 3. High bandwidth transport is connected +-- SDL does: +-- 1. Resume HMI level and commands added in previous session +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/SDL5_0/ConditionalResumption/common') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +function resumptionLevelFull() + common.getHMIConnection():ExpectNotification("BasicCommunication.ActivateApp", { appID = common.getHMIAppId() }) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE" }, + { hmiLevel = "FULL" }) + :Times(2) +end + +for option,appHMIType in pairs(common.appHMITypesByOption) do + --[[ Scenario ]] + runner.Title("Preconditions") + runner.Step("Set appHMIType", common.setAppHMIType, { 1, appHMIType }) + runner.Step("Clean environment", common.preconditions) + runner.Step("Set resumption config for " .. option, common.write_parameter_to_smart_device_link_ini, { option .. "TransportRequiredForResumption", "TCP_WIFI" }) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("App registration", common.registerAppWOPTU) + runner.Step("Pin OnHashChange", common.pinOnHashChange) + runner.Step("App activation", common.activateApp) + for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) + end + + runner.Title("Test") + runner.Step("App reconnect", common.reconnect) + runner.Step("App resumption", common.registrationWithResumption, + { 1, resumptionLevelFull, common.resumptionDataAddCommands }) + + runner.Title("Postconditions") + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end \ No newline at end of file diff --git a/test_scripts/SDL5_0/ConditionalResumption/002_conditional_resumption_denied.lua b/test_scripts/SDL5_0/ConditionalResumption/002_conditional_resumption_denied.lua new file mode 100644 index 0000000000..9aece19bbb --- /dev/null +++ b/test_scripts/SDL5_0/ConditionalResumption/002_conditional_resumption_denied.lua @@ -0,0 +1,59 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0149-mt-registration-limitation.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. Command1, Command2, Command3 commands with vrCommands are added +-- 2. Session is restarted +-- 3. High bandwidth transport is not connected +-- SDL does: +-- 1. Resume commands added in previous session +-- 2. Don't resume HMI level +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/SDL5_0/ConditionalResumption/common') + +--[[ Test Configuration ]] +-- To handle the exception where HMI level can be resumed for a media app +config.application1.registerAppInterfaceParams.isMediaApplication = false +runner.testSettings.isSelfIncluded = false + +function resumptionLevelDenied() + common.getHMIConnection():ExpectNotification("BasicCommunication.ActivateApp"):Times(0) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE" }) +end + +for option,appHMIType in pairs(common.appHMITypesByOption) do + --[[ Scenario ]] + runner.Title("Preconditions") + runner.Step("Set appHMIType", common.setAppHMIType, { 1, appHMIType }) + runner.Step("Clean environment", common.preconditions) + runner.Step("Set resumption config for " .. option, common.write_parameter_to_smart_device_link_ini, + { option .. "TransportRequiredForResumption", "IAP_USB" }) + runner.Step("Set HMI level config for " .. option, common.writeLowBandwidthResumptionLevel, { option, "NONE" }) + runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + runner.Step("App registration", common.registerAppWOPTU) + runner.Step("Pin OnHashChange", common.pinOnHashChange) + runner.Step("App activation", common.activateApp) + for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) + end + + runner.Title("Test") + runner.Step("App reconnect", common.reconnect) + runner.Step("App resumption", common.registrationWithResumption, + { 1, resumptionLevelDenied, common.resumptionDataAddCommands }) + + runner.Title("Postconditions") + runner.Step("Clean sessions", common.cleanSessions) + runner.Step("Stop SDL", common.postconditions) +end \ No newline at end of file diff --git a/test_scripts/SDL5_0/ConditionalResumption/003_conditional_resumption_specific_hmi_level_navi.lua b/test_scripts/SDL5_0/ConditionalResumption/003_conditional_resumption_specific_hmi_level_navi.lua new file mode 100644 index 0000000000..a140b1bc33 --- /dev/null +++ b/test_scripts/SDL5_0/ConditionalResumption/003_conditional_resumption_specific_hmi_level_navi.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0149-mt-registration-limitation.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. App is connected with NAVIGATION appHMIType and isMediaApplication=false +-- 2. Command1, Command2, Command3 commands with vrCommands are added +-- 3. Session is restarted +-- 4. High bandwidth transport is not connected +-- SDL does: +-- 1. Resume commands added in previous session +-- 2. Resume app to HMI level specified in `NavigationLowBandwidthResumptionLevel` +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/SDL5_0/ConditionalResumption/common') + +--[[ Test Configuration ]] +-- To handle the exception where HMI level can be resumed for a media app +config.application1.registerAppInterfaceParams.isMediaApplication = false +runner.testSettings.isSelfIncluded = false + +function resumptionLevelNavi() + common.getHMIConnection():ExpectNotification("BasicCommunication.ActivateApp"):Times(0) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE" }, + { hmiLevel = "LIMITED" }) + :Times(2) +end + +local option = "Navigation" + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Set appHMIType", common.setAppHMIType, { 1, common.appHMITypesByOption[option] }) +runner.Step("Clean environment", common.preconditions) +runner.Step("Set resumption config for " .. option, common.write_parameter_to_smart_device_link_ini, + { option .. "TransportRequiredForResumption", "IAP_USB" }) +runner.Step("Set HMI level config for " .. option, common.writeLowBandwidthResumptionLevel, { option, "LIMITED" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Pin OnHashChange", common.pinOnHashChange) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) +end + +runner.Title("Test") +runner.Step("App reconnect", common.reconnect) +runner.Step("App resumption", common.registrationWithResumption, + { 1, resumptionLevelNavi, common.resumptionDataAddCommands }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) \ No newline at end of file diff --git a/test_scripts/SDL5_0/ConditionalResumption/004_conditional_resumption_specific_hmi_level_projection.lua b/test_scripts/SDL5_0/ConditionalResumption/004_conditional_resumption_specific_hmi_level_projection.lua new file mode 100644 index 0000000000..74df0da407 --- /dev/null +++ b/test_scripts/SDL5_0/ConditionalResumption/004_conditional_resumption_specific_hmi_level_projection.lua @@ -0,0 +1,61 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0149-mt-registration-limitation.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. App is connected with PROJECTION appHMIType and isMediaApplication=false +-- 2. Command1, Command2, Command3 commands with vrCommands are added +-- 3. Session is restarted +-- 4. High bandwidth transport is not connected +-- SDL does: +-- 1. Resume commands added in previous session +-- 2. Resume app to HMI level specified in `ProjectionLowBandwidthResumptionLevel` +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/SDL5_0/ConditionalResumption/common') + +--[[ Test Configuration ]] +-- To handle the exception where HMI level can be resumed for a media app +config.application1.registerAppInterfaceParams.isMediaApplication = false +runner.testSettings.isSelfIncluded = false + +function resumptionLevelProjection() + common.getHMIConnection():ExpectNotification("BasicCommunication.ActivateApp"):Times(0) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE" }, + { hmiLevel = "BACKGROUND" }) + :Times(2) +end + +local option = "Projection" + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Set appHMIType", common.setAppHMIType, { 1, common.appHMITypesByOption[option] }) +runner.Step("Clean environment", common.preconditions) +runner.Step("Set resumption config for " .. option, common.write_parameter_to_smart_device_link_ini, + { option .. "TransportRequiredForResumption", "IAP_USB" }) +runner.Step("Set HMI level config for " .. option, common.writeLowBandwidthResumptionLevel, { option, "BACKGROUND" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Pin OnHashChange", common.pinOnHashChange) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) +end + +runner.Title("Test") +runner.Step("App reconnect", common.reconnect) +runner.Step("App resumption", common.registrationWithResumption, + { 1, resumptionLevelProjection, common.resumptionDataAddCommands }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) \ No newline at end of file diff --git a/test_scripts/SDL5_0/ConditionalResumption/005_conditional_resumption_specific_hmi_level_media.lua b/test_scripts/SDL5_0/ConditionalResumption/005_conditional_resumption_specific_hmi_level_media.lua new file mode 100644 index 0000000000..c9beb909f3 --- /dev/null +++ b/test_scripts/SDL5_0/ConditionalResumption/005_conditional_resumption_specific_hmi_level_media.lua @@ -0,0 +1,60 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0149-mt-registration-limitation.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. App is connected with empty appHMIType and isMediaApplication=true +-- 2. Command1, Command2, Command3 commands with vrCommands are added +-- 3. Session is restarted +-- 4. High bandwidth transport is not connected +-- SDL does: +-- 1. Resume commands added in previous session +-- 2. Resume app to HMI level specified in `MediaLowBandwidthResumptionLevel` +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/SDL5_0/ConditionalResumption/common') + +--[[ Test Configuration ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true +runner.testSettings.isSelfIncluded = false + +function resumptionLevelMedia() + common.getHMIConnection():ExpectNotification("BasicCommunication.ActivateApp"):Times(1) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE" }, + { hmiLevel = "FULL" }) + :Times(2) +end + +local option = "EmptyApp" + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Set appHMIType", common.setAppHMIType, { 1, common.appHMITypesByOption[option] }) +runner.Step("Clean environment", common.preconditions) +runner.Step("Set resumption config for " .. option, common.write_parameter_to_smart_device_link_ini, + { option .. "TransportRequiredForResumption", "IAP_USB" }) +runner.Step("Set HMI level config for " .. option, common.writeMediaLowBandwidthResumptionLevel, { "FULL" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Pin OnHashChange", common.pinOnHashChange) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) +end + +runner.Title("Test") +runner.Step("App reconnect", common.reconnect) +runner.Step("App resumption", common.registrationWithResumption, + { 1, resumptionLevelMedia, common.resumptionDataAddCommands }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) \ No newline at end of file diff --git a/test_scripts/SDL5_0/ConditionalResumption/006_conditional_resumption_specific_hmi_level_choose_highest.lua b/test_scripts/SDL5_0/ConditionalResumption/006_conditional_resumption_specific_hmi_level_choose_highest.lua new file mode 100644 index 0000000000..8a09ddca61 --- /dev/null +++ b/test_scripts/SDL5_0/ConditionalResumption/006_conditional_resumption_specific_hmi_level_choose_highest.lua @@ -0,0 +1,63 @@ +--------------------------------------------------------------------------------------------------- +-- Proposal: https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0149-mt-registration-limitation.md +-- User story: TBD +-- Use case: TBD +-- +-- Requirement summary: TBD +-- +-- Description: +-- In case: +-- 1. App is connected with PROJECTION, NAVIGATION appHMIType and isMediaApplication=true +-- 2. Command1, Command2, Command3 commands with vrCommands are added +-- 3. Session is restarted +-- 4. High bandwidth transport is not connected +-- SDL does: +-- 1. Resume commands added in previous session +-- 2. Resume app to highest HMI level between `NavigationLowBandwidthResumptionLevel`, +-- `ProjectionLowBandwidthResumptionLevel`, and `MediaLowBandwidthResumptionLevel` +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('test_scripts/SDL5_0/ConditionalResumption/common') + +--[[ Test Configuration ]] +config.application1.registerAppInterfaceParams.isMediaApplication = true +runner.testSettings.isSelfIncluded = false + +function resumptionLevelMedia() + common.getHMIConnection():ExpectNotification("BasicCommunication.ActivateApp"):Times(1) + :Do(function(_,data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + common.getMobileSession():ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE" }, + { hmiLevel = "FULL" }) + :Times(2) +end + +local option = "EmptyApp" + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Set appHMIType", common.setAppHMIType, { 1, {"NAVIGATION", "PROJECTION"} }) +runner.Step("Clean environment", common.preconditions) +runner.Step("Set resumption config for " .. option, common.write_parameter_to_smart_device_link_ini, + { option .. "TransportRequiredForResumption", "IAP_USB" }) +runner.Step("Set HMI level config for " .. option, common.writeLowBandwidthResumptionLevel, { "Navigation", "LIMITED" }) +runner.Step("Set HMI level config for " .. option, common.writeLowBandwidthResumptionLevel, { "Projection", "BACKGROUND" }) +runner.Step("Set HMI level config for " .. option, common.writeMediaLowBandwidthResumptionLevel, { "FULL" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerAppWOPTU) +runner.Step("Pin OnHashChange", common.pinOnHashChange) +runner.Step("App activation", common.activateApp) +for i = 1,3 do + runner.Step("AddCommand" .. i, common.addCommand, { common.getAddCommandParams(i) }) +end + +runner.Title("Test") +runner.Step("App reconnect", common.reconnect) +runner.Step("App resumption", common.registrationWithResumption, + { 1, resumptionLevelMedia, common.resumptionDataAddCommands }) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) \ No newline at end of file diff --git a/test_scripts/SDL5_0/ConditionalResumption/common.lua b/test_scripts/SDL5_0/ConditionalResumption/common.lua new file mode 100644 index 0000000000..bb8d3ef996 --- /dev/null +++ b/test_scripts/SDL5_0/ConditionalResumption/common.lua @@ -0,0 +1,228 @@ +--------------------------------------------------------------------------------------------------- +-- Smoke API common module +--------------------------------------------------------------------------------------------------- +--[[ General configuration parameters ]] +config.mobileHost = "127.0.0.1" +config.defaultProtocolVersion = 2 + +--[[ Required Shared libraries ]] +local mobile_session = require("mobile_session") +local json = require("modules/json") + +local actions = require("user_modules/sequences/actions") +local consts = require("user_modules/consts") +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local commonSteps = require("user_modules/shared_testcases/commonSteps") +local commonTestCases = require("user_modules/shared_testcases/commonTestCases") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local test = require("user_modules/dummy_connecttest") +local utils = require('user_modules/utils') + +--[[ Local Variables ]] +local hmiAppIds = {} +local preloadedPT = commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + +local common = actions + +common.commandArray = {} + +common.appHMITypesByOption = { + EmptyApp = {}, + Default = {"DEFAULT"}, + Communication = {"COMMUNICATION"}, + Media = {"MEDIA"}, + Messaging = {"COMMUNICATION"}, + Navigation = {"NAVIGATION"}, + Information = {"INFORMATION"}, + Social = {"SOCIAL"}, + BackgroundProcess = {"BACKGROUND_PROCESS"}, + Testing = {"TESTING"}, + System = {"SYSTEM"}, + Projection = {"PROJECTION"}, + RemoteControl = {"REMOTE_CONTROL"} +} + +common.wait = utils.wait + +--[[Module functions]] +local basePreconditions = actions.preconditions +function common.preconditions() + basePreconditions() + commonPreconditions:BackupFile("smartDeviceLink.ini") + common.commandArray = {} + local params = common.getConfigAppParams(1) + params.hashID = nil + common.hashID = nil +end + +function common.pinOnHashChange(pAppId) + if not pAppId then pAppId = 1 end + common.getMobileSession(pAppId):ExpectNotification("OnHashChange") + :Pin() + :Times(AnyNumber()) + :Do(function(_, data) + common.hashId = data.payload.hashID + end) +end + +function common.cleanSessions() + for i = 1, common.getAppsCount() do + test.mobileSession[i]:StopRPC() + :Do(function(_, d) + utils.cprint(35, "Mobile session " .. d.sessionId .. " deleted") + test.mobileSession[i] = nil + end) + end + utils.wait() +end + +function common.write_parameter_to_smart_device_link_ini(param_name, param_value) + commonFunctions:write_parameter_to_smart_device_link_ini(param_name, param_value) +end + +function common.writeLowBandwidthResumptionLevel(hmi_type, hmi_level) + if hmi_type == "Projection" or hmi_type == "Navigation" then + commonFunctions:write_parameter_to_smart_device_link_ini(hmi_type .. "LowBandwidthResumptionLevel", hmi_level) + end +end + +function common.writeMediaLowBandwidthResumptionLevel(hmi_level) + commonFunctions:write_parameter_to_smart_device_link_ini("MediaLowBandwidthResumptionLevel", hmi_level) +end + +function common.registrationWithResumption(pAppId, pLevelResumpFunc, pDataResump) + if not pAppId then pAppId = 1 end + local mobSession = common.getMobileSession(pAppId) + mobSession:StartService(7) + :Do(function() + local params = common.getConfigAppParams(pAppId) + params.hashID = common.hashId + local corId = mobSession:SendRPC("RegisterAppInterface", common.getConfigAppParams(pAppId)) + test.hmiConnection:ExpectNotification("BasicCommunication.OnAppRegistered", + { application = { appName = common.getConfigAppParams(pAppId).appName } }) + :Do(function(_, d1) + common.setHMIAppId(d1.params.application.appID, pAppId) + if pDataResump then + pDataResump() + end + end) + mobSession:ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + if pLevelResumpFunc then + pLevelResumpFunc() + end + end) + end) +end + +function common.getAddCommandParams(pN) + local out = { + cmdID = pN, + vrCommands = { "vrCommand" .. pN}, + menuParams = { + menuName = "Command" .. pN + } + } + return out +end + +function common.setAppHMIType(pAppId, pAppHMIType) + if #pAppHMIType == 0 then pAppHMIType = nil end + config["application" .. pAppId].registerAppInterfaceParams.appHMIType = pAppHMIType +end + +function common.addCommand(pParams, pAppId) + if not pAppId then pAppId = 1 end + local mobSession = common.getMobileSession(pAppId) + local hmiConnection = common.getHMIConnection() + local cid = mobSession:SendRPC("AddCommand", pParams) + local requestUiParams = { + cmdID = pParams.cmdID, + menuParams = pParams.menuParams, + appID = common.getHMIAppId() + } + EXPECT_HMICALL("UI.AddCommand", requestUiParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + if pParams.vrCommands then + table.insert(common.commandArray, { cmdID = pParams.cmdID, vrCommand = pParams.vrCommands}) + local requestVrParams = { + cmdID = pParams.cmdID, + vrCommands = pParams.vrCommands, + type = "Command", + appID = common.getHMIAppId(pAppId) + } + EXPECT_HMICALL("VR.AddCommand", requestVrParams) + :Do(function(_,data) + hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) + end) + end + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS"}) +end + + +function common.resumptionDataAddCommands() + EXPECT_HMICALL("VR.AddCommand") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + for _, value in pairs(common.commandArray) do + if data.params.cmdID == value.cmdID then + local vrCommandCompareResult = commonFunctions:is_table_equal(data.params.vrCommands, value.vrCommand) + local Msg = "" + if vrCommandCompareResult == false then + Msg = "vrCommands in received VR.AddCommand are not match to expected result.\n" .. + "Actual result:" .. common.tableToString(data.params.vrCommands) .. "\n" .. + "Expected result:" .. common.tableToString(value.vrCommand) .."\n" + end + return vrCommandCompareResult, Msg + end + end + return true + end) + :Times(#common.commandArray) + + EXPECT_HMICALL("UI.AddCommand") + :Do(function(_, data) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) + end) + :ValidIf(function(_,data) + for k, value in pairs(common.commandArray) do + if data.params.cmdID == value.cmdID then + return true + elseif data.params.cmdID ~= value.cmdID and k == #common.commandArray then + return false, "Received cmdID in UI.AddCommand was not added previously before resumption" + end + end + end) + :Times(#common.commandArray) +end + +function common.resumptionDenied() + EXPECT_HMICALL("VR.AddCommand"):Times(0) + EXPECT_HMICALL("UI.AddCommand"):Times(0) +end + +function common.reconnect(pAppId) + if not pAppId then pAppId = 1 end + common.getMobileSession(pAppId):Stop() + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppUnregistered", + {appID = common.getHMIAppId(pAppId), unexpectedDisconnect = true}) + :Do(function() + test.mobileSession[pAppId] = mobile_session.MobileSession( + test, + test.mobileConnection, + config["application" .. pAppId].registerAppInterfaceParams) + test.mobileConnection:Connect() + end) +end + +local basePostconditions = actions.postconditions +function common.postconditions() + basePostconditions() + commonPreconditions:RestoreFile("smartDeviceLink.ini") +end + +return common \ No newline at end of file diff --git a/test_sets/SDL5_0/conditional_resumption.txt b/test_sets/SDL5_0/conditional_resumption.txt new file mode 100644 index 0000000000..7a9f3c2848 --- /dev/null +++ b/test_sets/SDL5_0/conditional_resumption.txt @@ -0,0 +1,6 @@ +./test_scripts/SDL5_0/ConditionalResumption/001_conditional_resumption_allowed.lua +./test_scripts/SDL5_0/ConditionalResumption/002_conditional_resumption_denied.lua +./test_scripts/SDL5_0/ConditionalResumption/003_conditional_resumption_specific_hmi_level_navi.lua +./test_scripts/SDL5_0/ConditionalResumption/004_conditional_resumption_specific_hmi_level_projection.lua +./test_scripts/SDL5_0/ConditionalResumption/005_conditional_resumption_specific_hmi_level_media.lua +./test_scripts/SDL5_0/ConditionalResumption/006_conditional_resumption_specific_hmi_level_choose_highest.lua \ No newline at end of file diff --git a/test_sets/SDL5_0/sdl_5_0_test_suite.txt b/test_sets/SDL5_0/sdl_5_0_test_suite.txt index bbb56bbf17..25e7b9940e 100644 --- a/test_sets/SDL5_0/sdl_5_0_test_suite.txt +++ b/test_sets/SDL5_0/sdl_5_0_test_suite.txt @@ -30,6 +30,15 @@ ./test_scripts/SDL5_0/vrCommandOptional/001_create_interaction_choice_set_invalid_data.lua ./test_scripts/SDL5_0/vrCommandOptional/002_perform_interaction_invalid_data.lua ; +;Disable HMI Level resumption based on app and transport type +; +./test_scripts/SDL5_0/ConditionalResumption/001_conditional_resumption_allowed.lua +./test_scripts/SDL5_0/ConditionalResumption/002_conditional_resumption_denied.lua +./test_scripts/SDL5_0/ConditionalResumption/003_conditional_resumption_specific_hmi_level_navi.lua +./test_scripts/SDL5_0/ConditionalResumption/004_conditional_resumption_specific_hmi_level_projection.lua +./test_scripts/SDL5_0/ConditionalResumption/005_conditional_resumption_specific_hmi_level_media.lua +./test_scripts/SDL5_0/ConditionalResumption/006_conditional_resumption_specific_hmi_level_choose_highest.lua +; ;DTLS Encryption ; ./test_scripts/Security/DTLS/001_StartRPC_service.lua From d140b63e65507f15ac5009656b9cb42761f8bdea Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Wed, 26 Sep 2018 15:31:15 -0400 Subject: [PATCH 657/681] Allow setting of commented out ini values --- user_modules/shared_testcases/commonFunctions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_modules/shared_testcases/commonFunctions.lua b/user_modules/shared_testcases/commonFunctions.lua index 87a103df81..750e969528 100644 --- a/user_modules/shared_testcases/commonFunctions.lua +++ b/user_modules/shared_testcases/commonFunctions.lua @@ -919,7 +919,7 @@ function commonFunctions:write_parameter_to_smart_device_link_ini(param_name, pa local result = false for line in io.lines(path_to_ini_file) do if is_find_string == false then - if string.match(line, "^%s*"..param_name.."%s*=%s*") ~= nil then + if string.match(line, "[; ]*"..param_name..".*=.*") ~= nil then line = param_name.." = "..param_value is_find_string = true end From a9408ed25fe31a1c0495ff766cb64b857ae8e553 Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Wed, 26 Sep 2018 15:32:12 -0400 Subject: [PATCH 658/681] Fix error when registering non-audio app --- user_modules/sequences/actions.lua | 9 ++++++++- user_modules/shared_testcases/commonFunctions.lua | 9 +++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/user_modules/sequences/actions.lua b/user_modules/sequences/actions.lua index c59c655d85..281b69b31a 100644 --- a/user_modules/sequences/actions.lua +++ b/user_modules/sequences/actions.lua @@ -156,8 +156,15 @@ function m.activateApp(pAppId) if not pAppId then pAppId = 1 end local requestId = m.getHMIConnection():SendRequest("SDL.ActivateApp", { appID = m.getHMIAppId(pAppId) }) m.getHMIConnection():ExpectResponse(requestId) + local params = m.getConfigAppParams(pAppId) + local audioStreamingState = "NOT_AUDIBLE" + if params.isMediaApplication or + commonFunctions:table_contains(params.appHMIType, "NAVIGATION") or + commonFunctions:table_contains(params.appHMIType, "COMMUNICATION") then + audioStreamingState = "AUDIBLE" + end m.getMobileSession(pAppId):ExpectNotification("OnHMIStatus", - { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) + { hmiLevel = "FULL", audioStreamingState = audioStreamingState, systemContext = "MAIN" }) utils.wait() end diff --git a/user_modules/shared_testcases/commonFunctions.lua b/user_modules/shared_testcases/commonFunctions.lua index 750e969528..398c7be0d4 100644 --- a/user_modules/shared_testcases/commonFunctions.lua +++ b/user_modules/shared_testcases/commonFunctions.lua @@ -335,6 +335,14 @@ function commonFunctions:is_table_equal(table1, table2) end return true end + +function commonFunctions:table_contains(table, value) + if not table then return false end + for _,val in pairs(table) do + if val == value then return true end + end + return false +end --------------------------------------------------------------------------------------------- @@ -926,6 +934,7 @@ function commonFunctions:write_parameter_to_smart_device_link_ini(param_name, pa end new_file_content = new_file_content..line.."\n" end + if is_find_string == true then local file = io.open(path_to_ini_file, "w") if file then From cee93234779ac0e6d67b72c12e379878629e4c0a Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Wed, 26 Sep 2018 15:40:25 -0400 Subject: [PATCH 659/681] Fix typo --- test_scripts/SDL5_0/ConditionalResumption/common.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/SDL5_0/ConditionalResumption/common.lua b/test_scripts/SDL5_0/ConditionalResumption/common.lua index bb8d3ef996..57d2a262aa 100644 --- a/test_scripts/SDL5_0/ConditionalResumption/common.lua +++ b/test_scripts/SDL5_0/ConditionalResumption/common.lua @@ -31,7 +31,7 @@ common.appHMITypesByOption = { Default = {"DEFAULT"}, Communication = {"COMMUNICATION"}, Media = {"MEDIA"}, - Messaging = {"COMMUNICATION"}, + Messaging = {"MESSAGING"}, Navigation = {"NAVIGATION"}, Information = {"INFORMATION"}, Social = {"SOCIAL"}, From 9a5334288a808f8a1ebca9fb97b8b7950f8befcf Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Thu, 27 Sep 2018 00:25:46 +0300 Subject: [PATCH 660/681] Correct validation of result on URLs cycling during PTU retry sequence --- ...gh_The_URLs_During_Retry_Sequence_HTTP.lua | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/test_scripts/Policies/build_options/097_ATF_PTU_Cycleing_Through_The_URLs_During_Retry_Sequence_HTTP.lua b/test_scripts/Policies/build_options/097_ATF_PTU_Cycleing_Through_The_URLs_During_Retry_Sequence_HTTP.lua index 0ac042164e..3b7d257a4a 100644 --- a/test_scripts/Policies/build_options/097_ATF_PTU_Cycleing_Through_The_URLs_During_Retry_Sequence_HTTP.lua +++ b/test_scripts/Policies/build_options/097_ATF_PTU_Cycleing_Through_The_URLs_During_Retry_Sequence_HTTP.lua @@ -78,6 +78,12 @@ function Test:Update_LPT() EXPECT_RESPONSE(corId, { success = true, resultCode = "SUCCESS" }) end +function Test:ActivateNewApp() + local RequestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = self.applications["Test Application"] }) + EXPECT_HMIRESPONSE(RequestId) + self.mobileSession:ExpectNotification("OnHMIStatus", { hmiLevel = "FULL" }) +end + --[[ Test ]] commonFunctions:newTestCasesGroup("Test") @@ -123,20 +129,20 @@ function Test.ShowSequence() print("--------------------------------------------------") end --- function Test.print() --- print_table(r_expected) --- print_table(r_actual) --- end - -for i = 1, 4 do - Test["ValidateResult" .. i] = function(self) - if(r_actual[i] ~= nil) then - if r_expected[i] ~= r_actual[i] then - local m = table.concat({"\nExpected url:\n", tostring(r_expected[i]), "\nActual:\n", tostring(r_actual[i]), "\n"}) - self:FailTestCase(m) +function Test:ValidateResult() + local function contains(pTbl, pItem) + for _, e in pairs(pTbl) do + if e == pItem then return true end + end + return false + end + if #r_actual ~= #r_expected then + self:FailTestCase("\nExpected number of requests: " .. #r_expected .. ", actual: " .. #r_actual) + else + for _, e in pairs(r_expected) do + if not contains(r_actual, e) then + self:FailTestCase("\nExpected item '" .. e .."' is not found") end - else - self:FailTestCase("Actual url is empty") end end end From e7b7a262ff6e4777bac2985b258b76fb5bd2e437 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 28 Sep 2018 17:33:07 +0300 Subject: [PATCH 661/681] Add extended timeout for request --- .../111_ATF_Start_PTU_retry_sequence_PROPRIETARY.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/test_scripts/Policies/build_options/111_ATF_Start_PTU_retry_sequence_PROPRIETARY.lua b/test_scripts/Policies/build_options/111_ATF_Start_PTU_retry_sequence_PROPRIETARY.lua index 24108cb111..6fae508fd9 100644 --- a/test_scripts/Policies/build_options/111_ATF_Start_PTU_retry_sequence_PROPRIETARY.lua +++ b/test_scripts/Policies/build_options/111_ATF_Start_PTU_retry_sequence_PROPRIETARY.lua @@ -112,6 +112,7 @@ function Test:TestStep_RetrySequenceStart() EXPECT_HMICALL("BasicCommunication.PolicyUpdate"):Times(0) self.mobileSession:ExpectNotification("OnSystemRequest", { requestType = "PROPRIETARY" }):Times(1) + :Timeout(40000) commonTestCases:DelayedExp(40000) end From 8dcd64056a46f3cb9fbe56739c2c41828e671ef1 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Fri, 28 Sep 2018 17:34:16 +0300 Subject: [PATCH 662/681] Remove script 102 since requirement is covered in 111 --- ...TF_Timeout_countdown_start_PROPRIETARY.lua | 103 ------------------ .../policies_happy_paths_PROPRIETARY.txt | 1 - 2 files changed, 104 deletions(-) delete mode 100644 test_scripts/Policies/build_options/102_ATF_Timeout_countdown_start_PROPRIETARY.lua diff --git a/test_scripts/Policies/build_options/102_ATF_Timeout_countdown_start_PROPRIETARY.lua b/test_scripts/Policies/build_options/102_ATF_Timeout_countdown_start_PROPRIETARY.lua deleted file mode 100644 index c30017aa63..0000000000 --- a/test_scripts/Policies/build_options/102_ATF_Timeout_countdown_start_PROPRIETARY.lua +++ /dev/null @@ -1,103 +0,0 @@ --- Requirements summary: --- [PolicyTableUpdate] "timeout" countdown start --- --- Description: --- SDL must forward OnSystemRequest(request_type=PROPRIETARY, url, appID) with encrypted PTS --- snapshot as a hybrid data to mobile application with value. "fileType" must be --- assigned as "JSON" in mobile app notification. --- 1. Used preconditions --- SDL is built with "-DEXTENDED_POLICY: PROPRIETARY" flag --- Application is registered. --- PTU is requested. --- SDL->HMI: SDL.OnStatusUpdate(UPDATE_NEEDED) --- SDL->HMI:SDL.PolicyUpdate(file, timeout, retry[]) --- HMI -> SDL: SDL.GetURLs () --- HMI->SDL: BasicCommunication.OnSystemRequest ('url', requestType:PROPRIETARY, appID="default") --- SDL->app: OnSystemRequest ('url', requestType:PROPRIETARY, fileType="JSON", appID) --- 2. Performed steps --- Do not send SystemRequest from --- --- Expected result: --- SDL waits for SystemRequest response from within 'timeout' value, if no obtained, --- it starts retry sequence ---------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local commonSteps = require('user_modules/shared_testcases/commonSteps') -local commonFunctions = require('user_modules/shared_testcases/commonFunctions') -local testCasesForPolicyTableSnapshot = require('user_modules/shared_testcases/testCasesForPolicyTableSnapshot') - ---[[ Local Functions ]] -local function timestamp() - local f = io.popen("date +%s") - local o = f:read("*all") - f:close() - return (o:gsub("\n", "")) -end - ---[[ General Precondition before ATF start ]] -commonFunctions:SDLForceStop() -commonSteps:DeleteLogsFileAndPolicyTable() - ---ToDo: shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed -config.defaultProtocolVersion = 2 - ---[[ General Settings for configuration ]] -Test = require('connecttest') -require('cardinalities') -require('user_modules/AppTypes') - ---[[ Test ]] -commonFunctions:newTestCasesGroup("Test") -function Test:TestStep_Sending_PTS_to_mobile_application() - local time_system_request = {} - local is_test_fail = false - - local RequestId_GetUrls = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) - EXPECT_HMIRESPONSE(RequestId_GetUrls) - :Do(function() - self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest",{ requestType = "PROPRIETARY", fileName = "PolicyTableUpdate" }) - --first retry sequence - local seconds_between_retries = {} - local timeout_pts = testCasesForPolicyTableSnapshot:get_data_from_PTS("module_config.timeout_after_x_seconds") - for i = 1, #testCasesForPolicyTableSnapshot.pts_seconds_between_retries do - seconds_between_retries[i] = testCasesForPolicyTableSnapshot.pts_seconds_between_retries[i].value - end - local time_wait = (timeout_pts*seconds_between_retries[1]*1000 + 10000) - local function verify_retry_sequence() - local time_1 = timestamp() -- time PolicyUpdate - local time_2 = time_system_request[#time_system_request] - local timeout = (time_1 - time_2) - if( ( timeout > (timeout_pts + 2) ) or ( timeout < (timeout_pts - 2) )) then - is_test_fail = true - commonFunctions:printError("ERROR: timeout for first retry sequence is not as expected: "..timeout_pts.." sec (5 sec tolerance). real: "..timeout.." sec") - else - print("timeout is as expected: "..timeout_pts.." sec. real: "..timeout) - end - end - EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY", fileType = "JSON"}) - :Do(function() time_system_request[#time_system_request + 1] = timestamp() end) - EXPECT_HMICALL("BasicCommunication.PolicyUpdate") - :Do(function(exp,data) - if(exp.occurences > 1) then - is_test_fail = true - commonFunctions:printError("ERROR: PTU sequence is restarted again!") - end - verify_retry_sequence() - self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) - end) - :Timeout(time_wait) - end) - - if(is_test_fail == true) then - self:FailTestCase("Test is FAILED. See prints.") - end -end - ---[[ Postconditions ]] -commonFunctions:newTestCasesGroup("Postconditions") - -function Test.Postcondition_Force_Stop_SDL() - StopSDL() -end - -return Test diff --git a/test_sets/policies_happy_paths_PROPRIETARY.txt b/test_sets/policies_happy_paths_PROPRIETARY.txt index 9afb19e82a..08c4d710f2 100644 --- a/test_sets/policies_happy_paths_PROPRIETARY.txt +++ b/test_sets/policies_happy_paths_PROPRIETARY.txt @@ -8,7 +8,6 @@ ./test_scripts/Policies/build_options/096_ATF_SDL_Send_PolicyUpdat_To_HMI_In_Case_PTU_Is_Triggered_PROPRIETARY.lua ./test_scripts/Policies/build_options/099_ATF_SDL_Send_BC_PolicyUpdate_To_HMI_In_Case_PTU_Is_Triggered_PROPRIETARY.lua ./test_scripts/Policies/build_options/100_ATF_PTU_Transfer_Several_Apps_Different_HMI_Levels_PROPRIETARY.lua -./test_scripts/Policies/build_options/102_ATF_Timeout_countdown_start_PROPRIETARY.lua ./test_scripts/Policies/build_options/103_ATF_Timeout_wait_response_PTU_PROPRIETARY.lua ./test_scripts/Policies/build_options/104_ATF_Transfer_OnSystemRequest_toApp_PROPRIETARY.lua ./test_scripts/Policies/build_options/105_ATF_PM_change_status_UPDATE_NEEDED_after_timeout_expired_PROPRIETARY.lua From 41fb73c58e5940f2451841a42b5f99d02830142f Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 1 Oct 2018 10:49:24 +0300 Subject: [PATCH 663/681] Correct expected result for LIMITED and keepContext=true --- ..._audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua index 1e3abb62d8..c072875918 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/SetInteriorVehicleData/016_Change_audio_source_from_MOBILE_APP_keepContext_true_LIMITED.lua @@ -12,7 +12,7 @@ -- 3) App tries to change audio source from MOBILE_APP with keepContext = true -- SDL must: -- 1) Change audio source successfully --- 2) Change HMI level to BACKGROUND and change audioStreamingState to "NOT_AUDIBLE" +-- 2) Not change HMI level, but change audioStreamingState to "NOT_AUDIBLE" --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -68,7 +68,7 @@ local function setVehicleData() end) mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS" }) mobSession:ExpectNotification("OnHMIStatus", - { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + { hmiLevel = "LIMITED", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) end local function bringAppToLIMITED() From cb4bacb505f9e088b391b252ffe86c653e10001b Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 1 Oct 2018 11:56:48 +0300 Subject: [PATCH 664/681] Change number of expected OnStreaming notifications --- .../MobileProjection/Phase2/019_SDL_stop_audio_video.lua | 4 ++-- .../Phase2/smoke/019_SDL_stop_audio_video.lua | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua b/test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua index a443c6ae1a..bf52f8a6a5 100644 --- a/test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua +++ b/test_scripts/MobileProjection/Phase2/019_SDL_stop_audio_video.lua @@ -89,8 +89,8 @@ local function changeAudioSource() videoStreamingState = "NOT_STREAMABLE" }) common.wait(2000) - common.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = false }) - common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = false }) + common.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = false }):Times(AtLeast(1)) + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = false }):Times(AtLeast(1)) common.getHMIConnection():ExpectRequest("Navigation.StopAudioStream", { appID = common.getHMIAppId() }) :Do(function(_, data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) diff --git a/test_scripts/MobileProjection/Phase2/smoke/019_SDL_stop_audio_video.lua b/test_scripts/MobileProjection/Phase2/smoke/019_SDL_stop_audio_video.lua index a443c6ae1a..bf52f8a6a5 100644 --- a/test_scripts/MobileProjection/Phase2/smoke/019_SDL_stop_audio_video.lua +++ b/test_scripts/MobileProjection/Phase2/smoke/019_SDL_stop_audio_video.lua @@ -89,8 +89,8 @@ local function changeAudioSource() videoStreamingState = "NOT_STREAMABLE" }) common.wait(2000) - common.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = false }) - common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = false }) + common.getHMIConnection():ExpectNotification("Navigation.OnAudioDataStreaming", { available = false }):Times(AtLeast(1)) + common.getHMIConnection():ExpectNotification("Navigation.OnVideoDataStreaming", { available = false }):Times(AtLeast(1)) common.getHMIConnection():ExpectRequest("Navigation.StopAudioStream", { appID = common.getHMIAppId() }) :Do(function(_, data) common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", {}) From b9d09a9f70291717e69dba4ede5c721750868198 Mon Sep 17 00:00:00 2001 From: igapchuck Date: Mon, 27 Aug 2018 10:26:12 +0300 Subject: [PATCH 665/681] Sript for reproduce defect 2447. Resumption: revoked app still be resumed as FULL. --- ...n_revoked_app_still_be_resumed_as_FULL.lua | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 test_scripts/Defects/5_0/2447_Resumption_revoked_app_still_be_resumed_as_FULL.lua diff --git a/test_scripts/Defects/5_0/2447_Resumption_revoked_app_still_be_resumed_as_FULL.lua b/test_scripts/Defects/5_0/2447_Resumption_revoked_app_still_be_resumed_as_FULL.lua new file mode 100644 index 0000000000..438aaf338f --- /dev/null +++ b/test_scripts/Defects/5_0/2447_Resumption_revoked_app_still_be_resumed_as_FULL.lua @@ -0,0 +1,98 @@ +---------------------------------------------------------------------------------------------------- +-- GitHub issue: https://github.com/smartdevicelink/sdl_core/issues/2447 +---------------------------------------------------------------------------------------------------- +-- Reproduction Steps: +-- 1) Register app with name = App1 and Id = 999 with uncheck Policy File Update +-- 2) Enter FULL +-- 3) Force stop application +-- 4) Start SPT then register another app and send LPT update. Then app in step 1 becomes revoked +-- 5) Register app with name = App1 and Id = 999 + +-- Expected Behavior: +-- SDL can't resume App1 as FULL +---------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('user_modules/sequences/actions') +local json = require('modules/json') +local utils = require("user_modules/utils") +local test = require("user_modules/dummy_connecttest") + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function PTUFuncToClearApp1Policy(tbl) + tbl.policy_table.app_policies[common.getConfigAppParams(1).fullAppID] = json.null +end + +local function cleanMobileSessions() + for i = 1, #test.mobileSession do + test.mobileSession[i] = nil + end +end + +local function unexpectedDisconnect() + common.getMobileConnection():Close() + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppUnregistered", + { unexpectedDisconnect = true }) +end + +local function reconnectMobileConnection() + common.getMobileConnection():Connect() +end + +local function checkAppIsNotResumed(pAppId) + common.getHMIConnection():ExpectRequest("BasicCommunication.ActivateApp") + :Times(0) + common.getMobileSession(pAppId):ExpectNotification("OnHMIStatus") + :Times(0) + utils.wait(10000) +end + +local function registerApp(pAppId, pParamsId, pTimePolicyUpdate) + if not pAppId then pAppId = 1 end + common.getMobileSession(pAppId):StartService(7) + :Do(function() + local corId = common.getMobileSession(pAppId):SendRPC("RegisterAppInterface", common.getConfigAppParams(pParamsId)) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", + { application = { appName = common.getConfigAppParams(pParamsId).appName } }) + :Do(function(_, d1) + common.setHMIAppId(d1.params.application.appID, pAppId) + common.getHMIConnection():ExpectRequest("BasicCommunication.PolicyUpdate") + :Do(function(_, d2) + common.getHMIConnection():SendResponse(d2.id, d2.method, "SUCCESS", { }) + end) + :Times(pTimePolicyUpdate) + end) + common.getMobileSession(pAppId):ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + common.getMobileSession(pAppId):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + common.getMobileSession(pAppId):ExpectNotification("OnPermissionsChange") + :Times(AnyNumber()) + end) + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) + +runner.Title("Test") +runner.Step("Register App1", common.registerApp, { 1 }) +-- update is performed because of SDL issue +runner.Step("PTU, revoke App1", common.policyTableUpdate) +runner.Step("Activate App1", common.activateApp, { 1 }) +runner.Step("Force stop App1", unexpectedDisconnect) +runner.Step("CleanMobileSessions", cleanMobileSessions) +runner.Step("Reopen mobile connection", reconnectMobileConnection) + +-- fuction registerApp is redefined because of ATF issue +runner.Step("Register App2", registerApp, { 1, 2, 1 }) +runner.Step("PTU, revoke App1", common.policyTableUpdate, { PTUFuncToClearApp1Policy }) +runner.Step("Register App1", registerApp, { 2, 1, 0 }) +runner.Step("Check App1 is not resumed in FULL", checkAppIsNotResumed, { 2 }) +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From ab020c9e3eb9c67019d7ca902c580d80dfc836cd Mon Sep 17 00:00:00 2001 From: Myza Taras Date: Fri, 21 Sep 2018 17:45:30 +0300 Subject: [PATCH 666/681] Script for defect 2480 --- ...DD_notification_once_upon_registration.lua | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 test_scripts/Defects/5_0/2480_Vefiry_that_SDL_sends_OnDD_notification_once_upon_registration.lua diff --git a/test_scripts/Defects/5_0/2480_Vefiry_that_SDL_sends_OnDD_notification_once_upon_registration.lua b/test_scripts/Defects/5_0/2480_Vefiry_that_SDL_sends_OnDD_notification_once_upon_registration.lua new file mode 100644 index 0000000000..e994692876 --- /dev/null +++ b/test_scripts/Defects/5_0/2480_Vefiry_that_SDL_sends_OnDD_notification_once_upon_registration.lua @@ -0,0 +1,84 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/2480 +-- +-- Description: +-- Many DD_ OFF notifications are received. +-- Pre-conditions: +-- 1) Vehicle Ignition On and Running +-- Steps to reproduce: +-- 1) Perform Master Reset +-- 2) Connect device +-- 3) Register 2 apps +-- 4) HMI sends DD notifications with DD_ON and DD_OFF +-- Expected: +-- 1) DD notifications received after each app registration and after receiving DD notification from HMI +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('user_modules/sequences/actions') +local utils = require('user_modules/utils') + +-- [[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Variables ]] +local OnDDValue = { "DD_ON", "DD_OFF" } + +--[[ Local Functions ]] +local function rai_n(pAppId) + common.getMobileSession(pAppId):StartService(7) + :Do(function() + local corId = common.getMobileSession(pAppId):SendRPC("RegisterAppInterface", common.getConfigAppParams(pAppId)) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppRegistered", + { application = { appName = common.getConfigAppParams(pAppId).appName } }) + :Do(function(_, d1) + common.setHMIAppId(d1.params.application.appID, pAppId) + end) + common.getMobileSession(pAppId):ExpectResponse(corId, { success = true, resultCode = "SUCCESS" }) + :Do(function() + common.getMobileSession(pAppId):ExpectNotification("OnHMIStatus", + { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) + :Times(1) + common.getMobileSession(pAppId):ExpectNotification("OnPermissionsChange") + common.getMobileSession(pAppId):ExpectNotification("OnDriverDistraction", { state = "DD_OFF" }) + if pAppId == 2 then + common.getMobileSession(1):ExpectNotification("OnDriverDistraction") + :Times(0) + end + end) + end) +end + +local function onDriverDistraction(pOnDDValue) + local request = { state = pOnDDValue } + common.getHMIConnection():SendNotification("UI.OnDriverDistraction", request) + common.getMobileSession(1):ExpectNotification("OnDriverDistraction", request) + common.getMobileSession(2):ExpectNotification("OnDriverDistraction", request) + utils.wait(6000) +end + +local function masterReset() + common.getHMIConnection():SendNotification("BasicCommunication.OnExitAllApplications", {reason = "MASTER_RESET"}) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + :Do(function() + StopSDL() + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("Master reset", masterReset) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("RAI_first_app", rai_n, { 1, true }) +runner.Step("RAI_second_app", rai_n, { 2, true }) + +runner.Title("Test") +for _, v in pairs(OnDDValue) do + runner.Step("OnDriverDistraction with state " .. v .. " Positive Case", onDriverDistraction, { v }) +end + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From 6db58abe1d8a378921f0f225173ef3d2a79edb67 Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Wed, 3 Oct 2018 14:18:00 -0400 Subject: [PATCH 667/681] Fix broken policy tests on fix/allow_user_consent_for_default_group branch of Core --- .../PTU_with_permissions_for_app_1234567.json | 16 ++- .../003_ATF_HP_User_Consent_Yes.lua | 103 ++++++------------ .../004_ATF_HP_User_Consent_NO.lua | 79 ++++++-------- ...egister_App_Interface_App_Unauthorized.lua | 2 +- ...Interface_Order_Of_Nickname_Validation.lua | 2 +- .../189_ATF_isAppPermissionsRevoked_true.lua | 7 +- 6 files changed, 78 insertions(+), 131 deletions(-) diff --git a/files/PTU_with_permissions_for_app_1234567.json b/files/PTU_with_permissions_for_app_1234567.json index 7234d411c9..4f68fc2f54 100644 --- a/files/PTU_with_permissions_for_app_1234567.json +++ b/files/PTU_with_permissions_for_app_1234567.json @@ -254,16 +254,14 @@ } }, "Permission_for_1234567": { - "user_consent_prompt": "New_permissions", + "user_consent_prompt": "New_permissions", "rpcs": { - "OnHMIStatus": { "hmi_levels": ["BACKGROUND", "FULL", "LIMITED", "NONE"] }, - "OnPermissionsChange": { "hmi_levels": ["BACKGROUND", "FULL", @@ -276,20 +274,17 @@ "LIMITED", "NONE"] }, - "Show": { "hmi_levels": ["BACKGROUND", "FULL", "LIMITED"] }, - "SystemRequest": { "hmi_levels": ["BACKGROUND", "FULL", "LIMITED", "NONE"] } - } }, "DialNumberOnly": { @@ -698,6 +693,15 @@ "consumer_friendly_messages": { "version": "001.001.024", "messages": { + "New_permissions": { + "languages": { + "en-us": { + "tts": "TTS value", + "line1": "Line 1", + "line2": "Line 2" + } + } + }, "AppPermissions": { "languages": { "de-de": { diff --git a/test_scripts/Policies/App_Permissions/003_ATF_HP_User_Consent_Yes.lua b/test_scripts/Policies/App_Permissions/003_ATF_HP_User_Consent_Yes.lua index 3fa5923832..609d8e8a8c 100644 --- a/test_scripts/Policies/App_Permissions/003_ATF_HP_User_Consent_Yes.lua +++ b/test_scripts/Policies/App_Permissions/003_ATF_HP_User_Consent_Yes.lua @@ -48,31 +48,6 @@ commonPreconditions:Connecttest_without_ExitBySDLDisconnect_WithoutOpenConnectio --TODO(istoimenova): shall be removed when issue: "ATF does not stop HB timers by closing session and connection" is fixed config.defaultProtocolVersion = 2 ---[[ Local variables ]] -local RPC_Permission_for_1234567 = {} - ---[[ Local Functions ]] -local function Get_RPCs() - --Permission_for_1234567 - testCasesForPolicyTableSnapshot:extract_pts() - - for i = 1, #testCasesForPolicyTableSnapshot.pts_elements do - - if ( string.sub(testCasesForPolicyTableSnapshot.pts_elements[i].name,1,string.len("functional_groupings.Permission_for_1234567.rpcs.")) == "functional_groupings.Permission_for_1234567.rpcs." ) then - local str = string.match(testCasesForPolicyTableSnapshot.pts_elements[i].name, "functional_groupings%.Permission_for_1234567%.rpcs%.(%S+)%.%S+%.%S+") - if(#RPC_Permission_for_1234567 == 0) then - RPC_Permission_for_1234567[#RPC_Permission_for_1234567 + 1] = str - end - - if(RPC_Permission_for_1234567[#RPC_Permission_for_1234567] ~= str) then - RPC_Permission_for_1234567[#RPC_Permission_for_1234567 + 1] = str - -- allowed_rps[#allowed_rps + 1] = str - end - end - end - -end - --[[ General Settings for configuration ]] Test = require('user_modules/connecttest_connect_device') require('cardinalities') @@ -162,49 +137,35 @@ function Test:Precondition_Activate_App_And_Consent_Device() EXPECT_RESPONSE(CorIdRAI, { success = true, resultCode = "SUCCESS"}) end -function Test:Precondition_DeactivateApp() - self.hmiConnection:SendNotification("BasicCommunication.OnAppDeactivated", {appID = self.applications["SPT"], reason = "GENERAL"}) - EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "LIMITED"}) -end - function Test:Precondition_UpdatePolicyWithPTU() + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" + .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATING" }, { status = "UP_TO_DATE" }):Times(2) local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() - self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", - { + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", - fileName = "filename" + fileName = pts_file_name } ) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) :Do(function() - local CorIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", - { - fileName = "PolicyTableUpdate", - requestType = "PROPRIETARY" - }, "files/PTU_with_permissions_for_app_1234567.json") - local systemRequestId + local CorIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", { + requestType = "PROPRIETARY" }, "files/PTU_with_permissions_for_app_1234567.json") EXPECT_HMICALL("BasicCommunication.SystemRequest") - :Do(function(_,data) - systemRequestId = data.id - self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", - { - policyfile = "/tmp/fs/mp/images/ivsu_cache/PolicyTableUpdate" - }) - local function to_run() - self.hmiConnection:SendResponse(systemRequestId,"BasicCommunication.SystemRequest", "SUCCESS", {}) - end - RUN_AFTER(to_run, 800) - self.mobileSession:ExpectResponse(CorIdSystemRequest, {success = true, resultCode = "SUCCESS"}) + :Do(function(_, data) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = data.params.fileName }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) + self.mobileSession:ExpectResponse(CorIdSystemRequest, { success = true, resultCode = "SUCCESS" }) end) end) end --[[ Test ]] function Test:TestStep_User_Consents_New_Permissions_After_App_Activation() - Get_RPCs() + self.hmiConnection:SendNotification("BasicCommunication.OnAppDeactivated", {appID = self.applications["SPT"], reason = "GENERAL"}) local RequestIdActivateApp = self.hmiConnection:SendRequest("SDL.ActivateApp", {appID = self.applications["SPT"]}) EXPECT_HMIRESPONSE(RequestIdActivateApp, @@ -214,25 +175,26 @@ function Test:TestStep_User_Consents_New_Permissions_After_App_Activation() isAppPermissionsRevoked = false, isAppRevoked = false}, method = "SDL.ActivateApp"}) - - local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) - EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage, - { result = { code = 0, - messages = {{ messageCode = "DataConsent"}}, - method = "SDL.GetUserFriendlyMessage"}}) - - local RequestIdListOfPermissions = self.hmiConnection:SendRequest("SDL.GetListOfPermissions", { appID = self.applications["SPT"] }) - EXPECT_HMIRESPONSE(RequestIdListOfPermissions, - { result = { - code = 0, - allowedFunctions = {{name = "New_permissions"}} }, - method = "SDL.GetListOfPermissions"}) - :Do(function(_,data) - local functionalGroupID = data.result.allowedFunctions[1].id - self.hmiConnection:SendNotification("SDL.OnAppPermissionConsent", - { appID = self.applications["SPT"], source = "GUI", consentedFunctions = {{name = "New_permissions", allowed = true, id = functionalGroupID} }}) - end) - EXPECT_NOTIFICATION("OnPermissionsChange", {}) + :Do(function() + local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"New_permissions"}}) + EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage, + { result = { code = 0, + messages = {{ messageCode = "New_permissions"}}, + method = "SDL.GetUserFriendlyMessage"}}) + + local RequestIdListOfPermissions = self.hmiConnection:SendRequest("SDL.GetListOfPermissions", { appID = self.applications["SPT"] }) + EXPECT_HMIRESPONSE(RequestIdListOfPermissions, + { result = { + code = 0, + allowedFunctions = {{name = "New_permissions"}} }, + method = "SDL.GetListOfPermissions"}) + :Do(function(_,data) + local functionalGroupID = data.result.allowedFunctions[1].id + self.hmiConnection:SendNotification("SDL.OnAppPermissionConsent", + { appID = self.applications["SPT"], source = "GUI", consentedFunctions = {{name = "New_permissions", allowed = true, id = functionalGroupID} }}) + end) + EXPECT_NOTIFICATION("OnPermissionsChange", {}) + end) end function Test:TestStep_Check_Allowed_RPC() @@ -260,7 +222,6 @@ end --[[ Postconditions ]] commonFunctions:newTestCasesGroup("Postconditions") -testCasesForPolicyTable:Restore_preloaded_pt() function Test.Postcondition_StopSDL() StopSDL() end diff --git a/test_scripts/Policies/App_Permissions/004_ATF_HP_User_Consent_NO.lua b/test_scripts/Policies/App_Permissions/004_ATF_HP_User_Consent_NO.lua index 19e34c905c..816c3deadf 100644 --- a/test_scripts/Policies/App_Permissions/004_ATF_HP_User_Consent_NO.lua +++ b/test_scripts/Policies/App_Permissions/004_ATF_HP_User_Consent_NO.lua @@ -136,48 +136,35 @@ function Test:Precondition_Activate_App_And_Consent_Device() EXPECT_RESPONSE(CorIdRAI, { success = true, resultCode = "SUCCESS"}) end -function Test:Precondition_DeactivateApp() - self.hmiConnection:SendNotification("BasicCommunication.OnAppDeactivated", {appID = self.applications["SPT"], reason = "GENERAL"}) - EXPECT_NOTIFICATION("OnHMIStatus", {hmiLevel = "LIMITED"}) -end - function Test:Precondition_UpdatePolicyWithPTU() + local pts_file_name = commonFunctions:read_parameter_from_smart_device_link_ini("SystemFilesPath") .. "/" + .. commonFunctions:read_parameter_from_smart_device_link_ini("PathToSnapshot") + EXPECT_HMINOTIFICATION("SDL.OnStatusUpdate", { status = "UPDATING" }, { status = "UP_TO_DATE" }):Times(2) local RequestIdGetURLS = self.hmiConnection:SendRequest("SDL.GetURLS", { service = 7 }) EXPECT_HMIRESPONSE(RequestIdGetURLS) :Do(function() - self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", - { + self.hmiConnection:SendNotification("BasicCommunication.OnSystemRequest", { requestType = "PROPRIETARY", - fileName = "filename" + fileName = pts_file_name } ) EXPECT_NOTIFICATION("OnSystemRequest", { requestType = "PROPRIETARY" }) :Do(function() - local CorIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", - { - fileName = "PolicyTableUpdate", - requestType = "PROPRIETARY" - }, "files/PTU_with_permissions_for_app_1234567.json") - local systemRequestId + local CorIdSystemRequest = self.mobileSession:SendRPC("SystemRequest", { + requestType = "PROPRIETARY" }, "files/PTU_with_permissions_for_app_1234567.json") EXPECT_HMICALL("BasicCommunication.SystemRequest") - :Do(function(_,data) - systemRequestId = data.id - self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", - { - policyfile = "/tmp/fs/mp/images/ivsu_cache/PolicyTableUpdate" - }) - local function to_run() - self.hmiConnection:SendResponse(systemRequestId,"BasicCommunication.SystemRequest", "SUCCESS", {}) - end - RUN_AFTER(to_run, 800) - self.mobileSession:ExpectResponse(CorIdSystemRequest, {success = true, resultCode = "SUCCESS"}) + :Do(function(_, data) + self.hmiConnection:SendNotification("SDL.OnReceivedPolicyUpdate", { policyfile = data.params.fileName }) + self.hmiConnection:SendResponse(data.id, data.method, "SUCCESS", {}) end) + self.mobileSession:ExpectResponse(CorIdSystemRequest, { success = true, resultCode = "SUCCESS" }) end) end) end --[[ Test ]] function Test:TestStep_User_Consents_New_Permissions_After_App_Activation() + self.hmiConnection:SendNotification("BasicCommunication.OnAppDeactivated", {appID = self.applications["SPT"], reason = "GENERAL"}) local RequestIdActivateApp = self.hmiConnection:SendRequest("SDL.ActivateApp", {appID = self.applications["SPT"]}) EXPECT_HMIRESPONSE(RequestIdActivateApp, @@ -187,26 +174,27 @@ function Test:TestStep_User_Consents_New_Permissions_After_App_Activation() isAppPermissionsRevoked = false, isAppRevoked = false}, method = "SDL.ActivateApp"}) - - local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"DataConsent"}}) - EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage, - { result = { code = 0, - messages = {{ messageCode = "DataConsent"}}, - method = "SDL.GetUserFriendlyMessage"}}) - - local RequestIdListOfPermissions = self.hmiConnection:SendRequest("SDL.GetListOfPermissions", { appID = self.applications["SPT"] }) - EXPECT_HMIRESPONSE(RequestIdListOfPermissions, - { result = { - code = 0, - allowedFunctions = {{name = "New_permissions"}} }, - method = "SDL.GetListOfPermissions"}) - :Do(function(_,data) - local functionalGroupID = data.result.allowedFunctions[1].id - self.hmiConnection:SendNotification("SDL.OnAppPermissionConsent", - { appID = self.applications["SPT"], source = "GUI", consentedFunctions = {{name = "New_permissions", allowed = false, id = functionalGroupID} }}) - end) - EXPECT_NOTIFICATION("OnPermissionsChange", {}):Times(0) - commonTestCases:DelayedExp(5000) + :Do(function() + local RequestIdGetUserFriendlyMessage = self.hmiConnection:SendRequest("SDL.GetUserFriendlyMessage", {language = "EN-US", messageCodes = {"New_permissions"}}) + EXPECT_HMIRESPONSE(RequestIdGetUserFriendlyMessage, + { result = { code = 0, + messages = {{ messageCode = "New_permissions"}}, + method = "SDL.GetUserFriendlyMessage"}}) + + local RequestIdListOfPermissions = self.hmiConnection:SendRequest("SDL.GetListOfPermissions", { appID = self.applications["SPT"] }) + EXPECT_HMIRESPONSE(RequestIdListOfPermissions, + { result = { + code = 0, + allowedFunctions = {{name = "New_permissions"}} }, + method = "SDL.GetListOfPermissions"}) + :Do(function(_,data) + local functionalGroupID = data.result.allowedFunctions[1].id + self.hmiConnection:SendNotification("SDL.OnAppPermissionConsent", + { appID = self.applications["SPT"], source = "GUI", consentedFunctions = {{name = "New_permissions", allowed = false, id = functionalGroupID} }}) + end) + EXPECT_NOTIFICATION("OnPermissionsChange", {}):Times(0) + commonTestCases:DelayedExp(5000) + end) end function Test:TestStep_Check_RPC_Disallowed_By_User() @@ -221,7 +209,6 @@ end --[[ Postconditions ]] commonFunctions:newTestCasesGroup("Postconditions") -testCasesForPolicyTable:Restore_preloaded_pt() function Test.Postcondition_StopSDL() StopSDL() end diff --git a/test_scripts/Policies/appID_Management/031_ATF_Register_App_Interface_App_Unauthorized.lua b/test_scripts/Policies/appID_Management/031_ATF_Register_App_Interface_App_Unauthorized.lua index 2a93180000..1c281e84dc 100644 --- a/test_scripts/Policies/appID_Management/031_ATF_Register_App_Interface_App_Unauthorized.lua +++ b/test_scripts/Policies/appID_Management/031_ATF_Register_App_Interface_App_Unauthorized.lua @@ -40,7 +40,7 @@ local mobileSession = require("mobile_session") --[[ Preconditions ]] commonFunctions:newTestCasesGroup("Preconditions") -function Test:Pecondition_trigger_getting_device_consent() +function Test:Precondition_trigger_getting_device_consent() testCasesForPolicyTable:trigger_getting_device_consent(self, config.application1.registerAppInterfaceParams.appName, utils.getDeviceMAC()) end diff --git a/test_scripts/Policies/appID_Management/033_ATF_Register_App_Interface_Order_Of_Nickname_Validation.lua b/test_scripts/Policies/appID_Management/033_ATF_Register_App_Interface_Order_Of_Nickname_Validation.lua index a3f72c8823..7b82d2675a 100644 --- a/test_scripts/Policies/appID_Management/033_ATF_Register_App_Interface_Order_Of_Nickname_Validation.lua +++ b/test_scripts/Policies/appID_Management/033_ATF_Register_App_Interface_Order_Of_Nickname_Validation.lua @@ -55,7 +55,7 @@ end --[[ Test ]] commonFunctions:newTestCasesGroup("Test") function Test:RegisterNewApp() - config.application2.registerAppInterfaceParams.appName = config.application1.registerAppInterfaceParams.appName + config.application2.registerAppInterfaceParams.appName = "INCORRECT_NAME" config.application2.registerAppInterfaceParams.fullAppID = "123_xyz" local corId = self.mobileSession2:SendRPC("RegisterAppInterface", config.application2.registerAppInterfaceParams) self.mobileSession2:ExpectResponse(corId, { success = false, resultCode = "DISALLOWED" }) diff --git a/test_scripts/Policies/user_consent_of_Policies/189_ATF_isAppPermissionsRevoked_true.lua b/test_scripts/Policies/user_consent_of_Policies/189_ATF_isAppPermissionsRevoked_true.lua index 997d638144..f7b7cdd24d 100644 --- a/test_scripts/Policies/user_consent_of_Policies/189_ATF_isAppPermissionsRevoked_true.lua +++ b/test_scripts/Policies/user_consent_of_Policies/189_ATF_isAppPermissionsRevoked_true.lua @@ -180,12 +180,7 @@ function Test:TestStep_Activate_app_isAppPermissionRevoked_true() code = 0, method = "SDL.ActivateApp", isAppRevoked = false, - isAppPermissionsRevoked = true, - appRevokedPermissions = - { - { name = "DrivingCharacteristics"} - } - } + isAppPermissionsRevoked = false } }) end From a8a1a777fe09b29768378cc3a7bd93147bdf6614 Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Fri, 5 Oct 2018 15:01:02 -0400 Subject: [PATCH 668/681] Fixes tests where subscribe is omitted defvalue of subscribe is false, this corrects the expectations in the RC to account for this. --- ...t_response_from_HMI_with_isSubscribed.lua} | 15 ++---- ...t_response_from_HMI_with_isSubscribed.lua} | 44 ++++++++---------- .../000_cache_2_apps_sequence.lua | 12 ++--- ...D_with_subscription_after_OnInteriorVD.lua | 4 +- ...bscribe_false_different_modules_2_apps.lua | 2 +- ...teriorVD_limitation_after_subscription.lua | 2 +- ...imitation_rejected_after_unsubscribing.lua | 4 +- .../038_OnInteriorVD_one_parameter.lua | 4 +- ...t_response_from_HMI_with_isSubscribed.lua} | 46 +++++++++---------- .../SDL5_0/rc_AUDIO_LIGHT_HMI_SETTINGS.txt | 2 +- test_sets/SDL5_0/rc_CLIMATE_RADIO.txt | 2 +- test_sets/SDL5_0/rc_SEAT.txt | 2 +- test_sets/SDL5_0/sdl_5_0_test_suite.txt | 6 +-- test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt | 2 +- test_sets/rc_CLIMATE_RADIO.txt | 2 +- test_sets/rc_SEAT.txt | 2 +- 16 files changed, 66 insertions(+), 85 deletions(-) rename test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/{013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua => 013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua} (87%) rename test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/{013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua => 013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua} (68%) rename test_scripts/RC/SEAT/GetInteriorVehicleData/{011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua => 011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua} (65%) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua similarity index 87% rename from test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua rename to test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index 3be5a76c40..f7a34aec07 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -13,7 +13,7 @@ -- 3) and with "isSubscribed" parameter from HMI -- SDL must: -- 1) transfer GetInteriorVehicleData_response with resultCode: <"any-result"> --- and without "isSubscribed" param to the related app +-- and with "isSubscribed" param to the related app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -40,7 +40,7 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequestCo }) end) :ValidIf(function(_, data) -- no subscribe parameter - if data.params.subscribe == nil then + if (isSubscriptionActive and data.params.subscribe == false) or data.params.subscribe == nil then return true end return false, 'Parameter "subscribe" is transfered with to HMI value: ' .. tostring(data.params.subscribe) @@ -48,14 +48,9 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequestCo :Times(pHMIrequestCount) mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = common.getModuleControlDataForResponse(pModuleType) + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = isSubscriptionActive }) - :ValidIf(function(_, data) -- no isSubscribed parameter - if data.payload.isSubscribed == nil then - return true - end - return false, 'Parameter "isSubscribed" is transfered to App with value: ' .. tostring(data.payload.isSubscribed) - end) end --[[ Scenario ]] @@ -73,7 +68,7 @@ end for _, mod in pairs(common.modulesWithoutSeat) do runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) - runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true, 0 }) + runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true, 1 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua similarity index 68% rename from test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index a3331683c7..0b26bf531a 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -13,7 +13,7 @@ -- 3) and with "isSubscribed" parameter from HMI -- SDL must: -- 1) transfer GetInteriorVehicleData_response with resultCode: <"any-result"> --- and without "isSubscribed" param to the related app +-- and with "isSubscribed" param to the related app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -23,38 +23,34 @@ local commonRC = require('test_scripts/RC/commonRC') runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, isSubscriptionActive, pHMIRequest) - local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType - -- no subscribe parameter - }) +local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequestCount) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType + -- no subscribe parameter + }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - moduleType = pModuleType - }) + moduleType = pModuleType + }) :Do(function(_, data) - commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlData(pModuleType), - isSubscribed = isSubscriptionActive -- return current value of subscription - }) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = isSubscriptionActive -- return current value of subscription + }) end) :ValidIf(function(_, data) -- no subscribe parameter - if data.params.subscribe == nil then + if (isSubscriptionActive and data.params.subscribe == false) or data.params.subscribe == nil then return true end return false, 'Parameter "subscribe" is transfered with to HMI value: ' .. tostring(data.params.subscribe) end) - :Times(pHMIRequest) + :Times(pHMIrequestCount) - commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = commonRC.getModuleControlData(pModuleType) - }) - :ValidIf(function(_, data) -- no isSubscribed parameter - if data.payload.isSubscribed == nil then - return true - end - return false, 'Parameter "isSubscribed" is transfered to App with value: ' .. tostring(data.payload.isSubscribed) - end) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = isSubscriptionActive + }) end --[[ Scenario ]] @@ -72,7 +68,7 @@ end for _, mod in pairs(commonRC.modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) - runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true, 0 }) + runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true, 1 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua b/test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua index 19ec102972..eb0a676647 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua @@ -16,16 +16,14 @@ -- 8. App2 sends GetInteriorVD(module_1) without subscribe parameter -- 9. HMI sends OnInteriorVD(data for module_1) -- 10. App1 sends GetInteriorVD(module_1) with subscribe=false --- 11. App2 sends GetInteriorVD(module_1) with subscribe=false +-- 11. App2 sends GetInteriorVD(module_1) with subscribe=nil -- SDL must -- 1. send GetInteriorVD(module_1, without subscribe parameter, without appId) request to HMI by processing request from app1 -- 2. send GetInteriorVD(module_1, without subscribe parameter, without appId) request to HMI by processing request from app2 -- 3. send GetInteriorVD(module_1, subscribe=true, without appId) request to HMI by processing request from app1 -- 4. update data for module_1 in cache and send OnInteriorVD notification to mobile app1 -- 5. not send GetInteriorVD(module_1, subscribe=true, without appId) request to HMI by processing request from app1 --- 6. not send GetInteriorVD(module_1, without subscribe parameter, without appId) request to HMI by processing request from app1 -- 7. not send GetInteriorVD(module_1, subscribe=true, without appId) request to HMI by processing request from app2 --- 8. not send GetInteriorVD(module_1, without subscribe parameter, without appId) request to HMI by processing request from app2 -- 9. update data for module_1 in cache and send OnInteriorVD notification to mobile app1 and mobile app2 -- 10. not send GetInteriorVD(module_1, subscribe=false, without appId) request to HMI by processing request from app1 -- 11. send GetInteriorVD(module_1, subscribe=true, without appId) request to HMI by processing request from app2 @@ -66,20 +64,16 @@ for _, mod in pairs(common.modules) do { mod, true, 1 }) runner.Step("App1 GetInteriorVehicleData with subscribe=true without request to HMI " .. mod, common.GetInteriorVehicleData, { mod, true, false, 1 }) - runner.Step("App1 GetInteriorVehicleData without request to HMI " .. mod, common.GetInteriorVehicleData, - { mod, nil, false, 1 }) -- Block 'Subscribe app2' from diagram runner.Step("App2 GetInteriorVehicleData with subscribe=true without request to HMI" .. mod, common.GetInteriorVehicleData, { mod, true, false, 2 }) - runner.Step("App2 GetInteriorVehicleData without request to HMI " .. mod, common.GetInteriorVehicleData, - { mod, nil, false, 2 }) runner.Step("App1 and App2 OnInteriorVehicleData for " .. mod, OnInteriorVDUpdatedData2Apps, { mod }) -- Block 'Un-Subscribe' from diagram runner.Step("App1 GetInteriorVehicleData with subscribe=false without request to HMI " .. mod, common.GetInteriorVehicleData, { mod, false, false, 1 }) - runner.Step("App2 GetInteriorVehicleData with subscribe=false " .. mod, common.GetInteriorVehicleData, - { mod, false, true, 2 }) + runner.Step("App2 GetInteriorVehicleData without subscribe " .. mod, common.GetInteriorVehicleData, + { mod, nil, true, 2 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/InteriorVehicleData_cache/014_GetInteriorVD_with_subscription_after_OnInteriorVD.lua b/test_scripts/RC/InteriorVehicleData_cache/014_GetInteriorVD_with_subscription_after_OnInteriorVD.lua index e4b74c8361..67fb39441a 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/014_GetInteriorVD_with_subscription_after_OnInteriorVD.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/014_GetInteriorVD_with_subscription_after_OnInteriorVD.lua @@ -11,7 +11,7 @@ -- 2. HMI sends OnInteriorVD with params changing for module_1 -- 3. Mobile app sends GetInteriorVD(module_1, without subscribe parameter) request -- SDL must --- 1. not send GetInteriorVD request to HMI +-- 1. send GetInteriorVD request to HMI -- 2. send GetinteriorVD response to mobile app with actual data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] @@ -36,7 +36,7 @@ for _, mod in pairs(common.modules) do runner.Step("OnInteriorVehicleData for " .. mod, common.OnInteriorVD, { mod, true, 1 }) runner.Step("GetInteriorVehicleData without subscribe " .. mod, common.GetInteriorVehicleData, - { mod, nil, false, 1 }) + { mod, nil, true, 1 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua index ff44a225be..2ecb1087f3 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua @@ -38,7 +38,7 @@ runner.Step("App2 GetInteriorVehicleData with subscribe=true " .. common.modules runner.Step("App1 GetInteriorVehicleData with subscribe=false " .. common.modules[1], common.GetInteriorVehicleData, { common.modules[1], false, true, 1 }) runner.Step("App2 GetInteriorVehicleData without subscribe " .. common.modules[2], common.GetInteriorVehicleData, - { common.modules[2], nil, false, 2 }) + { common.modules[2], nil, true, 2 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/028_GetInteriorVD_limitation_after_subscription.lua b/test_scripts/RC/InteriorVehicleData_cache/028_GetInteriorVD_limitation_after_subscription.lua index 50e483700c..204584272b 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/028_GetInteriorVD_limitation_after_subscription.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/028_GetInteriorVD_limitation_after_subscription.lua @@ -34,7 +34,7 @@ runner.Title("Test") for i=1,7 do runner.Step("GetInteriorVehicleData without subscribe parameter " .. i, common.GetInteriorVehicleData, - {"CLIMATE", nil, false, 1 }) + {"CLIMATE", true, false, 1 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/InteriorVehicleData_cache/029_GetInteriorVD_limitation_rejected_after_unsubscribing.lua b/test_scripts/RC/InteriorVehicleData_cache/029_GetInteriorVD_limitation_rejected_after_unsubscribing.lua index 6b7b15a241..a492dea640 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/029_GetInteriorVD_limitation_rejected_after_unsubscribing.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/029_GetInteriorVD_limitation_rejected_after_unsubscribing.lua @@ -31,8 +31,8 @@ runner.Step("Register app", common.registerAppWOPTU, { 1 }) runner.Step("Activate app", common.activateApp, { 1 }) runner.Step("GetInteriorVehicleData with subscribe=true", common.GetInteriorVehicleData, {"CLIMATE", true, true, 1 }) -runner.Step("GetInteriorVehicleData without subscribe", common.GetInteriorVehicleData, - {"CLIMATE", nil, false, 1 }) +runner.Step("GetInteriorVehicleData without subscribe=true", common.GetInteriorVehicleData, + {"CLIMATE", true, false, 1 }) runner.Step("GetInteriorVehicleData with subscribe=false", common.GetInteriorVehicleData, {"CLIMATE", false, true, 1 }) diff --git a/test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua b/test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua index c348586a25..9073ca78cf 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua @@ -11,7 +11,7 @@ -- 2. HMI sends OnInteriorVD with one param changing for module_1 -- 3. Mobile app1 sends GetInteriorVD(module_1, without subscribe parameter) request -- SDL must --- 1. not send GetInteriorVD request to HMI +-- 1. send GetInteriorVD request to HMI -- 2. send GetinteriorVD response to mobile app2 with actual data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] @@ -63,7 +63,7 @@ for _, mod in pairs(common.modules) do runner.Step("App1 OnInteriorVehicleData for " .. mod, common.OnInteriorVD, { mod, true, 1, getModuleData(mod, OnInteriorVDparams[mod]) }) runner.Step("App2 GetInteriorVehicleData without subscribe " .. mod, common.GetInteriorVehicleData, - { mod, nil, false, 1 }) + { mod, nil, true, 1 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua similarity index 65% rename from test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua rename to test_scripts/RC/SEAT/GetInteriorVehicleData/011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index 24350508fb..1065025064 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -11,7 +11,7 @@ -- 3) and with "isSubscribed" parameter from HMI -- SDL must: -- 1) transfer GetInteriorVehicleData_response with resultCode: <"any-result"> --- and without "isSubscribed" param to the related app +-- and with "isSubscribed" param to the related app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -21,41 +21,37 @@ local commonRC = require('test_scripts/RC/commonRC') runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequest) - local mobSession = commonRC.getMobileSession() - local cid = mobSession:SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType - -- no subscribe parameter - }) +local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequestCount) + local mobileSession = common.getMobileSession() + local cid = mobileSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType + -- no subscribe parameter + }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - moduleType = pModuleType - }) + moduleType = pModuleType + }) :Do(function(_, data) - commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlData(pModuleType), - isSubscribed = isSubscriptionActive -- return current value of subscription - }) + common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = isSubscriptionActive -- return current value of subscription + }) end) :ValidIf(function(_, data) -- no subscribe parameter - if data.params.subscribe == nil then + if (isSubscriptionActive and data.params.subscribe == false) or data.params.subscribe == nil then return true end return false, 'Parameter "subscribe" is transfered with to HMI value: ' .. tostring(data.params.subscribe) end) - :Times(pHMIrequest) + :Times(pHMIrequestCount) - mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = commonRC.getModuleControlData(pModuleType) - }) - :ValidIf(function(_, data) -- no isSubscribed parameter - if data.payload.isSubscribed == nil then - return true - end - return false, 'Parameter "isSubscribed" is transfered to App with value: ' .. tostring(data.payload.isSubscribed) - end) + mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = common.getModuleControlDataForResponse(pModuleType), + isSubscribed = isSubscriptionActive + }) end + --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) @@ -66,7 +62,7 @@ runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("GetInteriorVehicleData SEAT NoSubscription", getDataForModule, { "SEAT", false, 1 }) runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) -runner.Step("GetInteriorVehicleData SEAT ActiveSubscription_subscribe", getDataForModule, { "SEAT", true, 0 }) +runner.Step("GetInteriorVehicleData SEAT ActiveSubscription_subscribe", getDataForModule, { "SEAT", true, 1 }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/SDL5_0/rc_AUDIO_LIGHT_HMI_SETTINGS.txt b/test_sets/SDL5_0/rc_AUDIO_LIGHT_HMI_SETTINGS.txt index faae0fd39d..120768c434 100644 --- a/test_sets/SDL5_0/rc_AUDIO_LIGHT_HMI_SETTINGS.txt +++ b/test_sets/SDL5_0/rc_AUDIO_LIGHT_HMI_SETTINGS.txt @@ -10,7 +10,7 @@ ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua -./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua diff --git a/test_sets/SDL5_0/rc_CLIMATE_RADIO.txt b/test_sets/SDL5_0/rc_CLIMATE_RADIO.txt index d39912361e..6abac980fe 100644 --- a/test_sets/SDL5_0/rc_CLIMATE_RADIO.txt +++ b/test_sets/SDL5_0/rc_CLIMATE_RADIO.txt @@ -23,7 +23,7 @@ ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua -./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/CLIMATE_RADIO/ButtonPress/001_success_flow_for_climate_and_radio.lua ./test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua diff --git a/test_sets/SDL5_0/rc_SEAT.txt b/test_sets/SDL5_0/rc_SEAT.txt index 91c5bf122c..363333e309 100644 --- a/test_sets/SDL5_0/rc_SEAT.txt +++ b/test_sets/SDL5_0/rc_SEAT.txt @@ -14,7 +14,7 @@ ./test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua -./test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/SEAT/OnInteriorVehicleData/001_Success_flow.lua ./test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua diff --git a/test_sets/SDL5_0/sdl_5_0_test_suite.txt b/test_sets/SDL5_0/sdl_5_0_test_suite.txt index 25e7b9940e..8293b5c1a1 100644 --- a/test_sets/SDL5_0/sdl_5_0_test_suite.txt +++ b/test_sets/SDL5_0/sdl_5_0_test_suite.txt @@ -284,7 +284,7 @@ ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua -./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/CLIMATE_RADIO/ButtonPress/001_success_flow_for_climate_and_radio.lua ./test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua @@ -393,7 +393,7 @@ ./test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua -./test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/SEAT/OnInteriorVehicleData/001_Success_flow.lua ./test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -424,7 +424,7 @@ ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua -./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua diff --git a/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt b/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt index faae0fd39d..120768c434 100644 --- a/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt +++ b/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt @@ -10,7 +10,7 @@ ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua -./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua diff --git a/test_sets/rc_CLIMATE_RADIO.txt b/test_sets/rc_CLIMATE_RADIO.txt index d39912361e..6abac980fe 100644 --- a/test_sets/rc_CLIMATE_RADIO.txt +++ b/test_sets/rc_CLIMATE_RADIO.txt @@ -23,7 +23,7 @@ ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua -./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/CLIMATE_RADIO/ButtonPress/001_success_flow_for_climate_and_radio.lua ./test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua diff --git a/test_sets/rc_SEAT.txt b/test_sets/rc_SEAT.txt index 91c5bf122c..363333e309 100644 --- a/test_sets/rc_SEAT.txt +++ b/test_sets/rc_SEAT.txt @@ -14,7 +14,7 @@ ./test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua -./test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/SEAT/OnInteriorVehicleData/001_Success_flow.lua ./test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua From 04cb046f4c4add50173099e68c576d1a8b1a4918 Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Mon, 8 Oct 2018 09:42:41 -0400 Subject: [PATCH 669/681] Fixes panics resulting from copy-paste error --- ..._parameter_but_response_from_HMI_with_isSubscribed.lua | 8 ++++---- ..._parameter_but_response_from_HMI_with_isSubscribed.lua | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index 0b26bf531a..b0ed240ed6 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -24,7 +24,7 @@ runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequestCount) - local mobileSession = common.getMobileSession() + local mobileSession = commonRC.getMobileSession() local cid = mobileSession:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType -- no subscribe parameter @@ -34,8 +34,8 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequestCo moduleType = pModuleType }) :Do(function(_, data) - common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = common.getModuleControlDataForResponse(pModuleType), + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlDataForResponse(pModuleType), isSubscribed = isSubscriptionActive -- return current value of subscription }) end) @@ -48,7 +48,7 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequestCo :Times(pHMIrequestCount) mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = common.getModuleControlDataForResponse(pModuleType), + moduleData = commonRC.getModuleControlDataForResponse(pModuleType), isSubscribed = isSubscriptionActive }) end diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index 1065025064..7ca99d61a9 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -22,7 +22,7 @@ runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequestCount) - local mobileSession = common.getMobileSession() + local mobileSession = commonRC.getMobileSession() local cid = mobileSession:SendRPC("GetInteriorVehicleData", { moduleType = pModuleType -- no subscribe parameter @@ -32,8 +32,8 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequestCo moduleType = pModuleType }) :Do(function(_, data) - common.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = common.getModuleControlDataForResponse(pModuleType), + commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { + moduleData = commonRC.getModuleControlDataForResponse(pModuleType), isSubscribed = isSubscriptionActive -- return current value of subscription }) end) @@ -46,7 +46,7 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequestCo :Times(pHMIrequestCount) mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = common.getModuleControlDataForResponse(pModuleType), + moduleData = commonRC.getModuleControlDataForResponse(pModuleType), isSubscribed = isSubscriptionActive }) end From e080b4a76f9ffd4bd698ca5992b06e6f38202656 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 10 Oct 2018 09:19:30 -0400 Subject: [PATCH 670/681] Add new line at the end of test sets to run them on CI --- test_sets/SDL5_0/conditional_resumption.txt | 2 +- test_sets/SDL5_0/duplicate_correlation_ids.txt | 2 +- test_sets/SDL5_0/full_app_id.txt | 2 +- test_sets/SDL5_0/sdl_5_0_test_suite.txt | 2 +- test_sets/SDL5_0/template_color_schemes.txt | 2 +- test_sets/SDL5_0/vr_command_optional.txt | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test_sets/SDL5_0/conditional_resumption.txt b/test_sets/SDL5_0/conditional_resumption.txt index 7a9f3c2848..6e37b1accb 100644 --- a/test_sets/SDL5_0/conditional_resumption.txt +++ b/test_sets/SDL5_0/conditional_resumption.txt @@ -3,4 +3,4 @@ ./test_scripts/SDL5_0/ConditionalResumption/003_conditional_resumption_specific_hmi_level_navi.lua ./test_scripts/SDL5_0/ConditionalResumption/004_conditional_resumption_specific_hmi_level_projection.lua ./test_scripts/SDL5_0/ConditionalResumption/005_conditional_resumption_specific_hmi_level_media.lua -./test_scripts/SDL5_0/ConditionalResumption/006_conditional_resumption_specific_hmi_level_choose_highest.lua \ No newline at end of file +./test_scripts/SDL5_0/ConditionalResumption/006_conditional_resumption_specific_hmi_level_choose_highest.lua diff --git a/test_sets/SDL5_0/duplicate_correlation_ids.txt b/test_sets/SDL5_0/duplicate_correlation_ids.txt index 78a3c9e7e1..4e4cfa0211 100644 --- a/test_sets/SDL5_0/duplicate_correlation_ids.txt +++ b/test_sets/SDL5_0/duplicate_correlation_ids.txt @@ -1 +1 @@ -./test_scripts/SDL5_0/DuplicateCorrIDs/001_DuplicateCorrelationIDs_INVALID_ID.lua \ No newline at end of file +./test_scripts/SDL5_0/DuplicateCorrIDs/001_DuplicateCorrelationIDs_INVALID_ID.lua diff --git a/test_sets/SDL5_0/full_app_id.txt b/test_sets/SDL5_0/full_app_id.txt index e2fc12c9ab..27fc2d4940 100644 --- a/test_sets/SDL5_0/full_app_id.txt +++ b/test_sets/SDL5_0/full_app_id.txt @@ -1,2 +1,2 @@ ./test_scripts/SDL5_0/FullAppID/001_PTU_full_app_ID_true.lua -./test_scripts/SDL5_0/FullAppID/002_PTU_full_app_ID_false.lua \ No newline at end of file +./test_scripts/SDL5_0/FullAppID/002_PTU_full_app_ID_false.lua diff --git a/test_sets/SDL5_0/sdl_5_0_test_suite.txt b/test_sets/SDL5_0/sdl_5_0_test_suite.txt index 8293b5c1a1..2f7994a219 100644 --- a/test_sets/SDL5_0/sdl_5_0_test_suite.txt +++ b/test_sets/SDL5_0/sdl_5_0_test_suite.txt @@ -581,4 +581,4 @@ ./test_scripts/API/VehicleData/UnsubscribeVehicleData/001_Success_flow.lua ./test_scripts/API/VehicleData/UnsubscribeVehicleData/002_RPC_parameter_not_yet_subscribed_IGNORED_flow.lua ./test_scripts/API/VehicleData/UnsubscribeVehicleData/003_RPC_parameter_already_unsubscribed_Result_IGNORED_flow.lua -./test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua \ No newline at end of file +./test_scripts/API/VehicleData/UnsubscribeVehicleData/004_RPC_parameter_disallowed_by_policies_Result_DISALLOWED_flow.lua diff --git a/test_sets/SDL5_0/template_color_schemes.txt b/test_sets/SDL5_0/template_color_schemes.txt index 8863fed70a..fe2685c5ef 100644 --- a/test_sets/SDL5_0/template_color_schemes.txt +++ b/test_sets/SDL5_0/template_color_schemes.txt @@ -1,3 +1,3 @@ ./test_scripts/SDL5_0/TemplateColorSchemes/001_TemplateColorSchemes_setDisplayWithColorsAndNewLayoutSuccess.lua ./test_scripts/SDL5_0/TemplateColorSchemes/002_TemplateColorSchemes_setDisplayWithColorsRejected.lua -./test_scripts/SDL5_0/TemplateColorSchemes/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua \ No newline at end of file +./test_scripts/SDL5_0/TemplateColorSchemes/003_TemplateColorSchemes_setDisplayWithSameColorsSuccess.lua diff --git a/test_sets/SDL5_0/vr_command_optional.txt b/test_sets/SDL5_0/vr_command_optional.txt index ff3d7090d7..dd828eda89 100644 --- a/test_sets/SDL5_0/vr_command_optional.txt +++ b/test_sets/SDL5_0/vr_command_optional.txt @@ -1,2 +1,2 @@ ./test_scripts/SDL5_0/vrCommandOptional/001_create_interaction_choice_set_invalid_data.lua -./test_scripts/SDL5_0/vrCommandOptional/002_perform_interaction_invalid_data.lua \ No newline at end of file +./test_scripts/SDL5_0/vrCommandOptional/002_perform_interaction_invalid_data.lua From ac80e9ca652930299502604c889131b81e338b0e Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 10 Oct 2018 09:38:49 -0400 Subject: [PATCH 671/681] Exclude failed test scripts from test sets and add link to GitHub issue --- test_sets/policies_happy_paths_EXTERNAL_PROPRIETARY.txt | 4 +--- test_sets/policies_happy_paths_HTTP.txt | 3 +-- test_sets/policies_happy_paths_PROPRIETARY.txt | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/test_sets/policies_happy_paths_EXTERNAL_PROPRIETARY.txt b/test_sets/policies_happy_paths_EXTERNAL_PROPRIETARY.txt index 2adf7b69d4..b399ea3971 100644 --- a/test_sets/policies_happy_paths_EXTERNAL_PROPRIETARY.txt +++ b/test_sets/policies_happy_paths_EXTERNAL_PROPRIETARY.txt @@ -45,7 +45,6 @@ ./test_scripts/Policies/appID_Management/045_ATF_Register_App_Interface_Assign_Default_Policies_To_Application_Which_Appid_Does_Not_Exist_In_LPT.lua ./test_scripts/Policies/appID_Management/046_ATF_Register_App_Interface_Assign_Existing_Policies_To_Application_Which_Appid_Exists_In_LPT.lua ./test_scripts/Policies/build_options/047_ATF_SDL_Build_DEXTENDED_POLICY_EXTERNAL_PROPRIETARY.lua -;./test_scripts/Policies/build_options/090_ATF_For_PTU_use_consented_device_only.lua CI_issue_with_more_than_one_device_connected ./test_scripts/Policies/Policies_Security/119_ATF_P_Policies_Performance_Requirement.lua ./test_scripts/Policies/Policies_Security/120_ATF_PolicyTable_Certificate_EMPTY_value.lua ./test_scripts/Policies/Policy_Table_Update/121_ATF_PTU_AppID_NotListed_PT_DeviceConsented_SecondApp.lua @@ -142,7 +141,6 @@ ./test_scripts/Policies/user_consent_of_Policies/212_ATF_Data_consent_device_not_in_LPT.lua ./test_scripts/Policies/user_consent_of_Policies/213_ATF_No_user_consent_prompt_in_group.lua ./test_scripts/Policies/user_consent_of_Policies/214_ATF_User_consent_prompt_persists.lua -;./test_scripts/Policies/user_consent_of_Policies/215_ATF_User_clears_all_applications.lua CI_issue_with_more_than_one_device_connected ./test_scripts/Policies/user_consent_of_Policies/216_ATF_User_consent_storage_in_LPT.lua ./test_scripts/Policies/user_consent_of_Policies/217_ATF_Consent_status_allowed_on_device_connect.lua ./test_scripts/Policies/user_consent_of_Policies/218_ATF_Consent_status_not_allowed_on_device_connect.lua @@ -229,7 +227,7 @@ ./test_scripts/Policies/Validation_of_PolicyTables/299_ATF_Memory_Kb_Constraints_Ignoring.lua ./test_scripts/Policies/Validation_of_PolicyTables/300_ATF_HP_Applying_Heart_Beat_Timeout_Ms_From_PT.lua ./test_scripts/Policies/Validation_of_PolicyTables/301_ATF_usage_and_error_counts_update_app_registration_language_vui.lua -./test_scripts/Policies/Validation_of_PolicyTables/302_ATF_HP_Applying_Heart_Beat_Timeout_Ms_After_PTU.lua +;./test_scripts/Policies/Validation_of_PolicyTables/302_ATF_HP_Applying_Heart_Beat_Timeout_Ms_After_PTU.lua 2550 ./test_scripts/Policies/Validation_of_PolicyTables/303_ATF_HP_Usage_And_Error_Counts_For_AppID.lua ./test_scripts/Policies/Validation_of_PolicyTables/304_ATF_HP_Validation_Count_Of_User_Selections.lua ./test_scripts/Policies/Validation_of_PolicyTables/306_ATF_Update_count_of_run_attempts_while_revoked_in_PT.lua diff --git a/test_sets/policies_happy_paths_HTTP.txt b/test_sets/policies_happy_paths_HTTP.txt index a6d882d4b1..4d7fec8300 100644 --- a/test_sets/policies_happy_paths_HTTP.txt +++ b/test_sets/policies_happy_paths_HTTP.txt @@ -5,7 +5,7 @@ ./test_scripts/Policies/build_options/054_ATF_Request_PTU_UPDATE_NEEDED_new_PTU_Request_HTTP.lua ./test_scripts/Policies/build_options/055_ATF_Policy_Table_Snapshot_Creation_HTTP.lua ./test_scripts/Policies/build_options/056_ATF_PTU_Transfer_Several_Apps_Different_HMI_Levels_HTTP.lua -./test_scripts/Policies/build_options/057_ATF_PTS_Define_URL_to_send_PTS_HTTP.lua +;./test_scripts/Policies/build_options/057_ATF_PTS_Define_URL_to_send_PTS_HTTP.lua 1219 ./test_scripts/Policies/build_options/058_ATF_HMI_sends_GetURLs_no_app_registered_HTTP.lua ./test_scripts/Policies/build_options/059_ATF_HMI_sends_GetURLs_one_app_registered_HTTP.lua ./test_scripts/Policies/build_options/060_ATF_Timeout_to_wait_response_PTU_HTTP.lua @@ -30,7 +30,6 @@ ./test_scripts/Policies/build_options/080_ATF_PTU_OnStatsusUpdate_Trigger_UPDATE_NEEDED_HTTP.lua ./test_scripts/Policies/build_options/081_ATF_PTU_OnStatsusUpdate_Trigger_UPDATING_HTTP.lua ./test_scripts/Policies/build_options/082_ATF_PTU_OnStatsusUpdate_Trigger_UP_TO_DATE_HTTP.lua -;./test_scripts/Policies/build_options/083_ATF_PTU_UTF8_Encoding_Check_HTTP.lua Requirement_could_not_be_checked_based_on_clarification ./test_scripts/Policies/build_options/084_ATF_Default_Policy_For_The_App_After_PTU_HTTP.lua ./test_scripts/Policies/build_options/085_ATF_PTU_In_Progress_New_App_Registers_HTTP.lua ./test_scripts/Policies/build_options/086_ATF_PTU_Merging_wtih_LPT_HTTP.lua diff --git a/test_sets/policies_happy_paths_PROPRIETARY.txt b/test_sets/policies_happy_paths_PROPRIETARY.txt index 08c4d710f2..d6418ed9a4 100644 --- a/test_sets/policies_happy_paths_PROPRIETARY.txt +++ b/test_sets/policies_happy_paths_PROPRIETARY.txt @@ -16,7 +16,7 @@ ./test_scripts/Policies/build_options/108_ATF_PTU_Trigger_days_PROPRIETARY.lua ./test_scripts/Policies/build_options/109_ATF_PTU_Trigger_IGN_cycles_PROPRIETARY.lua ./test_scripts/Policies/build_options/110_ATF_PTU_Trigger_kilometers_PROPRIETARY.lua -./test_scripts/Policies/build_options/111_ATF_Start_PTU_retry_sequence_PROPRIETARY.lua +;./test_scripts/Policies/build_options/111_ATF_Start_PTU_retry_sequence_PROPRIETARY.lua 1210 ./test_scripts/Policies/build_options/112_ATF_transfer_SystemRequest_from_app_to_HMI_PROPRIETARY.lua ./test_scripts/Policies/build_options/113_ATF_transfer_SystemRequest_from_HMI_to_app_PROPRIETARY.lua ./test_scripts/Policies/build_options/114_ATF_Register_NewApp_not_exist_inLocalPT_FinishPTU_PROPRIETARY.lua From 92ce35dc51d2f935c8eb0140cf77f2beb8caf6b0 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 10 Oct 2018 11:06:18 -0400 Subject: [PATCH 672/681] Exclude failed test scripts from Mobile Projection test sets and add link to GitHub issue --- test_sets/SDL5_0/mobile_projection_2.txt | 2 +- test_sets/SDL5_0/mobile_projection_2_smoke.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test_sets/SDL5_0/mobile_projection_2.txt b/test_sets/SDL5_0/mobile_projection_2.txt index fce382a1d1..44b22cb7cb 100644 --- a/test_sets/SDL5_0/mobile_projection_2.txt +++ b/test_sets/SDL5_0/mobile_projection_2.txt @@ -20,4 +20,4 @@ ./test_scripts/MobileProjection/Phase2/020_different_types_apps_interactions.lua ./test_scripts/MobileProjection/Phase2/021_two_apps_and_deactivation.lua ./test_scripts/MobileProjection/Phase2/022_two_apps_proj_media_and_deactivation_streaming.lua -./test_scripts/MobileProjection/Phase2/023_two_apps_navi_comm_and_deactivation_streaming.lua +;./test_scripts/MobileProjection/Phase2/023_two_apps_navi_comm_and_deactivation_streaming.lua 2642 diff --git a/test_sets/SDL5_0/mobile_projection_2_smoke.txt b/test_sets/SDL5_0/mobile_projection_2_smoke.txt index 9afa00eb91..ee0806fc08 100644 --- a/test_sets/SDL5_0/mobile_projection_2_smoke.txt +++ b/test_sets/SDL5_0/mobile_projection_2_smoke.txt @@ -19,4 +19,4 @@ ./test_scripts/MobileProjection/Phase2/smoke/020_different_types_apps_interactions.lua ./test_scripts/MobileProjection/Phase2/smoke/021_two_apps_and_deactivation.lua ./test_scripts/MobileProjection/Phase2/smoke/022_two_apps_proj_media_and_deactivation_streaming.lua -./test_scripts/MobileProjection/Phase2/smoke/023_two_apps_navi_comm_and_deactivation_streaming.lua +;./test_scripts/MobileProjection/Phase2/smoke/023_two_apps_navi_comm_and_deactivation_streaming.lua 2642 From 415cf45381dc69f8d56a45c47d9c6f660eef1e17 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Wed, 10 Oct 2018 11:40:59 -0400 Subject: [PATCH 673/681] Revert "Merge pull request #2098 from smartdevicelink/fix/subscribe_default_value" This reverts commit b8cfdca310c464dfca2719be00a2d6917b617171, reversing changes made to 75d20750f0801a6090eeb34d015b993d5288ddf7. # Conflicts: # test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua # test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua --- ...t_response_from_HMI_with_isSubscribed.lua} | 15 ++++--- ...t_response_from_HMI_with_isSubscribed.lua} | 42 ++++++++++-------- .../000_cache_2_apps_sequence.lua | 12 +++-- ...D_with_subscription_after_OnInteriorVD.lua | 4 +- ...bscribe_false_different_modules_2_apps.lua | 2 +- ...teriorVD_limitation_after_subscription.lua | 2 +- ...imitation_rejected_after_unsubscribing.lua | 4 +- .../038_OnInteriorVD_one_parameter.lua | 4 +- ...t_response_from_HMI_with_isSubscribed.lua} | 44 ++++++++++--------- .../SDL5_0/rc_AUDIO_LIGHT_HMI_SETTINGS.txt | 2 +- test_sets/SDL5_0/rc_CLIMATE_RADIO.txt | 2 +- test_sets/SDL5_0/rc_SEAT.txt | 2 +- test_sets/SDL5_0/sdl_5_0_test_suite.txt | 6 +-- test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt | 2 +- test_sets/rc_CLIMATE_RADIO.txt | 2 +- test_sets/rc_SEAT.txt | 2 +- 16 files changed, 83 insertions(+), 64 deletions(-) rename test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/{013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua => 013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua} (87%) rename test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/{013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua => 013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua} (70%) rename test_scripts/RC/SEAT/GetInteriorVehicleData/{011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua => 011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua} (68%) diff --git a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua similarity index 87% rename from test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua rename to test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index f7a34aec07..3be5a76c40 100644 --- a/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -13,7 +13,7 @@ -- 3) and with "isSubscribed" parameter from HMI -- SDL must: -- 1) transfer GetInteriorVehicleData_response with resultCode: <"any-result"> --- and with "isSubscribed" param to the related app +-- and without "isSubscribed" param to the related app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -40,7 +40,7 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequestCo }) end) :ValidIf(function(_, data) -- no subscribe parameter - if (isSubscriptionActive and data.params.subscribe == false) or data.params.subscribe == nil then + if data.params.subscribe == nil then return true end return false, 'Parameter "subscribe" is transfered with to HMI value: ' .. tostring(data.params.subscribe) @@ -48,9 +48,14 @@ local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequestCo :Times(pHMIrequestCount) mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = common.getModuleControlDataForResponse(pModuleType), - isSubscribed = isSubscriptionActive + moduleData = common.getModuleControlDataForResponse(pModuleType) }) + :ValidIf(function(_, data) -- no isSubscribed parameter + if data.payload.isSubscribed == nil then + return true + end + return false, 'Parameter "isSubscribed" is transfered to App with value: ' .. tostring(data.payload.isSubscribed) + end) end --[[ Scenario ]] @@ -68,7 +73,7 @@ end for _, mod in pairs(common.modulesWithoutSeat) do runner.Step("Subscribe app to " .. mod, common.subscribeToModule, { mod }) - runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true, 1 }) + runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true, 0 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua similarity index 70% rename from test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua rename to test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index b0ed240ed6..a3331683c7 100644 --- a/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -13,7 +13,7 @@ -- 3) and with "isSubscribed" parameter from HMI -- SDL must: -- 1) transfer GetInteriorVehicleData_response with resultCode: <"any-result"> --- and with "isSubscribed" param to the related app +-- and without "isSubscribed" param to the related app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -23,34 +23,38 @@ local commonRC = require('test_scripts/RC/commonRC') runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequestCount) - local mobileSession = commonRC.getMobileSession() - local cid = mobileSession:SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType - -- no subscribe parameter - }) +local function getDataForModule(pModuleType, isSubscriptionActive, pHMIRequest) + local cid = commonRC.getMobileSession():SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType + -- no subscribe parameter + }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - moduleType = pModuleType - }) + moduleType = pModuleType + }) :Do(function(_, data) commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlDataForResponse(pModuleType), - isSubscribed = isSubscriptionActive -- return current value of subscription - }) + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = isSubscriptionActive -- return current value of subscription + }) end) :ValidIf(function(_, data) -- no subscribe parameter - if (isSubscriptionActive and data.params.subscribe == false) or data.params.subscribe == nil then + if data.params.subscribe == nil then return true end return false, 'Parameter "subscribe" is transfered with to HMI value: ' .. tostring(data.params.subscribe) end) - :Times(pHMIrequestCount) + :Times(pHMIRequest) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = commonRC.getModuleControlDataForResponse(pModuleType), - isSubscribed = isSubscriptionActive - }) + commonRC.getMobileSession():ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = commonRC.getModuleControlData(pModuleType) + }) + :ValidIf(function(_, data) -- no isSubscribed parameter + if data.payload.isSubscribed == nil then + return true + end + return false, 'Parameter "isSubscribed" is transfered to App with value: ' .. tostring(data.payload.isSubscribed) + end) end --[[ Scenario ]] @@ -68,7 +72,7 @@ end for _, mod in pairs(commonRC.modules) do runner.Step("Subscribe app to " .. mod, commonRC.subscribeToModule, { mod }) - runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true, 1 }) + runner.Step("GetInteriorVehicleData " .. mod .. " ActiveSubscription_subscribe", getDataForModule, { mod, true, 0 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua b/test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua index eb0a676647..19ec102972 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/000_cache_2_apps_sequence.lua @@ -16,14 +16,16 @@ -- 8. App2 sends GetInteriorVD(module_1) without subscribe parameter -- 9. HMI sends OnInteriorVD(data for module_1) -- 10. App1 sends GetInteriorVD(module_1) with subscribe=false --- 11. App2 sends GetInteriorVD(module_1) with subscribe=nil +-- 11. App2 sends GetInteriorVD(module_1) with subscribe=false -- SDL must -- 1. send GetInteriorVD(module_1, without subscribe parameter, without appId) request to HMI by processing request from app1 -- 2. send GetInteriorVD(module_1, without subscribe parameter, without appId) request to HMI by processing request from app2 -- 3. send GetInteriorVD(module_1, subscribe=true, without appId) request to HMI by processing request from app1 -- 4. update data for module_1 in cache and send OnInteriorVD notification to mobile app1 -- 5. not send GetInteriorVD(module_1, subscribe=true, without appId) request to HMI by processing request from app1 +-- 6. not send GetInteriorVD(module_1, without subscribe parameter, without appId) request to HMI by processing request from app1 -- 7. not send GetInteriorVD(module_1, subscribe=true, without appId) request to HMI by processing request from app2 +-- 8. not send GetInteriorVD(module_1, without subscribe parameter, without appId) request to HMI by processing request from app2 -- 9. update data for module_1 in cache and send OnInteriorVD notification to mobile app1 and mobile app2 -- 10. not send GetInteriorVD(module_1, subscribe=false, without appId) request to HMI by processing request from app1 -- 11. send GetInteriorVD(module_1, subscribe=true, without appId) request to HMI by processing request from app2 @@ -64,16 +66,20 @@ for _, mod in pairs(common.modules) do { mod, true, 1 }) runner.Step("App1 GetInteriorVehicleData with subscribe=true without request to HMI " .. mod, common.GetInteriorVehicleData, { mod, true, false, 1 }) + runner.Step("App1 GetInteriorVehicleData without request to HMI " .. mod, common.GetInteriorVehicleData, + { mod, nil, false, 1 }) -- Block 'Subscribe app2' from diagram runner.Step("App2 GetInteriorVehicleData with subscribe=true without request to HMI" .. mod, common.GetInteriorVehicleData, { mod, true, false, 2 }) + runner.Step("App2 GetInteriorVehicleData without request to HMI " .. mod, common.GetInteriorVehicleData, + { mod, nil, false, 2 }) runner.Step("App1 and App2 OnInteriorVehicleData for " .. mod, OnInteriorVDUpdatedData2Apps, { mod }) -- Block 'Un-Subscribe' from diagram runner.Step("App1 GetInteriorVehicleData with subscribe=false without request to HMI " .. mod, common.GetInteriorVehicleData, { mod, false, false, 1 }) - runner.Step("App2 GetInteriorVehicleData without subscribe " .. mod, common.GetInteriorVehicleData, - { mod, nil, true, 2 }) + runner.Step("App2 GetInteriorVehicleData with subscribe=false " .. mod, common.GetInteriorVehicleData, + { mod, false, true, 2 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/InteriorVehicleData_cache/014_GetInteriorVD_with_subscription_after_OnInteriorVD.lua b/test_scripts/RC/InteriorVehicleData_cache/014_GetInteriorVD_with_subscription_after_OnInteriorVD.lua index 67fb39441a..e4b74c8361 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/014_GetInteriorVD_with_subscription_after_OnInteriorVD.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/014_GetInteriorVD_with_subscription_after_OnInteriorVD.lua @@ -11,7 +11,7 @@ -- 2. HMI sends OnInteriorVD with params changing for module_1 -- 3. Mobile app sends GetInteriorVD(module_1, without subscribe parameter) request -- SDL must --- 1. send GetInteriorVD request to HMI +-- 1. not send GetInteriorVD request to HMI -- 2. send GetinteriorVD response to mobile app with actual data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] @@ -36,7 +36,7 @@ for _, mod in pairs(common.modules) do runner.Step("OnInteriorVehicleData for " .. mod, common.OnInteriorVD, { mod, true, 1 }) runner.Step("GetInteriorVehicleData without subscribe " .. mod, common.GetInteriorVehicleData, - { mod, nil, true, 1 }) + { mod, nil, false, 1 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua b/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua index 2ecb1087f3..ff44a225be 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/020_GetInteriorVD_subscribe_false_different_modules_2_apps.lua @@ -38,7 +38,7 @@ runner.Step("App2 GetInteriorVehicleData with subscribe=true " .. common.modules runner.Step("App1 GetInteriorVehicleData with subscribe=false " .. common.modules[1], common.GetInteriorVehicleData, { common.modules[1], false, true, 1 }) runner.Step("App2 GetInteriorVehicleData without subscribe " .. common.modules[2], common.GetInteriorVehicleData, - { common.modules[2], nil, true, 2 }) + { common.modules[2], nil, false, 2 }) runner.Title("Postconditions") runner.Step("Stop SDL", common.postconditions) diff --git a/test_scripts/RC/InteriorVehicleData_cache/028_GetInteriorVD_limitation_after_subscription.lua b/test_scripts/RC/InteriorVehicleData_cache/028_GetInteriorVD_limitation_after_subscription.lua index 204584272b..50e483700c 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/028_GetInteriorVD_limitation_after_subscription.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/028_GetInteriorVD_limitation_after_subscription.lua @@ -34,7 +34,7 @@ runner.Title("Test") for i=1,7 do runner.Step("GetInteriorVehicleData without subscribe parameter " .. i, common.GetInteriorVehicleData, - {"CLIMATE", true, false, 1 }) + {"CLIMATE", nil, false, 1 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/InteriorVehicleData_cache/029_GetInteriorVD_limitation_rejected_after_unsubscribing.lua b/test_scripts/RC/InteriorVehicleData_cache/029_GetInteriorVD_limitation_rejected_after_unsubscribing.lua index a492dea640..6b7b15a241 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/029_GetInteriorVD_limitation_rejected_after_unsubscribing.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/029_GetInteriorVD_limitation_rejected_after_unsubscribing.lua @@ -31,8 +31,8 @@ runner.Step("Register app", common.registerAppWOPTU, { 1 }) runner.Step("Activate app", common.activateApp, { 1 }) runner.Step("GetInteriorVehicleData with subscribe=true", common.GetInteriorVehicleData, {"CLIMATE", true, true, 1 }) -runner.Step("GetInteriorVehicleData without subscribe=true", common.GetInteriorVehicleData, - {"CLIMATE", true, false, 1 }) +runner.Step("GetInteriorVehicleData without subscribe", common.GetInteriorVehicleData, + {"CLIMATE", nil, false, 1 }) runner.Step("GetInteriorVehicleData with subscribe=false", common.GetInteriorVehicleData, {"CLIMATE", false, true, 1 }) diff --git a/test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua b/test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua index 9073ca78cf..c348586a25 100644 --- a/test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua +++ b/test_scripts/RC/InteriorVehicleData_cache/038_OnInteriorVD_one_parameter.lua @@ -11,7 +11,7 @@ -- 2. HMI sends OnInteriorVD with one param changing for module_1 -- 3. Mobile app1 sends GetInteriorVD(module_1, without subscribe parameter) request -- SDL must --- 1. send GetInteriorVD request to HMI +-- 1. not send GetInteriorVD request to HMI -- 2. send GetinteriorVD response to mobile app2 with actual data --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] @@ -63,7 +63,7 @@ for _, mod in pairs(common.modules) do runner.Step("App1 OnInteriorVehicleData for " .. mod, common.OnInteriorVD, { mod, true, 1, getModuleData(mod, OnInteriorVDparams[mod]) }) runner.Step("App2 GetInteriorVehicleData without subscribe " .. mod, common.GetInteriorVehicleData, - { mod, nil, true, 1 }) + { mod, nil, false, 1 }) end runner.Title("Postconditions") diff --git a/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua b/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua similarity index 68% rename from test_scripts/RC/SEAT/GetInteriorVehicleData/011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua rename to test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua index 7ca99d61a9..24350508fb 100644 --- a/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +++ b/test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua @@ -11,7 +11,7 @@ -- 3) and with "isSubscribed" parameter from HMI -- SDL must: -- 1) transfer GetInteriorVehicleData_response with resultCode: <"any-result"> --- and with "isSubscribed" param to the related app +-- and without "isSubscribed" param to the related app --------------------------------------------------------------------------------------------------- --[[ Required Shared libraries ]] local runner = require('user_modules/script_runner') @@ -21,37 +21,41 @@ local commonRC = require('test_scripts/RC/commonRC') runner.testSettings.isSelfIncluded = false --[[ Local Functions ]] -local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequestCount) - local mobileSession = commonRC.getMobileSession() - local cid = mobileSession:SendRPC("GetInteriorVehicleData", { - moduleType = pModuleType - -- no subscribe parameter - }) +local function getDataForModule(pModuleType, isSubscriptionActive, pHMIrequest) + local mobSession = commonRC.getMobileSession() + local cid = mobSession:SendRPC("GetInteriorVehicleData", { + moduleType = pModuleType + -- no subscribe parameter + }) EXPECT_HMICALL("RC.GetInteriorVehicleData", { - moduleType = pModuleType - }) + moduleType = pModuleType + }) :Do(function(_, data) commonRC.getHMIConnection():SendResponse(data.id, data.method, "SUCCESS", { - moduleData = commonRC.getModuleControlDataForResponse(pModuleType), - isSubscribed = isSubscriptionActive -- return current value of subscription - }) + moduleData = commonRC.getModuleControlData(pModuleType), + isSubscribed = isSubscriptionActive -- return current value of subscription + }) end) :ValidIf(function(_, data) -- no subscribe parameter - if (isSubscriptionActive and data.params.subscribe == false) or data.params.subscribe == nil then + if data.params.subscribe == nil then return true end return false, 'Parameter "subscribe" is transfered with to HMI value: ' .. tostring(data.params.subscribe) end) - :Times(pHMIrequestCount) + :Times(pHMIrequest) - mobileSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", - moduleData = commonRC.getModuleControlDataForResponse(pModuleType), - isSubscribed = isSubscriptionActive - }) + mobSession:ExpectResponse(cid, { success = true, resultCode = "SUCCESS", + moduleData = commonRC.getModuleControlData(pModuleType) + }) + :ValidIf(function(_, data) -- no isSubscribed parameter + if data.payload.isSubscribed == nil then + return true + end + return false, 'Parameter "isSubscribed" is transfered to App with value: ' .. tostring(data.payload.isSubscribed) + end) end - --[[ Scenario ]] runner.Title("Preconditions") runner.Step("Clean environment", commonRC.preconditions) @@ -62,7 +66,7 @@ runner.Step("Activate App", commonRC.activateApp) runner.Title("Test") runner.Step("GetInteriorVehicleData SEAT NoSubscription", getDataForModule, { "SEAT", false, 1 }) runner.Step("Subscribe app to SEAT", commonRC.subscribeToModule, { "SEAT" }) -runner.Step("GetInteriorVehicleData SEAT ActiveSubscription_subscribe", getDataForModule, { "SEAT", true, 1 }) +runner.Step("GetInteriorVehicleData SEAT ActiveSubscription_subscribe", getDataForModule, { "SEAT", true, 0 }) runner.Title("Postconditions") runner.Step("Stop SDL", commonRC.postconditions) diff --git a/test_sets/SDL5_0/rc_AUDIO_LIGHT_HMI_SETTINGS.txt b/test_sets/SDL5_0/rc_AUDIO_LIGHT_HMI_SETTINGS.txt index 120768c434..faae0fd39d 100644 --- a/test_sets/SDL5_0/rc_AUDIO_LIGHT_HMI_SETTINGS.txt +++ b/test_sets/SDL5_0/rc_AUDIO_LIGHT_HMI_SETTINGS.txt @@ -10,7 +10,7 @@ ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua -./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua diff --git a/test_sets/SDL5_0/rc_CLIMATE_RADIO.txt b/test_sets/SDL5_0/rc_CLIMATE_RADIO.txt index 6abac980fe..d39912361e 100644 --- a/test_sets/SDL5_0/rc_CLIMATE_RADIO.txt +++ b/test_sets/SDL5_0/rc_CLIMATE_RADIO.txt @@ -23,7 +23,7 @@ ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua -./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/CLIMATE_RADIO/ButtonPress/001_success_flow_for_climate_and_radio.lua ./test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua diff --git a/test_sets/SDL5_0/rc_SEAT.txt b/test_sets/SDL5_0/rc_SEAT.txt index 363333e309..91c5bf122c 100644 --- a/test_sets/SDL5_0/rc_SEAT.txt +++ b/test_sets/SDL5_0/rc_SEAT.txt @@ -14,7 +14,7 @@ ./test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua -./test_scripts/RC/SEAT/GetInteriorVehicleData/011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/SEAT/OnInteriorVehicleData/001_Success_flow.lua ./test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua diff --git a/test_sets/SDL5_0/sdl_5_0_test_suite.txt b/test_sets/SDL5_0/sdl_5_0_test_suite.txt index 2f7994a219..322cab704a 100644 --- a/test_sets/SDL5_0/sdl_5_0_test_suite.txt +++ b/test_sets/SDL5_0/sdl_5_0_test_suite.txt @@ -284,7 +284,7 @@ ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua -./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/CLIMATE_RADIO/ButtonPress/001_success_flow_for_climate_and_radio.lua ./test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua @@ -393,7 +393,7 @@ ./test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua -./test_scripts/RC/SEAT/GetInteriorVehicleData/011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/SEAT/OnInteriorVehicleData/001_Success_flow.lua ./test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua @@ -424,7 +424,7 @@ ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua -./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua diff --git a/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt b/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt index 120768c434..faae0fd39d 100644 --- a/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt +++ b/test_sets/rc_AUDIO_LIGHT_HMI_SETTINGS.txt @@ -10,7 +10,7 @@ ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/012_Transfering_of_HMI_resultCode_to_mobile.lua -./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/015_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua ./test_scripts/RC/AUDIO_LIGHT_HMI_SETTINGS/GetInteriorVehicleData/016_RADIO_GPSdata_in_HMI_response.lua diff --git a/test_sets/rc_CLIMATE_RADIO.txt b/test_sets/rc_CLIMATE_RADIO.txt index 6abac980fe..d39912361e 100644 --- a/test_sets/rc_CLIMATE_RADIO.txt +++ b/test_sets/rc_CLIMATE_RADIO.txt @@ -23,7 +23,7 @@ ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/010_Disallow_flow_in_case_moduleType_is_absent_in_LPT.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/011_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/012_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua -./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/013_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/CLIMATE_RADIO/GetInteriorVehicleData/014_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/CLIMATE_RADIO/ButtonPress/001_success_flow_for_climate_and_radio.lua ./test_scripts/RC/CLIMATE_RADIO/ButtonPress/002_disallow_flow_by_policy_for_climate.lua diff --git a/test_sets/rc_SEAT.txt b/test_sets/rc_SEAT.txt index 363333e309..91c5bf122c 100644 --- a/test_sets/rc_SEAT.txt +++ b/test_sets/rc_SEAT.txt @@ -14,7 +14,7 @@ ./test_scripts/RC/SEAT/GetInteriorVehicleData/008_Existence_of_OnIVD_in_case_of_successfull_unsubscribing_without_isSubscribe_from_HMI.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/009_GENERIC_ERROR_in_case_HMI_respond_with_READ_ONLY.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/010_Transfering_of_isSubscribed_parameter_in_case_request_from_Mob_app_with_subscribe_parameter_but_response_from_HMI_without_isSubscribed.lua -./test_scripts/RC/SEAT/GetInteriorVehicleData/011_Presence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua +./test_scripts/RC/SEAT/GetInteriorVehicleData/011_Absence_of_isSubscribed_parameter_in_case_request_from_Mob_app_without_subscribe_parameter_but_response_from_HMI_with_isSubscribed.lua ./test_scripts/RC/SEAT/GetInteriorVehicleData/012_Absence_of_subscribe_parameter_in_request_for_HMI_in_case_of_2nd_Subscription_UnSubscription.lua ./test_scripts/RC/SEAT/OnInteriorVehicleData/001_Success_flow.lua ./test_scripts/RC/SEAT/OnInteriorVehicleData/002_Absence_of_OnIVD_in_case_of_successfull_subscribing_with_isSubscribe_false_from_HMI.lua From a703e033f386730d5a042b8a229307d289c8ef74 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Wed, 10 Oct 2018 15:40:58 -0400 Subject: [PATCH 674/681] Stabilize smoke tests for EXT SDL flow --- test_scripts/Smoke/commonSmoke.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/Smoke/commonSmoke.lua b/test_scripts/Smoke/commonSmoke.lua index 5cd398e36f..e933ff955b 100644 --- a/test_scripts/Smoke/commonSmoke.lua +++ b/test_scripts/Smoke/commonSmoke.lua @@ -279,7 +279,7 @@ function commonSmoke.registerApp(pAppId, self) :Do(function() mobSession:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) - mobSession:ExpectNotification("OnPermissionsChange") + mobSession:ExpectNotification("OnPermissionsChange"):Times(AtLeast(1)) mobSession:ExpectNotification("OnDriverDistraction", { state = "DD_OFF" }) end) end) From a925c9c907afdf6eb4b5d24cdc99b6df31e5517e Mon Sep 17 00:00:00 2001 From: Oleg Krupenich Date: Thu, 11 Oct 2018 16:21:36 +0300 Subject: [PATCH 675/681] ATF script for defect #1030 --- ...DRIVER_DISTRACTION_VIOLATION)_from_HMI.lua | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 test_scripts/Defects/5_0/1030_API_SDL_sends_OnAppInterfaceUnregistered(DRIVER_DISTRACTION_VIOLATION)_to_app_when_receives_OnExitApplication(DRIVER_DISTRACTION_VIOLATION)_from_HMI.lua diff --git a/test_scripts/Defects/5_0/1030_API_SDL_sends_OnAppInterfaceUnregistered(DRIVER_DISTRACTION_VIOLATION)_to_app_when_receives_OnExitApplication(DRIVER_DISTRACTION_VIOLATION)_from_HMI.lua b/test_scripts/Defects/5_0/1030_API_SDL_sends_OnAppInterfaceUnregistered(DRIVER_DISTRACTION_VIOLATION)_to_app_when_receives_OnExitApplication(DRIVER_DISTRACTION_VIOLATION)_from_HMI.lua new file mode 100644 index 0000000000..2586b6c1e0 --- /dev/null +++ b/test_scripts/Defects/5_0/1030_API_SDL_sends_OnAppInterfaceUnregistered(DRIVER_DISTRACTION_VIOLATION)_to_app_when_receives_OnExitApplication(DRIVER_DISTRACTION_VIOLATION)_from_HMI.lua @@ -0,0 +1,50 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/1030 +-- +-- Description: +-- [API] SDL sends OnAppInterfaceUnregistered(DRIVER_DISTRACTION_VIOLATION) to app +-- when receives OnExitApplication(DRIVER_DISTRACTION_VIOLATION) from HMI +-- +-- +-- Preconditions: +-- 1) SDL Core and HMI are started. App is registered +-- 2) App is None +-- +-- Steps: +-- 1) From HMI: send BasicCommunication.OnExitApplication", +-- {reason = "DRIVER_DISTRACTION_VIOLATION", AppId=ID of app in the precondition} +-- +-- Expected result: +-- SDL doesn't send OnAppInterfaceUnregistered(reason = "DRIVER_DISTRACTION_VIOLATION") to mobile app +-- App is not registered +--------------------------------------------------------------------------------------------------- + +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local common = require('user_modules/sequences/actions') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local Functions ]] +local function sendOnExitApplication() + common.getHMIConnection():SendNotification("BasicCommunication.OnExitApplication", + {reason = "DRIVER_DISTRACTION_VIOLATION", appID = 1 }) + common.getHMIConnection():ExpectNotification("BasicCommunication.OnAppUnregistered", + {unexpectedDisconnect = false, appID = 1}) + :Times(0) +end + + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", common.preconditions) +runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) +runner.Step("App registration", common.registerApp) +runner.Step("Activate App", common.activateApp) + +runner.Title("Test") +runner.Step("SDL recieves OnExitApplication from HMI", sendOnExitApplication) + +runner.Title("Postconditions") +runner.Step("Stop SDL", common.postconditions) From c5bed076148c8a975efd3ea71adb65cc584f4975 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Thu, 11 Oct 2018 16:17:40 -0400 Subject: [PATCH 676/681] Update min rpc patch version --- .../PlayPauseButton/002_play_pause_v4_invalid_data.lua | 3 ++- .../VersionNegotiation/001_register_legacy_app.lua | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/test_scripts/SDL5_0/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua b/test_scripts/SDL5_0/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua index a6bdf9a865..1ad2e8b0c4 100644 --- a/test_scripts/SDL5_0/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua +++ b/test_scripts/SDL5_0/MobileVersioning/PlayPauseButton/002_play_pause_v4_invalid_data.lua @@ -32,7 +32,8 @@ local commonSmoke = require('test_scripts/Smoke/commonSmoke') config.application1.registerAppInterfaceParams.syncMsgVersion = { majorVersion = 4, - minorVersion = 5 + minorVersion = 5, + patchVersion = 1 } --[[ Local Functions ]] diff --git a/test_scripts/SDL5_0/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua b/test_scripts/SDL5_0/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua index 04be8b9469..4ed1308253 100644 --- a/test_scripts/SDL5_0/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua +++ b/test_scripts/SDL5_0/MobileVersioning/VersionNegotiation/001_register_legacy_app.lua @@ -100,6 +100,7 @@ local function RegisterAppInterface(self) self.mobileSession1:ExpectResponse(CorIdRAI, { success = true, resultCode = "SUCCESS", syncMsgVersion = { majorVersion = 4, minorVersion = 5, + patchVersion = 1 }}) self.mobileSession1:ExpectNotification("OnHMIStatus", { hmiLevel = "NONE", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }) From 4305b2b9cc5a35a7acb5202a57cfc388b3998559 Mon Sep 17 00:00:00 2001 From: GetmanetsIrina Date: Fri, 12 Oct 2018 15:10:51 -0400 Subject: [PATCH 677/681] Script for issue 2670 --- ...670_2_GetInteriorVD_after_ignition_off.lua | 100 ++++++++++++++++++ ...670_3_GetInteriorVD_after_ignition_off.lua | 85 +++++++++++++++ ...670_4_GetInteriorVD_after_ignition_off.lua | 90 ++++++++++++++++ .../2670_GetInteriorVD_after_ignition_off.lua | 88 +++++++++++++++ 4 files changed, 363 insertions(+) create mode 100644 test_scripts/Defects/5_0/2670_2_GetInteriorVD_after_ignition_off.lua create mode 100644 test_scripts/Defects/5_0/2670_3_GetInteriorVD_after_ignition_off.lua create mode 100644 test_scripts/Defects/5_0/2670_4_GetInteriorVD_after_ignition_off.lua create mode 100644 test_scripts/Defects/5_0/2670_GetInteriorVD_after_ignition_off.lua diff --git a/test_scripts/Defects/5_0/2670_2_GetInteriorVD_after_ignition_off.lua b/test_scripts/Defects/5_0/2670_2_GetInteriorVD_after_ignition_off.lua new file mode 100644 index 0000000000..338642a13a --- /dev/null +++ b/test_scripts/Defects/5_0/2670_2_GetInteriorVD_after_ignition_off.lua @@ -0,0 +1,100 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/2670 +-- +-- Steps to reproduce: +-- 1. Define module type module_1 and in default section in preloaded_pt.json +-- 2. Update groups in default with "RemoteControl" group +-- 3. Register RC app +-- 4. App requests successful GetInteriorVD with module_1 +-- 5. App requests GetInteriorVD with module_2 with DISALLOWED resultCode to mobile application +-- 6. Perform IGN_OFF and IGN_ON +-- 7. Register same RC app +-- 8. App requests successful GetInteriorVD with module_1 +-- 9. App requests GetInteriorVD with module_2 with DISALLOWED resultCode to mobile application +-- 10. Perform IGN_OFF and IGN_ON +-- 11. Register same RC app +-- 12. Request GetInteriorVD with allowed module_1 +-- 13. Request GetInteriorVD with not allowed module_2 +-- SDL must: +-- 1. process GetInteriorVD with allowed module_1 successful and resend request to HMI +-- 2. process GetInteriorVD with not allowed module_2 with resultCode DISALLOWED +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local actions = require("user_modules/sequences/actions") +local test = require("user_modules/dummy_connecttest") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local json = require("modules/json") +local utils = require('user_modules/utils') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local function ]] +local function updatePreloadedPT() + if not pCountOfRCApps then pCountOfRCApps = 2 end + local preloadedFile = commonPreconditions:GetPathToSDL() + .. commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + local preloadedTable = utils.jsonFileToTable(preloadedFile) + preloadedTable.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + preloadedTable.policy_table.functional_groupings["RemoteControl"].rpcs.OnRCStatus = { + hmi_levels = { "FULL", "BACKGROUND", "LIMITED", "NONE" } + } + preloadedTable.policy_table.app_policies.default.groups = {"Base-4", "RemoteControl"} + preloadedTable.policy_table.app_policies.default.moduleType = { "CLIMATE", "SEAT", "AUDIO", "LIGHT", "HMI_SETTINGS"} + utils.tableToJsonFile(preloadedTable, preloadedFile) +end + +function preconditions() + actions.preconditions() + updatePreloadedPT() +end + +local function ignitionOff() + actions.getHMIConnection():SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete") + :Do(function() + actions.getHMIConnection():SendNotification("BasicCommunication.OnExitAllApplications",{ reason = "IGNITION_OFF" }) + actions.getMobileSession():ExpectNotification("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) + end) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + :Do(function() + test.mobileSession[1] = nil + StopSDL() + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", preconditions) +runner.Step("Backup preloaded pt", commonPreconditions.BackupFile, { test, "sdl_preloaded_pt.json" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", actions.start) +runner.Step("RAI", actions.registerAppWOPTU) +runner.Step("Activate App", actions.activateApp) +runner.Step("GetInteriorVehicleData SEAT", commonRC.subscribeToModule, { "SEAT" }) +runner.Step("GetInteriorVehicleData RADIO", commonRC.rpcDenied, + { "RADIO", 1, "GetInteriorVehicleData", "DISALLOWED" }) + +-- runner.Title("Test") +runner.Step("ignitionOff", ignitionOff) +runner.Step("Start SDL, HMI, connect Mobile, start Session", actions.start) +runner.Step("RAI", actions.registerAppWOPTU) +runner.Step("Activate App", actions.activateApp) +runner.Step("GetInteriorVehicleData SEAT", commonRC.subscribeToModule, { "SEAT" }) +runner.Step("GetInteriorVehicleData RADIO", commonRC.rpcDenied, + { "RADIO", 1, "GetInteriorVehicleData", "DISALLOWED" }) + +runner.Step("ignitionOff", ignitionOff) +runner.Step("Start SDL, HMI, connect Mobile, start Session", actions.start) +runner.Step("RAI", actions.registerAppWOPTU) +runner.Step("Activate App", actions.activateApp) +runner.Step("GetInteriorVehicleData SEAT", commonRC.subscribeToModule, { "SEAT" }) +runner.Step("GetInteriorVehicleData RADIO", commonRC.rpcDenied, + { "RADIO", 1, "GetInteriorVehicleData", "DISALLOWED" }) + +runner.Title("Postconditions") +runner.Step("Restore preloaded pt", commonPreconditions.RestoreFile, { test, "sdl_preloaded_pt.json" }) +runner.Step("Stop SDL", actions.postconditions) diff --git a/test_scripts/Defects/5_0/2670_3_GetInteriorVD_after_ignition_off.lua b/test_scripts/Defects/5_0/2670_3_GetInteriorVD_after_ignition_off.lua new file mode 100644 index 0000000000..9050ad6491 --- /dev/null +++ b/test_scripts/Defects/5_0/2670_3_GetInteriorVD_after_ignition_off.lua @@ -0,0 +1,85 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/2670 +-- +-- Steps to reproduce: +-- 1. Empty array is defined in moduleType parameter in default section in preloaded_pt.json +-- 2. Update groups in default with "RemoteControl" group +-- 3. Register RC app +-- 4. App requests successful GetInteriorVD with module_1 +-- 5. App requests successful GetInteriorVD with module_2 +-- 6. Perform IGN_OFF and IGN_ON +-- 7. Register same RC app +-- 8. Request GetInteriorVD with allowed module_1 +-- 9. Request GetInteriorVD with allowed module_2 +-- SDL must: +-- 1. process GetInteriorVD with allowed module_1 successful and resend request to HMI +-- 2. process GetInteriorVD with allowed module_2 successful and resend request to HMI +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local actions = require("user_modules/sequences/actions") +local test = require("user_modules/dummy_connecttest") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local json = require("modules/json") +local utils = require('user_modules/utils') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local function ]] +local function updatePreloadedPT() + if not pCountOfRCApps then pCountOfRCApps = 2 end + local preloadedFile = commonPreconditions:GetPathToSDL() + .. commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + local preloadedTable = utils.jsonFileToTable(preloadedFile) + preloadedTable.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + preloadedTable.policy_table.functional_groupings["RemoteControl"].rpcs.OnRCStatus = { + hmi_levels = { "FULL", "BACKGROUND", "LIMITED", "NONE" } + } + preloadedTable.policy_table.app_policies.default.groups = {"Base-4", "RemoteControl"} + preloadedTable.policy_table.app_policies.default.moduleType = json.EMPTY_ARRAY + utils.tableToJsonFile(preloadedTable, preloadedFile) +end + +function preconditions() + actions.preconditions() + updatePreloadedPT() +end + +local function ignitionOff() + actions.getHMIConnection():SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete") + :Do(function() + actions.getHMIConnection():SendNotification("BasicCommunication.OnExitAllApplications",{ reason = "IGNITION_OFF" }) + actions.getMobileSession():ExpectNotification("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) + end) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + :Do(function() + test.mobileSession[1] = nil + StopSDL() + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", preconditions) +runner.Step("Backup preloaded pt", commonPreconditions.BackupFile, { test, "sdl_preloaded_pt.json" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", actions.start) +runner.Step("RAI", actions.registerAppWOPTU) +runner.Step("Activate App", actions.activateApp) +runner.Step("GetInteriorVehicleData SEAT", commonRC.subscribeToModule, { "SEAT" }) +runner.Step("GetInteriorVehicleData RADIO", commonRC.subscribeToModule,{ "RADIO" }) +-- runner.Title("Test") +runner.Step("ignitionOff", ignitionOff) +runner.Step("Start SDL, HMI, connect Mobile, start Session", actions.start) +runner.Step("RAI", actions.registerAppWOPTU) +runner.Step("Activate App", actions.activateApp) +runner.Step("GetInteriorVehicleData SEAT", commonRC.subscribeToModule, { "SEAT" }) +runner.Step("GetInteriorVehicleData RADIO", commonRC.subscribeToModule,{ "RADIO" }) + +runner.Title("Postconditions") +runner.Step("Restore preloaded pt", commonPreconditions.RestoreFile, { test, "sdl_preloaded_pt.json" }) +runner.Step("Stop SDL", actions.postconditions) diff --git a/test_scripts/Defects/5_0/2670_4_GetInteriorVD_after_ignition_off.lua b/test_scripts/Defects/5_0/2670_4_GetInteriorVD_after_ignition_off.lua new file mode 100644 index 0000000000..5a5bc51e28 --- /dev/null +++ b/test_scripts/Defects/5_0/2670_4_GetInteriorVD_after_ignition_off.lua @@ -0,0 +1,90 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/2670 +-- +-- Steps to reproduce: +-- 1. default section in preloaded_pt.json is defined without moduleType parameter +-- 2. Update groups in default with "RemoteControl" group +-- 3. Register RC app +-- 4. App requests GetInteriorVD with module_1 with DISALLOWED resultCode in response from SDL +-- 5. AApp requests GetInteriorVD with module_2 with DISALLOWED resultCode in response from SDL +-- 6. Perform IGN_OFF and IGN_ON +-- 7. Register same RC app +-- 8. Request GetInteriorVD with allowed module_1 +-- 9. Request GetInteriorVD with allowed module_2 +-- SDL must: +-- 1. process GetInteriorVD with not allowed module_1 and respond with DISALLOWED resultCode to mobile app +-- 2. process GetInteriorVD with not allowed module_2 and respond with DISALLOWED resultCode to mobile app +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local actions = require("user_modules/sequences/actions") +local test = require("user_modules/dummy_connecttest") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local json = require("modules/json") +local utils = require('user_modules/utils') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local function ]] +local function updatePreloadedPT() + if not pCountOfRCApps then pCountOfRCApps = 2 end + local preloadedFile = commonPreconditions:GetPathToSDL() + .. commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + local preloadedTable = utils.jsonFileToTable(preloadedFile) + preloadedTable.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + preloadedTable.policy_table.functional_groupings["RemoteControl"].rpcs.OnRCStatus = { + hmi_levels = { "FULL", "BACKGROUND", "LIMITED", "NONE" } + } + preloadedTable.policy_table.app_policies.default.groups = {"Base-4", "RemoteControl"} + preloadedTable.policy_table.app_policies.default.moduleType = nil + utils.tableToJsonFile(preloadedTable, preloadedFile) +end + +function preconditions() + actions.preconditions() + updatePreloadedPT() +end + +local function ignitionOff() + actions.getHMIConnection():SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete") + :Do(function() + actions.getHMIConnection():SendNotification("BasicCommunication.OnExitAllApplications",{ reason = "IGNITION_OFF" }) + actions.getMobileSession():ExpectNotification("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) + end) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + :Do(function() + test.mobileSession[1] = nil + StopSDL() + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", preconditions) +runner.Step("Backup preloaded pt", commonPreconditions.BackupFile, { test, "sdl_preloaded_pt.json" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", actions.start) +runner.Step("RAI", actions.registerAppWOPTU) +runner.Step("Activate App", actions.activateApp) + +-- runner.Title("Test") +runner.Step("GetInteriorVehicleData SEAT", commonRC.rpcDenied, + { "SEAT", 1, "GetInteriorVehicleData", "DISALLOWED" }) +runner.Step("GetInteriorVehicleData RADIO", commonRC.rpcDenied, + { "RADIO", 1, "GetInteriorVehicleData", "DISALLOWED" }) +runner.Step("ignitionOff", ignitionOff) +runner.Step("Start SDL, HMI, connect Mobile, start Session", actions.start) +runner.Step("RAI", actions.registerApp) +runner.Step("Activate App", actions.activateApp) +runner.Step("GetInteriorVehicleData SEAT", commonRC.rpcDenied, + { "SEAT", 1, "GetInteriorVehicleData", "DISALLOWED" }) +runner.Step("GetInteriorVehicleData RADIO", commonRC.rpcDenied, + { "RADIO", 1, "GetInteriorVehicleData", "DISALLOWED" }) + +runner.Title("Postconditions") +runner.Step("Restore preloaded pt", commonPreconditions.RestoreFile, { test, "sdl_preloaded_pt.json" }) +runner.Step("Stop SDL", actions.postconditions) diff --git a/test_scripts/Defects/5_0/2670_GetInteriorVD_after_ignition_off.lua b/test_scripts/Defects/5_0/2670_GetInteriorVD_after_ignition_off.lua new file mode 100644 index 0000000000..84ac64dc94 --- /dev/null +++ b/test_scripts/Defects/5_0/2670_GetInteriorVD_after_ignition_off.lua @@ -0,0 +1,88 @@ +--------------------------------------------------------------------------------------------------- +-- User story: https://github.com/smartdevicelink/sdl_core/issues/2670 +-- +-- Steps to reproduce: +-- 1. Define module type module_1 and in default section in preloaded_pt.json +-- 2. Update groups in default with "RemoteControl" group +-- 3. Register RC app +-- 4. App requests successful GetInteriorVD with module_1 +-- 5. App requests GetInteriorVD with module_2 with DISALLOWED resultCode to mobile application +-- 6. Perform IGN_OFF and IGN_ON +-- 7. Register same RC app +-- 8. Request GetInteriorVD with allowed module_1 +-- 9. Request GetInteriorVD with not allowed module_2 +-- SDL must: +-- 1. process GetInteriorVD with allowed module_1 successful and resend request to HMI +-- 2. process GetInteriorVD with not allowed module_2 with resultCode DISALLOWED +--------------------------------------------------------------------------------------------------- +--[[ Required Shared libraries ]] +local runner = require('user_modules/script_runner') +local commonRC = require('test_scripts/RC/commonRC') +local actions = require("user_modules/sequences/actions") +local test = require("user_modules/dummy_connecttest") +local commonPreconditions = require('user_modules/shared_testcases/commonPreconditions') +local commonFunctions = require("user_modules/shared_testcases/commonFunctions") +local json = require("modules/json") +local utils = require('user_modules/utils') + +--[[ Test Configuration ]] +runner.testSettings.isSelfIncluded = false + +--[[ Local function ]] +local function updatePreloadedPT() + if not pCountOfRCApps then pCountOfRCApps = 2 end + local preloadedFile = commonPreconditions:GetPathToSDL() + .. commonFunctions:read_parameter_from_smart_device_link_ini("PreloadedPT") + local preloadedTable = utils.jsonFileToTable(preloadedFile) + preloadedTable.policy_table.functional_groupings["DataConsent-2"].rpcs = json.null + preloadedTable.policy_table.functional_groupings["RemoteControl"].rpcs.OnRCStatus = { + hmi_levels = { "FULL", "BACKGROUND", "LIMITED", "NONE" } + } + preloadedTable.policy_table.app_policies.default.groups = {"Base-4", "RemoteControl"} + preloadedTable.policy_table.app_policies.default.moduleType = { "CLIMATE", "SEAT", "AUDIO", "LIGHT", "HMI_SETTINGS"} + utils.tableToJsonFile(preloadedTable, preloadedFile) +end + +function preconditions() + actions.preconditions() + updatePreloadedPT() +end + +local function ignitionOff() + actions.getHMIConnection():SendNotification("BasicCommunication.OnExitAllApplications", { reason = "SUSPEND" }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLPersistenceComplete") + :Do(function() + actions.getHMIConnection():SendNotification("BasicCommunication.OnExitAllApplications",{ reason = "IGNITION_OFF" }) + actions.getMobileSession():ExpectNotification("OnAppInterfaceUnregistered", { reason = "IGNITION_OFF" }) + end) + EXPECT_HMINOTIFICATION("BasicCommunication.OnAppUnregistered", { unexpectedDisconnect = false }) + EXPECT_HMINOTIFICATION("BasicCommunication.OnSDLClose") + :Do(function() + test.mobileSession[1] = nil + StopSDL() + end) +end + +--[[ Scenario ]] +runner.Title("Preconditions") +runner.Step("Clean environment", preconditions) +runner.Step("Backup preloaded pt", commonPreconditions.BackupFile, { test, "sdl_preloaded_pt.json" }) +runner.Step("Start SDL, HMI, connect Mobile, start Session", actions.start) +runner.Step("RAI", actions.registerAppWOPTU) +runner.Step("Activate App", actions.activateApp) +runner.Step("GetInteriorVehicleData SEAT", commonRC.subscribeToModule, { "SEAT" }) +runner.Step("GetInteriorVehicleData RADIO", commonRC.rpcDenied, + { "RADIO", 1, "GetInteriorVehicleData", "DISALLOWED" }) + +-- runner.Title("Test") +runner.Step("ignitionOff", ignitionOff) +runner.Step("Start SDL, HMI, connect Mobile, start Session", actions.start) +runner.Step("RAI", actions.registerAppWOPTU) +runner.Step("Activate App", actions.activateApp) +runner.Step("GetInteriorVehicleData SEAT", commonRC.subscribeToModule, { "SEAT" }) +runner.Step("GetInteriorVehicleData RADIO", commonRC.rpcDenied, + { "RADIO", 1, "GetInteriorVehicleData", "DISALLOWED" }) + +runner.Title("Postconditions") +runner.Step("Restore preloaded pt", commonPreconditions.RestoreFile, { test, "sdl_preloaded_pt.json" }) +runner.Step("Stop SDL", actions.postconditions) From 96d3c65f7a71aa37d5226d53936c6ac96a453d5c Mon Sep 17 00:00:00 2001 From: JackLivio Date: Mon, 15 Oct 2018 13:23:28 -0400 Subject: [PATCH 678/681] Make HD radio enable true --- test_scripts/RC/commonRC.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_scripts/RC/commonRC.lua b/test_scripts/RC/commonRC.lua index 0a9b246a34..66d06f6027 100644 --- a/test_scripts/RC/commonRC.lua +++ b/test_scripts/RC/commonRC.lua @@ -385,7 +385,7 @@ function commonRC.getAnotherModuleControlData(module_type) signalChangeThreshold = 20, radioEnable = true, state = "ACQUIRING", - hdRadioEnable = false, + hdRadioEnable = true, sisData = { stationShortName = "Name2", stationIDNumber = { From 6793de7e3585014582ef247adaf14ab262e7de73 Mon Sep 17 00:00:00 2001 From: Dmitriy Boltovskiy Date: Mon, 15 Oct 2018 16:04:54 -0400 Subject: [PATCH 679/681] Add test set for SSL Handshake test scripts --- test_sets/SDL5_0/ssl_handshake.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 test_sets/SDL5_0/ssl_handshake.txt diff --git a/test_sets/SDL5_0/ssl_handshake.txt b/test_sets/SDL5_0/ssl_handshake.txt new file mode 100644 index 0000000000..8af3bc2be5 --- /dev/null +++ b/test_sets/SDL5_0/ssl_handshake.txt @@ -0,0 +1,18 @@ +./test_scripts/Security/SSLHandshakeFlow/001_Navi_Predefined_cert_valid_SUCCESS.lua +./test_scripts/Security/SSLHandshakeFlow/002_Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua +./test_scripts/Security/SSLHandshakeFlow/003_Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua +./test_scripts/Security/SSLHandshakeFlow/004_Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua +./test_scripts/Security/SSLHandshakeFlow/005_Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua +./test_scripts/Security/SSLHandshakeFlow/006_Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua +./test_scripts/Security/SSLHandshakeFlow/007_Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua +./test_scripts/Security/SSLHandshakeFlow/008_Non-Navi_Predefined_cert_valid_SUCCESS.lua +./test_scripts/Security/SSLHandshakeFlow/009_Non-Navi_Predefined_cert_expired_PTU_cert_valid_SUCCESS.lua +./test_scripts/Security/SSLHandshakeFlow/010_Non-Navi_Predefined_cert_expired_PTU_cert_missing_NACK.lua +./test_scripts/Security/SSLHandshakeFlow/011_Non-Navi_Predefined_cert_expired_PTU_cert_expired_NACK.lua +./test_scripts/Security/SSLHandshakeFlow/012_Non-Navi_Predefined_cert_missing_PTU_cert_valid_SUCCESS.lua +./test_scripts/Security/SSLHandshakeFlow/013_Non-Navi_Predefined_cert_missing_PTU_cert_missing_NACK.lua +./test_scripts/Security/SSLHandshakeFlow/014_Non-Navi_Predefined_cert_missing_PTU_cert_expired_NACK.lua +./test_scripts/Security/SSLHandshakeFlow/015_Navi-Predefined_cert_valid_PTU_is_not_started.lua +./test_scripts/Security/SSLHandshakeFlow/016_Non-Navi-Predefined_cert_valid_PTU_is_not_started.lua +./test_scripts/Security/SSLHandshakeFlow/017_App_Name_no_impact_SUCCESS.lua +;./test_scripts/Security/SSLHandshakeFlow/018_V5_happy_path_SUCCESS.lua From 3c35190213fefe186275b6a0d3f2942fbe397bea Mon Sep 17 00:00:00 2001 From: theresalech Date: Fri, 19 Oct 2018 10:29:10 -0400 Subject: [PATCH 680/681] Update third_party.md Fix Lua link --- third_party.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party.md b/third_party.md index 44bdcc8b01..730f81825f 100644 --- a/third_party.md +++ b/third_party.md @@ -30,4 +30,4 @@ The third party software included and used by this project is: * Licensed under MIT License * The library is included in the build folder -* See [https://github.com/facebook/react](https://github.com/facebook/react) \ No newline at end of file +* See [https://www.lua.org/ftp](https://www.lua.org/ftp) From 940135390f347f48a56c20ef17c7a1f0fc93c093 Mon Sep 17 00:00:00 2001 From: Shobhit Adlakha Date: Fri, 19 Oct 2018 11:21:26 -0400 Subject: [PATCH 681/681] Revert "Scripts to check issue 1905" --- ...ated_during_active_embedded_navigation.lua | 55 ------------------- 1 file changed, 55 deletions(-) delete mode 100644 test_scripts/Defects/5_0/1905_Navigation_app_must_be_activated_during_active_embedded_navigation.lua diff --git a/test_scripts/Defects/5_0/1905_Navigation_app_must_be_activated_during_active_embedded_navigation.lua b/test_scripts/Defects/5_0/1905_Navigation_app_must_be_activated_during_active_embedded_navigation.lua deleted file mode 100644 index e759e8a9b0..0000000000 --- a/test_scripts/Defects/5_0/1905_Navigation_app_must_be_activated_during_active_embedded_navigation.lua +++ /dev/null @@ -1,55 +0,0 @@ --- User story: https://github.com/SmartDeviceLink/sdl_core/issues/1905 --- --- Precondition: --- 1) SDL and HMI are started. --- 2) Navigation app is registered. --- 3) Navigation app in BACKGROUND and NOT_AUDIBLE due to active embedded navigation . --- Description: --- Navigation app must be activated during active embedded navigation --- Steps to reproduce: --- 1) User activates this navigation app and SDL receives from HMI: --- a) OnEventChanged(EMBEDDED_NAVI, isActive=false) --- b) SDL.ActivateApp () --- Expected result: --- SDL must respond SDL.ActivateApp (SUCCESS) to HMI send OnHMIStatus (FULL, AUDIBLE) to mobile app. --- a. Navigation app activation is the trigger for HMI to switch off embedded navigation --- b. HMI switches off embedded navigation and sends OnEventChanged (EMBEDDED_NAVI, isActive=false) to SDL --- Actual result: --- SDL does not set required HMILevel and audioStreamingState. ---------------------------------------------------------------------------------------------------- ---[[ Required Shared libraries ]] -local runner = require('user_modules/script_runner') -local common = require('test_scripts/Defects/commonDefects') - ---[[ Local Variables ]] -config.application1.registerAppInterfaceParams.appHMIType = { "NAVIGATION" } -config.application1.registerAppInterfaceParams.isMediaApplication = false - ---[[ Local Variables ]] -local function onEventChange(self) - self.hmiConnection:SendNotification("BasicCommunication.OnEventChanged", {eventName = "EMBEDDED_NAVI", isActive = true}) - self.mobileSession1:ExpectNotification("OnHMIStatus", - { hmiLevel = "BACKGROUND", audioStreamingState = "NOT_AUDIBLE", systemContext = "MAIN" }, - { hmiLevel = "FULL", audioStreamingState = "AUDIBLE", systemContext = "MAIN" }) - :Times(2) - :Do(function(exp) - if exp.occurences == 1 then - self.hmiConnection:SendNotification("BasicCommunication.OnEventChanged", {eventName = "EMBEDDED_NAVI", isActive = false}) - local requestId = self.hmiConnection:SendRequest("SDL.ActivateApp", { appID = common.getHMIAppId(1) }) - EXPECT_HMIRESPONSE(requestId) - end - end) -end - ---[[ Scenario ]] -runner.Title("Preconditions") -runner.Step("Clean environment", common.preconditions) -runner.Step("Start SDL, HMI, connect Mobile, start Session", common.start) -runner.Step("RAI", common.rai_n) -runner.Step("Activate App", common.activate_app) - -runner.Title("Test") -runner.Step("onEventChange EMBEDDED_NAVI true", onEventChange) - -runner.Title("Postconditions") -runner.Step("Stop SDL", common.postconditions)

    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